diff --git a/Telegram/Resources/icons/menu/read_react_s.png b/Telegram/Resources/icons/menu/read_react_s.png new file mode 100644 index 000000000..8bc379107 Binary files /dev/null and b/Telegram/Resources/icons/menu/read_react_s.png differ diff --git a/Telegram/Resources/icons/menu/read_react_s@2x.png b/Telegram/Resources/icons/menu/read_react_s@2x.png new file mode 100644 index 000000000..6faa7707b Binary files /dev/null and b/Telegram/Resources/icons/menu/read_react_s@2x.png differ diff --git a/Telegram/Resources/icons/menu/read_react_s@3x.png b/Telegram/Resources/icons/menu/read_react_s@3x.png new file mode 100644 index 000000000..1be7ec033 Binary files /dev/null and b/Telegram/Resources/icons/menu/read_react_s@3x.png differ diff --git a/Telegram/Resources/tl/api.tl b/Telegram/Resources/tl/api.tl index 3208541fb..eeb3dc749 100644 --- a/Telegram/Resources/tl/api.tl +++ b/Telegram/Resources/tl/api.tl @@ -407,6 +407,7 @@ updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long to updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector = Update; updateUser#20529438 user_id:long = Update; updateAutoSaveSettings#ec05b097 = Update; +updateGroupInvitePrivacyForbidden#ccf08ad6 user_id:long = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -1373,7 +1374,7 @@ availableReaction#c077ec01 flags:# inactive:flags.0?true premium:flags.2?true re messages.availableReactionsNotModified#9f071957 = messages.AvailableReactions; messages.availableReactions#768e3aad hash:int reactions:Vector = messages.AvailableReactions; -messagePeerReaction#b156fe9c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:Reaction = MessagePeerReaction; +messagePeerReaction#8c79b63c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer date:int reaction:Reaction = MessagePeerReaction; groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel; @@ -2040,4 +2041,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats; -// LAYER 154 +// LAYER 155 diff --git a/Telegram/SourceFiles/api/api_who_reacted.cpp b/Telegram/SourceFiles/api/api_who_reacted.cpp index 815f85d59..86e0a5881 100644 --- a/Telegram/SourceFiles/api/api_who_reacted.cpp +++ b/Telegram/SourceFiles/api/api_who_reacted.cpp @@ -111,6 +111,7 @@ struct Context { struct Userpic { not_null peer; TimeId date = 0; + bool dateReacted = false; QString customEntityData; mutable Ui::PeerUserpicView view; mutable InMemoryKey uniqueKey; @@ -301,14 +302,15 @@ struct State { }; parsed.list.reserve(data.vreactions().v.size()); for (const auto &vote : data.vreactions().v) { - vote.match([&](const auto &data) { - parsed.list.push_back(PeerWithReaction{ - .peerWithDate = { - .peer = peerFromMTP(data.vpeer_id()), - }, - .reaction = Data::ReactionFromMTP( - data.vreaction()), - }); + const auto &data = vote.data(); + parsed.list.push_back(PeerWithReaction{ + .peerWithDate = { + .peer = peerFromMTP(data.vpeer_id()), + .date = data.vdate().v, + .dateReacted = true, + }, + .reaction = Data::ReactionFromMTP( + data.vreaction()), }); } entry.data = std::move(parsed); @@ -343,10 +345,11 @@ struct State { peerWithDate.peer, [](const PeerWithReaction &p) { return p.peerWithDate.peer; }); - if (i != end(list)) { - i->peerWithDate.date = peerWithDate.date; - } else { + if (i == end(list)) { list.push_back({ .peerWithDate = peerWithDate }); + } else if (!i->peerWithDate.date) { + i->peerWithDate.date = peerWithDate.date; + i->peerWithDate.dateReacted = peerWithDate.dateReacted; } } reacted.read = std::move(read.list); @@ -394,6 +397,7 @@ bool UpdateUserpics( struct ResolvedPeer { PeerData *peer = nullptr; TimeId date = 0; + bool dateReacted = false; ReactionId reaction; }; const auto peers = ranges::views::all( @@ -402,6 +406,7 @@ bool UpdateUserpics( return ResolvedPeer{ .peer = owner.peerLoaded(id.peerWithDate.peer), .date = id.peerWithDate.date, + .dateReacted = id.peerWithDate.dateReacted, .reaction = id.reaction, }; }) | ranges::views::filter([](ResolvedPeer resolved) { @@ -425,6 +430,7 @@ bool UpdateUserpics( const auto i = ranges::find(was, peer, &Userpic::peer); if (i != end(was) && i->view.cloud) { i->date = resolved.date; + i->dateReacted = resolved.dateReacted; now.push_back(std::move(*i)); now.back().customEntityData = data; continue; @@ -432,6 +438,7 @@ bool UpdateUserpics( now.push_back(Userpic{ .peer = peer, .date = resolved.date, + .dateReacted = resolved.dateReacted, .customEntityData = data, }); auto &userpic = now.back(); @@ -479,12 +486,14 @@ void RegenerateParticipants(not_null state, int small, int large) { if (was != end(old)) { was->name = peer->name(); was->date = FormatReadDate(date, currentDate); + was->dateReacted = userpic.dateReacted; now.push_back(std::move(*was)); continue; } now.push_back({ .name = peer->name(), .date = FormatReadDate(date, currentDate), + .dateReacted = userpic.dateReacted, .customEntityData = userpic.customEntityData, .userpicLarge = GenerateUserpic(userpic, large), .userpicKey = userpic.uniqueKey, diff --git a/Telegram/SourceFiles/api/api_who_reacted.h b/Telegram/SourceFiles/api/api_who_reacted.h index b51623041..3fdcd8a56 100644 --- a/Telegram/SourceFiles/api/api_who_reacted.h +++ b/Telegram/SourceFiles/api/api_who_reacted.h @@ -37,6 +37,7 @@ enum class WhoReactedList { struct WhoReadPeer { PeerId peer = 0; TimeId date = 0; + bool dateReacted = false; friend inline bool operator==( const WhoReadPeer &a, diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index e8cc28f47..60bf94221 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -1100,6 +1100,8 @@ whoReadDateTop: 20px; whoReadDateSkip: 15px; whoReadDateChecks: icon{{ "menu/read_ticks_s", windowSubTextFg }}; whoReadDateChecksOver: icon{{ "menu/read_ticks_s", windowSubTextFgOver }}; +whoLikedDateHeart: icon{{ "menu/read_react_s", windowSubTextFg }}; +whoLikedDateHeartOver: icon{{ "menu/read_react_s", windowSubTextFgOver }}; whoReadDateChecksPosition: point(-7px, -4px); whoReadDateStyle: TextStyle(defaultTextStyle) { font: font(12px); diff --git a/Telegram/SourceFiles/ui/controls/who_reacted_context_action.cpp b/Telegram/SourceFiles/ui/controls/who_reacted_context_action.cpp index 5b17e3832..f4914b389 100644 --- a/Telegram/SourceFiles/ui/controls/who_reacted_context_action.cpp +++ b/Telegram/SourceFiles/ui/controls/who_reacted_context_action.cpp @@ -74,6 +74,7 @@ using Text::CustomEmojiFactory; struct EntryData { QString text; QString date; + bool dateReacted = false; QString customEntityData; QImage userpic; Fn callback; @@ -493,6 +494,7 @@ private: QImage _userpic; int _textWidth = 0; int _customSize = 0; + bool _dateReacted = false; }; @@ -543,6 +545,7 @@ void WhoReactedListMenu::EntryAction::setData(EntryData &&data) { { data.date }, MenuTextOptions); } + _dateReacted = data.dateReacted; _custom = _customEmojiFactory(data.customEntityData, [=] { update(); }); const auto ratio = style::DevicePixelRatio(); const auto size = Emoji::GetSizeNormal() / ratio; @@ -602,9 +605,9 @@ void WhoReactedListMenu::EntryAction::paint(Painter &&p) { const auto iconPosition = QPoint( st::defaultWhoRead.nameLeft, st::whoReadDateTop) + st::whoReadDateChecksPosition; - const auto &icon = selected - ? st::whoReadDateChecksOver - : st::whoReadDateChecks; + const auto &icon = _dateReacted + ? (selected ? st::whoLikedDateHeartOver : st::whoLikedDateHeart) + : (selected ? st::whoReadDateChecksOver : st::whoReadDateChecks); icon.paint(p, iconPosition, width()); p.setPen(selected ? _st.itemFgShortcutOver : _st.itemFgShortcut); _date.drawLeftElided( @@ -713,6 +716,7 @@ void WhoReactedListMenu::populate( append({ .text = participant.name, .date = participant.date, + .dateReacted = participant.dateReacted, .customEntityData = participant.customEntityData, .userpic = participant.userpicLarge, .callback = chosen, diff --git a/Telegram/SourceFiles/ui/controls/who_reacted_context_action.h b/Telegram/SourceFiles/ui/controls/who_reacted_context_action.h index 49d690ec4..c46f3e804 100644 --- a/Telegram/SourceFiles/ui/controls/who_reacted_context_action.h +++ b/Telegram/SourceFiles/ui/controls/who_reacted_context_action.h @@ -20,6 +20,7 @@ class PopupMenu; struct WhoReadParticipant { QString name; QString date; + bool dateReacted = false; QString customEntityData; QImage userpicSmall; QImage userpicLarge;