2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

Update API scheme on layer 145.

This commit is contained in:
John Preston
2022-08-16 14:28:17 +03:00
parent ba8673af5e
commit 60cc232884
40 changed files with 646 additions and 427 deletions

View File

@@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lottie/lottie_icon.h"
#include "storage/localimageloader.h"
#include "ui/image/image_location_factory.h"
#include "mtproto/mtproto_config.h"
#include "base/timer_rpl.h"
#include "apiwrap.h"
#include "styles/style_chat.h"
@@ -32,8 +33,35 @@ constexpr auto kRefreshFullListEach = 60 * 60 * crl::time(1000);
constexpr auto kPollEach = 20 * crl::time(1000);
constexpr auto kSizeForDownscale = 64;
[[nodiscard]] QString ReactionIdToLog(const ReactionId &id) {
if (const auto custom = id.custom()) {
return "custom:" + QString::number(custom);
}
return id.emoji();
}
} // namespace
ReactionId ReactionFromMTP(const MTPReaction &reaction) {
return reaction.match([](MTPDreactionEmpty) {
return ReactionId{ QString() };
}, [](const MTPDreactionEmoji &data) {
return ReactionId{ qs(data.vemoticon()) };
}, [](const MTPDreactionCustomEmoji &data) {
return ReactionId{ DocumentId(data.vdocument_id().v) };
});
}
MTPReaction ReactionToMTP(ReactionId id) {
if (const auto custom = id.custom()) {
return MTP_reactionCustomEmoji(MTP_long(custom));
}
const auto emoji = id.emoji();
return emoji.isEmpty()
? MTP_reactionEmpty()
: MTP_reactionEmoji(MTP_string(emoji));
}
Reactions::Reactions(not_null<Session*> owner)
: _owner(owner)
, _repaintTimer([=] { repaintCollected(); }) {
@@ -54,16 +82,18 @@ Reactions::Reactions(not_null<Session*> owner)
_repaintItems.remove(item);
}, _lifetime);
const auto appConfig = &_owner->session().account().appConfig();
appConfig->value(
) | rpl::start_with_next([=] {
const auto favorite = appConfig->get<QString>(
u"reactions_default"_q,
QString::fromUtf8("\xf0\x9f\x91\x8d"));
if (_favorite != favorite && !_saveFaveRequestId) {
_favorite = favorite;
_updated.fire({});
}
rpl::single(rpl::empty) | rpl::then(
_owner->session().mtp().config().updates()
) | rpl::map([=] {
const auto &config = _owner->session().mtp().configValues();
return config.reactionDefaultCustom
? ReactionId{ DocumentId(config.reactionDefaultCustom) }
: ReactionId{ config.reactionDefaultEmoji };
}) | rpl::filter([=](const ReactionId &id) {
return (_favorite != id) && !_saveFaveRequestId;
}) | rpl::start_with_next([=](ReactionId &&id) {
_favorite = std::move(id);
_updated.fire({});
}, _lifetime);
}
@@ -81,17 +111,17 @@ const std::vector<Reaction> &Reactions::list(Type type) const {
Unexpected("Type in Reactions::list.");
}
QString Reactions::favorite() const {
ReactionId Reactions::favorite() const {
return _favorite;
}
void Reactions::setFavorite(const QString &emoji) {
void Reactions::setFavorite(const ReactionId &emoji) {
const auto api = &_owner->session().api();
if (_saveFaveRequestId) {
api->request(_saveFaveRequestId).cancel();
}
_saveFaveRequestId = api->request(MTPmessages_SetDefaultReaction(
MTP_string(emoji)
ReactionToMTP(emoji)
)).done([=] {
_saveFaveRequestId = 0;
}).fail([=] {
@@ -108,12 +138,12 @@ rpl::producer<> Reactions::updates() const {
return _updated.events();
}
void Reactions::preloadImageFor(const QString &emoji) {
if (_images.contains(emoji)) {
void Reactions::preloadImageFor(const ReactionId &id) {
if (_images.contains(id)) {
return;
}
auto &set = _images.emplace(emoji).first->second;
const auto i = ranges::find(_available, emoji, &Reaction::emoji);
auto &set = _images.emplace(id).first->second;
const auto i = ranges::find(_available, id, &Reaction::id);
const auto document = (i == end(_available))
? nullptr
: i->centerIcon
@@ -127,8 +157,8 @@ void Reactions::preloadImageFor(const QString &emoji) {
}
}
void Reactions::preloadAnimationsFor(const QString &emoji) {
const auto i = ranges::find(_available, emoji, &Reaction::emoji);
void Reactions::preloadAnimationsFor(const ReactionId &id) {
const auto i = ranges::find(_available, id, &Reaction::id);
if (i == end(_available)) {
return;
}
@@ -146,7 +176,7 @@ void Reactions::preloadAnimationsFor(const QString &emoji) {
}
QImage Reactions::resolveImageFor(
const QString &emoji,
const ReactionId &emoji,
ImageSize size) {
const auto i = _images.find(emoji);
if (i == end(_images)) {
@@ -194,11 +224,11 @@ QImage Reactions::resolveImageFor(
}
void Reactions::resolveImages() {
for (auto &[emoji, set] : _images) {
for (auto &[id, set] : _images) {
if (!set.bottomInfo.isNull() || set.icon || set.media) {
continue;
}
const auto i = ranges::find(_available, emoji, &Reaction::emoji);
const auto i = ranges::find(_available, id, &Reaction::id);
const auto document = (i == end(_available))
? nullptr
: i->centerIcon
@@ -207,8 +237,8 @@ void Reactions::resolveImages() {
if (document) {
loadImage(set, document, !i->centerIcon);
} else {
LOG(("API Error: Reaction for emoji '%1' not found!"
).arg(emoji));
LOG(("API Error: Reaction '%1' not found!"
).arg(ReactionIdToLog(id)));
}
}
}
@@ -338,7 +368,7 @@ std::optional<Reaction> Reactions::parse(const MTPAvailableReaction &entry) {
data.vselect_animation());
return known
? std::make_optional(Reaction{
.emoji = emoji,
.id = ReactionId{ emoji },
.title = qs(data.vtitle()),
.staticIcon = _owner->processDocument(data.vstatic_icon()),
.appearAnimation = _owner->processDocument(
@@ -362,7 +392,7 @@ std::optional<Reaction> Reactions::parse(const MTPAvailableReaction &entry) {
});
}
void Reactions::send(not_null<HistoryItem*> item, const QString &chosen) {
void Reactions::send(not_null<HistoryItem*> item, const ReactionId &chosen) {
const auto id = item->fullId();
auto &api = _owner->session().api();
auto i = _sentRequests.find(id);
@@ -371,14 +401,14 @@ void Reactions::send(not_null<HistoryItem*> item, const QString &chosen) {
} else {
i = _sentRequests.emplace(id).first;
}
const auto flags = chosen.isEmpty()
const auto flags = chosen.empty()
? MTPmessages_SendReaction::Flag(0)
: MTPmessages_SendReaction::Flag::f_reaction;
i->second = api.request(MTPmessages_SendReaction(
MTP_flags(flags),
item->history()->peer->input,
MTP_int(id.msg),
MTP_string(chosen)
ReactionToMTP(chosen)
)).done([=](const MTPUpdates &result) {
_sentRequests.remove(id);
_owner->session().api().applyUpdates(result);
@@ -509,13 +539,13 @@ MessageReactions::MessageReactions(not_null<HistoryItem*> item)
: _item(item) {
}
void MessageReactions::add(const QString &reaction) {
void MessageReactions::add(const ReactionId &reaction) {
if (_chosen == reaction) {
return;
}
const auto history = _item->history();
const auto self = history->session().user();
if (!_chosen.isEmpty()) {
if (!_chosen.empty()) {
const auto i = _list.find(_chosen);
Assert(i != end(_list));
--i->second;
@@ -534,7 +564,7 @@ void MessageReactions::add(const QString &reaction) {
}
}
_chosen = reaction;
if (!reaction.isEmpty()) {
if (!reaction.empty()) {
if (_item->canViewReactions()) {
auto &list = _recent[reaction];
list.insert(begin(list), RecentReaction{ self });
@@ -547,7 +577,7 @@ void MessageReactions::add(const QString &reaction) {
}
void MessageReactions::remove() {
add(QString());
add(ReactionId());
}
bool MessageReactions::checkIfChanged(
@@ -558,10 +588,10 @@ bool MessageReactions::checkIfChanged(
// We'll apply non-stale data from the request response.
return false;
}
auto existing = base::flat_set<QString>();
auto existing = base::flat_set<ReactionId>();
for (const auto &count : list) {
const auto changed = count.match([&](const MTPDreactionCount &data) {
const auto reaction = qs(data.vreaction());
const auto reaction = ReactionFromMTP(data.vreaction());
const auto nowCount = data.vcount().v;
const auto i = _list.find(reaction);
const auto wasCount = (i != end(_list)) ? i->second : 0;
@@ -580,10 +610,10 @@ bool MessageReactions::checkIfChanged(
return true;
}
}
auto parsed = base::flat_map<QString, std::vector<RecentReaction>>();
auto parsed = base::flat_map<ReactionId, std::vector<RecentReaction>>();
for (const auto &reaction : recent) {
reaction.match([&](const MTPDmessagePeerReaction &data) {
const auto emoji = qs(data.vreaction());
const auto emoji = ReactionFromMTP(data.vreaction());
if (_list.contains(emoji)) {
parsed[emoji].push_back(RecentReaction{
.peer = owner.peer(peerFromMTP(data.vpeer_id())),
@@ -614,16 +644,16 @@ bool MessageReactions::change(
return false;
}
auto changed = false;
auto existing = base::flat_set<QString>();
auto existing = base::flat_set<ReactionId>();
for (const auto &count : list) {
count.match([&](const MTPDreactionCount &data) {
const auto reaction = qs(data.vreaction());
const auto reaction = ReactionFromMTP(data.vreaction());
if (!ignoreChosen) {
if (data.is_chosen() && _chosen != reaction) {
_chosen = reaction;
changed = true;
} else if (!data.is_chosen() && _chosen == reaction) {
_chosen = QString();
_chosen = ReactionId();
changed = true;
}
}
@@ -645,14 +675,14 @@ bool MessageReactions::change(
++i;
}
}
if (!_chosen.isEmpty() && !_list.contains(_chosen)) {
_chosen = QString();
if (!_chosen.empty() && !_list.contains(_chosen)) {
_chosen = ReactionId();
}
}
auto parsed = base::flat_map<QString, std::vector<RecentReaction>>();
auto parsed = base::flat_map<ReactionId, std::vector<RecentReaction>>();
for (const auto &reaction : recent) {
reaction.match([&](const MTPDmessagePeerReaction &data) {
const auto emoji = qs(data.vreaction());
const auto emoji = ReactionFromMTP(data.vreaction());
if (_list.contains(emoji)) {
parsed[emoji].push_back(RecentReaction{
.peer = owner.peer(peerFromMTP(data.vpeer_id())),
@@ -669,12 +699,12 @@ bool MessageReactions::change(
return changed;
}
const base::flat_map<QString, int> &MessageReactions::list() const {
const base::flat_map<ReactionId, int> &MessageReactions::list() const {
return _list;
}
auto MessageReactions::recent() const
-> const base::flat_map<QString, std::vector<RecentReaction>> & {
-> const base::flat_map<ReactionId, std::vector<RecentReaction>> & {
return _recent;
}
@@ -699,7 +729,7 @@ void MessageReactions::markRead() {
}
}
QString MessageReactions::chosen() const {
ReactionId MessageReactions::chosen() const {
return _chosen;
}