diff --git a/Telegram/SourceFiles/data/data_feed.cpp b/Telegram/SourceFiles/data/data_feed.cpp index 73fdd78bfd..9aa2a1a65f 100644 --- a/Telegram/SourceFiles/data/data_feed.cpp +++ b/Telegram/SourceFiles/data/data_feed.cpp @@ -76,10 +76,15 @@ void Feed::registerOne(not_null<ChannelData*> channel) { _parent->session().storage().remove( Storage::FeedMessagesInvalidate(_id)); - history->updateChatListExistence(); if (invisible && _channels.size() > 1) { updateChatListExistence(); + for (const auto history : _channels) { + history->updateChatListExistence(); + } + } else { + history->updateChatListExistence(); } + _parent->notifyFeedUpdated(this, FeedUpdateFlag::Channels); } } @@ -98,7 +103,11 @@ void Feed::unregisterOne(not_null<ChannelData*> channel) { history->updateChatListExistence(); if (visible && _channels.size() < 2) { updateChatListExistence(); + for (const auto history : _channels) { + history->updateChatListExistence(); + } } + _parent->notifyFeedUpdated(this, FeedUpdateFlag::Channels); } } @@ -138,6 +147,10 @@ void Feed::paintUserpic( } } +const std::vector<not_null<History*>> &Feed::channels() const { + return _channels; +} + bool Feed::justSetLastMessage(not_null<HistoryItem*> item) { if (_lastMessage && item->position() <= _lastMessage->position()) { return false; diff --git a/Telegram/SourceFiles/data/data_feed.h b/Telegram/SourceFiles/data/data_feed.h index 8bf6b6870e..7518f4cc48 100644 --- a/Telegram/SourceFiles/data/data_feed.h +++ b/Telegram/SourceFiles/data/data_feed.h @@ -15,6 +15,17 @@ class ChannelData; namespace Data { class Session; +class Feed; + +enum class FeedUpdateFlag { + Channels, + ChannelPhoto, +}; + +struct FeedUpdate { + not_null<Data::Feed*> feed; + FeedUpdateFlag flag; +}; MessagePosition FeedPositionFromMTP(const MTPFeedPosition &position); @@ -53,6 +64,8 @@ public: int y, int size) const override; + const std::vector<not_null<History*>> &channels() const; + private: void indexNameParts(); void recountLastMessage(); diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 96a7c1f7f3..c7495dc84d 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -299,6 +299,13 @@ void PeerData::setUserpicChecked( || _userpicLocation != location) { setUserpic(photoId, location, userpic); Notify::peerUpdatedDelayed(this, UpdateFlag::PhotoChanged); + if (const auto channel = asChannel()) { + if (const auto feed = channel->feed()) { + Auth().data().notifyFeedUpdated( + feed, + Data::FeedUpdateFlag::ChannelPhoto); + } + } } } diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 334f35949e..1562391765 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -327,6 +327,16 @@ rpl::producer<not_null<UserData*>> Session::megagroupParticipantAdded( }); } +void Session::notifyFeedUpdated( + not_null<Feed*> feed, + FeedUpdateFlag update) { + _feedUpdates.fire({ feed, update }); +} + +rpl::producer<FeedUpdate> Session::feedUpdated() const { + return _feedUpdates.events(); +} + void Session::notifyStickersUpdated() { _stickersUpdated.fire({}); } @@ -1422,17 +1432,17 @@ void Session::unregisterItemView(not_null<ViewElement*> view) { } } -not_null<Data::Feed*> Session::feed(FeedId id) { +not_null<Feed*> Session::feed(FeedId id) { if (const auto result = feedLoaded(id)) { return result; } const auto [it, ok] = _feeds.emplace( id, - std::make_unique<Data::Feed>(id, this)); + std::make_unique<Feed>(id, this)); return it->second.get(); } -Data::Feed *Session::feedLoaded(FeedId id) { +Feed *Session::feedLoaded(FeedId id) { const auto it = _feeds.find(id); return (it == end(_feeds)) ? nullptr : it->second.get(); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 8fa55c9c98..4c851e818c 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -29,6 +29,8 @@ class Reader; namespace Data { class Feed; +enum class FeedUpdateFlag; +struct FeedUpdate; class Session final { public: @@ -107,6 +109,9 @@ public: rpl::producer<not_null<UserData*>> megagroupParticipantAdded( not_null<ChannelData*> channel) const; + void notifyFeedUpdated(not_null<Feed*> feed, FeedUpdateFlag update); + rpl::producer<FeedUpdate> feedUpdated() const; + void notifyStickersUpdated(); rpl::producer<> stickersUpdated() const; void notifySavedGifsUpdated(); @@ -340,8 +345,8 @@ public: void registerItemView(not_null<ViewElement*> view); void unregisterItemView(not_null<ViewElement*> view); - not_null<Data::Feed*> feed(FeedId id); - Data::Feed *feedLoaded(FeedId id); + not_null<Feed*> feed(FeedId id); + Feed *feedLoaded(FeedId id); void forgetMedia(); @@ -454,6 +459,7 @@ private: rpl::event_stream<not_null<History*>> _historyChanged; rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved; rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded; + rpl::event_stream<FeedUpdate> _feedUpdates; rpl::event_stream<> _stickersUpdated; rpl::event_stream<> _savedGifsUpdated; @@ -510,7 +516,7 @@ private: base::flat_set<not_null<GameData*>> _gamesUpdated; std::deque<Dialogs::Key> _pinnedDialogs; - base::flat_map<FeedId, std::unique_ptr<Data::Feed>> _feeds; + base::flat_map<FeedId, std::unique_ptr<Feed>> _feeds; Groups _groups; std::map< not_null<const HistoryItem*>, diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 21094aab14..f9f0d39055 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -142,6 +142,12 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro } } })); + Auth().data().feedUpdated( + ) | rpl::start_with_next([=](const Data::FeedUpdate &update) { + updateDialogRow( + Dialogs::RowDescriptor(update.feed, MsgId(0)), + QRect(0, 0, getFullWidth(), st::dialogsRowHeight)); + }, lifetime()); _controller->activeChatEntryValue( ) | rpl::combine_previous( diff --git a/Telegram/SourceFiles/history/feed/history_feed_section.cpp b/Telegram/SourceFiles/history/feed/history_feed_section.cpp index 91b24e3c47..fcd2e420d7 100644 --- a/Telegram/SourceFiles/history/feed/history_feed_section.cpp +++ b/Telegram/SourceFiles/history/feed/history_feed_section.cpp @@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_message.h" #include "history/view/history_view_service_message.h" #include "history/history_item.h" -#include "mainwidget.h" #include "lang/lang_keys.h" #include "ui/widgets/buttons.h" #include "ui/widgets/shadow.h" @@ -25,7 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_feed_messages.h" #include "data/data_photo.h" #include "data/data_document.h" +#include "data/data_session.h" #include "storage/storage_feed_messages.h" +#include "mainwidget.h" +#include "auth_session.h" #include "styles/style_widgets.h" #include "styles/style_history.h" @@ -111,6 +113,27 @@ Widget::Widget( auto memento = HistoryView::ListMemento(position); _inner->restoreState(&memento); }, lifetime()); + + rpl::single( + Data::FeedUpdate{ _feed, Data::FeedUpdateFlag::Channels } + ) | rpl::then( + Auth().data().feedUpdated() + ) | rpl::filter([=](const Data::FeedUpdate &update) { + return (update.feed == _feed); + }) | rpl::start_with_next([=](const Data::FeedUpdate &update) { + checkForSingleChannelFeed(); + }, lifetime()); +} + +void Widget::checkForSingleChannelFeed() { + const auto &channels = _feed->channels(); + if (channels.size() > 1) { + return; + } else if (!channels.empty()) { + controller()->showPeerHistory(channels[0]); + } else { + controller()->clearSectionStack(); + } } Dialogs::RowDescriptor Widget::activeChat() const { diff --git a/Telegram/SourceFiles/history/feed/history_feed_section.h b/Telegram/SourceFiles/history/feed/history_feed_section.h index 0e2736b375..da199936c4 100644 --- a/Telegram/SourceFiles/history/feed/history_feed_section.h +++ b/Telegram/SourceFiles/history/feed/history_feed_section.h @@ -86,6 +86,7 @@ protected: void doSetInnerFocus() override; private: + void checkForSingleChannelFeed(); void onScroll(); void updateInnerVisibleArea(); void updateControlsGeometry();