Exemplo n.º 1
0
        public void InsertByTime(VisualBubble b)
        {
            if (Bubbles.Count > BubblesCapSize)
            {
                Bubbles.RemoveAt(0);
            }

            for (int i = Bubbles.Count - 1; i >= 0; i--)
            {
                var nBubble = Bubbles[i];
                if (nBubble.Time <= b.Time)
                {
                    // adding it to the end, we can do a simple contract
                    if (i == Bubbles.Count - 1)
                    {
                        Bubbles.Add(b);
                        if (b.Direction == Bubble.BubbleDirection.Incoming)
                        {
                            BubbleGroupSettingsManager.SetUnread(this, true);
                        }
                    }
                    // inserting, do a full contract
                    else
                    {
                        Bubbles.Insert(i + 1, b);
                    }
                    break;
                }

                // could not find a valid place to insert, then skip insertion.
                if (i == 0)
                {
                    return;
                }
            }

            if (Unified == null)
            {
                _bubblesInsertedCount++;
                if (_bubblesInsertedCount % 100 == 0)
                {
                    if (BubbleGroupSync.SupportsSyncAndIsRunning(this))
                    {
                        Action doSync = async() =>
                        {
                            using (Platform.AquireWakeLock("DisaSync"))
                            {
                                await Utils.Delay(1000);

                                await BubbleGroupSync.Sync(this, true);
                            }
                        };
                        doSync();
                    }
                }
            }

            RaiseBubbleInserted(b);
            RaiseUnifiedBubblesUpdatedIfUnified(b);
        }
Exemplo n.º 2
0
        protected internal void OnBubbleUpdated(VisualBubble bubble, BubbleGroup group)
        {
            if (Bubbles.Count >= BubblesCapSize)
            {
                Bubbles.RemoveAt(0);
            }

            var addedToEnd = false;

            var unreadIndicatorGuid = BubbleGroupSettingsManager.GetUnreadIndicatorGuid(this);

            for (int i = Bubbles.Count - 1; i >= 0; i--)
            {
                var nBubble = Bubbles[i];

                var unreadIndicatorIndex = -1;
                if (unreadIndicatorGuid != null && unreadIndicatorGuid == nBubble.ID)
                {
                    unreadIndicatorIndex = i;
                }

                if (nBubble.Time <= bubble.Time)
                {
                    // adding it to the end, we can do a simple contract
                    if (i == Bubbles.Count - 1)
                    {
                        addedToEnd = true;
                        Bubbles.Add(bubble);
                        if (bubble.Direction == Bubble.BubbleDirection.Incoming)
                        {
                            BubbleGroupSettingsManager.SetUnread(this, true);
                        }
                    }
                    // inserting, do a full contract
                    else
                    {
                        Bubbles.Insert(i + 1, bubble);
                    }
                    if (i >= unreadIndicatorIndex && bubble.Direction == Bubble.BubbleDirection.Outgoing)
                    {
                        BubbleGroupSettingsManager.SetUnreadIndicatorGuid(this, bubble.ID, false);
                    }
                    break;
                }

                // could not find a valid place to insert, then skip insertion.
                if (i == 0)
                {
                    return;
                }
            }

            if (SendingGroup != group && addedToEnd)
            {
                SendingGroup = group;
                BubbleGroupEvents.RaiseSendingServiceChange(this);
            }

            RaiseBubbleInserted(bubble);
        }
