Exemple #1
0
        internal void AddThread(YamsterThread thread, YamsterModelEventCollector eventCollector)
        {
            int index = this.threadsInternal.BinarySearch(thread,
                                                          Comparer <YamsterThread> .Create((x, y) => Math.Sign(x.ThreadId - y.ThreadId)));
            int deletedIndex = this.deletedThreadsInternal.BinarySearch(thread,
                                                                        Comparer <YamsterThread> .Create((x, y) => Math.Sign(x.ThreadId - y.ThreadId)));

            if (index >= 0 || deletedIndex >= 0)
            {
                throw new InvalidOperationException("Program Bug: The message was already added to this thread");
            }

            if (!thread.AllMessagesDeleted)
            {
                this.threadsInternal.Insert(~index, thread);

                if (thread.Read)
                {
                    this.NotifyThreadReadChanged(newReadValue: true, eventCollector: eventCollector);
                }
            }
            else
            {
                this.deletedThreadsInternal.Insert(~deletedIndex, thread);
            }
        }
Exemple #2
0
        internal void RemoveThread(YamsterThread thread, YamsterModelEventCollector eventCollector)
        {
            int index = this.threadsInternal.BinarySearch(thread,
                                                          Comparer <YamsterThread> .Create((x, y) => Math.Sign(x.ThreadId - y.ThreadId)));
            int deletedIndex = this.deletedThreadsInternal.BinarySearch(thread,
                                                                        Comparer <YamsterThread> .Create((x, y) => Math.Sign(x.ThreadId - y.ThreadId)));

            if (index < 0 && deletedIndex < 0)
            {
                Debug.Assert(false, "RemoveThread() called on thread that doesn't belong to this group");
                return;
            }

            if (index >= 0)
            {
                this.threadsInternal.RemoveAt(index);

                if (thread.Read)
                {
                    this.NotifyThreadReadChanged(newReadValue: false, eventCollector: eventCollector);
                }
            }
            else
            {
                this.deletedThreadsInternal.RemoveAt(deletedIndex);
            }
        }
Exemple #3
0
        internal void FixupUnresolvedObjectsForThread(YamsterThread thread, YamsterMessage latestMessage,
                                                      YamsterModelEventCollector eventCollector)
        {
            Debug.Assert(latestMessage.Thread == thread);

            DbThreadState dbThreadState;

            if (unresolvedThreadStatesById.TryGetValue(thread.ThreadId, out dbThreadState))
            {
                unresolvedThreadStatesById.Remove(thread.ThreadId);
                thread.SetDbThreadState(dbThreadState, eventCollector);
            }

            // Is this thread part of a conversation?
            long conversationId = latestMessage.DbMessage.ConversationId;

            if (conversationId != 0)
            {
                // Register the thread as the owner of this conversation
                this.threadsByConversationId[conversationId] = thread;

                // Is there an unresolved conversation object?
                DbConversation unresolvedConversation;
                if (this.unresolvedConversationsById.TryGetValue(conversationId, out unresolvedConversation))
                {
                    // Yes, so apply it now
                    this.unresolvedConversationsById.Remove(conversationId);
                    thread.UpdateConversation(unresolvedConversation, eventCollector);
                }
            }
        }
 internal FreshenThreadRequest(YamsterThread thread, MessagePuller messagePuller)
 {
     this.Thread        = thread;
     this.MessagePuller = messagePuller;
     this.State         = FreshenThreadState.Queued;
     this.Error         = null;
 }
Exemple #5
0
        void ProcessDbMessage(DbMessage record)
        {
            // Does the message exist yet?
            var message = this.GetMessageById(record.MessageId, nullIfMissing: true);

            bool messageIsNew = message == null;

            var eventCollector = new YamsterModelEventCollector();

            if (messageIsNew)
            {
                message = new YamsterMessage(record.MessageId, this);
                this.messagesById.Add(record.MessageId, message);
                eventCollector.NotifyAfterAdd(message);
                message.SetDbMessage(record, eventCollector);

                // For now we assume that messages cannot move between threads
                var           threadId = message.ThreadId;
                YamsterThread thread   = GetThreadById(threadId, nullIfMissing: true);
                if (thread == null)
                {
                    thread = new YamsterThread(threadId, message.Group, this);
                    threadsById.Add(threadId, thread);
                    eventCollector.NotifyAfterAdd(thread);
                    message.Group.AddThread(thread, eventCollector);

                    thread.AddMessage(message, eventCollector);

                    FixupUnresolvedObjectsForThread(thread, message, eventCollector);
                }
                else
                {
                    thread.AddMessage(message, eventCollector);
                }
            }
            else
            {
                message.SetDbMessage(record, eventCollector);
            }

            // Was there an unresolved message that we can process now?
            DbMessageState unresolvedMessageState;

            if (this.unresolvedMessageStatesById.TryGetValue(record.MessageId, out unresolvedMessageState))
            {
                this.unresolvedMessageStatesById.Remove(record.MessageId);
                ProcessDbMessageState(unresolvedMessageState, eventCollector);
            }

            if (messageIsNew)
            {
                CheckForListenedMessage(message, eventCollector);
            }

            eventCollector.FireEvents();
        }
