diff --git a/Telegram/SourceFiles/data/components/sponsored_messages.cpp b/Telegram/SourceFiles/data/components/sponsored_messages.cpp index ccd7ead26..7de46e59f 100644 --- a/Telegram/SourceFiles/data/components/sponsored_messages.cpp +++ b/Telegram/SourceFiles/data/components/sponsored_messages.cpp @@ -278,38 +278,52 @@ void SponsoredMessages::parse( }); } -void SponsoredMessages::fillTopBar( +FullMsgId SponsoredMessages::fillTopBar( not_null history, - not_null widget, - Fn hide) { + not_null widget) { + const auto it = _data.find(history); + if (it != end(_data)) { + auto &list = it->second; + if (!list.entries.empty()) { + const auto &entry = list.entries.front(); + const auto fullId = entry.itemFullId; + Ui::FillSponsoredMessageBar( + widget, + _session, + fullId, + entry.sponsored.from, + entry.sponsored.textWithEntities); + return fullId; + } + } + return {}; +} + +rpl::producer<> SponsoredMessages::itemRemoved(const FullMsgId &fullId) { + if (IsServerMsgId(fullId.msg) || !fullId) { + return rpl::never<>(); + } + const auto history = _session->data().history(fullId.peer); const auto it = _data.find(history); if (it == end(_data)) { - return; + return rpl::never<>(); } auto &list = it->second; - if (list.entries.empty()) { - return; + const auto entryIt = ranges::find_if(list.entries, [&](const Entry &e) { + return e.itemFullId == fullId; + }); + if (entryIt == end(list.entries)) { + return rpl::never<>(); } - auto &entry = list.entries.front(); - if (!entry.optionalDestructionNotifier) { - entry.optionalDestructionNotifier = std::make_unique(); + if (!entryIt->optionalDestructionNotifier) { + entryIt->optionalDestructionNotifier + = std::make_unique(); + entryIt->optionalDestructionNotifier->add([this, fullId] { + _itemRemoved.fire_copy(fullId); + }); } - const auto fullId = entry.itemFullId; - entry.optionalDestructionNotifier->add(std::move(hide)); - Ui::FillSponsoredMessageBar( - widget, - _session, - fullId, - entry.sponsored.from, - entry.sponsored.textWithEntities); - - const auto viewLifetime = widget->lifetime().make_state(); - widget->shownValue() | rpl::filter( - rpl::mappers::_1 - ) | rpl::start_with_next([=, this](bool shown) { - view(fullId); - viewLifetime->destroy(); - }, *viewLifetime); + return _itemRemoved.events( + ) | rpl::filter(rpl::mappers::_1 == fullId) | rpl::to_empty; } void SponsoredMessages::append( diff --git a/Telegram/SourceFiles/data/components/sponsored_messages.h b/Telegram/SourceFiles/data/components/sponsored_messages.h index 1f5715e6c..ebcefb9e2 100644 --- a/Telegram/SourceFiles/data/components/sponsored_messages.h +++ b/Telegram/SourceFiles/data/components/sponsored_messages.h @@ -104,10 +104,10 @@ public: void clearItems(not_null history); [[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const; void clicked(const FullMsgId &fullId, bool isMedia, bool isFullscreen); - void fillTopBar( + [[nodiscard]] FullMsgId fillTopBar( not_null history, - not_null widget, - Fn hide); + not_null widget); + [[nodiscard]] rpl::producer<> itemRemoved(const FullMsgId &); [[nodiscard]] AppendResult append(not_null history); void inject( @@ -167,6 +167,8 @@ private: base::flat_map, Request> _requests; base::flat_map _viewRequests; + rpl::event_stream _itemRemoved; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 81e160e85..2a9ced8b2 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -7648,21 +7648,33 @@ void HistoryWidget::createSponsoredMessageBar() { object_ptr(this)); _sponsoredMessageBar->entity()->resizeToWidth(_scroll->width()); - auto destruction = [this] { - if (_sponsoredMessageBar) { - _sponsoredMessageBar->toggle(false, anim::type::normal); - _sponsoredMessageBar->shownValue( - ) | rpl::start_with_next([=](bool shown) { - if (!shown) { - _sponsoredMessageBar = nullptr; - } - }, _sponsoredMessageBar->lifetime()); - } - }; - session().sponsoredMessages().fillTopBar( + const auto maybeFullId = session().sponsoredMessages().fillTopBar( _history, - _sponsoredMessageBar->entity(), - std::move(destruction)); + _sponsoredMessageBar->entity()); + session().sponsoredMessages().itemRemoved( + maybeFullId + ) | rpl::start_with_next([this] { + _sponsoredMessageBar->shownValue() | rpl::filter( + !rpl::mappers::_1 + ) | rpl::start_with_next([this] { + _sponsoredMessageBar = nullptr; + }, _sponsoredMessageBar->lifetime()); + _sponsoredMessageBar->toggle(false, anim::type::normal); + }, _sponsoredMessageBar->lifetime()); + + if (maybeFullId) { + const auto viewLifetime + = _sponsoredMessageBar->lifetime().make_state(); + rpl::combine( + _sponsoredMessageBar->entity()->heightValue(), + _sponsoredMessageBar->heightValue() + ) | rpl::filter( + rpl::mappers::_1 == rpl::mappers::_2 + ) | rpl::start_with_next([=] { + session().sponsoredMessages().view(maybeFullId); + viewLifetime->destroy(); + }, *viewLifetime); + } _sponsoredMessageBarHeight = 0; _sponsoredMessageBar->heightValue(