mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Use a custom animated emoji for collectible status.
This commit is contained in:
parent
d2be10cd4e
commit
c25adf8b57
13 changed files with 195 additions and 89 deletions
|
@ -935,13 +935,9 @@ int ColorSelector::resizeGetHeight(int newWidth) {
|
||||||
const auto session = &show->session();
|
const auto session = &show->session();
|
||||||
std::move(statusIdValue) | rpl::start_with_next([=](EmojiStatusId id) {
|
std::move(statusIdValue) | rpl::start_with_next([=](EmojiStatusId id) {
|
||||||
state->statusId = id;
|
state->statusId = id;
|
||||||
state->emoji = id.collectible // todo collectibles
|
state->emoji = id
|
||||||
? session->data().customEmojiManager().create(
|
? session->data().customEmojiManager().create(
|
||||||
id.collectible->documentId,
|
Data::EmojiStatusCustomId(id),
|
||||||
[=] { right->update(); })
|
|
||||||
: id.documentId
|
|
||||||
? session->data().customEmojiManager().create(
|
|
||||||
id.documentId,
|
|
||||||
[=] { right->update(); })
|
[=] { right->update(); })
|
||||||
: nullptr;
|
: nullptr;
|
||||||
right->resize(
|
right->resize(
|
||||||
|
|
|
@ -1129,17 +1129,16 @@ void EmojiListWidget::fillRecentFrom(
|
||||||
});
|
});
|
||||||
_recentCustomIds.emplace(fakeId);
|
_recentCustomIds.emplace(fakeId);
|
||||||
} else {
|
} else {
|
||||||
const auto documentId = id.collectible
|
|
||||||
? id.collectible->documentId
|
|
||||||
: id.documentId;
|
|
||||||
_recent.push_back({
|
_recent.push_back({
|
||||||
.collectible = id.collectible,
|
.collectible = id.collectible,
|
||||||
.custom = resolveCustomRecent(documentId),
|
.custom = resolveCustomRecent(id),
|
||||||
.id = {
|
.id = {
|
||||||
RecentEmojiDocument{ .id = documentId, .test = test },
|
RecentEmojiDocument{ .id = id.documentId, .test = test },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
_recentCustomIds.emplace(documentId);
|
_recentCustomIds.emplace(id.collectible
|
||||||
|
? id.collectible->documentId
|
||||||
|
: id.documentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1490,27 +1489,6 @@ void EmojiListWidget::drawCollapsedBadge(
|
||||||
text);
|
text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::drawCollectible(
|
|
||||||
QPainter &p,
|
|
||||||
QPoint position,
|
|
||||||
Data::EmojiStatusCollectible *collectible) {
|
|
||||||
if (!collectible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto inner = QRect(position, st::emojiPanArea);
|
|
||||||
auto gradient = QRadialGradient(inner.center(), inner.height() / 2);
|
|
||||||
gradient.setStops({
|
|
||||||
{ 0., collectible->centerColor },
|
|
||||||
{ 1., collectible->edgeColor },
|
|
||||||
});
|
|
||||||
p.setBrush(gradient);
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.drawRoundedRect(
|
|
||||||
inner,
|
|
||||||
st::emojiPanRadius,
|
|
||||||
st::emojiPanRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmojiListWidget::drawRecent(
|
void EmojiListWidget::drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const ExpandingContext &context,
|
const ExpandingContext &context,
|
||||||
|
@ -1547,14 +1525,12 @@ void EmojiListWidget::drawRecent(
|
||||||
|
|
||||||
auto q = Painter(&_premiumMarkFrameCache);
|
auto q = Painter(&_premiumMarkFrameCache);
|
||||||
_emojiPaintContext->position = QPoint();
|
_emojiPaintContext->position = QPoint();
|
||||||
drawCollectible(q, position, recent.collectible.get());
|
|
||||||
custom->paint(q, *_emojiPaintContext);
|
custom->paint(q, *_emojiPaintContext);
|
||||||
q.end();
|
q.end();
|
||||||
|
|
||||||
p.drawImage(exactPosition, _premiumMarkFrameCache);
|
p.drawImage(exactPosition, _premiumMarkFrameCache);
|
||||||
} else {
|
} else {
|
||||||
_emojiPaintContext->position = exactPosition;
|
_emojiPaintContext->position = exactPosition;
|
||||||
drawCollectible(p, position, recent.collectible.get());
|
|
||||||
custom->paint(p, *_emojiPaintContext);
|
custom->paint(p, *_emojiPaintContext);
|
||||||
}
|
}
|
||||||
} else if (const auto emoji = std::get_if<EmojiPtr>(&recent.id.data)) {
|
} else if (const auto emoji = std::get_if<EmojiPtr>(&recent.id.data)) {
|
||||||
|
@ -1609,7 +1585,6 @@ void EmojiListWidget::drawCustom(
|
||||||
_emojiPaintContext->position = position
|
_emojiPaintContext->position = position
|
||||||
+ _innerPosition
|
+ _innerPosition
|
||||||
+ _customPosition;
|
+ _customPosition;
|
||||||
drawCollectible(p, position, entry.collectible.get());
|
|
||||||
entry.custom->paint(p, *_emojiPaintContext);
|
entry.custom->paint(p, *_emojiPaintContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1643,8 +1618,15 @@ EmojiListWidget::ResolvedCustom EmojiListWidget::lookupCustomEmoji(
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
} else if (section == int(Section::Recent) && index < _recent.size()) {
|
} else if (section == int(Section::Recent) && index < _recent.size()) {
|
||||||
|
const auto &recent = _recent[index];
|
||||||
|
if (recent.collectible) {
|
||||||
|
return {
|
||||||
|
session().data().document(recent.collectible->documentId),
|
||||||
|
recent.collectible,
|
||||||
|
};
|
||||||
|
}
|
||||||
const auto document = std::get_if<RecentEmojiDocument>(
|
const auto document = std::get_if<RecentEmojiDocument>(
|
||||||
&_recent[index].id.data);
|
&recent.id.data);
|
||||||
if (document) {
|
if (document) {
|
||||||
return { session().data().document(document->id) };
|
return { session().data().document(document->id) };
|
||||||
}
|
}
|
||||||
|
@ -2342,11 +2324,12 @@ void EmojiListWidget::refreshCustom() {
|
||||||
auto set = std::vector<CustomOne>();
|
auto set = std::vector<CustomOne>();
|
||||||
set.reserve(list.size());
|
set.reserve(list.size());
|
||||||
for (const auto document : list) {
|
for (const auto document : list) {
|
||||||
if (_restrictedCustomList.contains(document->id)) {
|
const auto id = EmojiStatusId{ document->id };
|
||||||
|
if (_restrictedCustomList.contains(id.documentId)) {
|
||||||
continue;
|
continue;
|
||||||
} else if (const auto sticker = document->sticker()) {
|
} else if (const auto sticker = document->sticker()) {
|
||||||
set.push_back({
|
set.push_back({
|
||||||
.custom = resolveCustomEmoji(document, lookupId),
|
.custom = resolveCustomEmoji(id, document, lookupId),
|
||||||
.document = document,
|
.document = document,
|
||||||
.emoji = Ui::Emoji::Find(sticker->alt),
|
.emoji = Ui::Emoji::Find(sticker->alt),
|
||||||
});
|
});
|
||||||
|
@ -2401,18 +2384,19 @@ Fn<void()> EmojiListWidget::repaintCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomEmoji(
|
not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomEmoji(
|
||||||
|
EmojiStatusId id,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
uint64 setId) {
|
uint64 setId) {
|
||||||
Expects(document->sticker() != nullptr);
|
Expects(document->sticker() != nullptr);
|
||||||
|
|
||||||
const auto documentId = document->id;
|
const auto documentId = document->id;
|
||||||
const auto i = _customEmoji.find(documentId);
|
const auto i = _customEmoji.find(id);
|
||||||
const auto recentOnly = (i != end(_customEmoji)) && i->second.recentOnly;
|
const auto recentOnly = (i != end(_customEmoji)) && i->second.recentOnly;
|
||||||
if (i != end(_customEmoji) && !recentOnly) {
|
if (i != end(_customEmoji) && !recentOnly) {
|
||||||
return i->second.emoji.get();
|
return i->second.emoji.get();
|
||||||
}
|
}
|
||||||
auto instance = document->owner().customEmojiManager().create(
|
auto instance = document->owner().customEmojiManager().create(
|
||||||
document,
|
Data::EmojiStatusCustomId(id),
|
||||||
repaintCallback(documentId, setId),
|
repaintCallback(documentId, setId),
|
||||||
Data::CustomEmojiManager::SizeTag::Large);
|
Data::CustomEmojiManager::SizeTag::Large);
|
||||||
if (recentOnly) {
|
if (recentOnly) {
|
||||||
|
@ -2426,7 +2410,7 @@ not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomEmoji(
|
||||||
return i->second.emoji.get();
|
return i->second.emoji.get();
|
||||||
}
|
}
|
||||||
return _customEmoji.emplace(
|
return _customEmoji.emplace(
|
||||||
documentId,
|
id,
|
||||||
CustomEmojiInstance{ .emoji = std::move(instance) }
|
CustomEmojiInstance{ .emoji = std::move(instance) }
|
||||||
).first->second.emoji.get();
|
).first->second.emoji.get();
|
||||||
}
|
}
|
||||||
|
@ -2444,27 +2428,37 @@ Ui::Text::CustomEmoji *EmojiListWidget::resolveCustomRecent(
|
||||||
|
|
||||||
not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomRecent(
|
not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomRecent(
|
||||||
DocumentId documentId) {
|
DocumentId documentId) {
|
||||||
const auto i = _customRecent.find(documentId);
|
return resolveCustomRecent(EmojiStatusId{ documentId });
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<Ui::Text::CustomEmoji*> EmojiListWidget::resolveCustomRecent(
|
||||||
|
EmojiStatusId id) {
|
||||||
|
const auto i = id.collectible
|
||||||
|
? end(_customRecent)
|
||||||
|
: _customRecent.find(id.documentId);
|
||||||
if (i != end(_customRecent)) {
|
if (i != end(_customRecent)) {
|
||||||
return i->second.get();
|
return i->second.get();
|
||||||
}
|
}
|
||||||
const auto j = _customEmoji.find(documentId);
|
const auto j = _customEmoji.find(id);
|
||||||
if (j != end(_customEmoji)) {
|
if (j != end(_customEmoji)) {
|
||||||
return j->second.emoji.get();
|
return j->second.emoji.get();
|
||||||
}
|
}
|
||||||
|
const auto documentId = id.collectible
|
||||||
|
? id.collectible->documentId
|
||||||
|
: id.documentId;
|
||||||
auto repaint = repaintCallback(documentId, RecentEmojiSectionSetId());
|
auto repaint = repaintCallback(documentId, RecentEmojiSectionSetId());
|
||||||
if (_customRecentFactory) {
|
if (_customRecentFactory && !id.collectible) {
|
||||||
return _customRecent.emplace(
|
return _customRecent.emplace(
|
||||||
documentId,
|
id.documentId,
|
||||||
_customRecentFactory(documentId, std::move(repaint))
|
_customRecentFactory(id.documentId, std::move(repaint))
|
||||||
).first->second.get();
|
).first->second.get();
|
||||||
}
|
}
|
||||||
auto custom = session().data().customEmojiManager().create(
|
auto custom = session().data().customEmojiManager().create(
|
||||||
documentId,
|
Data::EmojiStatusCustomId(id),
|
||||||
std::move(repaint),
|
std::move(repaint),
|
||||||
Data::CustomEmojiManager::SizeTag::Large);
|
Data::CustomEmojiManager::SizeTag::Large);
|
||||||
return _customEmoji.emplace(
|
return _customEmoji.emplace(
|
||||||
documentId,
|
id,
|
||||||
CustomEmojiInstance{ .emoji = std::move(custom), .recentOnly = true }
|
CustomEmojiInstance{ .emoji = std::move(custom), .recentOnly = true }
|
||||||
).first->second.emoji.get();
|
).first->second.emoji.get();
|
||||||
}
|
}
|
||||||
|
@ -2489,7 +2483,7 @@ void EmojiListWidget::refreshEmojiStatusCollectibles() {
|
||||||
if (const auto sticker = document->sticker()) {
|
if (const auto sticker = document->sticker()) {
|
||||||
set.push_back({
|
set.push_back({
|
||||||
.collectible = status.collectible,
|
.collectible = status.collectible,
|
||||||
.custom = resolveCustomEmoji(document, setId),
|
.custom = resolveCustomEmoji(status, document, setId),
|
||||||
.document = document,
|
.document = document,
|
||||||
.emoji = Ui::Emoji::Find(sticker->alt),
|
.emoji = Ui::Emoji::Find(sticker->alt),
|
||||||
});
|
});
|
||||||
|
|
|
@ -325,10 +325,6 @@ private:
|
||||||
void selectCustom(FileChosen data);
|
void selectCustom(FileChosen data);
|
||||||
void paint(Painter &p, ExpandingContext context, QRect clip);
|
void paint(Painter &p, ExpandingContext context, QRect clip);
|
||||||
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
|
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
|
||||||
void drawCollectible(
|
|
||||||
QPainter &p,
|
|
||||||
QPoint position,
|
|
||||||
Data::EmojiStatusCollectible *collectible);
|
|
||||||
void drawRecent(
|
void drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const ExpandingContext &context,
|
const ExpandingContext &context,
|
||||||
|
@ -389,12 +385,15 @@ private:
|
||||||
void fillRecent();
|
void fillRecent();
|
||||||
void fillRecentFrom(const std::vector<EmojiStatusId> &list);
|
void fillRecentFrom(const std::vector<EmojiStatusId> &list);
|
||||||
[[nodiscard]] not_null<Ui::Text::CustomEmoji*> resolveCustomEmoji(
|
[[nodiscard]] not_null<Ui::Text::CustomEmoji*> resolveCustomEmoji(
|
||||||
|
EmojiStatusId id,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
uint64 setId);
|
uint64 setId);
|
||||||
[[nodiscard]] Ui::Text::CustomEmoji *resolveCustomRecent(
|
[[nodiscard]] Ui::Text::CustomEmoji *resolveCustomRecent(
|
||||||
Core::RecentEmojiId customId);
|
Core::RecentEmojiId customId);
|
||||||
[[nodiscard]] not_null<Ui::Text::CustomEmoji*> resolveCustomRecent(
|
[[nodiscard]] not_null<Ui::Text::CustomEmoji*> resolveCustomRecent(
|
||||||
DocumentId documentId);
|
DocumentId documentId);
|
||||||
|
[[nodiscard]] not_null<Ui::Text::CustomEmoji*> resolveCustomRecent(
|
||||||
|
EmojiStatusId id);
|
||||||
[[nodiscard]] Fn<void()> repaintCallback(
|
[[nodiscard]] Fn<void()> repaintCallback(
|
||||||
DocumentId documentId,
|
DocumentId documentId,
|
||||||
uint64 setId);
|
uint64 setId);
|
||||||
|
@ -432,7 +431,7 @@ private:
|
||||||
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
|
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
|
||||||
std::vector<CustomSet> _custom;
|
std::vector<CustomSet> _custom;
|
||||||
base::flat_set<DocumentId> _restrictedCustomList;
|
base::flat_set<DocumentId> _restrictedCustomList;
|
||||||
base::flat_map<DocumentId, CustomEmojiInstance> _customEmoji;
|
base::flat_map<EmojiStatusId, CustomEmojiInstance> _customEmoji;
|
||||||
base::flat_map<
|
base::flat_map<
|
||||||
DocumentId,
|
DocumentId,
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji>> _customRecent;
|
std::unique_ptr<Ui::Text::CustomEmoji>> _customRecent;
|
||||||
|
|
|
@ -559,4 +559,9 @@ EmojiStatusId EmojiStatuses::fromUniqueGift(
|
||||||
return { .collectible = collectible };
|
return { .collectible = collectible };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmojiStatusCollectible *EmojiStatuses::collectibleInfo(CollectibleId id) {
|
||||||
|
const auto i = _collectibleData.find(id);
|
||||||
|
return (i != end(_collectibleData)) ? i->second.get() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
void set(EmojiStatusId id, TimeId until = 0);
|
void set(EmojiStatusId id, TimeId until = 0);
|
||||||
void set(not_null<PeerData*> peer, EmojiStatusId id, TimeId until = 0);
|
void set(not_null<PeerData*> peer, EmojiStatusId id, TimeId until = 0);
|
||||||
[[nodiscard]] EmojiStatusId fromUniqueGift(const Data::UniqueGift &gift);
|
[[nodiscard]] EmojiStatusId fromUniqueGift(const Data::UniqueGift &gift);
|
||||||
|
[[nodiscard]] EmojiStatusCollectible *collectibleInfo(CollectibleId id);
|
||||||
|
|
||||||
void registerAutomaticClear(not_null<PeerData*> peer, TimeId until);
|
void registerAutomaticClear(not_null<PeerData*> peer, TimeId until);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_forum_topic.h" // ParseTopicIconEmojiEntity.
|
#include "data/data_forum_topic.h" // ParseTopicIconEmojiEntity.
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
|
@ -28,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "chat_helpers/stickers_lottie.h"
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
#include "storage/file_download.h" // kMaxFileInMemory
|
#include "storage/file_download.h" // kMaxFileInMemory
|
||||||
#include "ui/chat/chats_filter_tag.h"
|
#include "ui/chat/chats_filter_tag.h"
|
||||||
|
#include "ui/effects/premium_stars_colored.h"
|
||||||
#include "ui/effects/credits_graphics.h"
|
#include "ui/effects/credits_graphics.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "ui/text/custom_emoji_instance.h"
|
#include "ui/text/custom_emoji_instance.h"
|
||||||
|
@ -117,6 +119,10 @@ private:
|
||||||
return u"force-static:"_q;
|
return u"force-static:"_q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QString CollectiblePrefix() {
|
||||||
|
return u"collectible:"_q;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] QString InternalPadding(QMargins value) {
|
[[nodiscard]] QString InternalPadding(QMargins value) {
|
||||||
return value.isNull() ? QString() : QString(",%1,%2,%3,%4"
|
return value.isNull() ? QString() : QString(",%1,%2,%3,%4"
|
||||||
).arg(value.left()
|
).arg(value.left()
|
||||||
|
@ -568,6 +574,20 @@ std::unique_ptr<Ui::Text::CustomEmoji> CustomEmojiManager::create(
|
||||||
const auto ratio = style::DevicePixelRatio();
|
const auto ratio = style::DevicePixelRatio();
|
||||||
const auto size = EmojiSizeFromTag(tag) / ratio;
|
const auto size = EmojiSizeFromTag(tag) / ratio;
|
||||||
return userpic(data, std::move(update), size);
|
return userpic(data, std::move(update), size);
|
||||||
|
} else if (data.startsWith(CollectiblePrefix())) {
|
||||||
|
const auto id = data.mid(CollectiblePrefix().size()).toULongLong();
|
||||||
|
const auto emojiStatuses = &session().data().emojiStatuses();
|
||||||
|
auto info = emojiStatuses->collectibleInfo(id);
|
||||||
|
Assert(info != nullptr);
|
||||||
|
const auto documentId = info->documentId;
|
||||||
|
auto inner = create(documentId, base::duplicate(update), tag);
|
||||||
|
return Ui::Premium::MakeCollectibleEmoji(
|
||||||
|
data,
|
||||||
|
info->centerColor,
|
||||||
|
info->edgeColor,
|
||||||
|
std::move(inner),
|
||||||
|
std::move(update),
|
||||||
|
FrameSizeFromTag(tag) / style::DevicePixelRatio());
|
||||||
} else if (const auto parsed = Data::ParseTopicIconEmojiEntity(data)) {
|
} else if (const auto parsed = Data::ParseTopicIconEmojiEntity(data)) {
|
||||||
return MakeTopicIconEmoji(parsed, std::move(update), tag);
|
return MakeTopicIconEmoji(parsed, std::move(update), tag);
|
||||||
}
|
}
|
||||||
|
@ -1147,4 +1167,14 @@ Ui::Text::CustomEmojiFactory ReactedMenuFactory(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CollectibleCustomEmojiId(Data::EmojiStatusCollectible &data) {
|
||||||
|
return CollectiblePrefix() + QString::number(data.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EmojiStatusCustomId(const EmojiStatusId &id) {
|
||||||
|
return id.collectible
|
||||||
|
? CollectibleCustomEmojiId(*id.collectible)
|
||||||
|
: SerializeCustomEmojiId(id.documentId);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -223,4 +223,8 @@ void InsertCustomEmoji(
|
||||||
[[nodiscard]] Ui::Text::CustomEmojiFactory ReactedMenuFactory(
|
[[nodiscard]] Ui::Text::CustomEmojiFactory ReactedMenuFactory(
|
||||||
not_null<Main::Session*> session);
|
not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
[[nodiscard]] QString CollectibleCustomEmojiId(
|
||||||
|
Data::EmojiStatusCollectible &data);
|
||||||
|
[[nodiscard]] QString EmojiStatusCustomId(const EmojiStatusId &id);
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -113,11 +113,11 @@ namespace {
|
||||||
Data::PeerUpdate::Flag::EmojiStatus
|
Data::PeerUpdate::Flag::EmojiStatus
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
const auto id = peer->emojiStatusId();
|
const auto id = peer->emojiStatusId();
|
||||||
const auto documentId = id.collectible
|
return id.collectible
|
||||||
? id.collectible->documentId
|
? rpl::single(Ui::Text::SingleCustomEmoji(
|
||||||
: id.documentId;
|
Data::EmojiStatusCustomId(id)))
|
||||||
return documentId
|
: id.documentId
|
||||||
? ResolveIsCustom(owner, documentId)
|
? ResolveIsCustom(owner, id.documentId)
|
||||||
: rpl::single(TextWithEntities());
|
: rpl::single(TextWithEntities());
|
||||||
}) | rpl::flatten_latest() | rpl::distinct_until_changed();
|
}) | rpl::flatten_latest() | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,7 +371,7 @@ struct Message::CommentsButton {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message::FromNameStatus {
|
struct Message::FromNameStatus {
|
||||||
DocumentId id = 0;
|
EmojiStatusId id;
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
};
|
};
|
||||||
|
@ -1767,14 +1767,14 @@ void Message::paintFromName(
|
||||||
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
||||||
const auto y = trect.top();
|
const auto y = trect.top();
|
||||||
auto color = nameFg;
|
auto color = nameFg;
|
||||||
color.setAlpha(115); // todo collectibles
|
color.setAlpha(115);
|
||||||
const auto id = from ? from->emojiStatusId().documentId : 0;
|
const auto id = from ? from->emojiStatusId() : EmojiStatusId();
|
||||||
if (_fromNameStatus->id != id) {
|
if (_fromNameStatus->id != id) {
|
||||||
const auto that = const_cast<Message*>(this);
|
const auto that = const_cast<Message*>(this);
|
||||||
_fromNameStatus->custom = id
|
_fromNameStatus->custom = id
|
||||||
? std::make_unique<Ui::Text::LimitedLoopsEmoji>(
|
? std::make_unique<Ui::Text::LimitedLoopsEmoji>(
|
||||||
history()->owner().customEmojiManager().create(
|
history()->owner().customEmojiManager().create(
|
||||||
id,
|
Data::EmojiStatusCustomId(id),
|
||||||
[=] { that->customEmojiRepaint(); }),
|
[=] { that->customEmojiRepaint(); }),
|
||||||
kPlayStatusLimit)
|
kPlayStatusLimit)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
@ -2379,7 +2379,7 @@ void Message::unloadHeavyPart() {
|
||||||
_comments = nullptr;
|
_comments = nullptr;
|
||||||
if (_fromNameStatus) {
|
if (_fromNameStatus) {
|
||||||
_fromNameStatus->custom = nullptr;
|
_fromNameStatus->custom = nullptr;
|
||||||
_fromNameStatus->id = 0;
|
_fromNameStatus->id = EmojiStatusId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,12 +130,9 @@ void Badge::setContent(Content content) {
|
||||||
: id
|
: id
|
||||||
? nullptr
|
? nullptr
|
||||||
: &_st.premium;
|
: &_st.premium;
|
||||||
const auto documentId = id.collectible
|
if (id) {
|
||||||
? id.collectible->documentId
|
|
||||||
: id.documentId;
|
|
||||||
if (documentId) {
|
|
||||||
_emojiStatus = _session->data().customEmojiManager().create(
|
_emojiStatus = _session->data().customEmojiManager().create(
|
||||||
documentId,
|
Data::EmojiStatusCustomId(id),
|
||||||
[raw = _view.data()] { raw->update(); },
|
[raw = _view.data()] { raw->update(); },
|
||||||
sizeTag());
|
sizeTag());
|
||||||
if (_customStatusLoopsLimit > 0) {
|
if (_customStatusLoopsLimit > 0) {
|
||||||
|
|
|
@ -8,10 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/premium_stars_colored.h"
|
#include "ui/effects/premium_stars_colored.h"
|
||||||
|
|
||||||
#include "ui/effects/premium_graphics.h" // GiftGradientStops.
|
#include "ui/effects/premium_graphics.h" // GiftGradientStops.
|
||||||
|
#include "ui/text/text_custom_emoji.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui::Premium {
|
||||||
namespace Premium {
|
|
||||||
|
|
||||||
ColoredMiniStars::ColoredMiniStars(
|
ColoredMiniStars::ColoredMiniStars(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
@ -106,5 +106,79 @@ void ColoredMiniStars::setCenter(const QRect &rect) {
|
||||||
setSize(ministarsRect.size());
|
setSize(ministarsRect.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Premium
|
std::unique_ptr<Text::CustomEmoji> MakeCollectibleEmoji(
|
||||||
} // namespace Ui
|
QStringView entityData,
|
||||||
|
QColor centerColor,
|
||||||
|
QColor edgeColor,
|
||||||
|
std::unique_ptr<Text::CustomEmoji> inner,
|
||||||
|
Fn<void()> update,
|
||||||
|
int size) {
|
||||||
|
class Emoji final : public Text::CustomEmoji {
|
||||||
|
public:
|
||||||
|
Emoji(
|
||||||
|
QStringView entityData,
|
||||||
|
QColor centerColor,
|
||||||
|
QColor edgeColor,
|
||||||
|
std::unique_ptr<Ui::Text::CustomEmoji> inner,
|
||||||
|
Fn<void()> update,
|
||||||
|
int size)
|
||||||
|
: _entityData(entityData.toString())
|
||||||
|
, _stars([=](QRect) { update(); }, MiniStars::Type::SlowStars)
|
||||||
|
, _centerColor(centerColor)
|
||||||
|
, _edgeColor(edgeColor)
|
||||||
|
, _inner(std::move(inner))
|
||||||
|
, _size(size) {
|
||||||
|
_stars.setColorOverride(QGradientStops{
|
||||||
|
{ 0., edgeColor },
|
||||||
|
{ 1., centerColor },
|
||||||
|
});
|
||||||
|
_stars.setSize(QSize(size, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
int width() override {
|
||||||
|
return _inner->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString entityData() override {
|
||||||
|
return _entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(QPainter &p, const Context &context) override {
|
||||||
|
_stars.setPosition(context.position);
|
||||||
|
_stars.paint(p);
|
||||||
|
|
||||||
|
_inner->paint(p, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unload() override {
|
||||||
|
_inner->unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ready() override {
|
||||||
|
return _inner->ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readyInDefaultState() override {
|
||||||
|
return _inner->readyInDefaultState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString _entityData;
|
||||||
|
ColoredMiniStars _stars;
|
||||||
|
QColor _centerColor;
|
||||||
|
QColor _edgeColor;
|
||||||
|
std::unique_ptr<Text::CustomEmoji> _inner;
|
||||||
|
int _size = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::make_unique<Emoji>(
|
||||||
|
entityData,
|
||||||
|
centerColor,
|
||||||
|
edgeColor,
|
||||||
|
std::move(inner),
|
||||||
|
std::move(update),
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui::Premium
|
||||||
|
|
|
@ -11,8 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class RpWidget;
|
class RpWidget;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Premium {
|
namespace Ui::Text {
|
||||||
|
class CustomEmoji;
|
||||||
|
} // namespace Ui::Text
|
||||||
|
|
||||||
|
namespace Ui::Premium {
|
||||||
|
|
||||||
class ColoredMiniStars final {
|
class ColoredMiniStars final {
|
||||||
public:
|
public:
|
||||||
|
@ -32,7 +37,7 @@ public:
|
||||||
void setPaused(bool paused);
|
void setPaused(bool paused);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::Premium::MiniStars _ministars;
|
MiniStars _ministars;
|
||||||
QRectF _ministarsRect;
|
QRectF _ministarsRect;
|
||||||
QImage _frame;
|
QImage _frame;
|
||||||
QImage _mask;
|
QImage _mask;
|
||||||
|
@ -42,5 +47,12 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Premium
|
[[nodiscard]] std::unique_ptr<Text::CustomEmoji> MakeCollectibleEmoji(
|
||||||
} // namespace Ui
|
QStringView entityData,
|
||||||
|
QColor centerColor,
|
||||||
|
QColor edgeColor,
|
||||||
|
std::unique_ptr<Text::CustomEmoji> inner,
|
||||||
|
Fn<void()> update,
|
||||||
|
int size);
|
||||||
|
|
||||||
|
} // namespace Ui::Premium
|
||||||
|
|
|
@ -239,17 +239,11 @@ int PeerBadge::drawPremiumEmojiStatus(
|
||||||
using namespace Ui::Text;
|
using namespace Ui::Text;
|
||||||
auto &manager = peer->session().data().customEmojiManager();
|
auto &manager = peer->session().data().customEmojiManager();
|
||||||
_emojiStatus->id = id;
|
_emojiStatus->id = id;
|
||||||
_emojiStatus->emoji = id.collectible // todo collectibles
|
_emojiStatus->emoji = std::make_unique<LimitedLoopsEmoji>(
|
||||||
? std::make_unique<LimitedLoopsEmoji>(
|
manager.create(
|
||||||
manager.create(
|
Data::EmojiStatusCustomId(id),
|
||||||
id.collectible->documentId,
|
descriptor.customEmojiRepaint),
|
||||||
descriptor.customEmojiRepaint),
|
kPlayStatusLimit);
|
||||||
kPlayStatusLimit)
|
|
||||||
: std::make_unique<LimitedLoopsEmoji>(
|
|
||||||
manager.create(
|
|
||||||
id.documentId,
|
|
||||||
descriptor.customEmojiRepaint),
|
|
||||||
kPlayStatusLimit);
|
|
||||||
}
|
}
|
||||||
_emojiStatus->emoji->paint(p, {
|
_emojiStatus->emoji->paint(p, {
|
||||||
.textColor = (*descriptor.premiumFg)->c,
|
.textColor = (*descriptor.premiumFg)->c,
|
||||||
|
|
Loading…
Add table
Reference in a new issue