Improve story source context menus.

This commit is contained in:
John Preston 2023-06-30 12:48:42 +04:00
parent 074a4e3c92
commit 6c960243a9
16 changed files with 99 additions and 82 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -3814,8 +3814,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji"; "lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
"lng_stories_my_name" = "My Story"; "lng_stories_my_name" = "My Story";
"lng_stories_hide_to_contacts" = "Archive"; "lng_stories_hide_to_contacts" = "Hide";
"lng_stories_show_in_chats" = "Unarchive"; "lng_stories_show_in_chats" = "Show in Chats";
"lng_stories_row_count#one" = "{count} Story"; "lng_stories_row_count#one" = "{count} Story";
"lng_stories_row_count#other" = "{count} Stories"; "lng_stories_row_count#other" = "{count} Stories";
"lng_stories_row_unread_and_one" = "{accumulated}, {user}"; "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_title" = "Stories Archive";
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile."; "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_reply_sent" = "Message Sent";
"lng_stories_hidden_to_contacts" = "Stories from {user} will now be shown in Contacts, not Chats."; "lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Contacts**.";
"lng_stories_shown_in_chats" = "Stories from {user} will now be shown in Chats, not 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_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#one" = "Are you sure you want to delete {count} story?";
"lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?"; "lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?";

View file

@ -57,10 +57,10 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
&sessionController->session()); &sessionController->session());
const auto raw = controller.get(); const auto raw = controller.get();
auto init = [=](not_null<PeerListBox*> box) { auto init = [=](not_null<PeerListBox*> box) {
using namespace Dialogs; using namespace Dialogs::Stories;
struct State { struct State {
Stories::List *stories = nullptr; List *stories = nullptr;
QPointer<::Ui::IconButton> toggleSort; QPointer<::Ui::IconButton> toggleSort;
Mode mode = ContactsBoxController::SortMode::Online; Mode mode = ContactsBoxController::SortMode::Online;
::Ui::Animations::Simple scrollAnimation; ::Ui::Animations::Simple scrollAnimation;
@ -82,10 +82,10 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
}); });
raw->setSortMode(Mode::Online); raw->setSortMode(Mode::Online);
auto list = object_ptr<Stories::List>( auto list = object_ptr<List>(
box, box,
st::dialogsStoriesList, st::dialogsStoriesList,
Stories::ContentForSession( ContentForSession(
&sessionController->session(), &sessionController->session(),
Data::StorySourcesList::Hidden), Data::StorySourcesList::Hidden),
[=] { return state->stories->height() - box->scrollTop(); }); [=] { return state->stories->height() - box->scrollTop(); });
@ -102,17 +102,9 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
Data::StorySourcesList::Hidden); Data::StorySourcesList::Hidden);
}, raw->lifetime()); }, raw->lifetime());
raw->showProfileRequests( raw->showMenuRequests(
) | rpl::start_with_next([=](uint64 id) { ) | rpl::start_with_next([=](const ShowMenuRequest &request) {
sessionController->showPeerInfo(PeerId(int64(id))); FillSourceMenu(sessionController, request);
}, raw->lifetime());
raw->toggleShown(
) | rpl::start_with_next([=](Stories::ToggleShownRequest request) {
stories->toggleHidden(
PeerId(int64(request.id)),
!request.shown,
sessionController->uiShow());
}, raw->lifetime()); }, raw->lifetime());
raw->loadMoreRequests( raw->loadMoreRequests(

View file

@ -76,7 +76,6 @@ StoriesSourceInfo StoriesSource::info() const {
.last = ids.empty() ? 0 : ids.back().date, .last = ids.empty() ? 0 : ids.back().date,
.unread = unread(), .unread = unread(),
.premium = user->isPremium(), .premium = user->isPremium(),
.hidden = hidden,
}; };
} }
@ -943,7 +942,7 @@ void Stories::toggleHidden(
tr::now, tr::now,
lt_user, lt_user,
Ui::Text::Bold(name), Ui::Text::Bold(name),
Ui::Text::WithEntities)); Ui::Text::RichLangValue));
} }
}); });

View file

