private async void OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { if (lvDialogs.ScrollingHost.ScrollableHeight - lvDialogs.ScrollingHost.VerticalOffset < 120) { if (ViewModel.IsFirstSliceLoaded) { ViewModel.UpdatingScrollMode = UpdatingScrollMode.KeepLastItemInView; } Arrow.Visibility = Visibility.Collapsed; } else { Arrow.Visibility = Visibility.Visible; } //if (ViewModel.Peer is TLInputPeerUser) //{ // lvDialogs.ScrollingHost.ViewChanged -= OnViewChanged; // return; //} var index0 = _panel.FirstVisibleIndex; var index1 = _panel.LastVisibleIndex; var show = false; var date = DateTime.Now; var message0 = default(TLMessageCommonBase); if (index0 > -1 && index1 > -1 /*&& (index0 != _lastIndex0 || index1 != _lastIndex1)*/) { //var container0 = lvDialogs.ContainerFromIndex(index0); //if (container0 != null) //{ // var item0 = lvDialogs.ItemFromContainer(container0); // if (item0 != null) // { // message0 = item0 as TLMessageCommonBase; // var date0 = BindConvert.Current.DateTime(message0.Date); // var service0 = message0 as TLMessageService; // if (service0 != null) // { // show = !(service0.Action is TLMessageActionDate); // } // else // { // show = true; // } // date = date0.Date; // } //} var messageIds = new TLVector <int>(); var dialog = ViewModel.Dialog; var channel = ViewModel.With as TLChannel; for (int i = index0; i <= index1; i++) { var container = lvDialogs.ContainerFromIndex(i); if (container != null) { var item = lvDialogs.ItemFromContainer(container); if (item != null && item is TLMessageCommonBase commonMessage && !commonMessage.IsOut && commonMessage.IsMentioned && commonMessage.IsMediaUnread && channel.IsMegaGroup) { commonMessage.IsMediaUnread = false; commonMessage.RaisePropertyChanged(() => commonMessage.IsMediaUnread); if (dialog != null) { dialog.UnreadMentionsCount = Math.Max(0, dialog.UnreadMentionsCount - 1); } messageIds.Add(commonMessage.Id); } } } if (messageIds.Count > 0) { ViewModel.ProtoService.ReadMessageContentsAsync(channel.ToInputChannel(), messageIds, null); } #region OLD //////Cache(); ////Cache(index0 + 1, index1); ////var itemsPerGroup = 0; ////var compositor = ElementCompositionPreview.GetElementVisual(lvDialogs); ////var props = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(lvDialogs.ScrollingHost); ////for (int i = index1; i >= index0; i--) ////{ //// var container = lvDialogs.ContainerFromIndex(i) as ListViewItem; //// if (container != null) //// { //// var item = container.Content as TLMessage; //// if (item != null && (item.IsFirst || i == index0) && (!item.IsOut || item.IsPost)) //// { //// var text = "0"; //// if (i == 0) //// { //// _wasFirst[i] = true; //// text = "Max(0, Reference.Y + Scrolling.Translation.Y)"; // Compression effect //// text = "0"; //// } //// else if (i == index0 && itemsPerGroup > 0) //// { //// _wasFirst[i] = true; //// text = "0"; //// } //// else if (i == index0) //// { //// _wasFirst[i] = true; //// text = "Min(0, Reference.Y + Scrolling.Translation.Y)"; //// } //// else //// { //// text = "Reference.Y + Scrolling.Translation.Y"; //// } //// var visual = ElementCompositionPreview.GetElementVisual(container); //// var offset = visual.Offset; //// if (offset.Y == 0) //// { //// var transform = container.TransformToVisual(lvDialogs); //// var point = transform.TransformPoint(new Point()); //// offset = new Vector3(0, (float)point.Y, 0); //// } //// var expression = visual.Compositor.CreateExpressionAnimation(text); //// expression.SetVector3Parameter("Reference", offset); //visual.Offset); //// expression.SetReferenceParameter("Scrolling", props); //// if (_inUse.ContainsKey(i) && _wasFirst.ContainsKey(i) && i != index0) //// { //// _wasFirst.Remove(i); //// var border = _inUse[i] as Border; //// var ellipse = ElementCompositionPreview.GetElementVisual(border.Child); //// ellipse.StopAnimation("Offset.Y"); //// ellipse.StartAnimation("Offset.Y", expression); //// } //// else if (!_inUse.ContainsKey(i)) //// { //// var ellipse = Push(i, item.FromId ?? 0, item); //// ellipse.StopAnimation("Offset.Y"); //// ellipse.StartAnimation("Offset.Y", expression); //// } //// itemsPerGroup = 0; //// } //// else if (item != null && item.IsOut) //// { //// } //// else //// { //// itemsPerGroup++; //// } //// } ////} #endregion //Update(); } if (show) { var paragraph = new Paragraph(); paragraph.Inlines.Add(new Run { Text = DateTimeToFormatConverter.ConvertDayGrouping(date) }); DateHeader.DataContext = message0; DateHeader.Visibility = Visibility.Visible; DateHeaderLabel.Blocks.Clear(); DateHeaderLabel.Blocks.Add(paragraph); } else { DateHeader.Visibility = Visibility.Collapsed; } if (e.IsIntermediate == false) { await Task.Delay(4000); DateHeader.Visibility = Visibility.Collapsed; } }
private void UpdateHeaderDate(bool intermediate) { var panel = Messages.ItemsPanelRoot as ItemsStackPanel; if (panel == null || panel.FirstVisibleIndex < 0) { return; } var top = 0d; var bottom = 0d; var knockout = SettingsService.Current.Diagnostics.BubbleKnockout; var start = knockout ? panel.FirstCacheIndex : panel.FirstVisibleIndex; var end = knockout ? panel.LastCacheIndex : panel.LastVisibleIndex; var minKnock = knockout; var minItem = true; var minDate = true; for (int i = start; i <= end; i++) { var container = Messages.ContainerFromIndex(i) as SelectorItem; if (container == null) { continue; } var message = Messages.ItemFromContainer(container) as MessageViewModel; if (message == null) { continue; } if (minKnock) { var negative = Messages.TransformToVisual(container); var relative = negative.TransformPoint(new Point()); top = relative.Y; bottom = relative.Y + Messages.ActualHeight; minKnock = false; } if (minItem && i >= panel.FirstVisibleIndex) { var transform = container.TransformToVisual(DateHeaderRelative); var point = transform.TransformPoint(new Point()); if (point.Y + container.ActualHeight >= 0) { minItem = false; if (message.SchedulingState is MessageSchedulingStateSendAtDate sendAtDate) { DateHeaderLabel.Text = string.Format(Strings.Resources.MessageScheduledOn, DateTimeToFormatConverter.ConvertDayGrouping(Utils.UnixTimestampToDateTime(sendAtDate.SendDate))); } else if (message.SchedulingState is MessageSchedulingStateSendWhenOnline) { DateHeaderLabel.Text = Strings.Resources.MessageScheduledUntilOnline; } else { DateHeaderLabel.Text = DateTimeToFormatConverter.ConvertDayGrouping(Utils.UnixTimestampToDateTime(message.Date)); } } } if (message.Content is MessageHeaderDate && minDate && i >= panel.FirstVisibleIndex) { var transform = container.TransformToVisual(DateHeaderRelative); var point = transform.TransformPoint(new Point()); var height = (float)DateHeader.ActualHeight; var offset = (float)point.Y + height; minDate = false; if (offset >= 0 && offset < height) { container.Opacity = 0; } else { container.Opacity = 1; } if (offset >= height && offset < height * 2) { _dateHeader.Offset = new Vector3(0, -height * 2 + offset, 0); } else { _dateHeader.Offset = new Vector3(); } } else { container.Opacity = 1; } if (knockout && container.ContentTemplateRoot is MessageBubble bubble) { bubble.UpdateKnockout(top / container.ActualHeight, bottom / container.ActualHeight); } top -= container.ActualHeight; bottom -= container.ActualHeight; } _dateHeaderTimer.Stop(); _dateHeaderTimer.Start(); VisualUtilities.SetIsVisible(DateHeaderPanel, true); }