mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-02 20:38:12 +00:00
The following are commits related to removed variables. apiwrap.cppe050e27
: kSaveDraftBeforeQuitTimeout app.cpp113f665
: serviceImageCacheSize boxes/auto_download_box.cppa0c6104
: checked(Source source, Type type) boxes/background_preview_box.cppb6edf45
: resultBytesPerPixelfe21b5a
: ms boxes/calendar_box.cppae97704
: yearIndex, monthIndex99bb093
: ms boxes/connection_box.cppf794d8d
: ping boxes/dictionaries_manager.cpp8353867
: session boxes/peer_list_box.cpp2ce2a14
: grayedWidth boxes/peers/add_participants_box.cpp07e010d
: chat, channel boxes/self_destruction_box.cppfe9f02e
: count chat_helpers/emoji_suggestions_widget.cppa12bc60
: is(QLatin1String string) chat_helpers/field_autocomplete.cpp8c7a35c
: atwidth, hashwidth chat_helpers/gifs_list_widget.cppff65734
: inlineItems3d846fc
: newSelectedd1687ab
: kSaveDraftBeforeQuitTimeout chat_helpers/stickers_dice_pack.cppc83e297
: kZeroDiceDocumentId chat_helpers/stickers_emoji_pack.cppd298953
: length chat_helpers/stickers_list_widget.cppeb75859
: index, x core/crash_reports.cpp5940ae6
: LaunchedDateTimeStr, LaunchedBinaryName data/data_changes.cpp 3c4e959:clearRealtime data/data_cloud_file.cpp4b354b0
: fromCloud, cacheTag data/data_document_media.cpp7db5359
: kMaxVideoFrameArea data/data_messages.cpp794e315
: wasCount data/data_photo_media.cppe27d2bc
: index data/data_wall_paper.cppb6edf45
: resultBytesPerPixel data/data_types.cppaa8f62d
: kWebDocumentCacheTag, kStorageCacheMask history/admin_log/history_admin_log_inner.cpp794e315
: canDelete, canForward history/history_location_manager.cpp60f45ab
: kCoordPrecision9f90d3a
: kMaxHttpRedirects history/history_message.cppcedf8a6
: kPinnedMessageTextLimit history/history_widget.cppb305924
: serviceColorefa5fc4
: hasForward5e7aa4f
: kTabbedSelectorToggleTooltipTimeoutMs, kTabbedSelectorToggleTooltipCount history/view/history_view_context_menu.cppfe1a90b
: isVideoLink, isVoiceLink, isAudioLink settings.cppe2f54eb
: defaultRecent settings/settings_folders.cppe8bf5bb
: kRefreshSuggestedTimeout ui/filter_icon_panel.cppc4a0bc1
: kDelayedHideTimeoutMs window/themes/window_theme_preview.cppef927c8
: mutedCounter ----- Modified variables boxes/stickers_box.cpp554eb3a
: _rows[pressedIndex] -> set data/data_notify_settings.cpp734c410
: muteForSeconds -> muteUntil history/view/history_view_list_widget.cpp07528be
: _items[index] -> viewe5f3bed
: fromState, tillState history/history.cppcd3c1c6
: kStatusShowClientsideRecordVideo -> kStatusShowClientsideRecordVoice storage/download_manager_mtproto.cppae8fb14
: _queues[dcId] -> queue storage/localstorage.cpp357caf8
: MTP::Environment::Production -> production
316 lines
7.2 KiB
C++
316 lines
7.2 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#include "chat_helpers/stickers_emoji_pack.h"
|
|
|
|
#include "chat_helpers/stickers_emoji_image_loader.h"
|
|
#include "history/history_item.h"
|
|
#include "lottie/lottie_common.h"
|
|
#include "ui/emoji_config.h"
|
|
#include "ui/text/text_isolated_emoji.h"
|
|
#include "ui/image/image.h"
|
|
#include "main/main_session.h"
|
|
#include "data/data_file_origin.h"
|
|
#include "data/data_session.h"
|
|
#include "data/data_document.h"
|
|
#include "core/core_settings.h"
|
|
#include "core/application.h"
|
|
#include "base/call_delayed.h"
|
|
#include "apiwrap.h"
|
|
#include "app.h"
|
|
#include "styles/style_history.h"
|
|
|
|
#include <QtCore/QBuffer>
|
|
|
|
namespace Stickers {
|
|
namespace {
|
|
|
|
constexpr auto kRefreshTimeout = 7200 * crl::time(1000);
|
|
|
|
[[nodiscard]] QSize SingleSize() {
|
|
const auto single = st::largeEmojiSize;
|
|
const auto outline = st::largeEmojiOutline;
|
|
return QSize(
|
|
2 * outline + single,
|
|
2 * outline + single
|
|
) * cIntRetinaFactor();
|
|
}
|
|
|
|
[[nodiscard]] const Lottie::ColorReplacements *ColorReplacements(int index) {
|
|
Expects(index >= 1 && index <= 5);
|
|
|
|
static const auto color1 = Lottie::ColorReplacements{
|
|
{
|
|
{ 0xf77e41U, 0xca907aU },
|
|
{ 0xffb139U, 0xedc5a5U },
|
|
{ 0xffd140U, 0xf7e3c3U },
|
|
{ 0xffdf79U, 0xfbefd6U },
|
|
},
|
|
1,
|
|
};
|
|
static const auto color2 = Lottie::ColorReplacements{
|
|
{
|
|
{ 0xf77e41U, 0xaa7c60U },
|
|
{ 0xffb139U, 0xc8a987U },
|
|
{ 0xffd140U, 0xddc89fU },
|
|
{ 0xffdf79U, 0xe6d6b2U },
|
|
},
|
|
2,
|
|
};
|
|
static const auto color3 = Lottie::ColorReplacements{
|
|
{
|
|
{ 0xf77e41U, 0x8c6148U },
|
|
{ 0xffb139U, 0xad8562U },
|
|
{ 0xffd140U, 0xc49e76U },
|
|
{ 0xffdf79U, 0xd4b188U },
|
|
},
|
|
3,
|
|
};
|
|
static const auto color4 = Lottie::ColorReplacements{
|
|
{
|
|
{ 0xf77e41U, 0x6e3c2cU },
|
|
{ 0xffb139U, 0x925a34U },
|
|
{ 0xffd140U, 0xa16e46U },
|
|
{ 0xffdf79U, 0xac7a52U },
|
|
},
|
|
4,
|
|
};
|
|
static const auto color5 = Lottie::ColorReplacements{
|
|
{
|
|
{ 0xf77e41U, 0x291c12U },
|
|
{ 0xffb139U, 0x472a22U },
|
|
{ 0xffd140U, 0x573b30U },
|
|
{ 0xffdf79U, 0x68493cU },
|
|
},
|
|
5,
|
|
};
|
|
static const auto list = std::array{
|
|
&color1,
|
|
&color2,
|
|
&color3,
|
|
&color4,
|
|
&color5,
|
|
};
|
|
return list[index - 1];
|
|
}
|
|
|
|
} // namespace
|
|
|
|
QSize LargeEmojiImage::Size() {
|
|
return SingleSize();
|
|
}
|
|
|
|
EmojiPack::EmojiPack(not_null<Main::Session*> session)
|
|
: _session(session) {
|
|
refresh();
|
|
|
|
session->data().itemRemoved(
|
|
) | rpl::filter([](not_null<const HistoryItem*> item) {
|
|
return item->isIsolatedEmoji();
|
|
}) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
|
|
remove(item);
|
|
}, _lifetime);
|
|
|
|
Core::App().settings().largeEmojiChanges(
|
|
) | rpl::start_with_next([=](bool large) {
|
|
refreshAll();
|
|
}, _lifetime);
|
|
|
|
Ui::Emoji::Updated(
|
|
) | rpl::start_with_next([=] {
|
|
_images.clear();
|
|
refreshAll();
|
|
}, _lifetime);
|
|
}
|
|
|
|
EmojiPack::~EmojiPack() = default;
|
|
|
|
bool EmojiPack::add(not_null<HistoryItem*> item) {
|
|
if (const auto emoji = item->isolatedEmoji()) {
|
|
_items[emoji].emplace(item);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void EmojiPack::remove(not_null<const HistoryItem*> item) {
|
|
Expects(item->isIsolatedEmoji());
|
|
|
|
const auto emoji = item->isolatedEmoji();
|
|
const auto i = _items.find(emoji);
|
|
Assert(i != end(_items));
|
|
const auto j = i->second.find(item);
|
|
Assert(j != end(i->second));
|
|
i->second.erase(j);
|
|
if (i->second.empty()) {
|
|
_items.erase(i);
|
|
}
|
|
}
|
|
|
|
auto EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) -> Sticker {
|
|
Expects(!emoji.empty());
|
|
|
|
if (emoji.items[1] != nullptr) {
|
|
return Sticker();
|
|
}
|
|
const auto first = emoji.items[0];
|
|
const auto i = _map.find(first);
|
|
if (i != end(_map)) {
|
|
return { i->second.get(), nullptr };
|
|
}
|
|
if (!first->colored()) {
|
|
return Sticker();
|
|
}
|
|
const auto j = _map.find(first->original());
|
|
if (j != end(_map)) {
|
|
const auto index = first->variantIndex(first);
|
|
return { j->second.get(), ColorReplacements(index) };
|
|
}
|
|
return Sticker();
|
|
}
|
|
|
|
std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
|
|
const auto i = _images.emplace(
|
|
emoji,
|
|
std::weak_ptr<LargeEmojiImage>()).first;
|
|
if (const auto result = i->second.lock()) {
|
|
return result;
|
|
}
|
|
auto result = std::make_shared<LargeEmojiImage>();
|
|
const auto raw = result.get();
|
|
const auto weak = base::make_weak(_session.get());
|
|
raw->load = [=] {
|
|
Core::App().emojiImageLoader().with([=](
|
|
const EmojiImageLoader &loader) {
|
|
crl::on_main(weak, [
|
|
=,
|
|
image = loader.prepare(emoji)
|
|
]() mutable {
|
|
const auto i = _images.find(emoji);
|
|
if (i != end(_images)) {
|
|
if (const auto strong = i->second.lock()) {
|
|
if (!strong->image) {
|
|
strong->load = nullptr;
|
|
strong->image.emplace(std::move(image));
|
|
_session->notifyDownloaderTaskFinished();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
raw->load = nullptr;
|
|
};
|
|
i->second = result;
|
|
return result;
|
|
}
|
|
|
|
void EmojiPack::refresh() {
|
|
if (_requestId) {
|
|
return;
|
|
}
|
|
_requestId = _session->api().request(MTPmessages_GetStickerSet(
|
|
MTP_inputStickerSetAnimatedEmoji()
|
|
)).done([=](const MTPmessages_StickerSet &result) {
|
|
_requestId = 0;
|
|
refreshDelayed();
|
|
result.match([&](const MTPDmessages_stickerSet &data) {
|
|
applySet(data);
|
|
});
|
|
}).fail([=](const RPCError &error) {
|
|
_requestId = 0;
|
|
refreshDelayed();
|
|
}).send();
|
|
}
|
|
|
|
void EmojiPack::applySet(const MTPDmessages_stickerSet &data) {
|
|
const auto stickers = collectStickers(data.vdocuments().v);
|
|
auto was = base::take(_map);
|
|
|
|
for (const auto &pack : data.vpacks().v) {
|
|
pack.match([&](const MTPDstickerPack &data) {
|
|
applyPack(data, stickers);
|
|
});
|
|
}
|
|
|
|
for (const auto &[emoji, document] : _map) {
|
|
const auto i = was.find(emoji);
|
|
if (i == end(was)) {
|
|
refreshItems(emoji);
|
|
} else {
|
|
if (i->second != document) {
|
|
refreshItems(i->first);
|
|
}
|
|
was.erase(i);
|
|
}
|
|
}
|
|
for (const auto &[emoji, Document] : was) {
|
|
refreshItems(emoji);
|
|
}
|
|
}
|
|
|
|
void EmojiPack::refreshAll() {
|
|
for (const auto &[emoji, list] : _items) {
|
|
refreshItems(list);
|
|
}
|
|
}
|
|
|
|
void EmojiPack::refreshItems(EmojiPtr emoji) {
|
|
const auto i = _items.find(IsolatedEmoji{ { emoji } });
|
|
if (i == end(_items)) {
|
|
return;
|
|
}
|
|
refreshItems(i->second);
|
|
}
|
|
|
|
void EmojiPack::refreshItems(
|
|
const base::flat_set<not_null<HistoryItem*>> &list) {
|
|
for (const auto &item : list) {
|
|
_session->data().requestItemViewRefresh(item);
|
|
}
|
|
}
|
|
|
|
void EmojiPack::applyPack(
|
|
const MTPDstickerPack &data,
|
|
const base::flat_map<uint64, not_null<DocumentData*>> &map) {
|
|
const auto emoji = [&] {
|
|
return Ui::Emoji::Find(qs(data.vemoticon()));
|
|
}();
|
|
const auto document = [&]() -> DocumentData * {
|
|
for (const auto &id : data.vdocuments().v) {
|
|
const auto i = map.find(id.v);
|
|
if (i != end(map)) {
|
|
return i->second.get();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}();
|
|
if (emoji && document) {
|
|
_map.emplace_or_assign(emoji, document);
|
|
}
|
|
}
|
|
|
|
base::flat_map<uint64, not_null<DocumentData*>> EmojiPack::collectStickers(
|
|
const QVector<MTPDocument> &list) const {
|
|
auto result = base::flat_map<uint64, not_null<DocumentData*>>();
|
|
for (const auto &sticker : list) {
|
|
const auto document = _session->data().processDocument(
|
|
sticker);
|
|
if (document->sticker()) {
|
|
result.emplace(document->id, document);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void EmojiPack::refreshDelayed() {
|
|
base::call_delayed(kRefreshTimeout, _session, [=] {
|
|
refresh();
|
|
});
|
|
}
|
|
|
|
} // namespace Stickers
|