mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Show reaction notifications in groups.
This commit is contained in:
parent
54e7dfe986
commit
1dd7cc956b
5 changed files with 58 additions and 42 deletions
|
@ -846,23 +846,19 @@ void HistoryItem::toggleReaction(const QString &reaction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryItem::updateReactions(const MTPMessageReactions *reactions) {
|
void HistoryItem::updateReactions(const MTPMessageReactions *reactions) {
|
||||||
const auto history = this->history();
|
|
||||||
const auto toUser = (reactions && out())
|
|
||||||
? history->peer->asUser()
|
|
||||||
: nullptr;
|
|
||||||
const auto toContact = toUser && toUser->isContact();
|
|
||||||
const auto hadUnread = hasUnreadReaction();
|
const auto hadUnread = hasUnreadReaction();
|
||||||
setReactions(reactions);
|
setReactions(reactions);
|
||||||
const auto hasUnread = hasUnreadReaction();
|
const auto hasUnread = hasUnreadReaction();
|
||||||
if (hasUnread && !hadUnread) {
|
if (hasUnread && !hadUnread) {
|
||||||
// This may read the reaction already.
|
|
||||||
addToUnreadThings(HistoryUnreadThings::AddType::New);
|
addToUnreadThings(HistoryUnreadThings::AddType::New);
|
||||||
if (toContact && hasUnreadReaction()) {
|
|
||||||
|
// Call to addToUnreadThings may have read the reaction already.
|
||||||
|
if (hasUnreadReaction()) {
|
||||||
const auto notification = ItemNotification{
|
const auto notification = ItemNotification{
|
||||||
this,
|
this,
|
||||||
ItemNotificationType::Reaction,
|
ItemNotificationType::Reaction,
|
||||||
};
|
};
|
||||||
history->pushNotification(notification);
|
history()->pushNotification(notification);
|
||||||
Core::App().notifications().schedule(notification);
|
Core::App().notifications().schedule(notification);
|
||||||
}
|
}
|
||||||
} else if (!hasUnread && hadUnread) {
|
} else if (!hasUnread && hadUnread) {
|
||||||
|
@ -947,22 +943,21 @@ QString HistoryItem::chosenReaction() const {
|
||||||
return _reactions ? _reactions->chosen() : QString();
|
return _reactions ? _reactions->chosen() : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HistoryItem::lookupHisReaction() const {
|
HistoryItemUnreadReaction HistoryItem::lookupUnreadReaction() const {
|
||||||
if (!_reactions) {
|
if (!_reactions) {
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
const auto &list = _reactions->list();
|
const auto recent = _reactions->recent();
|
||||||
if (list.empty()) {
|
for (const auto &[emoji, list] : _reactions->recent()) {
|
||||||
return QString();
|
const auto i = ranges::find(
|
||||||
|
list,
|
||||||
|
true,
|
||||||
|
&Data::RecentReaction::unread);
|
||||||
|
if (i != end(list)) {
|
||||||
|
return { .from = i->peer, .emoji = emoji };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const auto chosen = _reactions->chosen();
|
return {};
|
||||||
const auto &[first, count] = list.front();
|
|
||||||
if (chosen.isEmpty() || first != chosen || count > 1) {
|
|
||||||
return first;
|
|
||||||
} else if (list.size() == 1) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return list.back().first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crl::time HistoryItem::lastReactionsRefreshTime() const {
|
crl::time HistoryItem::lastReactionsRefreshTime() const {
|
||||||
|
|
|
@ -63,6 +63,15 @@ enum class Context : char;
|
||||||
class ElementDelegate;
|
class ElementDelegate;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
|
struct HistoryItemUnreadReaction {
|
||||||
|
PeerData *from = nullptr;
|
||||||
|
QString emoji;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (from != nullptr) && !emoji.isEmpty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct HiddenSenderInfo;
|
struct HiddenSenderInfo;
|
||||||
class History;
|
class History;
|
||||||
|
|
||||||
|
@ -373,7 +382,7 @@ public:
|
||||||
std::vector<Data::RecentReaction>> &;
|
std::vector<Data::RecentReaction>> &;
|
||||||
[[nodiscard]] bool canViewReactions() const;
|
[[nodiscard]] bool canViewReactions() const;
|
||||||
[[nodiscard]] QString chosenReaction() const;
|
[[nodiscard]] QString chosenReaction() const;
|
||||||
[[nodiscard]] QString lookupHisReaction() const;
|
[[nodiscard]] HistoryItemUnreadReaction lookupUnreadReaction() const;
|
||||||
[[nodiscard]] crl::time lastReactionsRefreshTime() const;
|
[[nodiscard]] crl::time lastReactionsRefreshTime() const;
|
||||||
|
|
||||||
[[nodiscard]] bool hasDirectLink() const;
|
[[nodiscard]] bool hasDirectLink() const;
|
||||||
|
|
|
@ -657,13 +657,14 @@ void System::showNext() {
|
||||||
const auto reactionNotification
|
const auto reactionNotification
|
||||||
= (notify->type == ItemNotificationType::Reaction);
|
= (notify->type == ItemNotificationType::Reaction);
|
||||||
const auto reaction = reactionNotification
|
const auto reaction = reactionNotification
|
||||||
? notify->item->lookupHisReaction()
|
? notify->item->lookupUnreadReaction()
|
||||||
: QString();
|
: HistoryItemUnreadReaction();
|
||||||
if (!reactionNotification || !reaction.isEmpty()) {
|
if (!reactionNotification || reaction) {
|
||||||
_manager->showNotification({
|
_manager->showNotification({
|
||||||
.item = notify->item,
|
.item = notify->item,
|
||||||
.forwardedCount = forwardedCount,
|
.forwardedCount = forwardedCount,
|
||||||
.reaction = reaction,
|
.reactionFrom = reaction.from,
|
||||||
|
.reactionEmoji = reaction.emoji,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -879,13 +880,14 @@ void Manager::openNotificationMessage(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
MsgId messageId) {
|
MsgId messageId) {
|
||||||
const auto openExactlyMessage = [&] {
|
const auto openExactlyMessage = [&] {
|
||||||
if (history->peer->isChannel()) {
|
const auto peer = history->peer;
|
||||||
|
if (peer->isBroadcast()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto item = history->owner().message(history->peer, messageId);
|
const auto item = history->owner().message(history->peer, messageId);
|
||||||
if (!item
|
if (!item
|
||||||
|| !item->isRegular()
|
|| !item->isRegular()
|
||||||
|| (!item->out() && !item->mentionsMe())) {
|
|| (!item->out() && (!item->mentionsMe() || peer->isUser()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -928,17 +930,17 @@ void Manager::notificationReplied(
|
||||||
void NativeManager::doShowNotification(NotificationFields &&fields) {
|
void NativeManager::doShowNotification(NotificationFields &&fields) {
|
||||||
const auto options = getNotificationOptions(
|
const auto options = getNotificationOptions(
|
||||||
fields.item,
|
fields.item,
|
||||||
(fields.reaction.isEmpty()
|
(fields.reactionFrom
|
||||||
? ItemNotificationType::Message
|
? ItemNotificationType::Reaction
|
||||||
: ItemNotificationType::Reaction));
|
: ItemNotificationType::Message));
|
||||||
const auto item = fields.item;
|
const auto item = fields.item;
|
||||||
const auto peer = item->history()->peer;
|
const auto peer = item->history()->peer;
|
||||||
const auto reaction = fields.reaction;
|
const auto reactionFrom = fields.reactionFrom;
|
||||||
if (!reaction.isEmpty() && options.hideNameAndPhoto) {
|
if (reactionFrom && options.hideNameAndPhoto) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto scheduled = !options.hideNameAndPhoto
|
const auto scheduled = !options.hideNameAndPhoto
|
||||||
&& fields.reaction.isEmpty()
|
&& !reactionFrom
|
||||||
&& (item->out() || peer->isSelf())
|
&& (item->out() || peer->isSelf())
|
||||||
&& item->isFromScheduled();
|
&& item->isFromScheduled();
|
||||||
const auto title = options.hideNameAndPhoto
|
const auto title = options.hideNameAndPhoto
|
||||||
|
@ -947,13 +949,15 @@ void NativeManager::doShowNotification(NotificationFields &&fields) {
|
||||||
? tr::lng_notification_reminder(tr::now)
|
? tr::lng_notification_reminder(tr::now)
|
||||||
: peer->name;
|
: peer->name;
|
||||||
const auto fullTitle = addTargetAccountName(title, &peer->session());
|
const auto fullTitle = addTargetAccountName(title, &peer->session());
|
||||||
const auto subtitle = (options.hideNameAndPhoto || !reaction.isEmpty())
|
const auto subtitle = reactionFrom
|
||||||
|
? (reactionFrom != peer ? reactionFrom->name : QString())
|
||||||
|
: options.hideNameAndPhoto
|
||||||
? QString()
|
? QString()
|
||||||
: item->notificationHeader();
|
: item->notificationHeader();
|
||||||
const auto text = !reaction.isEmpty()
|
const auto text = reactionFrom
|
||||||
? TextWithPermanentSpoiler(ComposeReactionNotification(
|
? TextWithPermanentSpoiler(ComposeReactionNotification(
|
||||||
item,
|
item,
|
||||||
reaction,
|
fields.reactionEmoji,
|
||||||
options.hideMessageText))
|
options.hideMessageText))
|
||||||
: options.hideMessageText
|
: options.hideMessageText
|
||||||
? tr::lng_notification_preview(tr::now)
|
? tr::lng_notification_preview(tr::now)
|
||||||
|
|
|
@ -219,7 +219,8 @@ public:
|
||||||
struct NotificationFields {
|
struct NotificationFields {
|
||||||
not_null<HistoryItem*> item;
|
not_null<HistoryItem*> item;
|
||||||
int forwardedCount = 0;
|
int forwardedCount = 0;
|
||||||
QString reaction;
|
PeerData *reactionFrom = nullptr;
|
||||||
|
QString reactionEmoji;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Manager(not_null<System*> system) : _system(system) {
|
explicit Manager(not_null<System*> system) : _system(system) {
|
||||||
|
|
|
@ -78,8 +78,12 @@ Manager::Manager(System *system)
|
||||||
Manager::QueuedNotification::QueuedNotification(NotificationFields &&fields)
|
Manager::QueuedNotification::QueuedNotification(NotificationFields &&fields)
|
||||||
: history(fields.item->history())
|
: history(fields.item->history())
|
||||||
, peer(history->peer)
|
, peer(history->peer)
|
||||||
, reaction(fields.reaction)
|
, reaction(fields.reactionEmoji)
|
||||||
, author(reaction.isEmpty() ? fields.item->notificationHeader() : QString())
|
, author(!fields.reactionFrom
|
||||||
|
? fields.item->notificationHeader()
|
||||||
|
: (fields.reactionFrom != peer)
|
||||||
|
? fields.reactionFrom->name
|
||||||
|
: QString())
|
||||||
, item((fields.forwardedCount < 2) ? fields.item.get() : nullptr)
|
, item((fields.forwardedCount < 2) ? fields.item.get() : nullptr)
|
||||||
, forwardedCount(fields.forwardedCount)
|
, forwardedCount(fields.forwardedCount)
|
||||||
, fromScheduled(reaction.isEmpty() && (fields.item->out() || peer->isSelf())
|
, fromScheduled(reaction.isEmpty() && (fields.item->out() || peer->isSelf())
|
||||||
|
@ -814,10 +818,13 @@ void Notification::updateNotifyDisplay() {
|
||||||
p.setPen(st::dialogsTextFg);
|
p.setPen(st::dialogsTextFg);
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
const auto text = !_reaction.isEmpty()
|
const auto text = !_reaction.isEmpty()
|
||||||
? Manager::ComposeReactionNotification(
|
? (!_author.isEmpty()
|
||||||
|
? Ui::Text::PlainLink(_author).append(' ')
|
||||||
|
: TextWithEntities()
|
||||||
|
).append(Manager::ComposeReactionNotification(
|
||||||
_item,
|
_item,
|
||||||
_reaction,
|
_reaction,
|
||||||
options.hideMessageText)
|
options.hideMessageText))
|
||||||
: _item
|
: _item
|
||||||
? _item->toPreview({
|
? _item->toPreview({
|
||||||
.hideSender = reminder,
|
.hideSender = reminder,
|
||||||
|
|
Loading…
Add table
Reference in a new issue