mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Paint two-loops of custom emoji statuses.
This commit is contained in:
parent
da281c4d3d
commit
2618ee3d75
8 changed files with 153 additions and 48 deletions
Telegram
|
@ -246,7 +246,6 @@ dialogsVerifiedIconActive: icon {
|
|||
dialogsPremiumIcon: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
|
||||
dialogsPremiumIconOver: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBgOver }};
|
||||
dialogsPremiumIconActive: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBgActive }};
|
||||
dialogsPremiumIconOffset: point(5px, 0px);
|
||||
|
||||
historySendingIcon: icon {{ "dialogs/dialogs_sending", historySendingOutIconFg, point(5px, 5px) }};
|
||||
historySendingInvertedIcon: icon {{ "dialogs/dialogs_sending", historySendingInvertedIconFg, point(5px, 5px) }};
|
||||
|
|
|
@ -1172,6 +1172,9 @@ void ShowWhoReactedMenu(
|
|||
const Data::ReactionId &id,
|
||||
not_null<Window::SessionController*> controller,
|
||||
rpl::lifetime &lifetime) {
|
||||
struct State {
|
||||
int addedToBottom = 0;
|
||||
};
|
||||
const auto participantChosen = [=](uint64 id) {
|
||||
controller->showPeerInfo(PeerId(id));
|
||||
};
|
||||
|
@ -1194,6 +1197,7 @@ void ShowWhoReactedMenu(
|
|||
Data::ReactedMenuFactory(&controller->session()),
|
||||
participantChosen,
|
||||
showAllChosen);
|
||||
const auto state = lifetime.make_state<State>();
|
||||
Api::WhoReacted(
|
||||
item,
|
||||
id,
|
||||
|
@ -1203,7 +1207,7 @@ void ShowWhoReactedMenu(
|
|||
return !content.unknown;
|
||||
}) | rpl::start_with_next([=, &lifetime](Ui::WhoReadContent &&content) {
|
||||
const auto creating = !*menu;
|
||||
const auto refill = [=] {
|
||||
const auto refillTop = [=] {
|
||||
if (activeNonQuick) {
|
||||
(*menu)->addAction(tr::lng_context_set_as_quick(tr::now), [=] {
|
||||
reactions->setFavorite(id);
|
||||
|
@ -1211,26 +1215,34 @@ void ShowWhoReactedMenu(
|
|||
(*menu)->addSeparator();
|
||||
}
|
||||
};
|
||||
const auto appendBottom = [=] {
|
||||
state->addedToBottom = 0;
|
||||
if (const auto custom = id.custom()) {
|
||||
if (const auto set = owner->document(custom)->sticker()) {
|
||||
if (set->set.id) {
|
||||
state->addedToBottom = 2;
|
||||
AddEmojiPacksAction(
|
||||
menu->get(),
|
||||
{ set->set },
|
||||
EmojiPacksSource::Reaction,
|
||||
controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (creating) {
|
||||
*menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
context,
|
||||
st::whoReadMenu);
|
||||
(*menu)->lifetime().add(base::take(lifetime));
|
||||
refill();
|
||||
}
|
||||
filler->populate(menu->get(), content);
|
||||
|
||||
if (const auto custom = id.custom()) {
|
||||
if (const auto set = owner->document(custom)->sticker()) {
|
||||
if (set->set.id) {
|
||||
AddEmojiPacksAction(
|
||||
menu->get(),
|
||||
{ set->set },
|
||||
EmojiPacksSource::Reaction,
|
||||
controller);
|
||||
}
|
||||
}
|
||||
refillTop();
|
||||
}
|
||||
filler->populate(
|
||||
menu->get(),
|
||||
content,
|
||||
refillTop,
|
||||
state->addedToBottom,
|
||||
appendBottom);
|
||||
if (creating) {
|
||||
(*menu)->popup(position);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
constexpr auto kPlayStatusLimit = 2;
|
||||
const auto kPsaTooltipPrefix = "cloud_lng_tooltip_psa_";
|
||||
|
||||
std::optional<Window::SessionController*> ExtractController(
|
||||
|
@ -234,6 +235,13 @@ struct Message::CommentsButton {
|
|||
int rightActionCountWidth = 0;
|
||||
};
|
||||
|
||||
struct Message::FromNameStatus {
|
||||
DocumentId id = 0;
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
||||
Ui::Text::CustomEmojiColored colored;
|
||||
int skip = 0;
|
||||
};
|
||||
|
||||
LogEntryOriginal::LogEntryOriginal() = default;
|
||||
|
||||
LogEntryOriginal::LogEntryOriginal(LogEntryOriginal &&other)
|
||||
|
@ -277,8 +285,9 @@ Message::Message(
|
|||
}
|
||||
|
||||
Message::~Message() {
|
||||
if (_comments) {
|
||||
if (_comments || (_fromNameStatus && _fromNameStatus->custom)) {
|
||||
_comments = nullptr;
|
||||
_fromNameStatus = nullptr;
|
||||
checkHeavyPart();
|
||||
}
|
||||
}
|
||||
|
@ -547,6 +556,9 @@ QSize Message::performCountOptimalSize() {
|
|||
: item->hiddenSenderInfo()->nameText();
|
||||
auto namew = st::msgPadding.left()
|
||||
+ name.maxWidth()
|
||||
+ (_fromNameStatus
|
||||
? st::dialogsPremiumIcon.width()
|
||||
: 0)
|
||||
+ st::msgPadding.right();
|
||||
if (via && !displayForwardedFrom()) {
|
||||
namew += st::msgServiceFont->spacew + via->maxWidth;
|
||||
|
@ -1087,32 +1099,71 @@ void Message::paintFromName(
|
|||
availableWidth -= st::msgPadding.right() + rightWidth;
|
||||
}
|
||||
|
||||
p.setFont(st::msgNameFont);
|
||||
const auto stm = context.messageStyle();
|
||||
|
||||
const auto nameText = [&]() -> const Ui::Text::String * {
|
||||
const auto from = item->displayFrom();
|
||||
const auto service = (context.outbg || item->isPost());
|
||||
const auto st = context.st;
|
||||
const auto from = item->displayFrom();
|
||||
const auto info = from ? nullptr : item->hiddenSenderInfo();
|
||||
Assert(from || info);
|
||||
const auto service = (context.outbg || item->isPost());
|
||||
const auto st = context.st;
|
||||
const auto nameFg = !service
|
||||
? FromNameFg(context, from ? from->id : info->colorPeerId)
|
||||
: item->isSponsored()
|
||||
? st->boxTextFgGood()
|
||||
: stm->msgServiceFg;
|
||||
const auto nameText = [&] {
|
||||
if (from) {
|
||||
p.setPen(!service
|
||||
? FromNameFg(context, from->id)
|
||||
: item->isSponsored()
|
||||
? st->boxTextFgGood()
|
||||
: stm->msgServiceFg);
|
||||
validateFromNameText(from);
|
||||
return &_fromName;
|
||||
} else if (const auto info = item->hiddenSenderInfo()) {
|
||||
p.setPen(!service
|
||||
? FromNameFg(context, info->colorPeerId)
|
||||
: item->isSponsored()
|
||||
? st->boxTextFgGood()
|
||||
: stm->msgServiceFg);
|
||||
return &info->nameText();
|
||||
} else {
|
||||
Unexpected("Corrupt sender information in message.");
|
||||
return static_cast<const Ui::Text::String*>(&_fromName);
|
||||
}
|
||||
return &info->nameText();
|
||||
}();
|
||||
const auto statusWidth = _fromNameStatus ? st::dialogsPremiumIcon.width() : 0;
|
||||
if (statusWidth && availableWidth > statusWidth) {
|
||||
const auto x = availableLeft
|
||||
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
||||
const auto y = trect.top();
|
||||
const auto color = QColor(
|
||||
nameFg->c.red(),
|
||||
nameFg->c.green(),
|
||||
nameFg->c.blue(),
|
||||
nameFg->c.alpha() * 115 / 255);
|
||||
const auto user = from->asUser();
|
||||
const auto id = user ? user->emojiStatusId() : 0;
|
||||
if (_fromNameStatus->id != id) {
|
||||
const auto that = const_cast<Message*>(this);
|
||||
_fromNameStatus->custom = id
|
||||
? std::make_unique<Ui::Text::LimitedLoopsEmoji>(
|
||||
user->owner().customEmojiManager().create(
|
||||
id,
|
||||
[=] { that->customEmojiRepaint(); }),
|
||||
kPlayStatusLimit)
|
||||
: nullptr;
|
||||
if (id && !_fromNameStatus->id) {
|
||||
history()->owner().registerHeavyViewPart(that);
|
||||
} else if (!id && _fromNameStatus->id) {
|
||||
that->checkHeavyPart();
|
||||
}
|
||||
_fromNameStatus->id = id;
|
||||
}
|
||||
if (_fromNameStatus->custom) {
|
||||
clearCustomEmojiRepaint();
|
||||
_fromNameStatus->colored.color = color;
|
||||
_fromNameStatus->custom->paint(p, {
|
||||
.preview = color,
|
||||
.colored = &_fromNameStatus->colored,
|
||||
.now = context.now,
|
||||
.position = QPoint(
|
||||
x - 2 * _fromNameStatus->skip,
|
||||
y + _fromNameStatus->skip),
|
||||
.paused = delegate()->elementIsGifPaused(),
|
||||
});
|
||||
} else {
|
||||
st::dialogsPremiumIcon.paint(p, x, y, width(), color);
|
||||
}
|
||||
availableWidth -= statusWidth;
|
||||
}
|
||||
p.setFont(st::msgNameFont);
|
||||
p.setPen(nameFg);
|
||||
nameText->drawElided(p, availableLeft, trect.top(), availableWidth);
|
||||
const auto skipWidth = nameText->maxWidth() + st::msgServiceFont->spacew;
|
||||
availableLeft += skipWidth;
|
||||
|
@ -1382,7 +1433,9 @@ void Message::toggleCommentsButtonRipple(bool pressed) {
|
|||
}
|
||||
|
||||
bool Message::hasHeavyPart() const {
|
||||
return _comments || Element::hasHeavyPart();
|
||||
return _comments
|
||||
|| (_fromNameStatus && _fromNameStatus->custom)
|
||||
|| Element::hasHeavyPart();
|
||||
}
|
||||
|
||||
void Message::unloadHeavyPart() {
|
||||
|
@ -1391,6 +1444,9 @@ void Message::unloadHeavyPart() {
|
|||
_reactions->unloadCustomEmoji();
|
||||
}
|
||||
_comments = nullptr;
|
||||
if (_fromNameStatus) {
|
||||
_fromNameStatus->custom = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Message::showForwardsFromSender(
|
||||
|
@ -2245,7 +2301,13 @@ void Message::refreshReactions() {
|
|||
}
|
||||
|
||||
void Message::validateFromNameText(PeerData *from) const {
|
||||
const auto version = from ? from->nameVersion() : 0;
|
||||
if (!from) {
|
||||
if (_fromNameStatus) {
|
||||
_fromNameStatus = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto version = from->nameVersion();
|
||||
if (_fromNameVersion < version) {
|
||||
_fromNameVersion = version;
|
||||
_fromName.setText(
|
||||
|
@ -2253,6 +2315,16 @@ void Message::validateFromNameText(PeerData *from) const {
|
|||
from->name(),
|
||||
Ui::NameTextOptions());
|
||||
}
|
||||
if (from->isPremium()) {
|
||||
if (!_fromNameStatus) {
|
||||
_fromNameStatus = std::make_unique<FromNameStatus>();
|
||||
const auto size = st::emojiSize;
|
||||
const auto emoji = Ui::Text::AdjustCustomEmojiSize(size);
|
||||
_fromNameStatus->skip = (size - emoji) / 2;
|
||||
}
|
||||
} else if (_fromNameStatus) {
|
||||
_fromNameStatus = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Message::itemDataChanged() {
|
||||
|
|
|
@ -151,6 +151,7 @@ protected:
|
|||
|
||||
private:
|
||||
struct CommentsButton;
|
||||
struct FromNameStatus;
|
||||
|
||||
void initLogEntryOriginal();
|
||||
void initPsa();
|
||||
|
@ -258,6 +259,7 @@ private:
|
|||
mutable std::unique_ptr<CommentsButton> _comments;
|
||||
|
||||
mutable Ui::Text::String _fromName;
|
||||
mutable std::unique_ptr<FromNameStatus> _fromNameStatus;
|
||||
Ui::Text::String _rightBadge;
|
||||
mutable int _fromNameVersion = 0;
|
||||
int _bubbleWidthLimit = 0;
|
||||
|
|
|
@ -636,7 +636,9 @@ void WhoReactedListMenu::clear() {
|
|||
void WhoReactedListMenu::populate(
|
||||
not_null<PopupMenu*> menu,
|
||||
const WhoReadContent &content,
|
||||
Fn<void()> refillTopActions) {
|
||||
Fn<void()> refillTopActions,
|
||||
int addedToBottom,
|
||||
Fn<void()> appendBottomActions) {
|
||||
const auto reactions = ranges::count_if(
|
||||
content.participants,
|
||||
[](const auto &p) { return !p.customEntityData.isEmpty(); });
|
||||
|
@ -649,6 +651,7 @@ void WhoReactedListMenu::populate(
|
|||
if (refillTopActions) {
|
||||
refillTopActions();
|
||||
}
|
||||
addedToBottom = 0;
|
||||
}
|
||||
auto index = 0;
|
||||
const auto append = [&](EntryData &&data) {
|
||||
|
@ -661,7 +664,12 @@ void WhoReactedListMenu::populate(
|
|||
menu->menu()->st(),
|
||||
std::move(data));
|
||||
_actions.push_back(item.get());
|
||||
menu->addAction(std::move(item));
|
||||
const auto count = int(menu->actions().size());
|
||||
if (addedToBottom > 0 && addedToBottom <= count) {
|
||||
menu->insertAction(count - addedToBottom, std::move(item));
|
||||
} else {
|
||||
menu->addAction(std::move(item));
|
||||
}
|
||||
}
|
||||
++index;
|
||||
};
|
||||
|
@ -682,7 +690,9 @@ void WhoReactedListMenu::populate(
|
|||
.callback = _showAllChosen,
|
||||
});
|
||||
}
|
||||
|
||||
if (!addedToBottom && appendBottomActions) {
|
||||
appendBottomActions();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -65,7 +65,9 @@ public:
|
|||
void populate(
|
||||
not_null<PopupMenu*> menu,
|
||||
const WhoReadContent &content,
|
||||
Fn<void()> refillTopActions = nullptr);
|
||||
Fn<void()> refillTopActions = nullptr,
|
||||
int addedToBottom = 0,
|
||||
Fn<void()> appendBottomActions = nullptr);
|
||||
|
||||
private:
|
||||
class EntryAction;
|
||||
|
|
|
@ -17,6 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_dialogs.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kPlayStatusLimit = 2;
|
||||
|
||||
} // namespace
|
||||
|
||||
void UnreadBadge::setText(const QString &text, bool active) {
|
||||
_text = text;
|
||||
|
@ -177,11 +182,14 @@ int PeerBadge::drawGetWidth(
|
|||
>();
|
||||
}
|
||||
if (_emojiStatus->id != id) {
|
||||
using namespace Ui::Text;
|
||||
auto &manager = peer->session().data().customEmojiManager();
|
||||
_emojiStatus->id = id;
|
||||
_emojiStatus->emoji = manager.create(
|
||||
id,
|
||||
descriptor.customEmojiRepaint);
|
||||
_emojiStatus->emoji = std::make_unique<LimitedLoopsEmoji>(
|
||||
manager.create(
|
||||
id,
|
||||
descriptor.customEmojiRepaint),
|
||||
kPlayStatusLimit);
|
||||
}
|
||||
_emojiStatus->colored->color = (*descriptor.premiumFg)->c;
|
||||
_emojiStatus->emoji->paint(p, {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 51657b3c8a643c9ca2721029fd48f63390417042
|
||||
Subproject commit a5766cb1f6bfcd208814b0b71322128ecb47039a
|
Loading…
Add table
Reference in a new issue