Show message author to admins in monoforums.

This commit is contained in:
John Preston 2025-06-04 21:33:27 +04:00
parent ee3d70f879
commit 5c4b1f6638
7 changed files with 133 additions and 11 deletions

View file

@ -4252,6 +4252,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_seen_reacted#other" = "{count} Reacted"; "lng_context_seen_reacted#other" = "{count} Reacted";
"lng_context_seen_reacted_none" = "Nobody Reacted"; "lng_context_seen_reacted_none" = "Nobody Reacted";
"lng_context_seen_reacted_all" = "Show All Reactions"; "lng_context_seen_reacted_all" = "Show All Reactions";
"lng_context_sent_by" = "Sent by {user}";
"lng_context_set_as_quick" = "Set As Quick"; "lng_context_set_as_quick" = "Set As Quick";
"lng_context_filter_by_tag" = "Filter by Tag"; "lng_context_filter_by_tag" = "Filter by Tag";
"lng_context_tag_add_name" = "Add Name"; "lng_context_tag_add_name" = "Add Name";

View file

@ -269,6 +269,11 @@ whenReadPadding: margins(34px, 3px, 17px, 4px);
whenReadIconPosition: point(8px, 0px); whenReadIconPosition: point(8px, 0px);
whenReadSkip: 3px; whenReadSkip: 3px;
whenReadShowPadding: margins(6px, 0px, 6px, 2px); whenReadShowPadding: margins(6px, 0px, 6px, 2px);
whoSentItem: Menu(defaultMenu) {
itemPadding: margins(17px, 3px, 17px, 4px);
itemRightSkip: 0px;
itemStyle: whenReadStyle;
}
switchPmButton: RoundButton(defaultBoxButton) { switchPmButton: RoundButton(defaultBoxButton) {
width: 320px; width: 320px;

View file

@ -3103,7 +3103,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
leaderOrSelf, leaderOrSelf,
_controller); _controller);
} else if (leaderOrSelf) { } else if (leaderOrSelf) {
HistoryView::MaybeAddWhenEditedForwardedAction(_menu, leaderOrSelf); HistoryView::MaybeAddWhenEditedForwardedAction(
_menu,
leaderOrSelf,
_controller);
} }
if (_menu->empty()) { if (_menu->empty()) {

View file

@ -1706,6 +1706,10 @@ bool HistoryItem::isSponsored() const {
return _flags & MessageFlag::Sponsored; return _flags & MessageFlag::Sponsored;
} }
bool HistoryItem::canLookupMessageAuthor() const {
return isRegular() && _history->amMonoforumAdmin() && _from->isChannel();
}
bool HistoryItem::skipNotification() const { bool HistoryItem::skipNotification() const {
if (isSilent() && (_flags & MessageFlag::IsContactSignUp)) { if (isSilent() && (_flags & MessageFlag::IsContactSignUp)) {
return true; return true;
@ -1713,8 +1717,7 @@ bool HistoryItem::skipNotification() const {
if (forwarded->imported) { if (forwarded->imported) {
return true; return true;
} }
} else if (_history->amMonoforumAdmin() } else if (canLookupMessageAuthor()) {
&& from() == _history->peer->monoforumBroadcast()) {
return true; return true;
} }
return false; return false;

View file

@ -179,6 +179,7 @@ public:
[[nodiscard]] bool isFromScheduled() const; [[nodiscard]] bool isFromScheduled() const;
[[nodiscard]] bool isScheduled() const; [[nodiscard]] bool isScheduled() const;
[[nodiscard]] bool isSponsored() const; [[nodiscard]] bool isSponsored() const;
[[nodiscard]] bool canLookupMessageAuthor() const;
[[nodiscard]] bool skipNotification() const; [[nodiscard]] bool skipNotification() const;
[[nodiscard]] bool isUserpicSuggestion() const; [[nodiscard]] bool isUserpicSuggestion() const;
[[nodiscard]] BusinessShortcutId shortcutId() const; [[nodiscard]] BusinessShortcutId shortcutId() const;

View file

@ -113,7 +113,8 @@ bool HasEditMessageAction(
|| (context != Context::History || (context != Context::History
&& context != Context::Replies && context != Context::Replies
&& context != Context::ShortcutMessages && context != Context::ShortcutMessages
&& context != Context::ScheduledTopic)) { && context != Context::ScheduledTopic
&& context != Context::Monoforum)) {
return false; return false;
} }
const auto peer = item->history()->peer; const auto peer = item->history()->peer;
@ -1154,6 +1155,97 @@ void ShowWhoReadInfo(
controller->showSection(std::move(memento)); controller->showSection(std::move(memento));
} }
[[nodiscard]] rpl::producer<not_null<UserData*>> LookupMessageAuthor(
not_null<HistoryItem*> item) {
struct Author {
UserData *user = nullptr;
std::vector<Fn<void(UserData*)>> callbacks;
};
struct Authors {
base::flat_map<FullMsgId, Author> map;
};
static auto Cache = base::flat_map<not_null<Main::Session*>, Authors>();
const auto channel = item->history()->peer->asChannel();
const auto session = &channel->session();
const auto id = item->fullId();
if (!Cache.contains(session)) {
Cache.emplace(session);
session->lifetime().add([session] {
Cache.remove(session);
});
}
return [channel, id](auto consumer) {
const auto session = &channel->session();
auto &map = Cache[session].map;
auto i = map.find(id);
if (i == end(map)) {
i = map.emplace(id).first;
const auto finishWith = [=](UserData *user) {
auto &entry = Cache[session].map[id];
entry.user = user;
for (const auto &callback : base::take(entry.callbacks)) {
callback(user);
}
};
session->api().request(MTPchannels_GetMessageAuthor(
channel->inputChannel,
MTP_int(id.msg.bare)
)).done([=](const MTPUser &result) {
finishWith(session->data().processUser(result));
}).fail([=] {
finishWith(nullptr);
}).send();
} else if (const auto user = i->second.user
; user || i->second.callbacks.empty()) {
if (user) {
consumer.put_next(not_null(user));
}
return rpl::lifetime();
}
auto lifetime = rpl::lifetime();
const auto done = [=](UserData *result) {
if (result) {
consumer.put_next(not_null(result));
}
};
const auto guard = lifetime.make_state<base::has_weak_ptr>();
i->second.callbacks.push_back(crl::guard(guard, done));
return lifetime;
};
}
[[nodiscard]] base::unique_qptr<Ui::Menu::ItemBase> MakeMessageAuthorAction(
not_null<Ui::PopupMenu*> menu,
not_null<HistoryItem*> item,
not_null<Window::SessionController*> controller) {
const auto parent = menu->menu();
const auto user = std::make_shared<UserData*>(nullptr);
const auto action = Ui::Menu::CreateAction(
parent,
tr::lng_contacts_loading(tr::now),
[=] { if (*user) { controller->showPeerInfo(*user); } });
action->setDisabled(true);
auto lifetime = LookupMessageAuthor(
item
) | rpl::start_with_next([=](not_null<UserData*> author) {
action->setText(
tr::lng_context_sent_by(tr::now, lt_user, author->name()));
action->setDisabled(false);
*user = author;
});
auto result = base::make_unique_q<Ui::Menu::Action>(
menu->menu(),
st::whoSentItem,
action,
nullptr,
nullptr);
result->lifetime().add(std::move(lifetime));
return result;
}
} // namespace } // namespace
ContextMenuRequest::ContextMenuRequest( ContextMenuRequest::ContextMenuRequest(
@ -1292,7 +1384,7 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
if (hasWhoReactedItem) { if (hasWhoReactedItem) {
AddWhoReactedAction(result, list, item, list->controller()); AddWhoReactedAction(result, list, item, list->controller());
} else if (item) { } else if (item) {
MaybeAddWhenEditedForwardedAction(result, item); MaybeAddWhenEditedForwardedAction(result, item, list->controller());
} }
return result; return result;
@ -1466,9 +1558,10 @@ void AddSaveSoundForNotifications(
}, &st::menuIconSoundAdd); }, &st::menuIconSoundAdd);
} }
void AddWhenEditedForwardedActionHelper( void AddWhenEditedForwardedAuthorActionHelper(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
not_null<HistoryItem*> item, not_null<HistoryItem*> item,
not_null<Window::SessionController*> controller,
bool insertSeparator) { bool insertSeparator) {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) { if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
if (!forwarded->story && forwarded->psaType.isEmpty()) { if (!forwarded->story && forwarded->psaType.isEmpty()) {
@ -1489,6 +1582,12 @@ void AddWhenEditedForwardedActionHelper(
Api::WhenEdited(item->from(), edited->date))); Api::WhenEdited(item->from(), edited->date)));
} }
} }
if (item->canLookupMessageAuthor()) {
if (insertSeparator && !menu->empty()) {
menu->addSeparator(&st::expandedMenuSeparator);
}
menu->addAction(MakeMessageAuthorAction(menu, item, controller));
}
} }
void AddWhoReactedAction( void AddWhoReactedAction(
@ -1539,7 +1638,11 @@ void AddWhoReactedAction(
menu->addSeparator(&st::expandedMenuSeparator); menu->addSeparator(&st::expandedMenuSeparator);
} }
if (item->history()->peer->isUser()) { if (item->history()->peer->isUser()) {
AddWhenEditedForwardedActionHelper(menu, item, false); AddWhenEditedForwardedAuthorActionHelper(
menu,
item,
controller,
false);
menu->addAction(Ui::WhenReadContextAction( menu->addAction(Ui::WhenReadContextAction(
menu.get(), menu.get(),
Api::WhoReacted(item, context, st::defaultWhoRead, whoReadIds), Api::WhoReacted(item, context, st::defaultWhoRead, whoReadIds),
@ -1551,14 +1654,19 @@ void AddWhoReactedAction(
Data::ReactedMenuFactory(&controller->session()), Data::ReactedMenuFactory(&controller->session()),
participantChosen, participantChosen,
showAllChosen)); showAllChosen));
AddWhenEditedForwardedActionHelper(menu, item, true); AddWhenEditedForwardedAuthorActionHelper(
menu,
item,
controller,
true);
} }
} }
void MaybeAddWhenEditedForwardedAction( void MaybeAddWhenEditedForwardedAction(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
not_null<HistoryItem*> item) { not_null<HistoryItem*> item,
AddWhenEditedForwardedActionHelper(menu, item, true); not_null<Window::SessionController*> controller) {
AddWhenEditedForwardedAuthorActionHelper(menu, item, controller, true);
} }
void AddEditTagAction( void AddEditTagAction(

View file

@ -88,7 +88,8 @@ void AddWhoReactedAction(
not_null<Window::SessionController*> controller); not_null<Window::SessionController*> controller);
void MaybeAddWhenEditedForwardedAction( void MaybeAddWhenEditedForwardedAction(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
not_null<HistoryItem*> item); not_null<HistoryItem*> item,
not_null<Window::SessionController*> controller);
void ShowWhoReactedMenu( void ShowWhoReactedMenu(
not_null<base::unique_qptr<Ui::PopupMenu>*> menu, not_null<base::unique_qptr<Ui::PopupMenu>*> menu,
QPoint position, QPoint position,