diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ad95c3e93..e3240b970 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1709,6 +1709,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_context_seen_text#other" = "{count} Seen"; "lng_context_seen_listened#one" = "{count} Listened"; "lng_context_seen_listened#other" = "{count} Listened"; +"lng_context_seen_watched#one" = "{count} Watched"; +"lng_context_seen_watched#other" = "{count} Watched"; "lng_send_image_empty" = "Could not send an empty file: {name}"; "lng_send_image_too_large" = "Could not send a file, because it is larger than 1500 MB: {name}"; diff --git a/Telegram/SourceFiles/api/api_who_read.cpp b/Telegram/SourceFiles/api/api_who_read.cpp index b6f79cbaf..ffb1006cb 100644 --- a/Telegram/SourceFiles/api/api_who_read.cpp +++ b/Telegram/SourceFiles/api/api_who_read.cpp @@ -182,6 +182,7 @@ rpl::producer WhoRead( }) | ranges::views::transform([](UserData *user) { return Ui::WhoReadParticipant{ .name = user->name, + .id = user->id.value, }; }) | ranges::to_vector; return Ui::WhoReadContent{ diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 3f4df3b9a..d74c757d6 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1587,7 +1587,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { const auto itemId = item->fullId(); if (Api::WhoReadExists(item)) { const auto participantChosen = [=](uint64 id) { - controller->showPeerInfo(PeerId(UserId(id))); + controller->showPeerInfo(PeerId(id)); }; _menu->addAction(Ui::WhoReadContextAction( _menu.get(), diff --git a/Telegram/SourceFiles/ui/controls/who_read_context_action.cpp b/Telegram/SourceFiles/ui/controls/who_read_context_action.cpp index 65a6393db..6059ea6fc 100644 --- a/Telegram/SourceFiles/ui/controls/who_read_context_action.cpp +++ b/Telegram/SourceFiles/ui/controls/who_read_context_action.cpp @@ -41,10 +41,10 @@ private: void paint(Painter &p); void updateUserpicsFromContent(); - void setupSubMenu(); void resolveMinWidth(); void refreshText(); void refreshDimensions(); + void populateSubmenu(); const not_null _parentMenu; const not_null _dummyAction; @@ -81,19 +81,13 @@ Action::Action( rpl::never(), [=] { update(); })) , _st(parentMenu->menu()->st()) -, _height(st::ttlItemPadding.top() +, _height(_st.itemPadding.top() + _st.itemStyle.font->height - + st::ttlItemTimerFont->height - + st::ttlItemPadding.bottom()) { + + _st.itemPadding.bottom()) { const auto parent = parentMenu->menu(); setAcceptBoth(true); initResizeHook(parent->sizeValue()); - setClickedCallback([=] { - if (!_content.participants.empty()) { - setupSubMenu(); - } - }); resolveMinWidth(); auto copy = std::move( @@ -110,7 +104,11 @@ Action::Action( std::move( content ) | rpl::start_with_next([=](WhoReadContent &&content) { + const auto changed = (_content.participants != content.participants); _content = content; + if (changed) { + PostponeCall(this, [=] { populateSubmenu(); }); + } updateUserpicsFromContent(); refreshText(); refreshDimensions(); @@ -161,8 +159,19 @@ void Action::updateUserpicsFromContent() { _userpics->update(users, true); } -void Action::setupSubMenu() { - +void Action::populateSubmenu() { + if (_content.participants.empty()) { + _parentMenu->removeSubmenu(action()); + return; + } + const auto submenu = _parentMenu->ensureSubmenu(action()); + submenu->clearActions(); + for (const auto &participant : _content.participants) { + const auto chosen = [call = _participantChosen, id = participant.id] { + call(id); + }; + submenu->addAction(participant.name, chosen); + } } void Action::paint(Painter &p) { @@ -196,7 +205,9 @@ void Action::refreshText() { ? tr::lng_context_seen_loading(tr::now) : (count == 1) ? _content.participants.front().name - : _content.listened + : (_content.type == WhoReadType::Watched) + ? tr::lng_context_seen_watched(tr::now, lt_count, count) + : (_content.type == WhoReadType::Listened) ? tr::lng_context_seen_listened(tr::now, lt_count, count) : tr::lng_context_seen_text(tr::now, lt_count, count)) }, MenuTextOptions); @@ -250,6 +261,16 @@ void Action::handleKeyPress(not_null e) { } // namespace +bool operator==(const WhoReadParticipant &a, const WhoReadParticipant &b) { + return (a.id == b.id) + && (a.name == b.name) + && (a.userpicKey == b.userpicKey); +} + +bool operator!=(const WhoReadParticipant &a, const WhoReadParticipant &b) { + return !(a == b); +} + base::unique_qptr WhoReadContextAction( not_null menu, rpl::producer content, diff --git a/Telegram/SourceFiles/ui/controls/who_read_context_action.h b/Telegram/SourceFiles/ui/controls/who_read_context_action.h index 24f60669d..d577940d4 100644 --- a/Telegram/SourceFiles/ui/controls/who_read_context_action.h +++ b/Telegram/SourceFiles/ui/controls/who_read_context_action.h @@ -23,9 +23,18 @@ struct WhoReadParticipant { uint64 id = 0; }; +bool operator==(const WhoReadParticipant &a, const WhoReadParticipant &b); +bool operator!=(const WhoReadParticipant &a, const WhoReadParticipant &b); + +enum class WhoReadType { + Seen, + Listened, + Watched, +}; + struct WhoReadContent { std::vector participants; - bool listened = false; + WhoReadType type = WhoReadType::Seen; bool unknown = false; }; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index e0339b7da..6651d9f9b 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit e0339b7da1e344bf13b7544676da9613fa8a5640 +Subproject commit 6651d9f9b6fb7ebc9d18e6b3429862477d891b2e