diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index 1c259c6bd..1569b555d 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "history/history_item.h" #include "main/main_session.h" +#include "data/data_session.h" #include "apiwrap.h" namespace Data { @@ -48,6 +49,7 @@ void MessageReactions::add(const QString &reaction) { ++_list[reaction]; } sendRequest(); + _item->history()->owner().requestItemResize(_item); } void MessageReactions::set( @@ -80,6 +82,7 @@ void MessageReactions::set( _chosen = QString(); } } + _item->history()->owner().requestItemResize(_item); } const base::flat_map &MessageReactions::list() const { diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 7e08d4d25..19ccda5af 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -513,6 +513,9 @@ HistoryMessage::HistoryMessage( setGroupId( MessageGroupId::FromRaw(history->peer->id, groupedId->v)); } + if (const auto reactions = data.vreactions()) { + updateReactions(*reactions); + } applyTTL(data); } diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index b4e6ca364..fb10ae3e2 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -1064,6 +1064,10 @@ void HistoryService::createFromMtp(const MTPDmessage &message) { default: Unexpected("Media type in HistoryService::createFromMtp()"); } + + if (const auto reactions = message.vreactions()) { + updateReactions(*reactions); + } } void HistoryService::createFromMtp(const MTPDmessageService &message) { diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 71a52f6b0..288e777d5 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "mainwidget.h" #include "main/main_session.h" +#include "ui/text/text_options.h" #include "window/window_session_controller.h" #include "apiwrap.h" @@ -236,6 +237,25 @@ LogEntryOriginal &LogEntryOriginal::operator=(LogEntryOriginal &&other) { LogEntryOriginal::~LogEntryOriginal() = default; +void Reactions::update(const base::flat_map &list) { + auto sorted = ranges::view::all( + list + ) | ranges::view::transform([](const auto &pair) { + return std::make_pair(pair.first, pair.second); + }) | ranges::to_vector; + ranges::sort(sorted, std::greater<>(), &std::pair::second); + + auto fullCount = 0; + auto composed = QString(); + for (const auto &[string, count] : sorted) { + composed.append(string); + fullCount += count; + } + composed += QString::number(fullCount); + + text.setText(st::msgDateTextStyle, composed, Ui::NameTextOptions()); +} + Message::Message( not_null delegate, not_null data, @@ -317,6 +337,14 @@ QSize Message::performCountOptimalSize() { refreshEditedBadge(); refreshRightBadge(); + if (const auto list = item->reactions(); !list.empty()) { + AddComponents(Reactions::Bit()); + const auto reactions = Get(); + reactions->update(list); + } else { + RemoveComponents(Reactions::Bit()); + } + if (drawBubble()) { const auto forwarded = item->Get(); const auto reply = displayedReply(); @@ -1778,7 +1806,11 @@ void Message::drawInfo( const auto viewIconTop = infoBottom + st::historyViewsTop; const auto pinIconTop = infoBottom + st::historyPinTop; auto left = infoRight - infoW; - if (auto views = item->Get()) { + if (const auto reactions = Get()) { + reactions->text.draw(p, left, dateY, reactions->text.maxWidth()); + left += reactions->text.maxWidth() + st::historyReactionsSkip; + } + if (const auto views = item->Get()) { const auto textTop = infoBottom - st::msgDateFont->descent; if (views->replies.count > 0 && !views->commentsMegagroupId @@ -1885,7 +1917,7 @@ bool Message::pointInTime( int Message::infoWidth() const { const auto item = message(); auto result = item->_timeWidth; - if (auto views = item->Get()) { + if (const auto views = item->Get()) { if (views->views.count >= 0) { result += st::historyViewsSpace + views->views.textWidth @@ -1915,6 +1947,9 @@ int Message::infoWidth() const { } else if (hasOutLayout()) { result += st::historySendStateSpace; } + if (const auto reactions = Get()) { + result += st::historyReactionsSkip + reactions->text.maxWidth(); + } return result; } @@ -1960,6 +1995,10 @@ int Message::timeLeft() const { if (displayPinIcon()) { result += st::historyPinWidth; } + + if (const auto reactions = Get()) { + result += st::historyReactionsSkip + reactions->text.maxWidth(); + } return result; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 1496cb62b..fa3beaf94 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -39,6 +39,12 @@ struct PsaTooltipState : public RuntimeComponent { mutable bool buttonVisible = true; }; +struct Reactions : public RuntimeComponent { + void update(const base::flat_map &list); + + Ui::Text::String text; +}; + class Message : public Element, public base::has_weak_ptr { public: Message( diff --git a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp index 18d3d0017..b73cf8628 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp @@ -148,6 +148,14 @@ QSize Contact::countOptimalSize() { accumulate_max(maxWidth, tleft + _name.maxWidth() + tright); accumulate_min(maxWidth, st::msgMaxWidth); auto minHeight = st.padding.top() + st.thumbSize + st.padding.bottom(); + const auto msgsigned = item->Get(); + const auto views = item->Get(); + if ((msgsigned && !msgsigned->isAnonymousRank) + || (views + && (views->views.count >= 0 || views->replies.count > 0)) + || !item->reactions().empty()) { + minHeight += st::msgDateFont->height - st::msgDateDelta.y(); + } if (!isBubbleTop()) { minHeight -= st::msgFileTopMinus; } diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 7c94afd1e..b1467248d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -273,6 +273,7 @@ QSize Document::countOptimalSize() { if (!captioned && ((msgsigned && !msgsigned->isAnonymousRank) || (views && (views->views.count >= 0 || views->replies.count > 0)) + || !item->reactions().empty() || _parent->displayEditedBadge())) { minHeight += st::msgDateFont->height - st::msgDateDelta.y(); } diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index af0930954..7d688e711 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -209,6 +209,8 @@ historyPinOutIcon: icon {{ "history_pin", historyOutIconFg }}; historyPinOutSelectedIcon: icon {{ "history_pin", historyOutIconFgSelected }}; historyPinInvertedIcon: icon {{ "history_pin", historySendingInvertedIconFg }}; +historyReactionsSkip: 8px; + historyComposeField: InputField(defaultInputField) { font: msgFont; textMargins: margins(0px, 0px, 0px, 0px);