diff --git a/Telegram/Resources/icons/menu/stories_archive.png b/Telegram/Resources/icons/menu/stories_archive.png new file mode 100644 index 000000000..d86b5dc87 Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_archive.png differ diff --git a/Telegram/Resources/icons/menu/stories_archive@2x.png b/Telegram/Resources/icons/menu/stories_archive@2x.png new file mode 100644 index 000000000..f2c59be33 Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_archive@2x.png differ diff --git a/Telegram/Resources/icons/menu/stories_archive@3x.png b/Telegram/Resources/icons/menu/stories_archive@3x.png new file mode 100644 index 000000000..f6369c74c Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_archive@3x.png differ diff --git a/Telegram/Resources/icons/menu/stories_saved.png b/Telegram/Resources/icons/menu/stories_saved.png new file mode 100644 index 000000000..727dc35f3 Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_saved.png differ diff --git a/Telegram/Resources/icons/menu/stories_saved@2x.png b/Telegram/Resources/icons/menu/stories_saved@2x.png new file mode 100644 index 000000000..3e68c6182 Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_saved@2x.png differ diff --git a/Telegram/Resources/icons/menu/stories_saved@3x.png b/Telegram/Resources/icons/menu/stories_saved@3x.png new file mode 100644 index 000000000..9fc3db0d6 Binary files /dev/null and b/Telegram/Resources/icons/menu/stories_saved@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 04a9b2710..228366602 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3814,8 +3814,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji"; "lng_stories_my_name" = "My Story"; -"lng_stories_hide_to_contacts" = "Archive"; -"lng_stories_show_in_chats" = "Unarchive"; +"lng_stories_hide_to_contacts" = "Hide"; +"lng_stories_show_in_chats" = "Show in Chats"; "lng_stories_row_count#one" = "{count} Story"; "lng_stories_row_count#other" = "{count} Stories"; "lng_stories_row_unread_and_one" = "{accumulated}, {user}"; @@ -3832,8 +3832,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stories_archive_title" = "Stories Archive"; "lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile."; "lng_stories_reply_sent" = "Message Sent"; -"lng_stories_hidden_to_contacts" = "Stories from {user} will now be shown in Contacts, not Chats."; -"lng_stories_shown_in_chats" = "Stories from {user} will now be shown in Chats, not Contacts."; +"lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Contacts**."; +"lng_stories_shown_in_chats" = "Stories of {user} were moved above the **Chats List**."; "lng_stories_delete_one_sure" = "Are you sure you want to delete this story?"; "lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?"; "lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?"; diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index b1c87eaff..2bf72ee92 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -57,10 +57,10 @@ object_ptr PrepareContactsBox( &sessionController->session()); const auto raw = controller.get(); auto init = [=](not_null box) { - using namespace Dialogs; + using namespace Dialogs::Stories; struct State { - Stories::List *stories = nullptr; + List *stories = nullptr; QPointer<::Ui::IconButton> toggleSort; Mode mode = ContactsBoxController::SortMode::Online; ::Ui::Animations::Simple scrollAnimation; @@ -82,10 +82,10 @@ object_ptr PrepareContactsBox( }); raw->setSortMode(Mode::Online); - auto list = object_ptr( + auto list = object_ptr( box, st::dialogsStoriesList, - Stories::ContentForSession( + ContentForSession( &sessionController->session(), Data::StorySourcesList::Hidden), [=] { return state->stories->height() - box->scrollTop(); }); @@ -102,17 +102,9 @@ object_ptr PrepareContactsBox( Data::StorySourcesList::Hidden); }, raw->lifetime()); - raw->showProfileRequests( - ) | rpl::start_with_next([=](uint64 id) { - sessionController->showPeerInfo(PeerId(int64(id))); - }, raw->lifetime()); - - raw->toggleShown( - ) | rpl::start_with_next([=](Stories::ToggleShownRequest request) { - stories->toggleHidden( - PeerId(int64(request.id)), - !request.shown, - sessionController->uiShow()); + raw->showMenuRequests( + ) | rpl::start_with_next([=](const ShowMenuRequest &request) { + FillSourceMenu(sessionController, request); }, raw->lifetime()); raw->loadMoreRequests( diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index 15710d021..61c41ffa3 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -76,7 +76,6 @@ StoriesSourceInfo StoriesSource::info() const { .last = ids.empty() ? 0 : ids.back().date, .unread = unread(), .premium = user->isPremium(), - .hidden = hidden, }; } @@ -943,7 +942,7 @@ void Stories::toggleHidden( tr::now, lt_user, Ui::Text::Bold(name), - Ui::Text::WithEntities)); + Ui::Text::RichLangValue)); } }); diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index 648535187..630e8cc31 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -43,7 +43,6 @@ struct StoriesSourceInfo { TimeId last = 0; bool unread = false; bool premium = false; - bool hidden = false; friend inline bool operator==( StoriesSourceInfo, diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 35a19da9a..091ebaf16 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -347,17 +347,9 @@ InnerWidget::InnerWidget( Data::StorySourcesList::NotHidden); }, lifetime()); - _stories->showProfileRequests( - ) | rpl::start_with_next([=](uint64 id) { - _controller->showPeerInfo(PeerId(int64(id))); - }, lifetime()); - - _stories->toggleShown( - ) | rpl::start_with_next([=](Stories::ToggleShownRequest request) { - session().data().stories().toggleHidden( - PeerId(int64(request.id)), - !request.shown, - _controller->uiShow()); + _stories->showMenuRequests( + ) | rpl::start_with_next([=](const Stories::ShowMenuRequest &request) { + FillSourceMenu(_controller, request); }, lifetime()); _stories->loadMoreRequests( diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp index e686811aa..253b789ce 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.cpp @@ -17,9 +17,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_stories.h" #include "data/data_user.h" #include "dialogs/ui/dialogs_stories_list.h" +#include "info/stories/info_stories_widget.h" +#include "info/info_controller.h" +#include "info/info_memento.h" #include "main/main_session.h" #include "lang/lang_keys.h" #include "ui/painter.h" +#include "window/window_session_controller.h" +#include "styles/style_menu_icons.h" namespace Dialogs::Stories { namespace { @@ -325,9 +330,7 @@ State::State(not_null data, Data::StorySourcesList list) } Content State::next() { - auto result = Content{ - .hidden = (_list == Data::StorySourcesList::Hidden) - }; + auto result = Content(); const auto &sources = _data->sources(_list); result.elements.reserve(sources.size()); for (const auto &info : sources) { @@ -349,9 +352,6 @@ Content State::next() { : user->shortName()), .thumbnail = std::move(userpic), .unread = info.unread, - .suggestHide = !info.hidden, - .suggestUnhide = info.hidden, - .profile = true, .skipSmall = user->isSelf(), }); } @@ -466,4 +466,51 @@ std::shared_ptr MakeStoryThumbnail( }); } +void FillSourceMenu( + not_null controller, + const ShowMenuRequest &request) { + const auto owner = &controller->session().data(); + const auto peer = owner->peer(PeerId(request.id)); + const auto &add = request.callback; + if (peer->isSelf()) { + add(tr::lng_stories_archive_button(tr::now), [=] { + controller->showSection(Info::Stories::Make( + peer, + Info::Stories::Tab::Archive)); + }, &st::menuIconStoriesArchive); + add(tr::lng_stories_my_title(tr::now), [=] { + controller->showSection(Info::Stories::Make(peer)); + }, &st::menuIconStoriesSaved); + } else { + add(tr::lng_profile_send_message(tr::now), [=] { + controller->showPeerHistory(peer); + }, &st::menuIconChatBubble); + add(tr::lng_context_view_profile(tr::now), [=] { + controller->showPeerInfo(peer); + }, &st::menuIconProfile); + const auto in = [&](Data::StorySourcesList list) { + return ranges::contains( + owner->stories().sources(list), + peer->id, + &Data::StoriesSourceInfo::id); + }; + const auto toggle = [=](bool shown) { + owner->stories().toggleHidden( + peer->id, + !shown, + controller->uiShow()); + }; + if (in(Data::StorySourcesList::NotHidden)) { + add(tr::lng_stories_hide_to_contacts(tr::now), [=] { + toggle(false); + }, &st::menuIconCancel); + } + if (in(Data::StorySourcesList::Hidden)) { + add(tr::lng_stories_show_in_chats(tr::now), [=] { + toggle(true); + }, &st::menuIconAddToFolder); + } + } +} + } // namespace Dialogs::Stories diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.h b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.h index bdbb3afea..b42715d54 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_content.h @@ -16,10 +16,15 @@ namespace Main { class Session; } // namespace Main +namespace Window { +class SessionController; +} // namespace Window + namespace Dialogs::Stories { struct Content; class Thumbnail; +struct ShowMenuRequest; [[nodiscard]] rpl::producer ContentForSession( not_null session, @@ -32,4 +37,8 @@ class Thumbnail; [[nodiscard]] std::shared_ptr MakeStoryThumbnail( not_null story); +void FillSourceMenu( + not_null controller, + const ShowMenuRequest &request); + } // namespace Dialogs::Stories diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp index a76cb5deb..b94ef43b1 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/ui/dialogs_stories_list.h" #include "lang/lang_keys.h" +#include "ui/widgets/menu/menu_add_action_callback_factory.h" #include "ui/widgets/popup_menu.h" #include "ui/painter.h" #include "styles/style_dialogs.h" @@ -108,9 +109,6 @@ void List::showContent(Content &&content) { item.nameCache = QImage(); } item.element.unread = element.unread; - item.element.suggestHide = element.suggestHide; - item.element.suggestUnhide = element.suggestUnhide; - item.element.profile = element.profile; } else { _data.items.emplace_back(Item{ .element = element }); } @@ -237,12 +235,8 @@ rpl::producer List::clicks() const { return _clicks.events(); } -rpl::producer List::showProfileRequests() const { - return _showProfileRequests.events(); -} - -rpl::producer List::toggleShown() const { - return _toggleShown.events(); +rpl::producer List::showMenuRequests() const { + return _showMenuRequests.events(); } rpl::producer List::toggleExpandedRequests() const { @@ -852,24 +846,16 @@ void List::contextMenuEvent(QContextMenuEvent *e) { if (_selected < 0 || _data.empty()) { return; } - - auto &item = _data.items[_selected]; - _menu = base::make_unique_q(this); - - const auto id = item.element.id; - if (item.element.profile) { - _menu->addAction(tr::lng_context_view_profile(tr::now), [=] { - _showProfileRequests.fire_copy(id); - }); - } - 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 }); }); + _menu = base::make_unique_q( + this, + st::popupMenuWithIcons); + _showMenuRequests.fire({ + _data.items[_selected].element.id, + Ui::Menu::CreateAddActionCallback(_menu), + }); + if (_menu->empty()) { + _menu = nullptr; + return; } const auto updateAfterMenuDestroyed = [=] { const auto globalPosition = QCursor::pos(); @@ -882,12 +868,8 @@ void List::contextMenuEvent(QContextMenuEvent *e) { _menu.get(), &QObject::destroyed, crl::guard(&_menuGuard, updateAfterMenuDestroyed)); - if (_menu->empty()) { - _menu = nullptr; - } else { - _menu->popup(e->globalPos()); - e->accept(); - } + _menu->popup(e->globalPos()); + e->accept(); } bool List::finishDragging() { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h index e1bebe00f..49391432c 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_stories_list.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/qt/qt_compare.h" #include "base/timer.h" #include "base/weak_ptr.h" +#include "ui/widgets/menu/menu_add_action_callback.h" #include "ui/rp_widget.h" class QPainter; @@ -36,9 +37,6 @@ struct Element { QString name; std::shared_ptr thumbnail; bool unread : 1 = false; - bool suggestHide : 1 = false; - bool suggestUnhide : 1 = false; - bool profile : 1 = false; bool skipSmall : 1 = false; friend inline bool operator==( @@ -48,16 +46,15 @@ struct Element { struct Content { std::vector elements; - bool hidden = false; friend inline bool operator==( const Content &a, const Content &b) = default; }; -struct ToggleShownRequest { +struct ShowMenuRequest { uint64 id = 0; - bool shown = false; + Ui::Menu::MenuCallback callback; }; class List final : public Ui::RpWidget { @@ -72,8 +69,7 @@ public: void setTouchScrollActive(bool active); [[nodiscard]] rpl::producer clicks() const; - [[nodiscard]] rpl::producer showProfileRequests() const; - [[nodiscard]] rpl::producer toggleShown() const; + [[nodiscard]] rpl::producer showMenuRequests() const; [[nodiscard]] rpl::producer toggleExpandedRequests() const; [[nodiscard]] rpl::producer<> entered() const; [[nodiscard]] rpl::producer<> loadMoreRequests() const; @@ -169,8 +165,7 @@ private: Data _hidingData; Fn _shownHeight = 0; rpl::event_stream _clicks; - rpl::event_stream _showProfileRequests; - rpl::event_stream _toggleShown; + rpl::event_stream _showMenuRequests; rpl::event_stream _toggleExpandedRequests; rpl::event_stream<> _entered; rpl::event_stream<> _loadMoreRequests; diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index 7be43b08f..922cbaab8 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -104,6 +104,8 @@ menuIconNewWindow: icon {{ "menu/new_window", menuIconColor }}; menuIconChatBubble: icon {{ "menu/chat_bubble", menuIconColor }}; menuIconPhone: icon {{ "menu/phone", menuIconColor }}; menuIconChannel: icon {{ "menu/channel", menuIconColor }}; +menuIconStoriesSaved: icon {{ "menu/stories_saved", menuIconColor }}; +menuIconStoriesArchive: icon {{ "menu/stories_archive", menuIconColor }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }}; menuIconTTLAnyTextPosition: point(11px, 22px);