@ -43,7 +43,6 @@ struct StoriesSourceInfo {
TimeId last = 0; TimeId last = 0;
bool unread = false; bool unread = false;
bool premium = false; bool premium = false;
bool hidden = false;
friend inline bool operator==( friend inline bool operator==(
StoriesSourceInfo, StoriesSourceInfo,

View file

@ -347,17 +347,9 @@ InnerWidget::InnerWidget(
Data::StorySourcesList::NotHidden); Data::StorySourcesList::NotHidden);
}, lifetime()); }, lifetime());
_stories->showProfileRequests( _stories->showMenuRequests(
) | rpl::start_with_next([=](uint64 id) { ) | rpl::start_with_next([=](const Stories::ShowMenuRequest &request) {
_controller->showPeerInfo(PeerId(int64(id))); FillSourceMenu(_controller, request);
}, lifetime());
_stories->toggleShown(
) | rpl::start_with_next([=](Stories::ToggleShownRequest request) {
session().data().stories().toggleHidden(
PeerId(int64(request.id)),
!request.shown,
_controller->uiShow());
}, lifetime()); }, lifetime());
_stories->loadMoreRequests( _stories->loadMoreRequests(

View file

@ -17,9 +17,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_stories.h" #include "data/data_stories.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "dialogs/ui/dialogs_stories_list.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 "main/main_session.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "window/window_session_controller.h"
#include "styles/style_menu_icons.h"
namespace Dialogs::Stories { namespace Dialogs::Stories {
namespace { namespace {
@ -325,9 +330,7 @@ State::State(not_null<Data::Stories*> data, Data::StorySourcesList list)
} }
Content State::next() { Content State::next() {
auto result = Content{ auto result = Content();
.hidden = (_list == Data::StorySourcesList::Hidden)
};
const auto &sources = _data->sources(_list); const auto &sources = _data->sources(_list);
result.elements.reserve(sources.size()); result.elements.reserve(sources.size());
for (const auto &info : sources) { for (const auto &info : sources) {
@ -349,9 +352,6 @@ Content State::next() {
: user->shortName()), : user->shortName()),
.thumbnail = std::move(userpic), .thumbnail = std::move(userpic),
.unread = info.unread, .unread = info.unread,
.suggestHide = !info.hidden,
.suggestUnhide = info.hidden,
.profile = true,
.skipSmall = user->isSelf(), .skipSmall = user->isSelf(),
}); });
} }
@ -466,4 +466,51 @@ std::shared_ptr<Thumbnail> MakeStoryThumbnail(
}); });
} }
void FillSourceMenu(
not_null<Window::SessionController*> 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 } // namespace Dialogs::Stories

View file