Exemplo n.º 3
0
        internal static UnifiedBubbleGroup CreateUnifiedInternal(List <BubbleGroup> groups, BubbleGroup primaryGroup, string id = null)
        {
            var service = ServiceManager.GetUnified();

            if (service == null)
            {
                return(null);
            }

            var newBubble = new NewBubble(Time.GetNowUnixTimestamp(), Bubble.BubbleDirection.Incoming,
                                          Guid.NewGuid() + "@unified", null, false, service);
            var unified = new UnifiedBubbleGroup(groups, primaryGroup, newBubble, id);

            if (id == null)
            {
                var unread = groups.FirstOrDefault(BubbleGroupSettingsManager.GetUnread) != null;
                BubbleGroupSettingsManager.SetUnread(unified, unread);
            }

            foreach (var group in groups)
            {
                @group.RegisterUnified(unified);
            }

            var associatedPartiallyLoadedGroups = groups.Where(x => x.PartiallyLoaded).ToList();

            if (associatedPartiallyLoadedGroups.Any())
            {
                VisualBubble latest = null;
                foreach (var innerGroup in unified.Groups)
                {
                    var current = innerGroup.Bubbles.Last();
                    if (latest == null || current.Time > latest.Time)
                    {
                        latest = current;
                    }
                }
                if (latest != null)
                {
                    unified.Bubbles.Clear();
                    unified.Bubbles.Add(latest);
                }
                return(unified);
            }

            Populate(unified);

            return(unified);
        }
Exemplo n.º 4
0
        private static void SetUnread(BubbleGroup group, bool unread, bool updateUi = true, bool skipSendReadBubble = false, bool onlySetIfServiceRunning = true)
        {
            var unifiedGroup = @group as UnifiedBubbleGroup;

            if (unifiedGroup != null)
            {
                foreach (var innerGroup in unifiedGroup.Groups)
                {
                    SetUnread(innerGroup, false, skipSendReadBubble);
                }
            }

            Action @do = () =>
            {
                var updatedSomething = BubbleGroupSettingsManager.GetUnread(@group);
                BubbleGroupSettingsManager.SetUnread(@group, unread);

                if (unifiedGroup == null)
                {
                    if (!skipSendReadBubble)
                    {
                        if (@group.Service.Information.DoesSupport(typeof(ReadBubble)) && ServiceManager.IsRunning(@group.Service))
                        {
                            BubbleManager.Send(new ReadBubble(Time.GetNowUnixTimestamp(), Bubble.BubbleDirection.Outgoing,
                                                              @group.Service, @group.Address, null, Time.GetNowUnixTimestamp(), @group.IsParty, updatedSomething));
                        }
                    }
                }

                if (updateUi)
                {
                    BubbleGroupEvents.RaiseRefreshed(@group);
                }
            };

            if (onlySetIfServiceRunning && ServiceManager.IsRunning(@group.Service))
            {
                @do();
            }
            else if (!onlySetIfServiceRunning)
            {
                @do();
            }
        }
Exemplo n.º 5
0
        private static void SetUnread(BubbleGroup group, bool unread, bool updateUi = true, bool skipSendReadBubble = false, bool onlySetIfServiceRunning = true)
        {
            var unifiedGroup = @group as UnifiedBubbleGroup;

            if (unifiedGroup != null)
            {
                foreach (var innerGroup in unifiedGroup.Groups)
                {
                    SetUnread(innerGroup, unread, false, skipSendReadBubble, onlySetIfServiceRunning);
                }
            }

            var currentlyUnread = BubbleGroupSettingsManager.GetUnread(@group);

            if ((onlySetIfServiceRunning && ServiceManager.IsRunning(@group.Service)) || !onlySetIfServiceRunning)
            {
                BubbleGroupSettingsManager.SetUnread(@group, unread);
                if (unifiedGroup == null)
                {
                    if (!skipSendReadBubble)
                    {
                        if (@group.Service.Information.DoesSupport(typeof(ReadBubble)) && ServiceManager.IsRunning(@group.Service))
                        {
                            var readBubble = new ReadBubble(Time.GetNowUnixTimestamp(), Bubble.BubbleDirection.Outgoing,
                                                            @group.Service, @group.Address, null, Time.GetNowUnixTimestamp(), @group.IsParty, currentlyUnread);
                            if (@group.IsExtendedParty)
                            {
                                readBubble.ExtendedParty = true;
                            }
                            BubbleManager.Send(readBubble);
                        }
                    }
                }
                if (updateUi)
                {
                    BubbleGroupEvents.RaiseRefreshed(@group);
                }
            }
            else
            {
                BubbleGroupSettingsManager.SetUnreadOffline(@group, unread);
            }
        }
