diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 2f1e6cdfd..cb92da4b7 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -2730,7 +2730,7 @@ void History::cacheTopPromotion( const QString &message) { const auto changed = (isTopPromoted() != promoted); cacheTopPromoted(promoted); - if (_topPromotedType != type || _topPromotedMessage != message) { + if (topPromotionType() != type || _topPromotedMessage != message) { _topPromotedType = type; _topPromotedMessage = message; cloudDraftTextCache.clear(); @@ -2739,8 +2739,20 @@ void History::cacheTopPromotion( } } -QString History::topPromotionType() const { - return _topPromotedType; +QStringRef History::topPromotionType() const { + return topPromotionAboutShown() + ? _topPromotedType.midRef(5) + : _topPromotedType.midRef(0); +} + +bool History::topPromotionAboutShown() const { + return _topPromotedType.startsWith("seen^"); +} + +void History::markTopPromotionAboutShown() { + if (!topPromotionAboutShown()) { + _topPromotedType = "seen^" + _topPromotedType; + } } QString History::topPromotionMessage() const { diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 8e97d204a..adfa3d605 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -241,8 +241,10 @@ public: bool promoted, const QString &type, const QString &message); - [[nodiscard]] QString topPromotionType() const; + [[nodiscard]] QStringRef topPromotionType() const; [[nodiscard]] QString topPromotionMessage() const; + [[nodiscard]] bool topPromotionAboutShown() const; + void markTopPromotionAboutShown(); MsgId minMsgId() const; MsgId maxMsgId() const; diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index c557efb23..d9328ff7b 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -529,13 +529,6 @@ historyGroupSkip: 4px; historyGroupRadialSize: 44px; historyGroupRadialLine: 3px; -historyAboutProxy: FlatLabel(defaultFlatLabel) { - align: align(top); - textFg: windowSubTextFg; - minWidth: 300px; -} -historyAboutProxyPadding: margins(20px, 10px, 20px, 10px); - historyMapPoint: icon {{ "map_point", mapPointDrop }}; historyMapPointInner: icon {{ "map_point_inner", mapPointDot }}; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 9d0440268..4ecd52e78 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -88,13 +88,6 @@ int BinarySearchBlocksOrItems(const T &list, int edge) { return start; } -[[nodiscard]] crl::time CountToastDuration(const TextWithEntities &text) { - return std::clamp( - crl::time(1000) * text.text.size() / 14, - crl::time(1000) * 5, - crl::time(1000) * 8); -} - } // namespace // flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html @@ -2491,24 +2484,7 @@ void HistoryInner::elementShowPollResults( void HistoryInner::elementShowTooltip( const TextWithEntities &text, Fn hiddenCallback) { - if (const auto strong = _topToast.get()) { - strong->hideAnimated(); - } - _topToast = Ui::Toast::Show(_scroll, Ui::Toast::Config{ - .text = text, - .st = &st::historyInfoToast, - .durationMs = CountToastDuration(text), - .multiline = true, - .dark = true, - .slideSide = RectPart::Top, - }); - if (const auto strong = _topToast.get()) { - if (hiddenCallback) { - connect(strong->widget(), &QObject::destroyed, hiddenCallback); - } - } else if (hiddenCallback) { - hiddenCallback(); - } + _widget->showInfoTooltip(text, std::move(hiddenCallback)); } auto HistoryInner::getSelectionState() const diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 25ffcd55d..f1dfcc312 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -34,9 +34,6 @@ class SessionController; namespace Ui { class PopupMenu; -namespace Toast { -class Instance; -} // namespace Toast } // namespace Ui class HistoryWidget; @@ -384,7 +381,6 @@ private: QTimer _touchScrollTimer; base::unique_qptr _menu; - base::weak_ptr _topToast; bool _scrollDateShown = false; Ui::Animations::Simple _scrollDateOpacity; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c8399dde0..02a01bb32 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -243,6 +243,13 @@ void ShowErrorToast(const QString &text) { }); } +[[nodiscard]] crl::time CountToastDuration(const TextWithEntities &text) { + return std::clamp( + crl::time(1000) * text.text.size() / 14, + crl::time(1000) * 5, + crl::time(1000) * 8); +} + } // namespace HistoryWidget::HistoryWidget( @@ -565,7 +572,6 @@ HistoryWidget::HistoryWidget( } } if (update.flags & UpdateFlag::TopPromotedChanged) { - refreshAboutTopPromotion(); updateHistoryGeometry(); updateControlsVisibility(); updateControlsGeometry(); @@ -1649,6 +1655,7 @@ void HistoryWidget::showHistory( } clearHighlightMessages(); + hideInfoTooltip(anim::type::instant); if (_history) { if (_peer->id == peerId && !reload) { updateForwarding(); @@ -1903,6 +1910,7 @@ void HistoryWidget::showHistory( } } unreadCountUpdated(); // set _historyDown badge. + showAboutTopPromotion(); } else { _topBar->setActiveChat( Dialogs::Key(), @@ -2069,7 +2077,6 @@ void HistoryWidget::updateControlsVisibility() { if (_contactStatus) { _contactStatus->show(); } - refreshAboutTopPromotion(); if (!editingMessage() && (isBlocked() || isJoinChannel() || isMuteUnmute() || isBotStart())) { if (isBlocked()) { _joinChannel->hide(); @@ -2262,33 +2269,25 @@ void HistoryWidget::updateControlsVisibility() { updateMouseTracking(); } -void HistoryWidget::refreshAboutTopPromotion() { - if (_history->useTopPromotion()) { - const auto type = _history->topPromotionType(); - const auto custom = type.isEmpty() - ? QString() - : Lang::Current().getNonDefaultValue( - kPsaAboutPrefix + type.toUtf8()); - const auto text = type.isEmpty() - ? tr::lng_proxy_sponsor_about(tr::now, Ui::Text::RichLangValue) - : custom.isEmpty() - ? tr::lng_about_psa_default(tr::now, Ui::Text::RichLangValue) - : Ui::Text::RichLangValue(custom); - if (!_aboutTopPromotion || _aboutTopPromotionText != text) { - _aboutTopPromotionText = text; - _aboutTopPromotion = object_ptr>( - this, - object_ptr( - this, - rpl::single(_aboutTopPromotionText), - st::historyAboutProxy), - st::historyAboutProxyPadding); - } - _aboutTopPromotion->show(); - } else { - _aboutTopPromotionText = TextWithEntities(); - _aboutTopPromotion.destroy(); +void HistoryWidget::showAboutTopPromotion() { + Expects(_history != nullptr); + Expects(_list != nullptr); + + if (!_history->useTopPromotion() || _history->topPromotionAboutShown()) { + return; } + _history->markTopPromotionAboutShown(); + const auto type = _history->topPromotionType(); + const auto custom = type.isEmpty() + ? QString() + : Lang::Current().getNonDefaultValue( + kPsaAboutPrefix + type.toUtf8()); + const auto text = type.isEmpty() + ? tr::lng_proxy_sponsor_about(tr::now, Ui::Text::RichLangValue) + : custom.isEmpty() + ? tr::lng_about_psa_default(tr::now, Ui::Text::RichLangValue) + : Ui::Text::RichLangValue(custom); + showInfoTooltip(text, nullptr); } void HistoryWidget::updateMouseTracking() { @@ -4201,13 +4200,6 @@ void HistoryWidget::moveFieldControls() { } else { _muteUnmute->setGeometry(fullWidthButtonRect); } - - if (_aboutTopPromotion) { - _aboutTopPromotion->resizeToWidth(width()); - _aboutTopPromotion->moveToLeft( - 0, - fullWidthButtonRect.y() - _aboutTopPromotion->height()); - } } void HistoryWidget::updateFieldSize() { @@ -5225,9 +5217,6 @@ void HistoryWidget::updateHistoryGeometry( newScrollHeight -= _kbScroll->height(); } } - if (_aboutTopPromotion) { - newScrollHeight -= _aboutTopPromotion->height(); - } if (newScrollHeight <= 0) { return; } @@ -5932,6 +5921,37 @@ bool HistoryWidget::sendExistingPhoto(not_null photo) { return true; } +void HistoryWidget::showInfoTooltip( + const TextWithEntities &text, + Fn hiddenCallback) { + hideInfoTooltip(anim::type::normal); + _topToast = Ui::Toast::Show(_scroll, Ui::Toast::Config{ + .text = text, + .st = &st::historyInfoToast, + .durationMs = CountToastDuration(text), + .multiline = true, + .dark = true, + .slideSide = RectPart::Top, + }); + if (const auto strong = _topToast.get()) { + if (hiddenCallback) { + connect(strong->widget(), &QObject::destroyed, hiddenCallback); + } + } else if (hiddenCallback) { + hiddenCallback(); + } +} + +void HistoryWidget::hideInfoTooltip(anim::type animated) { + if (const auto strong = _topToast.get()) { + if (animated == anim::type::normal) { + strong->hideAnimated(); + } else { + strong->hide(); + } + } +} + void HistoryWidget::setFieldText( const TextWithTags &textWithTags, TextUpdateEvents events, @@ -6997,9 +7017,6 @@ void HistoryWidget::paintEvent(QPaintEvent *e) { } else if (const auto error = writeRestriction()) { drawRestrictedWrite(p, *error); } - if (_aboutTopPromotion) { - p.fillRect(_aboutTopPromotion->geometry(), st::historyReplyBg); - } if (_pinnedBar && !_pinnedBar->cancel->isHidden()) { drawPinnedBar(p); } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index eaf8855c1..2ff422952 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -60,6 +60,9 @@ class SilentToggle; class FlatButton; class LinkButton; class RoundButton; +namespace Toast { +class Instance; +} // namespace Toast } // namespace Ui namespace Window { @@ -242,6 +245,11 @@ public: bool sendExistingDocument(not_null document); bool sendExistingPhoto(not_null photo); + void showInfoTooltip( + const TextWithEntities &text, + Fn hiddenCallback); + void hideInfoTooltip(anim::type animated); + // Tabbed selector management. void pushTabbedSelectorToThirdSection( const Window::SectionShow ¶ms) override; @@ -380,7 +388,7 @@ private: void handlePeerUpdate(); void setMembersShowAreaActive(bool active); void handleHistoryChange(not_null history); - void refreshAboutTopPromotion(); + void showAboutTopPromotion(); void unreadCountUpdated(); [[nodiscard]] int computeMaxFieldHeight() const; @@ -734,8 +742,6 @@ private: object_ptr _joinChannel; object_ptr _muteUnmute; object_ptr _discuss; - object_ptr _aboutTopPromotion = { nullptr }; - TextWithEntities _aboutTopPromotionText; object_ptr _attachToggle; object_ptr _tabbedSelectorToggle; object_ptr _botKeyboardShow; @@ -802,6 +808,8 @@ private: bool _saveDraftText = false; QTimer _saveDraftTimer, _saveCloudDraftTimer; + base::weak_ptr _topToast; + object_ptr _topShadow; bool _inGrab = false;