Display custom emoji reactions under messages.

This commit is contained in:
John Preston 2022-08-26 13:35:19 +04:00
parent 14f937cb02
commit ba83836922
17 changed files with 178 additions and 47 deletions

View file

@ -592,8 +592,13 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
return true; return true;
} }
bool WhoReactedExists(not_null<HistoryItem*> item) { bool WhoReactedExists(
return item->canViewReactions() || WhoReadExists(item); not_null<HistoryItem*> item,
WhoReactedList list) {
if (item->canViewReactions() || WhoReadExists(item)) {
return true;
}
return (list == WhoReactedList::One) && item->history()->peer->isUser();
} }
rpl::producer<Ui::WhoReadContent> WhoReacted( rpl::producer<Ui::WhoReadContent> WhoReacted(

View file

@ -24,8 +24,15 @@ struct ReactionId;
namespace Api { namespace Api {
enum class WhoReactedList {
All,
One,
};
[[nodiscard]] bool WhoReadExists(not_null<HistoryItem*> item); [[nodiscard]] bool WhoReadExists(not_null<HistoryItem*> item);
[[nodiscard]] bool WhoReactedExists(not_null<HistoryItem*> item); [[nodiscard]] bool WhoReactedExists(
not_null<HistoryItem*> item,
WhoReactedList list);
struct WhoReadList { struct WhoReadList {
std::vector<PeerId> list; std::vector<PeerId> list;

View file

@ -77,11 +77,12 @@ constexpr auto kTopReactionsLimit = 10;
} // namespace } // namespace
PossibleItemReactions LookupPossibleReactions(not_null<HistoryItem*> item) { PossibleItemReactionsRef LookupPossibleReactions(
not_null<HistoryItem*> item) {
if (!item->canReact()) { if (!item->canReact()) {
return {}; return {};
} }
auto result = PossibleItemReactions(); auto result = PossibleItemReactionsRef();
const auto peer = item->history()->peer; const auto peer = item->history()->peer;
const auto session = &peer->session(); const auto session = &peer->session();
const auto reactions = &session->data().reactions(); const auto reactions = &session->data().reactions();
@ -157,6 +158,15 @@ PossibleItemReactions LookupPossibleReactions(not_null<HistoryItem*> item) {
return result; return result;
} }
PossibleItemReactions::PossibleItemReactions(
const PossibleItemReactionsRef &other)
: recent(other.recent | ranges::views::transform([](const auto &value) {
return *value;
}) | ranges::to_vector)
, morePremiumAvailable(other.morePremiumAvailable)
, customAllowed(other.customAllowed) {
}
Reactions::Reactions(not_null<Session*> owner) Reactions::Reactions(not_null<Session*> owner)
: _owner(owner) : _owner(owner)
, _topRefreshTimer([=] { refreshTop(); }) , _topRefreshTimer([=] { refreshTop(); })
@ -194,6 +204,10 @@ Reactions::Reactions(not_null<Session*> owner)
Reactions::~Reactions() = default; Reactions::~Reactions() = default;
Main::Session &Reactions::session() const {
return _owner->session();
}
void Reactions::refreshTop() { void Reactions::refreshTop() {
requestTop(); requestTop();
} }
@ -868,7 +882,7 @@ void MessageReactions::add(const ReactionId &id, bool addToRecent) {
} }
return removed; return removed;
}), end(_list)); }), end(_list));
if (_item->canViewReactions()) { if (_item->canViewReactions() || history->peer->isUser()) {
auto &list = _recent[id]; auto &list = _recent[id];
list.insert(begin(list), RecentReaction{ self }); list.insert(begin(list), RecentReaction{ self });
} }

View file