Exemplo n.º 6
0
        public void InsertByTime(VisualBubble b)
        {
            if (Bubbles.Count >= BubblesCapSize)
            {
                Bubbles.RemoveAt(0);
            }

            if (!(this is ComposeBubbleGroup))
            {
                var unreadIndicatorGuid = BubbleGroupSettingsManager.GetUnreadIndicatorGuid(this);
                for (int i = Bubbles.Count - 1; i >= 0; i--)
                {
                    var nBubble = Bubbles[i];

                    var unreadIndicatorIndex = -1;
                    if (unreadIndicatorGuid != null && unreadIndicatorGuid == nBubble.ID)
                    {
                        unreadIndicatorIndex = i;
                    }

                    // IMPORTANT: Our Time field is specified in seconds, however scenarios are appearing
                    //            (e.g., bots) where messages are sent in on the same second but still require
                    //            proper ordering. In this case, Services may set a flag specifying a fallback
                    //            to the ID assigned by the Service (e.g. Telegram).
                    if ((nBubble.Time == b.Time) &&
                        (nBubble.IsServiceIdSequence && b.IsServiceIdSequence))
                    {
                        if (string.Compare(
                                strA: nBubble.IdService,
                                strB: b.IdService,
                                ignoreCase: false,
                                culture: CultureInfo.InvariantCulture) < 0)
                        {
                            //
                            // Incoming bubble must be placed AFTER current bubble we are evaluating
                            //

                            if (i == Bubbles.Count - 1)
                            {
                                Bubbles.Add(b);
                                if (b.Direction == Bubble.BubbleDirection.Incoming)
                                {
                                    BubbleGroupSettingsManager.SetUnread(this, true);
                                }
                            }
                            else
                            {
                                Bubbles.Insert(i + 1, b);
                                if (i >= unreadIndicatorIndex && b.Direction == Bubble.BubbleDirection.Outgoing)
                                {
                                    BubbleGroupSettingsManager.SetUnreadIndicatorGuid(this, b.ID, false);
                                }
                            }
                        }
                        else
                        {
                            //
                            // Incoming bubble must be placed BEFORE current bubble we are evaluating
                            //

                            Bubbles.Insert(i, b);
                            if (i >= unreadIndicatorIndex && b.Direction == Bubble.BubbleDirection.Outgoing)
                            {
                                BubbleGroupSettingsManager.SetUnreadIndicatorGuid(this, b.ID, false);
                            }
                        }
                        break;
                    }
                    // OK, simpler scenario, incoming bubble must be placed AFTER current bubble we are evaluating
                    else if (nBubble.Time <= b.Time)
                    {
                        // adding it to the end, we can do a simple contract
                        if (i == Bubbles.Count - 1)
                        {
                            Bubbles.Add(b);
                            if (b.Direction == Bubble.BubbleDirection.Incoming)
                            {
                                BubbleGroupSettingsManager.SetUnread(this, true);
                            }
                        }
                        // inserting, do a full contract
                        else
                        {
                            Bubbles.Insert(i + 1, b);
                        }
                        if (i >= unreadIndicatorIndex && b.Direction == Bubble.BubbleDirection.Outgoing)
                        {
                            BubbleGroupSettingsManager.SetUnreadIndicatorGuid(this, b.ID, false);
                        }
                        break;
                    }

                    // could not find a valid place to insert, then skip insertion.
                    if (i == 0)
                    {
                        return;
                    }
                }
            }

            if (Unified == null)
            {
                _bubblesInsertedCount++;
                if (_bubblesInsertedCount % 100 == 0)
                {
                    if (BubbleGroupSync.SupportsSyncAndIsRunning(this))
                    {
                        Action doSync = async() =>
                        {
                            using (Platform.AquireWakeLock("DisaSync"))
                            {
                                await Utils.Delay(1000);

                                await BubbleGroupSync.Sync(this, true);
                            }
                        };
                        doSync();
                    }
                }
            }

            RaiseBubbleInserted(b);
            RaiseUnifiedBubblesUpdatedIfUnified(b);
        }