Exemple #6
0
        /// <summary>
        /// FreshenThread() asks the MessagePuller to refresh the specified thread as soon
        /// as possible, ignoring its normal algorithm priorities.
        /// </summary>
        /// <remarks>
        /// Since this operation may require multiple REST service calls and is subject to
        /// Yammer rate limits, it may still take a while to process.  The returned
        /// FreshenThreadRequest object can be used to track the progress.  Only one
        /// FreshenThread() request can be active at a time; any previous requests are
        /// canceled by a new call to FreshenThread().  Note that no processing will occur
        /// unless MessagePuller.Enabled=true and MessagePuller.Process() is being called
        /// at regular intervals.
        /// </remarks>
        public FreshenThreadRequest FreshenThread(YamsterThread thread)
        {
            FreshenThreadRequest interruptedRequest = freshenThreadRequest;

            freshenThreadRequest = new FreshenThreadRequest(thread, this);
            if (interruptedRequest != null)
            {
                interruptedRequest.SetError(new Exception("The operation was interrupted by a more recent request"));
            }
            return(freshenThreadRequest);
        }
Exemple #7
0
        void UpdateViewWithThread(YamsterThread thread)
        {
            bool shouldBeInView = false;

            if (CompiledFunc != null)
            {
                var executionContext = new YqlExecutionContext(this.appContext);
                executionContext.Thread = thread;
                shouldBeInView          = CompiledFunc(executionContext);
            }

            ViewedThread viewedThread = null;
            bool         isInView     = viewedThreadsById.TryGetValue(thread.ThreadId, out viewedThread);

            bool statisticsChanged = false;

            if (isInView)
            {
                if (!shouldBeInView)
                {
                    this.RemoveViewedThread(viewedThread);
                    NotifyViewChanged(YamsterViewChangeType.ModelLeaveView, thread);

                    // TotalItemCount changed
                    statisticsChanged = true;
                }
                else
                {
                    if (thread.Read != viewedThread.Read)
                    {
                        this.readThreadCount += thread.Read ? +1 : -1;
                        viewedThread.Read     = thread.Read;
                        statisticsChanged     = true;
                    }
                }
            }
            else
            {
                if (shouldBeInView)
                {
                    AddViewedThread(new ViewedThread(thread));
                    NotifyViewChanged(YamsterViewChangeType.ModelEnterView, thread);

                    // TotalItemCount changed
                    statisticsChanged = true;
                }
            }

            if (statisticsChanged)
            {
                NotifyViewChanged(YamsterViewChangeType.StatisticsChanged, null);
            }
        }
Exemple #8
0
        public YamsterThread GetThreadById(long threadId, bool nullIfMissing = false)
        {
            YamsterThread thread = null;

            if (!this.threadsById.TryGetValue(threadId, out thread))
            {
                if (!nullIfMissing)
                {
                    throw new KeyNotFoundException("The thread ID " + threadId + " was not found");
                }
            }
            return(thread);
        }
Exemple #9
0
 public YamsterThreadChangedEventArgs(YamsterThread thread, YamsterModelChangeType changeType)
     : base(changeType)
 {
     this.Thread = thread;
 }
Exemple #10
0
 public ViewedThread(YamsterThread thread)
 {
     this.Thread = thread;
     this.Read   = thread.Read;
 }
Exemple #11
0
 public static YamsterNewMessage CreateReply(YamsterThread threadBeingRepliedTo)
 {
     return(CreateReply(threadBeingRepliedTo.ThreadStarterMessage));
 }
Exemple #12
0
 internal void NotifyAddedToThread(YamsterThread thread)
 {
     this.thread = thread;
 }