From 1e8dfb73153c8c54536fd5d1c45525babdf4f645 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 4 Oct 2022 11:10:17 +0400 Subject: [PATCH] Partially support correct rounding near unwrapped media. --- .../admin_log/history_admin_log_inner.cpp | 4 +- .../SourceFiles/history/history_widget.cpp | 4 +- .../history/view/history_view_element.cpp | 65 ++++++++++++++++--- .../history/view/history_view_element.h | 29 +++++---- .../history/view/history_view_list_widget.cpp | 4 +- .../history/view/history_view_message.cpp | 17 ++++- .../history/view/history_view_message.h | 1 + .../history/view/media/history_view_gif.cpp | 4 ++ .../history/view/media/history_view_gif.h | 1 + .../history/view/media/history_view_media.h | 3 + .../view/media/history_view_media_unwrapped.h | 3 + .../support/support_autocomplete.cpp | 4 +- 12 files changed, 107 insertions(+), 32 deletions(-) diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index c27f3b7e9e..4fe72b8df2 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -889,8 +889,8 @@ void InnerWidget::itemsAdded(Direction direction, int addedCount) { const auto previous = _items[i].get(); view->setDisplayDate(view->dateTime().date() != previous->dateTime().date()); const auto attach = view->computeIsAttachToPrevious(previous); - view->setAttachToPrevious(attach); - previous->setAttachToNext(attach); + view->setAttachToPrevious(attach, previous); + previous->setAttachToNext(attach, view); } else { view->setDisplayDate(true); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 85f3f4d117..1e2d8ceff7 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -174,8 +174,8 @@ const char kOptionAutoScrollInactiveChat[] = namespace { -constexpr auto kMessagesPerPageFirst = 30; -constexpr auto kMessagesPerPage = 50; +constexpr auto kMessagesPerPageFirst = 10; +constexpr auto kMessagesPerPage = 10; constexpr auto kPreloadHeightsCount = 3; // when 3 screens to scroll left make a preload request constexpr auto kScrollToVoiceAfterScrolledMs = 1000; constexpr auto kSkipRepaintWhileScrollMs = 100; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index d56231e991..2ea9c8a7d2 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -368,8 +368,11 @@ Element::Element( ? QDateTime() : ItemDateTime(data)) , _text(st::msgMinWidth) -, _isScheduledUntilOnline(IsItemScheduledUntilOnline(data)) -, _flags(serviceFlag | Flag::NeedsResize) +, _flags(serviceFlag + | Flag::NeedsResize + | (IsItemScheduledUntilOnline(data) + ? Flag::ScheduledUntilOnline + : Flag())) , _context(delegate->elementContext()) { history()->owner().registerItemView(this); refreshMedia(replacing); @@ -546,6 +549,14 @@ bool Element::isAttachedToNext() const { return _flags & Flag::AttachedToNext; } +bool Element::isBubbleAttachedToPrevious() const { + return _flags & Flag::BubbleAttachedToPrevious; +} + +bool Element::isBubbleAttachedToNext() const { + return _flags & Flag::BubbleAttachedToNext; +} + int Element::skipBlockWidth() const { return st::msgDateSpace + infoWidth() - st::msgDateDelta.x(); } @@ -883,11 +894,12 @@ void Element::recountAttachToPreviousInBlocks() { return; } auto attachToPrevious = false; - if (const auto previous = previousDisplayedInBlocks()) { + const auto previous = previousDisplayedInBlocks(); + if (previous) { attachToPrevious = computeIsAttachToPrevious(previous); - previous->setAttachToNext(attachToPrevious); + previous->setAttachToNext(attachToPrevious, this); } - setAttachToPrevious(attachToPrevious); + setAttachToPrevious(attachToPrevious, previous); } void Element::recountDisplayDateInBlocks() { @@ -925,7 +937,8 @@ void Element::setDisplayDate(bool displayDate) { const auto item = data(); if (displayDate && !Has()) { AddComponents(DateBadge::Bit()); - Get()->init(ItemDateText(item, _isScheduledUntilOnline)); + Get()->init( + ItemDateText(item, (_flags & Flag::ScheduledUntilOnline))); setPendingResize(); } else if (!displayDate && Has()) { RemoveComponents(DateBadge::Bit()); @@ -933,22 +946,50 @@ void Element::setDisplayDate(bool displayDate) { } } -void Element::setAttachToNext(bool attachToNext) { +void Element::setAttachToNext(bool attachToNext, Element *next) { + Expects(next || !attachToNext); + + auto pending = false; if (attachToNext && !(_flags & Flag::AttachedToNext)) { _flags |= Flag::AttachedToNext; - setPendingResize(); + pending = true; } else if (!attachToNext && (_flags & Flag::AttachedToNext)) { _flags &= ~Flag::AttachedToNext; + pending = true; + } + const auto bubble = attachToNext && !next->unwrapped(); + if (bubble && !(_flags & Flag::BubbleAttachedToNext)) { + _flags |= Flag::BubbleAttachedToNext; + pending = true; + } else if (!bubble && (_flags & Flag::BubbleAttachedToNext)) { + _flags &= ~Flag::BubbleAttachedToNext; + pending = true; + } + if (pending) { setPendingResize(); } } -void Element::setAttachToPrevious(bool attachToPrevious) { +void Element::setAttachToPrevious(bool attachToPrevious, Element *previous) { + Expects(previous || !attachToPrevious); + + auto pending = false; if (attachToPrevious && !(_flags & Flag::AttachedToPrevious)) { _flags |= Flag::AttachedToPrevious; - setPendingResize(); + pending = true; } else if (!attachToPrevious && (_flags & Flag::AttachedToPrevious)) { _flags &= ~Flag::AttachedToPrevious; + pending = true; + } + const auto bubble = attachToPrevious && !previous->unwrapped(); + if (bubble && !(_flags & Flag::BubbleAttachedToPrevious)) { + _flags |= Flag::BubbleAttachedToPrevious; + pending = true; + } else if (!bubble && (_flags & Flag::BubbleAttachedToPrevious)) { + _flags &= ~Flag::BubbleAttachedToPrevious; + pending = true; + } + if (pending) { setPendingResize(); } } @@ -985,6 +1026,10 @@ bool Element::hasBubble() const { return false; } +bool Element::unwrapped() const { + return true; +} + bool Element::hasFastReply() const { return false; } diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index f66a5ffdb4..cdf1bf5956 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -240,14 +240,17 @@ class Element , public ClickHandlerHost , public base::has_weak_ptr { public: - enum class Flag : uchar { - ServiceMessage = 0x01, - NeedsResize = 0x02, - AttachedToPrevious = 0x04, - AttachedToNext = 0x08, - HiddenByGroup = 0x10, - SpecialOnlyEmoji = 0x20, - CustomEmojiRepainting = 0x40, + enum class Flag : uint16 { + ServiceMessage = 0x0001, + NeedsResize = 0x0002, + AttachedToPrevious = 0x0004, + AttachedToNext = 0x0008, + BubbleAttachedToPrevious = 0x0010, + BubbleAttachedToNext = 0x0020, + HiddenByGroup = 0x0040, + SpecialOnlyEmoji = 0x0080, + CustomEmojiRepainting = 0x0100, + ScheduledUntilOnline = 0x0200, }; using Flags = base::flags; friend inline constexpr auto is_flag_type(Flag) { return true; } @@ -281,6 +284,8 @@ public: [[nodiscard]] bool isAttachedToPrevious() const; [[nodiscard]] bool isAttachedToNext() const; + [[nodiscard]] bool isBubbleAttachedToPrevious() const; + [[nodiscard]] bool isBubbleAttachedToNext() const; [[nodiscard]] int skipBlockWidth() const; [[nodiscard]] int skipBlockHeight() const; @@ -304,11 +309,11 @@ public: [[nodiscard]] Ui::Text::OnlyCustomEmoji onlyCustomEmoji() const; // For blocks context this should be called only from recountAttachToPreviousInBlocks(). - void setAttachToPrevious(bool attachToNext); + void setAttachToPrevious(bool attachToNext, Element *previous = nullptr); // For blocks context this should be called only from recountAttachToPreviousInBlocks() // of the next item or when the next item is removed through nextInBlocksRemoved() call. - void setAttachToNext(bool attachToNext); + void setAttachToNext(bool attachToNext, Element *next = nullptr); // For blocks context this should be called only from recountDisplayDate(). void setDisplayDate(bool displayDate); @@ -369,6 +374,7 @@ public: [[nodiscard]] virtual bool hasOutLayout() const; [[nodiscard]] virtual bool drawBubble() const; [[nodiscard]] virtual bool hasBubble() const; + [[nodiscard]] virtual bool unwrapped() const; [[nodiscard]] virtual int minWidthForMedia() const { return 0; } @@ -523,9 +529,8 @@ private: int _y = 0; int _indexInBlock = -1; - bool _isScheduledUntilOnline = false; - mutable bool _heavyCustomEmoji = false; mutable Flags _flags = Flag(0); + mutable bool _heavyCustomEmoji = false; Context _context = Context(); }; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 2035b0f681..50d3ccf0fc 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -3358,8 +3358,8 @@ void ListWidget::refreshAttachmentsFromTill(int from, int till) { const auto nextDate = next->dateTime(); next->setDisplayDate(nextDate.date() != viewDate.date()); auto attached = next->computeIsAttachToPrevious(view); - next->setAttachToPrevious(attached); - view->setAttachToNext(attached); + next->setAttachToPrevious(attached, view); + view->setAttachToNext(attached, next); view = next; } } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 81de7a8017..8857049ee7 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -2635,6 +2635,19 @@ bool Message::hasBubble() const { return drawBubble(); } +bool Message::unwrapped() const { + const auto item = message(); + if (isHidden()) { + return true; + } else if (logEntryOriginal()) { + return false; + } + const auto media = this->media(); + return media + ? (!hasVisibleText() && media->unwrapped()) + : item->isEmpty(); +} + int Message::minWidthForMedia() const { auto result = infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()); const auto views = data()->Get(); @@ -3099,8 +3112,8 @@ QRect Message::countGeometry() const { } Ui::BubbleRounding Message::countMessageRounding() const { - const auto smallTop = isAttachedToPrevious(); - const auto smallBottom = isAttachedToNext(); + const auto smallTop = isBubbleAttachedToPrevious(); + const auto smallBottom = isBubbleAttachedToNext(); const auto media = smallBottom ? nullptr : this->media(); const auto keyboard = data()->inlineReplyKeyboard(); const auto skipTail = smallBottom diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index f76390c565..8c5cfaae99 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -118,6 +118,7 @@ public: bool hasOutLayout() const override; bool drawBubble() const override; bool hasBubble() const override; + bool unwrapped() const override; int minWidthForMedia() const override; bool hasFastReply() const override; bool displayFastReply() const override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 3d5656bfce..219e4ac84f 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -1252,6 +1252,10 @@ bool Gif::needsBubble() const { return false; } +bool Gif::unwrapped() const { + return isUnwrapped(); +} + QRect Gif::contentRectForReactions() const { if (!isUnwrapped()) { return QRect(0, 0, width(), height()); diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h index 3b9b3bf462..e5331b0c40 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.h +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h @@ -93,6 +93,7 @@ public: return _caption.toTextWithEntities(); } bool needsBubble() const override; + bool unwrapped() const override; bool customInfoLayout() const override { return _caption.isEmpty(); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 0e86bb67de..8c18ce2a2c 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -209,6 +209,9 @@ public: return TextWithEntities(); } [[nodiscard]] virtual bool needsBubble() const = 0; + [[nodiscard]] virtual bool unwrapped() const { + return false; + } [[nodiscard]] virtual bool customInfoLayout() const = 0; [[nodiscard]] virtual QRect contentRectForReactions() const { return QRect(0, 0, width(), height()); diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h index f80541aab7..af566ff712 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h @@ -85,6 +85,9 @@ public: bool needsBubble() const override { return false; } + bool unwrapped() const override { + return true; + } bool customInfoLayout() const override { return true; } diff --git a/Telegram/SourceFiles/support/support_autocomplete.cpp b/Telegram/SourceFiles/support/support_autocomplete.cpp index ba3183f24b..696a8457e3 100644 --- a/Telegram/SourceFiles/support/support_autocomplete.cpp +++ b/Telegram/SourceFiles/support/support_autocomplete.cpp @@ -514,8 +514,8 @@ void ConfirmContactBox::prepare() { auto maxWidth = 0; if (_comment) { - _comment->setAttachToNext(true); - _contact->setAttachToPrevious(true); + _comment->setAttachToNext(true, _contact.get()); + _contact->setAttachToPrevious(true, _comment.get()); _comment->initDimensions(); accumulate_max(maxWidth, _comment->maxWidth()); }