private void LoadDialogs()
        {
            TLDialogBase currentUserDialog = null;

            _dialogs = IoC.Get <ICacheService>().GetDialogs();

            var clearedDialogs = new List <TLDialogBase>();

            foreach (var d in _dialogs)
            {
                if (Skip(d))
                {
                    var user = d.With as TLUser;
                    if (user != null && user.IsSelf)
                    {
                        currentUserDialog = d;
                    }

                    continue;
                }

                clearedDialogs.Add(d);
            }

            if (currentUserDialog != null)
            {
                clearedDialogs.Insert(0, currentUserDialog);
            }
            else
            {
                var currentUser = IoC.Get <ICacheService>().GetUser(new TLInt(IoC.Get <IStateService>().CurrentUserId));

                currentUserDialog = new TLDialog {
                    Peer = new TLPeerUser {
                        Id = currentUser.Id
                    }, With = currentUser
                };
                clearedDialogs.Insert(0, currentUserDialog);
            }

            _dialogsSource = clearedDialogs;

            DialogRow currentRow = null;
            var       rows       = new Group <DialogRow>("group");

            Rows = rows;
            var groups = new ObservableCollection <Group <DialogRow> > {
                rows
            };
            var secondSlice = new List <DialogRow>();

            if (clearedDialogs.Count > 0)
            {
                var maxFirstSliceCount  = 12;
                var maxSecondSliceCount = 24;
                for (var i = 0; i < clearedDialogs.Count; i++)
                {
                    if (i % 4 == 0)
                    {
                        currentRow = new DialogRow();
                        if (i < maxFirstSliceCount)
                        {
                            rows.Add(currentRow);
                        }
                        else if (i < maxSecondSliceCount)
                        {
                            secondSlice.Add(currentRow);
                        }
                    }

                    var d = new DialogItem {
                        Dialog = clearedDialogs[i], Row = currentRow
                    };

                    DialogsSource.Add(d);

                    currentRow.Add(d);
                }
            }

            var lastDialog = _dialogs.LastOrDefault(x => x is TLDialog) as TLDialog;

            UpdateDialogsAsync(lastDialog);

            Execute.BeginOnUIThread(() =>
            {
                SetListVerticalAlignment(Rows.Count);
                Dialogs.ItemsSource = groups;
                Dialogs.Visibility  = Visibility.Visible;
                Dialogs.Opacity     = 0.0;

                Execute.BeginOnUIThread(() =>
                {
                    Dialogs.Opacity        = 1.0;
                    var storyboard         = new Storyboard();
                    var translateAnimaiton = new DoubleAnimationUsingKeyFrames();
                    translateAnimaiton.KeyFrames.Add(new EasingDoubleKeyFrame {
                        KeyTime = TimeSpan.FromSeconds(0.0), Value = Dialogs.ActualHeight
                    });
                    translateAnimaiton.KeyFrames.Add(new EasingDoubleKeyFrame {
                        KeyTime = TimeSpan.FromSeconds(0.4), Value = 0.0, EasingFunction = new ExponentialEase {
                            Exponent = 5.0, EasingMode = EasingMode.EaseOut
                        }
                    });
                    Storyboard.SetTarget(translateAnimaiton, Dialogs);
                    Storyboard.SetTargetProperty(translateAnimaiton, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
                    storyboard.Children.Add(translateAnimaiton);

                    storyboard.Begin();

                    if (secondSlice.Count > 0)
                    {
                        storyboard.Completed += (o, e) =>
                        {
                            foreach (var item in secondSlice)
                            {
                                Rows.Add(item);
                            }
                            _secondSliceLoaded = true;

                            LoadNextSlice();
                        };
                    }
                    else
                    {
                        _secondSliceLoaded = true;

                        LoadNextSlice();
                    }
                });
            });
        }
        public void LoadNextSlice()
        {
            if (!string.IsNullOrEmpty(Text))
            {
                return;
            }
            if (!_secondSliceLoaded)
            {
                return;
            }

            var maxSliceCount = int.MaxValue;
            var index         = 0;

            var lastRow = Rows.LastOrDefault();

            if (lastRow != null)
            {
                var lastDialogItem = lastRow.GetLast();
                if (lastDialogItem != null)
                {
                    index = DialogsSource.IndexOf(lastDialogItem);
                }
            }

            var currentRow = lastRow;

            if (currentRow != null && currentRow.HasEmptyItem())
            {
                for (index = index + 1; index < DialogsSource.Count; index++)
                {
                    if (!currentRow.HasEmptyItem())
                    {
                        break;
                    }

                    var d = DialogsSource[index];

                    d.Row = currentRow;

                    currentRow.Add(d, true);
                }
            }
            else
            {
                index++;
            }

            _lastSlice = new List <DialogRow>();
            for (var count = 0; index < DialogsSource.Count && count < maxSliceCount; index++, count++)
            {
                if (currentRow == null || !currentRow.HasEmptyItem())
                {
                    currentRow = new DialogRow();
                    _lastSlice.Add(currentRow);
                }

                var d = DialogsSource[index];
                d.Row = currentRow;

                currentRow.Add(d);
            }

            if (_lastSlice.Count > 0 &&
                Rows.Count < 10)
            {
                for (var i = 0; i < 10 - Rows.Count; i++)
                {
                    var row = _lastSlice.FirstOrDefault();
                    if (row != null)
                    {
                        _lastSlice.RemoveAt(0);
                        Rows.Add(row);
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }
        private void Search(string text)
        {
            if (!string.Equals(text, Text, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            if (_lastRequest != null)
            {
                _lastRequest.Cancel();
            }

            var trimmedText = Text.Trim();

            if (string.IsNullOrEmpty(trimmedText))
            {
                Execute.BeginOnUIThread(() =>
                {
                    if (!string.Equals(trimmedText, Text.Trim(), StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }

                    Rows.Clear();
                    var firstSliceCount = 5;
                    var count           = 0;
                    var secondSlice     = new List <DialogRow>();
                    foreach (var item in _previousRows)
                    {
                        if (count < firstSliceCount)
                        {
                            Rows.Add(item);
                            count++;
                        }
                        else
                        {
                            secondSlice.Add(item);
                        }
                    }
                    if (secondSlice.Count > 0)
                    {
                        Execute.BeginOnUIThread(() =>
                        {
                            if (!string.Equals(trimmedText, Text.Trim(), StringComparison.OrdinalIgnoreCase))
                            {
                                return;
                            }

                            foreach (var item in secondSlice)
                            {
                                Rows.Add(item);
                            }
                        });
                    }
                });

                return;
            }

            var nextRequest = GetNextRequest(text, DialogsSource);

            nextRequest.ProcessAsync(results =>
            {
                if (nextRequest.IsCanceled)
                {
                    return;
                }
                if (!string.Equals(Text, nextRequest.Text, StringComparison.OrdinalIgnoreCase))
                {
                    return;
                }

                Rows.Clear();
                if (results.Count > 0)
                {
                    DialogRow currentRow = null;
                    var secondSlice      = new List <DialogItem>();
                    var maxCount         = 16;
                    for (var i = 0; i < results.Count; i++)
                    {
                        var d = results[i];

                        if (i < maxCount)
                        {
                            if (i % 4 == 0)
                            {
                                currentRow = new DialogRow();
                                Rows.Add(currentRow);
                            }

                            currentRow.Add(d);
                            d.Row = currentRow;
                        }
                        else
                        {
                            secondSlice.Add(d);
                        }
                    }

                    if (secondSlice.Count > 0)
                    {
                        Execute.BeginOnUIThread(() =>
                        {
                            if (nextRequest.IsCanceled)
                            {
                                return;
                            }
                            if (!string.Equals(Text, nextRequest.Text, StringComparison.OrdinalIgnoreCase))
                            {
                                return;
                            }

                            for (var i = 0; i < secondSlice.Count; i++)
                            {
                                if (i % 4 == 0)
                                {
                                    currentRow = new DialogRow();
                                    Rows.Add(currentRow);
                                }

                                currentRow.Add(secondSlice[i]);
                                secondSlice[i].Row = currentRow;
                            }
                        });
                    }
                }
            });

            _searchResultsCache[nextRequest.Text] = nextRequest;
            _lastRequest = nextRequest;
        }