Load and reload interaction stickers.
This commit is contained in:
parent
35356a1736
commit
d152782115
|
@ -30,6 +30,18 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kRefreshTimeout = 7200 * crl::time(1000);
|
constexpr auto kRefreshTimeout = 7200 * crl::time(1000);
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<int> IndexFromEmoticon(const QString &emoticon) {
|
||||||
|
if (emoticon.size() < 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const auto first = emoticon[0].unicode();
|
||||||
|
return (first >= '1' && first <= '9')
|
||||||
|
? (first - '1')
|
||||||
|
: (first == 55357 && emoticon[1].unicode() == 56607)
|
||||||
|
? 9
|
||||||
|
: -1;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] QSize SingleSize() {
|
[[nodiscard]] QSize SingleSize() {
|
||||||
const auto single = st::largeEmojiSize;
|
const auto single = st::largeEmojiSize;
|
||||||
const auto outline = st::largeEmojiOutline;
|
const auto outline = st::largeEmojiOutline;
|
||||||
|
@ -207,6 +219,13 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto EmojiPack::animationsForEmoji(EmojiPtr emoji) const
|
||||||
|
-> const base::flat_map<int, not_null<DocumentData*>> & {
|
||||||
|
static const auto empty = base::flat_map<int, not_null<DocumentData*>>();
|
||||||
|
const auto i = _animations.find(emoji);
|
||||||
|
return (i != end(_animations)) ? i->second : empty;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiPack::refresh() {
|
void EmojiPack::refresh() {
|
||||||
if (_requestId) {
|
if (_requestId) {
|
||||||
return;
|
return;
|
||||||
|
@ -215,7 +234,7 @@ void EmojiPack::refresh() {
|
||||||
MTP_inputStickerSetAnimatedEmoji()
|
MTP_inputStickerSetAnimatedEmoji()
|
||||||
)).done([=](const MTPmessages_StickerSet &result) {
|
)).done([=](const MTPmessages_StickerSet &result) {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
refreshDelayed();
|
refreshAnimations();
|
||||||
result.match([&](const MTPDmessages_stickerSet &data) {
|
result.match([&](const MTPDmessages_stickerSet &data) {
|
||||||
applySet(data);
|
applySet(data);
|
||||||
});
|
});
|
||||||
|
@ -225,6 +244,24 @@ void EmojiPack::refresh() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiPack::refreshAnimations() {
|
||||||
|
if (_animationsRequestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_animationsRequestId = _session->api().request(MTPmessages_GetStickerSet(
|
||||||
|
MTP_inputStickerSetAnimatedEmojiAnimations()
|
||||||
|
)).done([=](const MTPmessages_StickerSet &result) {
|
||||||
|
_animationsRequestId = 0;
|
||||||
|
refreshDelayed();
|
||||||
|
result.match([&](const MTPDmessages_stickerSet &data) {
|
||||||
|
applyAnimationsSet(data);
|
||||||
|
});
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
_animationsRequestId = 0;
|
||||||
|
refreshDelayed();
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiPack::applySet(const MTPDmessages_stickerSet &data) {
|
void EmojiPack::applySet(const MTPDmessages_stickerSet &data) {
|
||||||
const auto stickers = collectStickers(data.vdocuments().v);
|
const auto stickers = collectStickers(data.vdocuments().v);
|
||||||
auto was = base::take(_map);
|
auto was = base::take(_map);
|
||||||
|
@ -251,6 +288,55 @@ void EmojiPack::applySet(const MTPDmessages_stickerSet &data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiPack::applyAnimationsSet(const MTPDmessages_stickerSet &data) {
|
||||||
|
const auto stickers = collectStickers(data.vdocuments().v);
|
||||||
|
const auto &packs = data.vpacks().v;
|
||||||
|
const auto indices = collectAnimationsIndices(packs);
|
||||||
|
|
||||||
|
_animations.clear();
|
||||||
|
for (const auto &pack : packs) {
|
||||||
|
pack.match([&](const MTPDstickerPack &data) {
|
||||||
|
const auto emoticon = qs(data.vemoticon());
|
||||||
|
if (IndexFromEmoticon(emoticon).has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto emoji = Ui::Emoji::Find(emoticon);
|
||||||
|
if (!emoji) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const auto &id : data.vdocuments().v) {
|
||||||
|
const auto i = indices.find(id.v);
|
||||||
|
if (i == end(indices)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto j = stickers.find(id.v);
|
||||||
|
if (j == end(stickers)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const auto index : i->second) {
|
||||||
|
_animations[emoji].emplace(index, j->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EmojiPack::collectAnimationsIndices(
|
||||||
|
const QVector<MTPStickerPack> &packs
|
||||||
|
) const -> base::flat_map<uint64, base::flat_set<int>> {
|
||||||
|
auto result = base::flat_map<uint64, base::flat_set<int>>();
|
||||||
|
for (const auto &pack : packs) {
|
||||||
|
pack.match([&](const MTPDstickerPack &data) {
|
||||||
|
if (const auto index = IndexFromEmoticon(qs(data.vemoticon()))) {
|
||||||
|
for (const auto &id : data.vdocuments().v) {
|
||||||
|
result[id.v].emplace(*index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiPack::refreshAll() {
|
void EmojiPack::refreshAll() {
|
||||||
for (const auto &[emoji, list] : _items) {
|
for (const auto &[emoji, list] : _items) {
|
||||||
refreshItems(list);
|
refreshItems(list);
|
||||||
|
|
|
@ -67,17 +67,25 @@ public:
|
||||||
[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
|
[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
|
||||||
[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
|
[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
|
||||||
|
|
||||||
|
[[nodiscard]] auto animationsForEmoji(EmojiPtr emoji) const
|
||||||
|
-> const base::flat_map<int, not_null<DocumentData*>> &;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ImageLoader;
|
class ImageLoader;
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
void refreshDelayed();
|
void refreshDelayed();
|
||||||
|
void refreshAnimations();
|
||||||
void applySet(const MTPDmessages_stickerSet &data);
|
void applySet(const MTPDmessages_stickerSet &data);
|
||||||
void applyPack(
|
void applyPack(
|
||||||
const MTPDstickerPack &data,
|
const MTPDstickerPack &data,
|
||||||
const base::flat_map<uint64, not_null<DocumentData*>> &map);
|
const base::flat_map<uint64, not_null<DocumentData*>> &map);
|
||||||
base::flat_map<uint64, not_null<DocumentData*>> collectStickers(
|
void applyAnimationsSet(const MTPDmessages_stickerSet &data);
|
||||||
const QVector<MTPDocument> &list) const;
|
[[nodiscard]] auto collectStickers(const QVector<MTPDocument> &list) const
|
||||||
|
-> base::flat_map<uint64, not_null<DocumentData*>>;
|
||||||
|
[[nodiscard]] auto collectAnimationsIndices(
|
||||||
|
const QVector<MTPStickerPack> &packs) const
|
||||||
|
-> base::flat_map<uint64, base::flat_set<int>>;
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
void refreshItems(EmojiPtr emoji);
|
void refreshItems(EmojiPtr emoji);
|
||||||
void refreshItems(const base::flat_set<not_null<HistoryItem*>> &list);
|
void refreshItems(const base::flat_set<not_null<HistoryItem*>> &list);
|
||||||
|
@ -90,6 +98,11 @@ private:
|
||||||
base::flat_map<EmojiPtr, std::weak_ptr<LargeEmojiImage>> _images;
|
base::flat_map<EmojiPtr, std::weak_ptr<LargeEmojiImage>> _images;
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
|
base::flat_map<
|
||||||
|
EmojiPtr,
|
||||||
|
base::flat_map<int, not_null<DocumentData*>>> _animations;
|
||||||
|
mtpRequestId _animationsRequestId = 0;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -674,6 +674,9 @@ not_null<Ui::PathShiftGradient*> InnerWidget::elementPathShiftGradient() {
|
||||||
void InnerWidget::elementReplyTo(const FullMsgId &to) {
|
void InnerWidget::elementReplyTo(const FullMsgId &to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::elementStartInteraction(not_null<const Element*> view) {
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::saveState(not_null<SectionMemento*> memento) {
|
void InnerWidget::saveState(not_null<SectionMemento*> memento) {
|
||||||
memento->setFilter(std::move(_filter));
|
memento->setFilter(std::move(_filter));
|
||||||
memento->setAdmins(std::move(_admins));
|
memento->setAdmins(std::move(_admins));
|
||||||
|
|
|
@ -137,6 +137,8 @@ public:
|
||||||
bool elementIsChatWide() override;
|
bool elementIsChatWide() override;
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
|
void elementStartInteraction(
|
||||||
|
not_null<const HistoryView::Element*> view) override;
|
||||||
|
|
||||||
~InnerWidget();
|
~InnerWidget();
|
||||||
|
|
||||||
|
|
|
@ -2689,6 +2689,9 @@ void HistoryInner::elementReplyTo(const FullMsgId &to) {
|
||||||
return _widget->replyToMessage(to);
|
return _widget->replyToMessage(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryInner::elementStartInteraction(not_null<const Element*> view) {
|
||||||
|
}
|
||||||
|
|
||||||
auto HistoryInner::getSelectionState() const
|
auto HistoryInner::getSelectionState() const
|
||||||
-> HistoryView::TopBarWidget::SelectedState {
|
-> HistoryView::TopBarWidget::SelectedState {
|
||||||
auto result = HistoryView::TopBarWidget::SelectedState {};
|
auto result = HistoryView::TopBarWidget::SelectedState {};
|
||||||
|
@ -3601,6 +3604,11 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
|
||||||
Instance->elementReplyTo(to);
|
Instance->elementReplyTo(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void elementStartInteraction(not_null<const Element*> view) override {
|
||||||
|
if (Instance) {
|
||||||
|
Instance->elementStartInteraction(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Result result;
|
static Result result;
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
bool elementIsChatWide();
|
bool elementIsChatWide();
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient();
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient();
|
||||||
void elementReplyTo(const FullMsgId &to);
|
void elementReplyTo(const FullMsgId &to);
|
||||||
|
void elementStartInteraction(not_null<const Element*> view);
|
||||||
|
|
||||||
void updateBotInfo(bool recount = true);
|
void updateBotInfo(bool recount = true);
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,11 @@ auto SimpleElementDelegate::elementPathShiftGradient()
|
||||||
void SimpleElementDelegate::elementReplyTo(const FullMsgId &to) {
|
void SimpleElementDelegate::elementReplyTo(const FullMsgId &to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SimpleElementDelegate::elementStartInteraction(
|
||||||
|
not_null<const Element*> view) {
|
||||||
|
}
|
||||||
|
|
||||||
TextSelection UnshiftItemSelection(
|
TextSelection UnshiftItemSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
uint16 byLength) {
|
uint16 byLength) {
|
||||||
|
@ -219,24 +224,6 @@ QString DateTooltipText(not_null<Element*> view) {
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_date,
|
lt_date,
|
||||||
base::unixtime::parse(forwarded->originalDate).toString(format));
|
base::unixtime::parse(forwarded->originalDate).toString(format));
|
||||||
if (const auto media = view->media()) {
|
|
||||||
if (media->hidesForwardedInfo()) {
|
|
||||||
const auto from = forwarded->originalSender
|
|
||||||
? forwarded->originalSender->shortName()
|
|
||||||
: forwarded->hiddenSenderInfo->firstName;
|
|
||||||
if (forwarded->imported) {
|
|
||||||
dateText += '\n' + tr::lng_signed_author(
|
|
||||||
tr::now,
|
|
||||||
lt_user,
|
|
||||||
from);
|
|
||||||
} else {
|
|
||||||
dateText += '\n' + tr::lng_forwarded(
|
|
||||||
tr::now,
|
|
||||||
lt_user,
|
|
||||||
from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (forwarded->imported) {
|
if (forwarded->imported) {
|
||||||
dateText = tr::lng_forwarded_imported(tr::now)
|
dateText = tr::lng_forwarded_imported(tr::now)
|
||||||
+ "\n\n" + dateText;
|
+ "\n\n" + dateText;
|
||||||
|
|
|
@ -90,6 +90,7 @@ public:
|
||||||
virtual bool elementIsChatWide() = 0;
|
virtual bool elementIsChatWide() = 0;
|
||||||
virtual not_null<Ui::PathShiftGradient*> elementPathShiftGradient() = 0;
|
virtual not_null<Ui::PathShiftGradient*> elementPathShiftGradient() = 0;
|
||||||
virtual void elementReplyTo(const FullMsgId &to) = 0;
|
virtual void elementReplyTo(const FullMsgId &to) = 0;
|
||||||
|
virtual void elementStartInteraction(not_null<const Element*> view) = 0;
|
||||||
|
|
||||||
virtual ~ElementDelegate() {
|
virtual ~ElementDelegate() {
|
||||||
}
|
}
|
||||||
|
@ -146,6 +147,7 @@ public:
|
||||||
bool elementIsChatWide() override;
|
bool elementIsChatWide() override;
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
|
void elementStartInteraction(not_null<const Element*> view) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[nodiscard]] not_null<Window::SessionController*> controller() const {
|
[[nodiscard]] not_null<Window::SessionController*> controller() const {
|
||||||
|
|
|
@ -1391,6 +1391,9 @@ void ListWidget::elementReplyTo(const FullMsgId &to) {
|
||||||
replyToMessageRequestNotify(to);
|
replyToMessageRequestNotify(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListWidget::elementStartInteraction(not_null<const Element*> view) {
|
||||||
|
}
|
||||||
|
|
||||||
void ListWidget::saveState(not_null<ListMemento*> memento) {
|
void ListWidget::saveState(not_null<ListMemento*> memento) {
|
||||||
memento->setAroundPosition(_aroundPosition);
|
memento->setAroundPosition(_aroundPosition);
|
||||||
auto state = countScrollState();
|
auto state = countScrollState();
|
||||||
|
|
|
@ -260,6 +260,7 @@ public:
|
||||||
bool elementIsChatWide() override;
|
bool elementIsChatWide() override;
|
||||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override;
|
||||||
void elementReplyTo(const FullMsgId &to) override;
|
void elementReplyTo(const FullMsgId &to) override;
|
||||||
|
void elementStartInteraction(not_null<const Element*> view) override;
|
||||||
|
|
||||||
void setEmptyInfoWidget(base::unique_qptr<Ui::RpWidget> &&w);
|
void setEmptyInfoWidget(base::unique_qptr<Ui::RpWidget> &&w);
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@ public:
|
||||||
_end->unloadHeavyPart();
|
_end->unloadHeavyPart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool hidesForwardedInfo() override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const not_null<Element*> _parent;
|
const not_null<Element*> _parent;
|
||||||
|
|
|
@ -233,10 +233,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual bool hidesForwardedInfo() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sometimes webpages can force the bubble to fit their size instead of
|
// Sometimes webpages can force the bubble to fit their size instead of
|
||||||
// allowing message text to be as wide as possible (like wallpapers).
|
// allowing message text to be as wide as possible (like wallpapers).
|
||||||
[[nodiscard]] virtual bool enforceBubbleWidth() const {
|
[[nodiscard]] virtual bool enforceBubbleWidth() const {
|
||||||
|
|
|
@ -461,9 +461,7 @@ int UnwrappedMedia::additionalWidth(
|
||||||
|
|
||||||
auto UnwrappedMedia::getDisplayedForwardedInfo() const
|
auto UnwrappedMedia::getDisplayedForwardedInfo() const
|
||||||
-> const HistoryMessageForwarded * {
|
-> const HistoryMessageForwarded * {
|
||||||
return _content->hidesForwardedInfo()
|
return _parent->data()->Get<HistoryMessageForwarded>();
|
||||||
? nullptr
|
|
||||||
: _parent->data()->Get<HistoryMessageForwarded>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -47,9 +47,6 @@ public:
|
||||||
}
|
}
|
||||||
virtual void refreshLink() {
|
virtual void refreshLink() {
|
||||||
}
|
}
|
||||||
[[nodiscard]] virtual bool hidesForwardedInfo() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
[[nodiscard]] virtual bool alwaysShowOutTimestamp() {
|
[[nodiscard]] virtual bool alwaysShowOutTimestamp() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -84,9 +81,6 @@ public:
|
||||||
bool customInfoLayout() const override {
|
bool customInfoLayout() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool hidesForwardedInfo() const override {
|
|
||||||
return _content->hidesForwardedInfo();
|
|
||||||
}
|
|
||||||
void stickerClearLoopPlayed() override {
|
void stickerClearLoopPlayed() override {
|
||||||
_content->stickerClearLoopPlayed();
|
_content->stickerClearLoopPlayed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool hidesForwardedInfo() override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resolveStarts(bool initSize = false);
|
void resolveStarts(bool initSize = false);
|
||||||
|
|
|
@ -296,9 +296,10 @@ void Sticker::refreshLink() {
|
||||||
const auto weak = base::make_weak(this);
|
const auto weak = base::make_weak(this);
|
||||||
_link = std::make_shared<LambdaClickHandler>([weak] {
|
_link = std::make_shared<LambdaClickHandler>([weak] {
|
||||||
const auto that = weak.get();
|
const auto that = weak.get();
|
||||||
if (!that) {
|
if (!that || !that->_lottieOncePlayed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
that->_parent->delegate()->elementStartInteraction(that->_parent);
|
||||||
that->_lottieOncePlayed = false;
|
that->_lottieOncePlayed = false;
|
||||||
that->_parent->history()->owner().requestViewRepaint(
|
that->_parent->history()->owner().requestViewRepaint(
|
||||||
that->_parent);
|
that->_parent);
|
||||||
|
|
Loading…
Reference in New Issue