mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show box with reacted users.
This commit is contained in:
parent
58c9494c03
commit
c6811640b5
14 changed files with 100 additions and 66 deletions
|
@ -1803,6 +1803,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_context_seen_watched#one" = "{count} Watched";
|
"lng_context_seen_watched#one" = "{count} Watched";
|
||||||
"lng_context_seen_watched#other" = "{count} Watched";
|
"lng_context_seen_watched#other" = "{count} Watched";
|
||||||
"lng_context_seen_watched_none" = "Nobody Watched";
|
"lng_context_seen_watched_none" = "Nobody Watched";
|
||||||
|
"lng_context_seen_reacted#one" = "{count} Reacted";
|
||||||
|
"lng_context_seen_reacted#other" = "{count} Reacted";
|
||||||
|
"lng_context_seen_reacted_none" = "Nobody Reacted";
|
||||||
|
"lng_context_seen_reacted_all" = "Show All Reactions";
|
||||||
|
|
||||||
"lng_send_image_empty" = "Could not send an empty file: {name}";
|
"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}";
|
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1500 MB: {name}";
|
||||||
|
|
|
@ -178,7 +178,7 @@ struct State {
|
||||||
&& (list.front().peer == item->history()->session().userPeerId());
|
&& (list.front().peer == item->history()->session().userPeerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Ui::WhoReadType DetectType(not_null<HistoryItem*> item) {
|
[[nodiscard]] Ui::WhoReadType DetectSeenType(not_null<HistoryItem*> item) {
|
||||||
if (const auto media = item->media()) {
|
if (const auto media = item->media()) {
|
||||||
if (!media->webpage()) {
|
if (!media->webpage()) {
|
||||||
if (const auto document = media->document()) {
|
if (const auto document = media->document()) {
|
||||||
|
@ -425,7 +425,7 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
|
||||||
if (!item->out()) {
|
if (!item->out()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto type = DetectType(item);
|
const auto type = DetectSeenType(item);
|
||||||
const auto unseen = (type == Ui::WhoReadType::Seen)
|
const auto unseen = (type == Ui::WhoReadType::Seen)
|
||||||
? item->unread()
|
? item->unread()
|
||||||
: item->isUnreadMedia();
|
: item->isUnreadMedia();
|
||||||
|
@ -469,33 +469,30 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
|
||||||
return [=](auto consumer) {
|
return [=](auto consumer) {
|
||||||
auto lifetime = rpl::lifetime();
|
auto lifetime = rpl::lifetime();
|
||||||
|
|
||||||
|
const auto resolveWhoRead = WhoReadExists(item);
|
||||||
|
|
||||||
const auto state = lifetime.make_state<State>();
|
const auto state = lifetime.make_state<State>();
|
||||||
state->current.type = [&] {
|
|
||||||
if (const auto media = item->media()) {
|
|
||||||
if (!media->webpage()) {
|
|
||||||
if (const auto document = media->document()) {
|
|
||||||
if (document->isVoiceMessage()) {
|
|
||||||
return Ui::WhoReadType::Listened;
|
|
||||||
} else if (document->isVideoMessage()) {
|
|
||||||
return Ui::WhoReadType::Watched;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ui::WhoReadType::Seen;
|
|
||||||
}();
|
|
||||||
const auto pushNext = [=] {
|
const auto pushNext = [=] {
|
||||||
consumer.put_next_copy(state->current);
|
consumer.put_next_copy(state->current);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto resolveWhoRead = WhoReadExists(item);
|
|
||||||
const auto resolveWhoReacted = item->canViewReactions();
|
const auto resolveWhoReacted = item->canViewReactions();
|
||||||
auto idsWithReactions = (resolveWhoRead && resolveWhoReacted)
|
auto idsWithReactions = (resolveWhoRead && resolveWhoReacted)
|
||||||
? WhoReadOrReactedIds(item, context)
|
? WhoReadOrReactedIds(item, context)
|
||||||
: resolveWhoRead
|
: resolveWhoRead
|
||||||
? (WhoReadIds(item, context) | rpl::map(WithEmptyReactions))
|
? (WhoReadIds(item, context) | rpl::map(WithEmptyReactions))
|
||||||
: WhoReactedIds(item, context);
|
: WhoReactedIds(item, context);
|
||||||
|
state->current.type = resolveWhoRead
|
||||||
|
? DetectSeenType(item)
|
||||||
|
: Ui::WhoReadType::Reacted;
|
||||||
if (resolveWhoReacted) {
|
if (resolveWhoReacted) {
|
||||||
|
const auto &list = item->reactions();
|
||||||
|
state->current.fullReactionsCount = ranges::accumulate(
|
||||||
|
list,
|
||||||
|
0,
|
||||||
|
ranges::plus{},
|
||||||
|
[](const auto &pair) { return pair.second; });
|
||||||
|
|
||||||
// #TODO reactions
|
// #TODO reactions
|
||||||
state->current.mostPopularReaction = item->reactions().front().first;
|
state->current.mostPopularReaction = item->reactions().front().first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,9 +670,6 @@ void InnerWidget::elementReplyTo(const FullMsgId &to) {
|
||||||
void InnerWidget::elementStartInteraction(not_null<const Element*> view) {
|
void InnerWidget::elementStartInteraction(not_null<const Element*> view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::elementShowReactions(not_null<const Element*> view) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void InnerWidget::elementShowSpoilerAnimation() {
|
void InnerWidget::elementShowSpoilerAnimation() {
|
||||||
_spoilerOpacity.stop();
|
_spoilerOpacity.stop();
|
||||||
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
||||||
|
|
|
@ -139,8 +139,6 @@ public:
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
void elementStartInteraction(
|
void elementStartInteraction(
|
||||||
not_null<const HistoryView::Element*> view) override;
|
not_null<const HistoryView::Element*> view) override;
|
||||||
void elementShowReactions(
|
|
||||||
not_null<const HistoryView::Element*> view) override;
|
|
||||||
void elementShowSpoilerAnimation() override;
|
void elementShowSpoilerAnimation() override;
|
||||||
|
|
||||||
~InnerWidget();
|
~InnerWidget();
|
||||||
|
|
|
@ -2082,13 +2082,26 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
const auto participantChosen = [=](uint64 id) {
|
const auto participantChosen = [=](uint64 id) {
|
||||||
controller->showPeerInfo(PeerId(id));
|
controller->showPeerInfo(PeerId(id));
|
||||||
};
|
};
|
||||||
|
const auto weak = Ui::MakeWeak(_menu.get());
|
||||||
|
const auto showAllChosen = [=, id = _dragStateItem->fullId()] {
|
||||||
|
// Pressing on an item that has a submenu doesn't hide it :(
|
||||||
|
if (const auto strong = weak.data()) {
|
||||||
|
strong->hideMenu();
|
||||||
|
}
|
||||||
|
if (const auto item = controller->session().data().message(id)) {
|
||||||
|
controller->window().show(HistoryView::ReactionsListBox(
|
||||||
|
controller,
|
||||||
|
item));
|
||||||
|
}
|
||||||
|
};
|
||||||
if (!_menu->empty()) {
|
if (!_menu->empty()) {
|
||||||
_menu->addSeparator();
|
_menu->addSeparator();
|
||||||
}
|
}
|
||||||
_menu->addAction(Ui::WhoReactedContextAction(
|
_menu->addAction(Ui::WhoReactedContextAction(
|
||||||
_menu.get(),
|
_menu.get(),
|
||||||
Api::WhoReacted(_dragStateItem, this, st::defaultWhoRead),
|
Api::WhoReacted(_dragStateItem, this, st::defaultWhoRead),
|
||||||
participantChosen));
|
participantChosen,
|
||||||
|
showAllChosen));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_menu->empty()) {
|
if (_menu->empty()) {
|
||||||
|
@ -2896,12 +2909,6 @@ void HistoryInner::elementStartInteraction(not_null<const Element*> view) {
|
||||||
_controller->emojiInteractions().startOutgoing(view);
|
_controller->emojiInteractions().startOutgoing(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::elementShowReactions(not_null<const Element*> view) {
|
|
||||||
_controller->window().show(HistoryView::ReactionsListBox(
|
|
||||||
_controller,
|
|
||||||
view->data()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryInner::elementShowSpoilerAnimation() {
|
void HistoryInner::elementShowSpoilerAnimation() {
|
||||||
_spoilerOpacity.stop();
|
_spoilerOpacity.stop();
|
||||||
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
||||||
|
@ -3857,11 +3864,6 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
|
||||||
Instance->elementStartInteraction(view);
|
Instance->elementStartInteraction(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void elementShowReactions(not_null<const Element*> view) override {
|
|
||||||
if (Instance) {
|
|
||||||
Instance->elementShowReactions(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void elementShowSpoilerAnimation() override {
|
void elementShowSpoilerAnimation() override {
|
||||||
if (Instance) {
|
if (Instance) {
|
||||||
Instance->elementShowSpoilerAnimation();
|
Instance->elementShowSpoilerAnimation();
|
||||||
|
|
|
@ -124,7 +124,6 @@ public:
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient();
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient();
|
||||||
void elementReplyTo(const FullMsgId &to);
|
void elementReplyTo(const FullMsgId &to);
|
||||||
void elementStartInteraction(not_null<const Element*> view);
|
void elementStartInteraction(not_null<const Element*> view);
|
||||||
void elementShowReactions(not_null<const Element*> view);
|
|
||||||
void elementShowSpoilerAnimation();
|
void elementShowSpoilerAnimation();
|
||||||
|
|
||||||
void updateBotInfo(bool recount = true);
|
void updateBotInfo(bool recount = true);
|
||||||
|
|
|
@ -187,10 +187,6 @@ void SimpleElementDelegate::elementStartInteraction(
|
||||||
not_null<const Element*> view) {
|
not_null<const Element*> view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleElementDelegate::elementShowReactions(
|
|
||||||
not_null<const Element*> view) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SimpleElementDelegate::elementShowSpoilerAnimation() {
|
void SimpleElementDelegate::elementShowSpoilerAnimation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,6 @@ public:
|
||||||
virtual not_null<Ui::PathShiftGradient*> elementPathShiftGradient() = 0;
|
virtual not_null<Ui::PathShiftGradient*> elementPathShiftGradient() = 0;
|
||||||
virtual void elementReplyTo(const FullMsgId &to) = 0;
|
virtual void elementReplyTo(const FullMsgId &to) = 0;
|
||||||
virtual void elementStartInteraction(not_null<const Element*> view) = 0;
|
virtual void elementStartInteraction(not_null<const Element*> view) = 0;
|
||||||
virtual void elementShowReactions(not_null<const Element*> view) = 0;
|
|
||||||
virtual void elementShowSpoilerAnimation() = 0;
|
virtual void elementShowSpoilerAnimation() = 0;
|
||||||
|
|
||||||
virtual ~ElementDelegate() {
|
virtual ~ElementDelegate() {
|
||||||
|
@ -158,7 +157,6 @@ public:
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
void elementStartInteraction(not_null<const Element*> view) override;
|
void elementStartInteraction(not_null<const Element*> view) override;
|
||||||
void elementShowReactions(not_null<const Element*> view) override;
|
|
||||||
void elementShowSpoilerAnimation() override;
|
void elementShowSpoilerAnimation() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1481,9 +1481,6 @@ void ListWidget::elementReplyTo(const FullMsgId &to) {
|
||||||
void ListWidget::elementStartInteraction(not_null<const Element*> view) {
|
void ListWidget::elementStartInteraction(not_null<const Element*> view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::elementShowReactions(not_null<const Element*> view) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListWidget::elementShowSpoilerAnimation() {
|
void ListWidget::elementShowSpoilerAnimation() {
|
||||||
_spoilerOpacity.stop();
|
_spoilerOpacity.stop();
|
||||||
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
_spoilerOpacity.start([=] { update(); }, 0., 1., st::fadeWrapDuration);
|
||||||
|
|
|
@ -290,7 +290,6 @@ public:
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
void elementStartInteraction(not_null<const Element*> view) override;
|
void elementStartInteraction(not_null<const Element*> view) override;
|
||||||
void elementShowReactions(not_null<const Element*> view) override;
|
|
||||||
void elementShowSpoilerAnimation() override;
|
void elementShowSpoilerAnimation() override;
|
||||||
|
|
||||||
void setEmptyInfoWidget(base::unique_qptr<Ui::RpWidget> &&w);
|
void setEmptyInfoWidget(base::unique_qptr<Ui::RpWidget> &&w);
|
||||||
|
|
|
@ -908,7 +908,7 @@ defaultWhoRead: WhoRead {
|
||||||
}
|
}
|
||||||
whoReadMenu: PopupMenu(popupMenuWithIcons) {
|
whoReadMenu: PopupMenu(popupMenuWithIcons) {
|
||||||
scrollPadding: margins(0px, 6px, 0px, 4px);
|
scrollPadding: margins(0px, 6px, 0px, 4px);
|
||||||
maxHeight: 387px;
|
maxHeight: 400px;
|
||||||
menu: Menu(menuWithIcons) {
|
menu: Menu(menuWithIcons) {
|
||||||
separatorPadding: margins(0px, 4px, 0px, 4px);
|
separatorPadding: margins(0px, 4px, 0px, 4px);
|
||||||
separatorWidth: 6px;
|
separatorWidth: 6px;
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/chat/group_call_userpics.h"
|
#include "ui/chat/group_call_userpics.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_menu_icons.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -58,7 +59,8 @@ public:
|
||||||
Action(
|
Action(
|
||||||
not_null<PopupMenu*> parentMenu,
|
not_null<PopupMenu*> parentMenu,
|
||||||
rpl::producer<WhoReadContent> content,
|
rpl::producer<WhoReadContent> content,
|
||||||
Fn<void(uint64)> participantChosen);
|
Fn<void(uint64)> participantChosen,
|
||||||
|
Fn<void()> showAllChosen);
|
||||||
|
|
||||||
bool isEnabled() const override;
|
bool isEnabled() const override;
|
||||||
not_null<QAction*> action() const override;
|
not_null<QAction*> action() const override;
|
||||||
|
@ -83,6 +85,7 @@ private:
|
||||||
const not_null<PopupMenu*> _parentMenu;
|
const not_null<PopupMenu*> _parentMenu;
|
||||||
const not_null<QAction*> _dummyAction;
|
const not_null<QAction*> _dummyAction;
|
||||||
const Fn<void(uint64)> _participantChosen;
|
const Fn<void(uint64)> _participantChosen;
|
||||||
|
const Fn<void()> _showAllChosen;
|
||||||
const std::unique_ptr<GroupCallUserpics> _userpics;
|
const std::unique_ptr<GroupCallUserpics> _userpics;
|
||||||
const style::Menu &_st;
|
const style::Menu &_st;
|
||||||
|
|
||||||
|
@ -170,8 +173,15 @@ void EntryAction::paint(Painter &&p) {
|
||||||
paintRipple(p, 0, 0);
|
paintRipple(p, 0, 0);
|
||||||
}
|
}
|
||||||
const auto photoSize = st::defaultWhoRead.photoSize;
|
const auto photoSize = st::defaultWhoRead.photoSize;
|
||||||
|
const auto photoLeft = st::defaultWhoRead.photoLeft;
|
||||||
const auto photoTop = (height() - photoSize) / 2;
|
const auto photoTop = (height() - photoSize) / 2;
|
||||||
p.drawImage(st::defaultWhoRead.photoLeft, photoTop, _userpic);
|
if (!_userpic.isNull()) {
|
||||||
|
p.drawImage(photoLeft, photoTop, _userpic);
|
||||||
|
} else if (!_emoji) {
|
||||||
|
st::menuIconReactions.paintInCenter(
|
||||||
|
p,
|
||||||
|
QRect(photoLeft, photoTop, photoSize, photoSize));
|
||||||
|
}
|
||||||
|
|
||||||
p.setPen(selected
|
p.setPen(selected
|
||||||
? _st.itemFgOver
|
? _st.itemFgOver
|
||||||
|
@ -201,11 +211,13 @@ void EntryAction::paint(Painter &&p) {
|
||||||
Action::Action(
|
Action::Action(
|
||||||
not_null<PopupMenu*> parentMenu,
|
not_null<PopupMenu*> parentMenu,
|
||||||
rpl::producer<WhoReadContent> content,
|
rpl::producer<WhoReadContent> content,
|
||||||
Fn<void(uint64)> participantChosen)
|
Fn<void(uint64)> participantChosen,
|
||||||
|
Fn<void()> showAllChosen)
|
||||||
: ItemBase(parentMenu->menu(), parentMenu->menu()->st())
|
: ItemBase(parentMenu->menu(), parentMenu->menu()->st())
|
||||||
, _parentMenu(parentMenu)
|
, _parentMenu(parentMenu)
|
||||||
, _dummyAction(CreateChild<QAction>(parentMenu->menu().get()))
|
, _dummyAction(CreateChild<QAction>(parentMenu->menu().get()))
|
||||||
, _participantChosen(std::move(participantChosen))
|
, _participantChosen(std::move(participantChosen))
|
||||||
|
, _showAllChosen(std::move(showAllChosen))
|
||||||
, _userpics(std::make_unique<GroupCallUserpics>(
|
, _userpics(std::make_unique<GroupCallUserpics>(
|
||||||
st::defaultWhoRead.userpics,
|
st::defaultWhoRead.userpics,
|
||||||
rpl::never<bool>(),
|
rpl::never<bool>(),
|
||||||
|
@ -263,6 +275,10 @@ Action::Action(
|
||||||
if (const auto onstack = _participantChosen) {
|
if (const auto onstack = _participantChosen) {
|
||||||
onstack(_content.participants.front().id);
|
onstack(_content.participants.front().id);
|
||||||
}
|
}
|
||||||
|
} else if (_content.fullReactionsCount > 0) {
|
||||||
|
if (const auto onstack = _showAllChosen) {
|
||||||
|
onstack();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
@ -280,7 +296,10 @@ void Action::resolveMinWidth() {
|
||||||
return _st.itemStyle.font->width(text);
|
return _st.itemStyle.font->width(text);
|
||||||
};
|
};
|
||||||
const auto maxTextWidth = std::max({
|
const auto maxTextWidth = std::max({
|
||||||
width(tr::lng_context_seen_text(tr::now, lt_count_short, 999999999)),
|
width(tr::lng_context_seen_reacted(
|
||||||
|
tr::now,
|
||||||
|
lt_count_short,
|
||||||
|
999'999'999)),
|
||||||
width(tr::lng_context_seen_text(tr::now, lt_count, 999)),
|
width(tr::lng_context_seen_text(tr::now, lt_count, 999)),
|
||||||
width(tr::lng_context_seen_listened(tr::now, lt_count, 999)),
|
width(tr::lng_context_seen_listened(tr::now, lt_count, 999)),
|
||||||
width(tr::lng_context_seen_watched(tr::now, lt_count, 999)) });
|
width(tr::lng_context_seen_watched(tr::now, lt_count, 999)) });
|
||||||
|
@ -327,21 +346,18 @@ void Action::populateSubmenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto submenu = _parentMenu->ensureSubmenu(action());
|
const auto submenu = _parentMenu->ensureSubmenu(action());
|
||||||
if (_submenuActions.size() > _content.participants.size()) {
|
const auto reactions = ranges::count_if(
|
||||||
|
_content.participants,
|
||||||
|
[](const auto &p) { return !p.reaction.isEmpty(); });
|
||||||
|
const auto addShowAll = (_content.fullReactionsCount > reactions);
|
||||||
|
const auto actionsCount = int(_content.participants.size())
|
||||||
|
+ (addShowAll ? 1 : 0);
|
||||||
|
if (_submenuActions.size() > actionsCount) {
|
||||||
_submenuActions.clear();
|
_submenuActions.clear();
|
||||||
submenu->clearActions();
|
submenu->clearActions();
|
||||||
}
|
}
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
for (const auto &participant : _content.participants) {
|
const auto append = [&](EntryData &&data) {
|
||||||
const auto chosen = [call = _participantChosen, id = participant.id] {
|
|
||||||
call(id);
|
|
||||||
};
|
|
||||||
auto data = EntryData{
|
|
||||||
.text = participant.name,
|
|
||||||
.reaction = participant.reaction,
|
|
||||||
.userpic = participant.userpicLarge,
|
|
||||||
.callback = chosen,
|
|
||||||
};
|
|
||||||
if (index < _submenuActions.size()) {
|
if (index < _submenuActions.size()) {
|
||||||
_submenuActions[index]->setData(std::move(data));
|
_submenuActions[index]->setData(std::move(data));
|
||||||
} else {
|
} else {
|
||||||
|
@ -353,6 +369,23 @@ void Action::populateSubmenu() {
|
||||||
submenu->addAction(std::move(item));
|
submenu->addAction(std::move(item));
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
|
};
|
||||||
|
for (const auto &participant : _content.participants) {
|
||||||
|
const auto chosen = [call = _participantChosen, id = participant.id] {
|
||||||
|
call(id);
|
||||||
|
};
|
||||||
|
append({
|
||||||
|
.text = participant.name,
|
||||||
|
.reaction = participant.reaction,
|
||||||
|
.userpic = participant.userpicLarge,
|
||||||
|
.callback = chosen,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (addShowAll) {
|
||||||
|
append({
|
||||||
|
.text = tr::lng_context_seen_reacted_all(tr::now),
|
||||||
|
.callback = _showAllChosen,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_parentMenu->checkSubmenuShow();
|
_parentMenu->checkSubmenuShow();
|
||||||
}
|
}
|
||||||
|
@ -410,13 +443,22 @@ void Action::paint(Painter &p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Action::refreshText() {
|
void Action::refreshText() {
|
||||||
const auto count = int(_content.participants.size());
|
const auto usersCount = int(_content.participants.size());
|
||||||
|
const auto count = std::max(_content.fullReactionsCount, usersCount);
|
||||||
_text.setMarkedText(
|
_text.setMarkedText(
|
||||||
_st.itemStyle,
|
_st.itemStyle,
|
||||||
{ (_content.unknown
|
{ (_content.unknown
|
||||||
? tr::lng_context_seen_loading(tr::now)
|
? tr::lng_context_seen_loading(tr::now)
|
||||||
: (count == 1)
|
: (count == 1)
|
||||||
? _content.participants.front().name
|
? _content.participants.front().name
|
||||||
|
: (_content.type == WhoReadType::Reacted
|
||||||
|
|| (count > 0 && _content.fullReactionsCount > usersCount))
|
||||||
|
? (count
|
||||||
|
? tr::lng_context_seen_reacted(
|
||||||
|
tr::now,
|
||||||
|
lt_count_short,
|
||||||
|
count)
|
||||||
|
: tr::lng_context_seen_reacted_none(tr::now))
|
||||||
: (_content.type == WhoReadType::Watched)
|
: (_content.type == WhoReadType::Watched)
|
||||||
? (count
|
? (count
|
||||||
? tr::lng_context_seen_watched(tr::now, lt_count, count)
|
? tr::lng_context_seen_watched(tr::now, lt_count, count)
|
||||||
|
@ -492,11 +534,13 @@ bool operator!=(const WhoReadParticipant &a, const WhoReadParticipant &b) {
|
||||||
base::unique_qptr<Menu::ItemBase> WhoReactedContextAction(
|
base::unique_qptr<Menu::ItemBase> WhoReactedContextAction(
|
||||||
not_null<PopupMenu*> menu,
|
not_null<PopupMenu*> menu,
|
||||||
rpl::producer<WhoReadContent> content,
|
rpl::producer<WhoReadContent> content,
|
||||||
Fn<void(uint64)> participantChosen) {
|
Fn<void(uint64)> participantChosen,
|
||||||
|
Fn<void()> showAllChosen) {
|
||||||
return base::make_unique_q<Action>(
|
return base::make_unique_q<Action>(
|
||||||
menu,
|
menu,
|
||||||
std::move(content),
|
std::move(content),
|
||||||
std::move(participantChosen));
|
std::move(participantChosen),
|
||||||
|
std::move(showAllChosen));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -34,18 +34,21 @@ enum class WhoReadType {
|
||||||
Seen,
|
Seen,
|
||||||
Listened,
|
Listened,
|
||||||
Watched,
|
Watched,
|
||||||
|
Reacted,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WhoReadContent {
|
struct WhoReadContent {
|
||||||
std::vector<WhoReadParticipant> participants;
|
std::vector<WhoReadParticipant> participants;
|
||||||
WhoReadType type = WhoReadType::Seen;
|
WhoReadType type = WhoReadType::Seen;
|
||||||
QString mostPopularReaction;
|
QString mostPopularReaction;
|
||||||
|
int fullReactionsCount = 0;
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] base::unique_qptr<Menu::ItemBase> WhoReactedContextAction(
|
[[nodiscard]] base::unique_qptr<Menu::ItemBase> WhoReactedContextAction(
|
||||||
not_null<PopupMenu*> menu,
|
not_null<PopupMenu*> menu,
|
||||||
rpl::producer<WhoReadContent> content,
|
rpl::producer<WhoReadContent> content,
|
||||||
Fn<void(uint64)> participantChosen);
|
Fn<void(uint64)> participantChosen,
|
||||||
|
Fn<void()> showAllChosen);
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0a0e5e12589d7918a31d60b100dc32de68ef2e8a
|
Subproject commit a3b3745d7c7ff94cfeac78daca2b0d89cb6c865e
|
Loading…
Add table
Reference in a new issue