@ -16,10 +16,15 @@ namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
namespace Window {
class SessionController;
} // namespace Window
namespace Dialogs::Stories { namespace Dialogs::Stories {
struct Content; struct Content;
class Thumbnail; class Thumbnail;
struct ShowMenuRequest;
[[nodiscard]] rpl::producer<Content> ContentForSession( [[nodiscard]] rpl::producer<Content> ContentForSession(
not_null<Main::Session*> session, not_null<Main::Session*> session,
@ -32,4 +37,8 @@ class Thumbnail;
[[nodiscard]] std::shared_ptr<Thumbnail> MakeStoryThumbnail( [[nodiscard]] std::shared_ptr<Thumbnail> MakeStoryThumbnail(
not_null<Data::Story*> story); not_null<Data::Story*> story);
void FillSourceMenu(
not_null<Window::SessionController*> controller,
const ShowMenuRequest &request);
} // namespace Dialogs::Stories } // namespace Dialogs::Stories

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/ui/dialogs_stories_list.h" #include "dialogs/ui/dialogs_stories_list.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "styles/style_dialogs.h" #include "styles/style_dialogs.h"
@ -108,9 +109,6 @@ void List::showContent(Content &&content) {
item.nameCache = QImage(); item.nameCache = QImage();
} }
item.element.unread = element.unread; item.element.unread = element.unread;
item.element.suggestHide = element.suggestHide;
item.element.suggestUnhide = element.suggestUnhide;
item.element.profile = element.profile;
} else { } else {
_data.items.emplace_back(Item{ .element = element }); _data.items.emplace_back(Item{ .element = element });
} }
@ -237,12 +235,8 @@ rpl::producer<uint64> List::clicks() const {
return _clicks.events(); return _clicks.events();
} }
rpl::producer<uint64> List::showProfileRequests() const { rpl::producer<ShowMenuRequest> List::showMenuRequests() const {
return _showProfileRequests.events(); return _showMenuRequests.events();
}
rpl::producer<ToggleShownRequest> List::toggleShown() const {
return _toggleShown.events();
} }
rpl::producer<bool> List::toggleExpandedRequests() const { rpl::producer<bool> List::toggleExpandedRequests() const {
@ -852,24 +846,16 @@ void List::contextMenuEvent(QContextMenuEvent *e) {
if (_selected < 0 || _data.empty()) { if (_selected < 0 || _data.empty()) {
return; return;
} }
_menu = base::make_unique_q<Ui::PopupMenu>(
auto &item = _data.items[_selected]; this,
_menu = base::make_unique_q<Ui::PopupMenu>(this); st::popupMenuWithIcons);
_showMenuRequests.fire({
const auto id = item.element.id; _data.items[_selected].element.id,
if (item.element.profile) { Ui::Menu::CreateAddActionCallback(_menu),
_menu->addAction(tr::lng_context_view_profile(tr::now), [=] { });
_showProfileRequests.fire_copy(id); if (_menu->empty()) {
}); _menu = nullptr;
} return;
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 updateAfterMenuDestroyed = [=] {
const auto globalPosition = QCursor::pos(); const auto globalPosition = QCursor::pos();
@ -882,12 +868,8 @@ void List::contextMenuEvent(QContextMenuEvent *e) {
_menu.get(), _menu.get(),
&QObject::destroyed, &QObject::destroyed,
crl::guard(&_menuGuard, updateAfterMenuDestroyed)); crl::guard(&_menuGuard, updateAfterMenuDestroyed));
if (_menu->empty()) { _menu->popup(e->globalPos());
_menu = nullptr; e->accept();
} else {
_menu->popup(e->globalPos());
e->accept();
}
} }
bool List::finishDragging() { bool List::finishDragging() {

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/qt/qt_compare.h" #include "base/qt/qt_compare.h"
#include "base/timer.h" #include "base/timer.h"
#include "base/weak_ptr.h" #include "base/weak_ptr.h"
#include "ui/widgets/menu/menu_add_action_callback.h"
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
class QPainter; class QPainter;
@ -36,9 +37,6 @@ struct Element {
QString name; QString name;
std::shared_ptr<Thumbnail> thumbnail; std::shared_ptr<Thumbnail> thumbnail;
bool unread : 1 = false; bool unread : 1 = false;
bool suggestHide : 1 = false;
bool suggestUnhide : 1 = false;
bool profile : 1 = false;
bool skipSmall : 1 = false; bool skipSmall : 1 = false;
friend inline bool operator==( friend inline bool operator==(
@ -48,16 +46,15 @@ struct Element {
struct Content { struct Content {
std::vector<Element> elements; std::vector<Element> elements;
bool hidden = false;
friend inline bool operator==( friend inline bool operator==(
const Content &a, const Content &a,
const Content &b) = default; const Content &b) = default;
}; };
struct ToggleShownRequest { struct ShowMenuRequest {
uint64 id = 0; uint64 id = 0;
bool shown = false; Ui::Menu::MenuCallback callback;
}; };
class List final : public Ui::RpWidget { class List final : public Ui::RpWidget {
@ -72,8 +69,7 @@ public:
void setTouchScrollActive(bool active); void setTouchScrollActive(bool active);
[[nodiscard]] rpl::producer<uint64> clicks() const; [[nodiscard]] rpl::producer<uint64> clicks() const;
[[nodiscard]] rpl::producer<uint64> showProfileRequests() const; [[nodiscard]] rpl::producer<ShowMenuRequest> showMenuRequests() const;
[[nodiscard]] rpl::producer<ToggleShownRequest> toggleShown() const;
[[nodiscard]] rpl::producer<bool> toggleExpandedRequests() const; [[nodiscard]] rpl::producer<bool> toggleExpandedRequests() const;
[[nodiscard]] rpl::producer<> entered() const; [[nodiscard]] rpl::producer<> entered() const;
[[nodiscard]] rpl::producer<> loadMoreRequests() const; [[nodiscard]] rpl::producer<> loadMoreRequests() const;
@ -169,8 +165,7 @@ private:
Data _hidingData; Data _hidingData;
Fn<int()> _shownHeight = 0; Fn<int()> _shownHeight = 0;
rpl::event_stream<uint64> _clicks; rpl::event_stream<uint64> _clicks;
rpl::event_stream<uint64> _showProfileRequests; rpl::event_stream<ShowMenuRequest> _showMenuRequests;
rpl::event_stream<ToggleShownRequest> _toggleShown;
rpl::event_stream<bool> _toggleExpandedRequests; rpl::event_stream<bool> _toggleExpandedRequests;
rpl::event_stream<> _entered; rpl::event_stream<> _entered;
rpl::event_stream<> _loadMoreRequests; rpl::event_stream<> _loadMoreRequests;

View file

@ -104,6 +104,8 @@ menuIconNewWindow: icon {{ "menu/new_window", menuIconColor }};
menuIconChatBubble: icon {{ "menu/chat_bubble", menuIconColor }}; menuIconChatBubble: icon {{ "menu/chat_bubble", menuIconColor }};
menuIconPhone: icon {{ "menu/phone", menuIconColor }}; menuIconPhone: icon {{ "menu/phone", menuIconColor }};
menuIconChannel: icon {{ "menu/channel", 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 }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
menuIconTTLAnyTextPosition: point(11px, 22px); menuIconTTLAnyTextPosition: point(11px, 22px);