@ -38,13 +38,22 @@ struct Reaction {
bool premium = false; bool premium = false;
}; };
struct PossibleItemReactions { struct PossibleItemReactionsRef {
std::vector<not_null<const Reaction*>> recent; std::vector<not_null<const Reaction*>> recent;
bool morePremiumAvailable = false; bool morePremiumAvailable = false;
bool customAllowed = false; bool customAllowed = false;
}; };
[[nodiscard]] PossibleItemReactions LookupPossibleReactions( struct PossibleItemReactions {
PossibleItemReactions() = default;
explicit PossibleItemReactions(const PossibleItemReactionsRef &other);
std::vector<Reaction> recent;
bool morePremiumAvailable = false;
bool customAllowed = false;
};
[[nodiscard]] PossibleItemReactionsRef LookupPossibleReactions(
not_null<HistoryItem*> item); not_null<HistoryItem*> item);
class Reactions final : private CustomEmojiManager::Listener { class Reactions final : private CustomEmojiManager::Listener {
@ -52,6 +61,11 @@ public:
explicit Reactions(not_null<Session*> owner); explicit Reactions(not_null<Session*> owner);
~Reactions(); ~Reactions();
[[nodiscard]] Session &owner() const {
return *_owner;
}
[[nodiscard]] Main::Session &session() const;
void refreshTop(); void refreshTop();
void refreshRecent(); void refreshRecent();
void refreshRecentDelayed(); void refreshRecentDelayed();

View file

@ -2011,13 +2011,15 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
} }
const auto hasWhoReactedItem = _dragStateItem const auto hasWhoReactedItem = _dragStateItem
&& Api::WhoReactedExists(_dragStateItem); && Api::WhoReactedExists(_dragStateItem, Api::WhoReactedList::All);
const auto clickedReaction = link const auto clickedReaction = link
? link->property( ? link->property(
kReactionsCountEmojiProperty).value<Data::ReactionId>() kReactionsCountEmojiProperty).value<Data::ReactionId>()
: Data::ReactionId(); : Data::ReactionId();
_whoReactedMenuLifetime.destroy(); _whoReactedMenuLifetime.destroy();
if (hasWhoReactedItem && !clickedReaction.empty()) { if (!clickedReaction.empty()
&& _dragStateItem
&& Api::WhoReactedExists(_dragStateItem, Api::WhoReactedList::One)) {
HistoryView::ShowWhoReactedMenu( HistoryView::ShowWhoReactedMenu(
&_menu, &_menu,
e->globalPos(), e->globalPos(),

View file

@ -948,7 +948,8 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
: nullptr; : nullptr;
const auto hasSelection = !request.selectedItems.empty() const auto hasSelection = !request.selectedItems.empty()
|| !request.selectedText.empty(); || !request.selectedText.empty();
const auto hasWhoReactedItem = item && Api::WhoReactedExists(item); const auto hasWhoReactedItem = item
&& Api::WhoReactedExists(item, Api::WhoReactedList::All);
auto result = base::make_unique_q<Ui::PopupMenu>( auto result = base::make_unique_q<Ui::PopupMenu>(
list, list,

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_custom_emoji.h" #include "history/view/media/history_view_custom_emoji.h"
#include "history/view/reactions/history_view_reactions_animation.h" #include "history/view/reactions/history_view_reactions_animation.h"
#include "history/view/reactions/history_view_reactions_button.h" #include "history/view/reactions/history_view_reactions_button.h"
#include "history/view/reactions/history_view_reactions.h"
#include "history/view/history_view_cursor_state.h" #include "history/view/history_view_cursor_state.h"
#include "history/history.h" #include "history/history.h"
#include "base/unixtime.h" #include "base/unixtime.h"
@ -430,6 +431,20 @@ void Element::prepareCustomEmojiPaint(
} }
} }
void Element::prepareCustomEmojiPaint(
Painter &p,
const Reactions::InlineList &reactions) const {
if (!reactions.hasCustomEmoji()) {
return;
}
clearCustomEmojiRepaint();
p.setInactive(delegate()->elementIsGifPaused());
if (!_heavyCustomEmoji) {
_heavyCustomEmoji = true;
history()->owner().registerHeavyViewPart(const_cast<Element*>(this));
}
}
//void Element::externalLottieProgressing(bool external) const { //void Element::externalLottieProgressing(bool external) const {
// if (const auto media = _media.get()) { // if (const auto media = _media.get()) {
// media->externalLottieProgressing(external); // media->externalLottieProgressing(external);

View file

@ -49,6 +49,7 @@ using PaintContext = Ui::ChatPaintContext;
namespace Reactions { namespace Reactions {
struct ButtonParameters; struct ButtonParameters;
class Animation; class Animation;
class InlineList;
} // namespace Reactions } // namespace Reactions
enum class Context : char { enum class Context : char {
@ -421,6 +422,9 @@ public:
void prepareCustomEmojiPaint( void prepareCustomEmojiPaint(
Painter &p, Painter &p,
const Ui::Text::String &text) const; const Ui::Text::String &text) const;
void prepareCustomEmojiPaint(
Painter &p,
const Reactions::InlineList &reactions) const;
void clearCustomEmojiRepaint() const; void clearCustomEmojiRepaint() const;
[[nodiscard]] ClickHandlerPtr fromPhotoLink() const { [[nodiscard]] ClickHandlerPtr fromPhotoLink() const {

View file

@ -2210,13 +2210,15 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
? _overElement->data().get() ? _overElement->data().get()
: nullptr; : nullptr;
const auto hasWhoReactedItem = overItem const auto hasWhoReactedItem = overItem
&& Api::WhoReactedExists(overItem); && Api::WhoReactedExists(overItem, Api::WhoReactedList::All);
const auto clickedReaction = link const auto clickedReaction = link
? link->property( ? link->property(
kReactionsCountEmojiProperty).value<Data::ReactionId>() kReactionsCountEmojiProperty).value<Data::ReactionId>()
: Data::ReactionId(); : Data::ReactionId();
_whoReactedMenuLifetime.destroy(); _whoReactedMenuLifetime.destroy();
if (hasWhoReactedItem && !clickedReaction.empty()) { if (!clickedReaction.empty()
&& overItem
&& Api::WhoReactedExists(overItem, Api::WhoReactedList::One)) {
HistoryView::ShowWhoReactedMenu( HistoryView::ShowWhoReactedMenu(
&_menu, &_menu,
e->globalPos(), e->globalPos(),

View file

@ -739,6 +739,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
g.setHeight(g.height() - reactionsHeight); g.setHeight(g.height() - reactionsHeight);
const auto reactionsPosition = QPoint(reactionsLeft + g.left(), g.top() + g.height() + st::mediaInBubbleSkip); const auto reactionsPosition = QPoint(reactionsLeft + g.left(), g.top() + g.height() + st::mediaInBubbleSkip);
p.translate(reactionsPosition); p.translate(reactionsPosition);
prepareCustomEmojiPaint(p, *_reactions);
_reactions->paint(p, context, g.width(), context.clip.translated(-reactionsPosition)); _reactions->paint(p, context, g.width(), context.clip.translated(-reactionsPosition));
if (context.reactionInfo) { if (context.reactionInfo) {
context.reactionInfo->position = reactionsPosition; context.reactionInfo->position = reactionsPosition;
@ -794,6 +795,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
trect.setHeight(trect.height() - reactionsHeight); trect.setHeight(trect.height() - reactionsHeight);
const auto reactionsPosition = QPoint(trect.left(), trect.top() + trect.height() + reactionsTop); const auto reactionsPosition = QPoint(trect.left(), trect.top() + trect.height() + reactionsTop);
p.translate(reactionsPosition); p.translate(reactionsPosition);
prepareCustomEmojiPaint(p, *_reactions);
_reactions->paint(p, context, g.width(), context.clip.translated(-reactionsPosition)); _reactions->paint(p, context, g.width(), context.clip.translated(-reactionsPosition));
if (context.reactionInfo) { if (context.reactionInfo) {
context.reactionInfo->position = reactionsPosition; context.reactionInfo->position = reactionsPosition;
@ -1385,6 +1387,9 @@ bool Message::hasHeavyPart() const {
void Message::unloadHeavyPart() { void Message::unloadHeavyPart() {
Element::unloadHeavyPart(); Element::unloadHeavyPart();
if (_reactions) {
_reactions->unloadCustomEmoji();
}
_comments = nullptr; _comments = nullptr;
} }
@ -2232,6 +2237,7 @@ void Message::refreshReactions() {
_reactions = std::make_unique<InlineList>( _reactions = std::make_unique<InlineList>(
&item->history()->owner().reactions(), &item->history()->owner().reactions(),
handlerFactory, handlerFactory,
[=] { customEmojiRepaint(); },
std::move(reactionsData)); std::move(reactionsData));
} else { } else {
_reactions->update(std::move(reactionsData), width()); _reactions->update(std::move(reactionsData), width());

View file

@ -14,9 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h" #include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_group_call_bar.h" #include "history/view/history_view_group_call_bar.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_message_reactions.h" #include "data/data_message_reactions.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "data/data_session.h"
#include "lang/lang_tag.h" #include "lang/lang_tag.h"
#include "ui/text/text_block.h"
#include "ui/chat/chat_style.h" #include "ui/chat/chat_style.h"
#include "styles/style_chat.h" #include "styles/style_chat.h"
@ -40,6 +43,7 @@ struct InlineList::Button {
mutable std::unique_ptr<Animation> animation; mutable std::unique_ptr<Animation> animation;
mutable QImage image; mutable QImage image;
mutable ClickHandlerPtr link; mutable ClickHandlerPtr link;
mutable std::unique_ptr<Ui::Text::CustomEmoji> custom;
std::unique_ptr<Userpics> userpics; std::unique_ptr<Userpics> userpics;
ReactionId id; ReactionId id;
QString countText; QString countText;
@ -51,9 +55,11 @@ struct InlineList::Button {
InlineList::InlineList( InlineList::InlineList(
not_null<::Data::Reactions*> owner, not_null<::Data::Reactions*> owner,
Fn<ClickHandlerPtr(ReactionId)> handlerFactory, Fn<ClickHandlerPtr(ReactionId)> handlerFactory,
Fn<void()> customEmojiRepaint,
Data &&data) Data &&data)
: _owner(owner) : _owner(owner)
, _handlerFactory(std::move(handlerFactory)) , _handlerFactory(std::move(handlerFactory))
, _customEmojiRepaint(std::move(customEmojiRepaint))
, _data(std::move(data)) { , _data(std::move(data)) {
layout(); layout();
} }
@ -76,6 +82,21 @@ void InlineList::removeSkipBlock() {
_skipBlock = {}; _skipBlock = {};
} }
bool InlineList::hasCustomEmoji() const {
return _hasCustomEmoji;
}
void InlineList::unloadCustomEmoji() {
if (!hasCustomEmoji()) {
return;
}
for (const auto &button : _buttons) {
if (const auto custom = button.custom.get()) {
custom->unload();
}
}
}
void InlineList::layout() { void InlineList::layout() {
layoutButtons(); layoutButtons();
initDimensions(); initDimensions();
@ -106,6 +127,7 @@ void InlineList::layoutButtons() {
< ranges::find(list, b->id, &::Data::Reaction::id); < ranges::find(list, b->id, &::Data::Reaction::id);
}); });
_hasCustomEmoji = false;
auto buttons = std::vector<Button>(); auto buttons = std::vector<Button>();
buttons.reserve(sorted.size()); buttons.reserve(sorted.size());
for (const auto &reaction : sorted) { for (const auto &reaction : sorted) {
@ -121,13 +143,22 @@ void InlineList::layoutButtons() {
setButtonCount(buttons.back(), reaction->count); setButtonCount(buttons.back(), reaction->count);
} }
buttons.back().chosen = reaction->my; buttons.back().chosen = reaction->my;
if (id.custom()) {
_hasCustomEmoji = true;
}
} }
_buttons = std::move(buttons); _buttons = std::move(buttons);
} }
InlineList::Button InlineList::prepareButtonWithId(const ReactionId &id) { InlineList::Button InlineList::prepareButtonWithId(const ReactionId &id) {
auto result = Button{ .id = id }; auto result = Button{ .id = id };
_owner->preloadImageFor(id); if (const auto customId = id.custom()) {
result.custom = _owner->owner().customEmojiManager().create(
customId,
_customEmojiRepaint);
} else {
_owner->preloadImageFor(id);
}
return result; return result;
} }
@ -353,16 +384,44 @@ void InlineList::paint(
p.setOpacity(bubbleProgress); p.setOpacity(bubbleProgress);
} }
} }
if (button.image.isNull()) { if (!button.custom && button.image.isNull()) {
button.image = _owner->resolveImageFor( button.image = _owner->resolveImageFor(
button.id, button.id,
::Data::Reactions::ImageSize::InlineList); ::Data::Reactions::ImageSize::InlineList);
} }
const auto textFg = !inbubble
? (chosen
? QPen(AdaptChosenServiceFg(st->msgServiceBg()->c))
: st->msgServiceFg())
: !chosen
? stm->msgServiceFg
: context.outbg
? (context.selected()
? st->historyFileOutIconFgSelected()
: st->historyFileOutIconFg())
: (context.selected()
? st->historyFileInIconFgSelected()
: st->historyFileInIconFg());
const auto image = QRect( const auto image = QRect(
inner.topLeft() + QPoint(skip, skip), inner.topLeft() + QPoint(skip, skip),
QSize(st::reactionInlineImage, st::reactionInlineImage)); QSize(st::reactionInlineImage, st::reactionInlineImage));
if (!button.image.isNull() && !skipImage) { if (!skipImage) {
p.drawImage(image.topLeft(), button.image); if (button.custom) {
if (!_customSkip) {
using namespace Ui::Text;
const auto size = st::emojiSize;
_customSkip = (size - AdjustCustomEmojiSize(size)) / 2;
}
button.custom->paint(p, {
.preview = textFg.color(),
.now = context.now,
.position = (inner.topLeft()
+ QPoint(_customSkip, _customSkip)),
.paused = p.inactive(),
});
} else if (!button.image.isNull()) {
p.drawImage(image.topLeft(), button.image);
}
} }
if (animating) { if (animating) {
animations.push_back({ animations.push_back({
@ -381,19 +440,7 @@ void InlineList::paint(
geometry.y() + st::reactionInlineUserpicsPadding.top(), geometry.y() + st::reactionInlineUserpicsPadding.top(),
button.userpics->image); button.userpics->image);
} else { } else {
p.setPen(!inbubble p.setPen(textFg);
? (chosen
? QPen(AdaptChosenServiceFg(st->msgServiceBg()->c))
: st->msgServiceFg())
: !chosen
? stm->msgServiceFg
: context.outbg
? (context.selected()
? st->historyFileOutIconFgSelected()
: st->historyFileOutIconFg())
: (context.selected()
? st->historyFileInIconFgSelected()
: st->historyFileInIconFg()));
const auto textTop = geometry.y() const auto textTop = geometry.y()
+ ((geometry.height() - st::semiboldFont->height) / 2); + ((geometry.height() - st::semiboldFont->height) / 2);
p.drawText( p.drawText(

View file

@ -53,6 +53,7 @@ public:
InlineList( InlineList(
not_null<::Data::Reactions*> owner, not_null<::Data::Reactions*> owner,
Fn<ClickHandlerPtr(ReactionId)> handlerFactory, Fn<ClickHandlerPtr(ReactionId)> handlerFactory,
Fn<void()> customEmojiRepaint,
Data &&data); Data &&data);
~InlineList(); ~InlineList();
@ -65,6 +66,9 @@ public:
void updateSkipBlock(int width, int height); void updateSkipBlock(int width, int height);
void removeSkipBlock(); void removeSkipBlock();
[[nodiscard]] bool hasCustomEmoji() const;
void unloadCustomEmoji();
void paint( void paint(
Painter &p, Painter &p,
const PaintContext &context, const PaintContext &context,
@ -105,9 +109,12 @@ private:
const not_null<::Data::Reactions*> _owner; const not_null<::Data::Reactions*> _owner;
const Fn<ClickHandlerPtr(ReactionId)> _handlerFactory; const Fn<ClickHandlerPtr(ReactionId)> _handlerFactory;
const Fn<void()> _customEmojiRepaint;
Data _data; Data _data;
std::vector<Button> _buttons; std::vector<Button> _buttons;
QSize _skipBlock; QSize _skipBlock;
mutable int _customSkip = 0;
bool _hasCustomEmoji = false;
}; };

View file

@ -441,7 +441,7 @@ void Manager::showButtonDelayed() {
[=]{ updateButton({}); }); [=]{ updateButton({}); });
} }
void Manager::applyList(Data::PossibleItemReactions &&reactions) { void Manager::applyList(const Data::PossibleItemReactionsRef &reactions) {
using Button = Strip::AddedButton; using Button = Strip::AddedButton;
_strip.applyList( _strip.applyList(
reactions.recent, reactions.recent,

View file

@ -23,7 +23,7 @@ class PopupMenu;
namespace Data { namespace Data {
struct ReactionId; struct ReactionId;
struct Reaction; struct Reaction;
struct PossibleItemReactions; struct PossibleItemReactionsRef;
class DocumentMedia; class DocumentMedia;
} // namespace Data } // namespace Data
@ -143,7 +143,7 @@ public:
using ReactionId = ::Data::ReactionId; using ReactionId = ::Data::ReactionId;
void applyList(Data::PossibleItemReactions &&reactions); void applyList(const Data::PossibleItemReactionsRef &reactions);
void updateButton(ButtonParameters parameters); void updateButton(ButtonParameters parameters);
void paint(Painter &p, const PaintContext &context); void paint(Painter &p, const PaintContext &context);

View file

@ -144,12 +144,12 @@ bool StripEmoji::ready() {
Selector::Selector( Selector::Selector(
not_null<QWidget*> parent, not_null<QWidget*> parent,
not_null<Window::SessionController*> parentController, not_null<Window::SessionController*> parentController,
Data::PossibleItemReactions &&reactions, const Data::PossibleItemReactionsRef &reactions,
IconFactory iconFactory, IconFactory iconFactory,
Fn<void(bool fast)> close) Fn<void(bool fast)> close)
: RpWidget(parent) : RpWidget(parent)
, _parentController(parentController.get()) , _parentController(parentController.get())
, _reactions(std::move(reactions)) , _reactions(reactions)
, _jumpedToPremium([=] { close(false); }) , _jumpedToPremium([=] { close(false); })
, _cachedRound( , _cachedRound(
QSize(2 * st::reactStripSkip + st::reactStripSize, st::reactStripHeight), QSize(2 * st::reactStripSkip + st::reactStripSize, st::reactStripHeight),
@ -198,14 +198,21 @@ int Selector::countWidth(int desiredWidth, int maxWidth) {
: _reactions.morePremiumAvailable : _reactions.morePremiumAvailable
? Strip::AddedButton::Premium ? Strip::AddedButton::Premium
: Strip::AddedButton::None; : Strip::AddedButton::None;
const auto &real = _reactions.recent;
auto list = std::vector<not_null<const Data::Reaction*>>();
list.reserve(_columns);
if (const auto cut = max - _columns) { if (const auto cut = max - _columns) {
_strip.applyList(ranges::make_subrange( const auto from = begin(real);
begin(_reactions.recent), const auto till = end(real) - (cut + (addedToMax ? 0 : 1));
end(_reactions.recent) - (cut + (addedToMax ? 0 : 1)) for (auto i = from; i != till; ++i) {
) | ranges::to_vector, added); list.push_back(&*i);
}
} else { } else {
_strip.applyList(_reactions.recent, added); for (const auto &reaction : real) {
list.push_back(&reaction);
}
} }
_strip.applyList(list, added);
_strip.clearAppearAnimations(false); _strip.clearAppearAnimations(false);
return std::max(2 * _skipx + _columns * _size, desiredWidth); return std::max(2 * _skipx + _columns * _size, desiredWidth);
} }
@ -583,11 +590,11 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
auto index = 0; auto index = 0;
const auto inStrip = _strip.count(); const auto inStrip = _strip.count();
for (const auto &reaction : _reactions.recent) { for (const auto &reaction : _reactions.recent) {
if (const auto id = reaction->id.custom()) { if (const auto id = reaction.id.custom()) {
recent.push_back(id); recent.push_back(id);
} else { } else {
recent.push_back(reaction->selectAnimation->id); recent.push_back(reaction.selectAnimation->id);
defaultReactionIds.emplace(recent.back(), reaction->id.emoji()); defaultReactionIds.emplace(recent.back(), reaction.id.emoji());
} }
if (index + 1 < inStrip) { if (index + 1 < inStrip) {
_defaultReactionInStripMap.emplace(recent.back(), index++); _defaultReactionInStripMap.emplace(recent.back(), index++);

View file

@ -40,7 +40,7 @@ public:
Selector( Selector(
not_null<QWidget*> parent, not_null<QWidget*> parent,
not_null<Window::SessionController*> parentController, not_null<Window::SessionController*> parentController,
Data::PossibleItemReactions &&reactions, const Data::PossibleItemReactionsRef &reactions,
IconFactory iconFactory, IconFactory iconFactory,
Fn<void(bool fast)> close); Fn<void(bool fast)> close);

View file

@ -1027,14 +1027,14 @@ sendAsButton: SendAsButton {
} }
reactionInlinePadding: margins(5px, 2px, 7px, 2px); reactionInlinePadding: margins(5px, 2px, 7px, 2px);
reactionInlineSize: 16px; reactionInlineSize: 18px;
reactionInlineImage: 28px; reactionInlineImage: 32px;
reactionInlineSkip: 3px; reactionInlineSkip: 3px;
reactionInlineBetween: 4px; reactionInlineBetween: 4px;
reactionInlineInBubbleLeft: -3px; reactionInlineInBubbleLeft: -3px;
reactionInlineUserpicsPadding: margins(1px, 1px, 1px, 1px); reactionInlineUserpicsPadding: margins(1px, 1px, 1px, 1px);
reactionInlineUserpics: GroupCallUserpics { reactionInlineUserpics: GroupCallUserpics {
size: 18px; size: 20px;
shift: 7px; shift: 7px;
stroke: 1px; stroke: 1px;
align: align(left); align: align(left);