diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 834592de6..1b62876ed 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -85,7 +85,7 @@ object_ptr PrepareContactsBox( st::dialogsStoriesList, Stories::ContentForSession( &sessionController->session(), - Data::StorySourcesList::All), + Data::StorySourcesList::Hidden), [=] { return state->stories->height() - box->scrollTop(); }); const auto raw = state->stories = stories.data(); box->peerListSetAboveWidget(object_ptr<::Ui::PaddingWrap<>>( @@ -97,7 +97,7 @@ object_ptr PrepareContactsBox( ) | rpl::start_with_next([=](uint64 id) { sessionController->openPeerStories( PeerId(int64(id)), - Data::StorySourcesList::All); + Data::StorySourcesList::Hidden); }, raw->lifetime()); raw->showProfileRequests( @@ -116,7 +116,7 @@ object_ptr PrepareContactsBox( raw->loadMoreRequests( ) | rpl::start_with_next([=] { sessionController->session().data().stories().loadMore( - Data::StorySourcesList::All); + Data::StorySourcesList::Hidden); }, raw->lifetime()); }; return Box(std::move(controller), std::move(init)); diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index f8a51b93e..525a0d200 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -419,8 +419,9 @@ void Stories::apply(const MTPDupdateStory &data) { sort(list); } }; - refreshInList(StorySourcesList::All); - if (!user->hasStoriesHidden()) { + if (user->hasStoriesHidden()) { + refreshInList(StorySourcesList::Hidden); + } else { refreshInList(StorySourcesList::NotHidden); } _sourceChanged.fire_copy(peerId); @@ -428,7 +429,8 @@ void Stories::apply(const MTPDupdateStory &data) { void Stories::apply(not_null peer, const MTPUserStories *data) { if (!data) { - applyDeletedFromSources(peer->id, StorySourcesList::All); + applyDeletedFromSources(peer->id, StorySourcesList::NotHidden); + applyDeletedFromSources(peer->id, StorySourcesList::Hidden); _all.erase(peer->id); _sourceChanged.fire_copy(peer->id); } else { @@ -449,7 +451,8 @@ void Stories::requestUserStories(not_null user) { parseAndApply(data.vstories()); }).fail([=] { _requestingUserStories.remove(user); - applyDeletedFromSources(user->id, StorySourcesList::All); + applyDeletedFromSources(user->id, StorySourcesList::NotHidden); + applyDeletedFromSources(user->id, StorySourcesList::Hidden); }).send(); } @@ -528,7 +531,8 @@ void Stories::parseAndApply(const MTPUserStories &stories) { } } if (result.ids.empty()) { - applyDeletedFromSources(peerId, StorySourcesList::All); + applyDeletedFromSources(peerId, StorySourcesList::NotHidden); + applyDeletedFromSources(peerId, StorySourcesList::Hidden); return; } else if (user->isSelf()) { result.readTill = result.ids.back().id; @@ -558,14 +562,15 @@ void Stories::parseAndApply(const MTPUserStories &stories) { sort(list); }; if (result.user->isContact()) { - add(StorySourcesList::All); - if (result.user->hasStoriesHidden()) { - applyDeletedFromSources(peerId, StorySourcesList::NotHidden); - } else { - add(StorySourcesList::NotHidden); - } + const auto hidden = result.user->hasStoriesHidden(); + using List = StorySourcesList; + add(hidden ? List::Hidden : List::NotHidden); + applyDeletedFromSources( + peerId, + hidden ? List::NotHidden : List::Hidden); } else { - applyDeletedFromSources(peerId, StorySourcesList::All); + applyDeletedFromSources(peerId, StorySourcesList::NotHidden); + applyDeletedFromSources(peerId, StorySourcesList::Hidden); } _sourceChanged.fire_copy(peerId); } @@ -725,11 +730,11 @@ void Stories::loadMore(StorySourcesList list) { if (_loadMoreRequestId[index] || _sourcesLoaded[index]) { return; } - const auto all = (list == StorySourcesList::All); + const auto hidden = (list == StorySourcesList::Hidden); const auto api = &_owner->session().api(); using Flag = MTPstories_GetAllStories::Flag; _loadMoreRequestId[index] = api->request(MTPstories_GetAllStories( - MTP_flags((all ? Flag::f_include_hidden : Flag()) + MTP_flags((hidden ? Flag::f_hidden : Flag()) | (_sourcesStates[index].isEmpty() ? Flag(0) : (Flag::f_next | Flag::f_state))), @@ -917,7 +922,7 @@ void Stories::applyRemovedFromActive(FullStoryId id) { if (i->second.ids.empty()) { _all.erase(i); removeFromList(StorySourcesList::NotHidden); - removeFromList(StorySourcesList::All); + removeFromList(StorySourcesList::Hidden); } _sourceChanged.fire_copy(id.peer); } @@ -925,21 +930,15 @@ void Stories::applyRemovedFromActive(FullStoryId id) { } void Stories::applyDeletedFromSources(PeerId id, StorySourcesList list) { - const auto removeFromList = [&](StorySourcesList from) { - auto &sources = _sources[static_cast(from)]; - const auto i = ranges::find( - sources, - id, - &StoriesSourceInfo::id); - if (i != end(sources)) { - sources.erase(i); - } - _sourcesChanged[static_cast(from)].fire({}); - }; - removeFromList(StorySourcesList::NotHidden); - if (list == StorySourcesList::All) { - removeFromList(StorySourcesList::All); + auto &sources = _sources[static_cast(list)]; + const auto i = ranges::find( + sources, + id, + &StoriesSourceInfo::id); + if (i != end(sources)) { + sources.erase(i); } + _sourcesChanged[static_cast(list)].fire({}); } void Stories::removeDependencyStory(not_null story) { @@ -1146,8 +1145,8 @@ void Stories::markAsRead(FullStoryId id, bool viewed) { sort(list); } }; - refreshInList(StorySourcesList::All); refreshInList(StorySourcesList::NotHidden); + refreshInList(StorySourcesList::Hidden); } _markReadTimer.callOnce(kMarkAsReadDelay); } @@ -1181,37 +1180,36 @@ void Stories::toggleHidden( return; } i->second.hidden = hidden; + const auto info = i->second.info(); const auto main = static_cast(StorySourcesList::NotHidden); - const auto all = static_cast(StorySourcesList::All); + const auto other = static_cast(StorySourcesList::Hidden); + const auto proj = &StoriesSourceInfo::id; if (hidden) { - const auto i = ranges::find( - _sources[main], - peerId, - &StoriesSourceInfo::id); + const auto i = ranges::find(_sources[main], peerId, proj); if (i != end(_sources[main])) { _sources[main].erase(i); _sourcesChanged[main].fire({}); } - const auto j = ranges::find(_sources[all], peerId, &StoriesSourceInfo::id); - if (j != end(_sources[all])) { - j->hidden = hidden; - _sourcesChanged[all].fire({}); + const auto j = ranges::find(_sources[other], peerId, proj); + if (j == end(_sources[other])) { + _sources[other].push_back(info); + } else { + *j = info; } + sort(StorySourcesList::Hidden); } else { - const auto i = ranges::find( - _sources[all], - peerId, - &StoriesSourceInfo::id); - if (i != end(_sources[all])) { - i->hidden = hidden; - _sourcesChanged[all].fire({}); - - auto &sources = _sources[main]; - if (!ranges::contains(sources, peerId, &StoriesSourceInfo::id)) { - sources.push_back(*i); - sort(StorySourcesList::NotHidden); - } + const auto i = ranges::find(_sources[other], peerId, proj); + if (i != end(_sources[other])) { + _sources[other].erase(i); + _sourcesChanged[other].fire({}); } + const auto j = ranges::find(_sources[main], peerId, proj); + if (j == end(_sources[main])) { + _sources[main].push_back(info); + } else { + *j = info; + } + sort(StorySourcesList::NotHidden); } } diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index c136bff5c..d082d05a6 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -172,7 +172,7 @@ enum class NoStory : uchar { enum class StorySourcesList : uchar { NotHidden, - All, + Hidden, }; struct StoriesContextSingle { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp index a0a8a8aaa..acce7637e 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp @@ -322,7 +322,9 @@ State::State(not_null data, Data::StorySourcesList list) } Content State::next() { - auto result = Content{ .full = (_list == Data::StorySourcesList::All) }; + auto result = Content{ + .hidden = (_list == Data::StorySourcesList::Hidden) + }; const auto &sources = _data->sources(_list); result.elements.reserve(sources.size()); for (const auto &info : sources) { @@ -344,7 +346,8 @@ Content State::next() { : user->shortName()), .thumbnail = std::move(userpic), .unread = info.unread, - .hidden = info.hidden, + .suggestHide = !info.hidden, + .suggestUnhide = info.hidden, .profile = true, .skipSmall = user->isSelf(), }); @@ -420,7 +423,7 @@ rpl::producer LastForPeer(not_null peer) { return; } auto resolving = false; - auto result = Content{ .full = true }; + auto result = Content{}; for (const auto id : ids) { const auto storyId = FullStoryId{ peerId, id }; const auto maybe = stories->lookup(storyId); diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp index 811fbc033..c54803ef6 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp @@ -102,7 +102,9 @@ void List::showContent(Content &&content) { item.nameCache = QImage(); } item.element.unread = element.unread; - item.element.hidden = element.hidden; + item.element.suggestHide = element.suggestHide; + item.element.suggestUnhide = element.suggestUnhide; + item.element.profile = element.profile; } else { _data.items.emplace_back(Item{ .element = element }); } @@ -762,17 +764,19 @@ void List::contextMenuEvent(QContextMenuEvent *e) { _menu = base::make_unique_q(this); const auto id = item.element.id; - const auto hidden = item.element.hidden; if (item.element.profile) { _menu->addAction(tr::lng_context_view_profile(tr::now), [=] { _showProfileRequests.fire_copy(id); }); } - if (!_content.full || hidden) { - _menu->addAction(hidden - ? tr::lng_stories_show_in_chats(tr::now) - : tr::lng_stories_hide_to_contacts(tr::now), - [=] { _toggleShown.fire({ .id = id, .shown = hidden }); }); + if (item.element.suggestHide) { + _menu->addAction( + tr::lng_stories_hide_to_contacts(tr::now), + [=] { _toggleShown.fire({ .id = id, .shown = false }); }); + } else if (item.element.suggestUnhide) { + _menu->addAction( + tr::lng_stories_show_in_chats(tr::now), + [=] { _toggleShown.fire({ .id = id, .shown = true }); }); } const auto updateAfterMenuDestroyed = [=] { const auto globalPosition = QCursor::pos(); diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h index a7826d892..8381a4289 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h @@ -34,10 +34,11 @@ struct Element { uint64 id = 0; QString name; std::shared_ptr thumbnail; - bool unread = false; - bool hidden = false; - bool profile = false; - bool skipSmall = false; + bool unread : 1 = false; + bool suggestHide : 1 = false; + bool suggestUnhide : 1 = false; + bool profile : 1 = false; + bool skipSmall : 1 = false; friend inline bool operator==( const Element &a, @@ -46,7 +47,7 @@ struct Element { struct Content { std::vector elements; - bool full = false; + bool hidden = false; friend inline bool operator==( const Content &a, diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index e3bcb489f..1ccafbc6f 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -129,7 +129,7 @@ messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true tes messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia; messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; -messageMediaStory#cbb20d88 flags:# user_id:long id:int story:flags.0?StoryItem = MessageMedia; +messageMediaStory#cbb20d88 flags:# via_mention:flags.1?true user_id:long id:int story:flags.0?StoryItem = MessageMedia; messageActionEmpty#b6aef7b0 = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector = MessageAction; @@ -2091,7 +2091,7 @@ stories.sendStory#424cd47a flags:# pinned:flags.2?true media:InputMedia caption: stories.editStory#2aae7a41 flags:# id:int media:flags.0?InputMedia caption:flags.1?string entities:flags.1?Vector privacy_rules:flags.2?Vector = Updates; stories.deleteStories#b5d501d7 id:Vector = Vector; stories.togglePinned#51602944 id:Vector pinned:Bool = Vector; -stories.getAllStories#eeb0d625 flags:# next:flags.1?true include_hidden:flags.2?true state:flags.0?string = stories.AllStories; +stories.getAllStories#eeb0d625 flags:# next:flags.1?true hidden:flags.2?true state:flags.0?string = stories.AllStories; stories.getUserStories#96d528e0 user_id:InputUser = stories.UserStories; stories.getPinnedStories#b471137 user_id:InputUser offset_id:int limit:int = stories.Stories; stories.getStoriesArchive#1f5bc5d2 offset_id:int limit:int = stories.Stories;