mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Track tag counts in all sublists.
This commit is contained in:
parent
d116c8fea0
commit
6f57302562
3 changed files with 179 additions and 99 deletions
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#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_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "ui/image/image_location_factory.h"
|
#include "ui/image/image_location_factory.h"
|
||||||
|
@ -258,6 +259,8 @@ Reactions::Reactions(not_null<Session*> owner)
|
||||||
, _repaintTimer([=] { repaintCollected(); }) {
|
, _repaintTimer([=] { repaintCollected(); }) {
|
||||||
refreshDefault();
|
refreshDefault();
|
||||||
|
|
||||||
|
_myTags.emplace(nullptr);
|
||||||
|
|
||||||
base::timer_each(
|
base::timer_each(
|
||||||
kRefreshFullListEach
|
kRefreshFullListEach
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -320,17 +323,18 @@ void Reactions::refreshDefault() {
|
||||||
requestDefault();
|
requestDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::refreshMyTags() {
|
void Reactions::refreshMyTags(SavedSublist *sublist) {
|
||||||
requestMyTags();
|
requestMyTags(sublist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::refreshMyTagsDelayed() {
|
void Reactions::refreshMyTagsDelayed() {
|
||||||
if (_myTagsRequestId || _myTagsRequestScheduled) {
|
auto &my = _myTags[nullptr];
|
||||||
|
if (my.requestId || my.requestScheduled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_myTagsRequestScheduled = true;
|
my.requestScheduled = true;
|
||||||
base::call_delayed(kMyTagsRequestTimeout, &_owner->session(), [=] {
|
base::call_delayed(kMyTagsRequestTimeout, &_owner->session(), [=] {
|
||||||
if (_myTagsRequestScheduled) {
|
if (_myTags[nullptr].requestScheduled) {
|
||||||
requestMyTags();
|
requestMyTags();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -346,20 +350,24 @@ const std::vector<Reaction> &Reactions::list(Type type) const {
|
||||||
case Type::Recent: return _recent;
|
case Type::Recent: return _recent;
|
||||||
case Type::Top: return _top;
|
case Type::Top: return _top;
|
||||||
case Type::All: return _available;
|
case Type::All: return _available;
|
||||||
case Type::MyTags: return _myTags;
|
case Type::MyTags:
|
||||||
|
return _myTags.find((SavedSublist*)nullptr)->second.tags;
|
||||||
case Type::Tags: return _tags;
|
case Type::Tags: return _tags;
|
||||||
}
|
}
|
||||||
Unexpected("Type in Reactions::list.");
|
Unexpected("Type in Reactions::list.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<MyTagInfo> &Reactions::myTagsInfo() const {
|
const std::vector<MyTagInfo> &Reactions::myTagsInfo() const {
|
||||||
return _myTagsInfo;
|
return _myTags.find((SavedSublist*)nullptr)->second.info;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &Reactions::myTagTitle(const ReactionId &id) const {
|
const QString &Reactions::myTagTitle(const ReactionId &id) const {
|
||||||
const auto i = ranges::find(_myTagsInfo, id, &::Data::MyTagInfo::id);
|
const auto i = _myTags.find((SavedSublist*)nullptr);
|
||||||
if (i != end(_myTagsInfo)) {
|
if (i != end(_myTags)) {
|
||||||
return i->title;
|
const auto j = ranges::find(i->second.info, id, &MyTagInfo::id);
|
||||||
|
if (j != end(i->second.info)) {
|
||||||
|
return j->title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static const auto kEmpty = QString();
|
static const auto kEmpty = QString();
|
||||||
return kEmpty;
|
return kEmpty;
|
||||||
|
@ -389,14 +397,18 @@ void Reactions::setFavorite(const ReactionId &id) {
|
||||||
applyFavorite(id);
|
applyFavorite(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::incrementMyTag(const ReactionId &id) {
|
void Reactions::incrementMyTag(const ReactionId &id, SavedSublist *sublist) {
|
||||||
auto i = ranges::find(_myTagsInfo, id, &MyTagInfo::id);
|
if (sublist) {
|
||||||
if (i == end(_myTagsInfo)) {
|
incrementMyTag(id, nullptr);
|
||||||
_myTagsInfo.push_back({ .id = id, .count = 0 });
|
}
|
||||||
i = end(_myTagsInfo) - 1;
|
auto &my = _myTags[sublist];
|
||||||
|
auto i = ranges::find(my.info, id, &MyTagInfo::id);
|
||||||
|
if (i == end(my.info)) {
|
||||||
|
my.info.push_back({ .id = id, .count = 0 });
|
||||||
|
i = end(my.info) - 1;
|
||||||
}
|
}
|
||||||
++i->count;
|
++i->count;
|
||||||
while (i != begin(_myTagsInfo)) {
|
while (i != begin(my.info)) {
|
||||||
auto j = i - 1;
|
auto j = i - 1;
|
||||||
if (j->count >= i->count) {
|
if (j->count >= i->count) {
|
||||||
break;
|
break;
|
||||||
|
@ -404,16 +416,18 @@ void Reactions::incrementMyTag(const ReactionId &id) {
|
||||||
std::swap(*i, *j);
|
std::swap(*i, *j);
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
scheduleMyTagsUpdate();
|
scheduleMyTagsUpdate(sublist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::decrementMyTag(const ReactionId &id) {
|
void Reactions::decrementMyTag(const ReactionId &id, SavedSublist *sublist) {
|
||||||
auto i = ranges::find(_myTagsInfo, id, &MyTagInfo::id);
|
if (sublist) {
|
||||||
if (i->count <= 0) {
|
decrementMyTag(id, nullptr);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
auto &my = _myTags[sublist];
|
||||||
|
auto i = ranges::find(my.info, id, &MyTagInfo::id);
|
||||||
|
if (i->count > 0) {
|
||||||
--i->count;
|
--i->count;
|
||||||
while (i + 1 != end(_myTagsInfo)) {
|
while (i + 1 != end(my.info)) {
|
||||||
auto j = i + 1;
|
auto j = i + 1;
|
||||||
if (j->count <= i->count) {
|
if (j->count <= i->count) {
|
||||||
break;
|
break;
|
||||||
|
@ -421,16 +435,24 @@ void Reactions::decrementMyTag(const ReactionId &id) {
|
||||||
std::swap(*i, *j);
|
std::swap(*i, *j);
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
scheduleMyTagsUpdate();
|
}
|
||||||
|
scheduleMyTagsUpdate(sublist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::renameTag(const ReactionId &id, const QString &name) {
|
void Reactions::renameTag(const ReactionId &id, const QString &name) {
|
||||||
auto i = ranges::find(_myTagsInfo, id, &MyTagInfo::id);
|
auto changed = false;
|
||||||
if (i == end(_myTagsInfo) || i->title == name) {
|
for (auto &[sublist, my] : _myTags) {
|
||||||
return;
|
auto i = ranges::find(my.info, id, &MyTagInfo::id);
|
||||||
|
if (i == end(my.info) || i->title == name) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
i->title = name;
|
i->title = name;
|
||||||
scheduleMyTagsUpdate();
|
changed = true;
|
||||||
|
scheduleMyTagsUpdate(sublist);
|
||||||
|
}
|
||||||
|
if (!changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_myTagRenamed.fire_copy(id);
|
_myTagRenamed.fire_copy(id);
|
||||||
|
|
||||||
using Flag = MTPmessages_UpdateSavedReactionTag::Flag;
|
using Flag = MTPmessages_UpdateSavedReactionTag::Flag;
|
||||||
|
@ -441,15 +463,17 @@ void Reactions::renameTag(const ReactionId &id, const QString &name) {
|
||||||
)).send();
|
)).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::scheduleMyTagsUpdate() {
|
void Reactions::scheduleMyTagsUpdate(SavedSublist *sublist) {
|
||||||
_myTagsUpdateScheduled = true;
|
auto &my = _myTags[sublist];
|
||||||
|
my.updateScheduled = true;
|
||||||
crl::on_main(&session(), [=] {
|
crl::on_main(&session(), [=] {
|
||||||
if (!_myTagsUpdateScheduled) {
|
auto &my = _myTags[sublist];
|
||||||
|
if (!my.updateScheduled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_myTagsUpdateScheduled = false;
|
my.updateScheduled = false;
|
||||||
_myTags = resolveByInfos(_myTagsInfo, _unresolvedMyTags);
|
my.tags = resolveByInfos(my.info, _unresolvedMyTags, sublist);
|
||||||
_myTagsUpdated.fire({});
|
_myTagsUpdated.fire_copy(sublist);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +539,10 @@ rpl::producer<> Reactions::favoriteUpdates() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> Reactions::myTagsUpdates() const {
|
rpl::producer<> Reactions::myTagsUpdates() const {
|
||||||
return _myTagsUpdated.events();
|
return _myTagsUpdated.events(
|
||||||
|
) | rpl::filter(
|
||||||
|
!rpl::mappers::_1
|
||||||
|
) | rpl::to_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> Reactions::tagsUpdates() const {
|
rpl::producer<> Reactions::tagsUpdates() const {
|
||||||
|
@ -768,25 +795,29 @@ void Reactions::requestGeneric() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::requestMyTags() {
|
void Reactions::requestMyTags(SavedSublist *sublist) {
|
||||||
if (_myTagsRequestId) {
|
auto &my = _myTags[sublist];
|
||||||
|
if (my.requestId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &api = _owner->session().api();
|
auto &api = _owner->session().api();
|
||||||
_myTagsRequestScheduled = false;
|
my.requestScheduled = false;
|
||||||
_myTagsRequestId = api.request(MTPmessages_GetSavedReactionTags(
|
using Flag = MTPmessages_GetSavedReactionTags::Flag;
|
||||||
MTP_flags(0),
|
my.requestId = api.request(MTPmessages_GetSavedReactionTags(
|
||||||
MTP_inputPeerEmpty(),
|
MTP_flags(sublist ? Flag::f_peer : Flag()),
|
||||||
MTP_long(_myTagsHash)
|
(sublist ? sublist->peer()->input : MTP_inputPeerEmpty()),
|
||||||
|
MTP_long(my.hash)
|
||||||
)).done([=](const MTPmessages_SavedReactionTags &result) {
|
)).done([=](const MTPmessages_SavedReactionTags &result) {
|
||||||
_myTagsRequestId = 0;
|
auto &my = _myTags[sublist];
|
||||||
|
my.requestId = 0;
|
||||||
result.match([&](const MTPDmessages_savedReactionTags &data) {
|
result.match([&](const MTPDmessages_savedReactionTags &data) {
|
||||||
updateMyTags(data);
|
updateMyTags(sublist, data);
|
||||||
}, [](const MTPDmessages_savedReactionTagsNotModified&) {
|
}, [](const MTPDmessages_savedReactionTagsNotModified&) {
|
||||||
});
|
});
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
_myTagsRequestId = 0;
|
auto &my = _myTags[sublist];
|
||||||
_myTagsHash = 0;
|
my.requestId = 0;
|
||||||
|
my.hash = 0;
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,20 +909,25 @@ void Reactions::updateGeneric(const MTPDmessages_stickerSet &data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::updateMyTags(const MTPDmessages_savedReactionTags &data) {
|
void Reactions::updateMyTags(
|
||||||
_myTagsHash = data.vhash().v;
|
SavedSublist *sublist,
|
||||||
|
const MTPDmessages_savedReactionTags &data) {
|
||||||
|
auto &my = _myTags[sublist];
|
||||||
|
my.hash = data.vhash().v;
|
||||||
auto list = ListFromMTP(data);
|
auto list = ListFromMTP(data);
|
||||||
auto renamed = base::flat_set<ReactionId>();
|
auto renamed = base::flat_set<ReactionId>();
|
||||||
|
if (!sublist) {
|
||||||
for (const auto &info : list) {
|
for (const auto &info : list) {
|
||||||
const auto j = ranges::find(_myTagsInfo, info.id, &MyTagInfo::id);
|
const auto j = ranges::find(my.info, info.id, &MyTagInfo::id);
|
||||||
const auto was = (j != end(_myTagsInfo)) ? j->title : QString();
|
const auto was = (j != end(my.info)) ? j->title : QString();
|
||||||
if (info.title != was) {
|
if (info.title != was) {
|
||||||
renamed.emplace(info.id);
|
renamed.emplace(info.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_myTagsInfo = std::move(list);
|
}
|
||||||
_myTags = resolveByInfos(_myTagsInfo, _unresolvedMyTags);
|
my.info = std::move(list);
|
||||||
_myTagsUpdated.fire({});
|
my.tags = resolveByInfos(my.info, _unresolvedMyTags, sublist);
|
||||||
|
_myTagsUpdated.fire_copy(sublist);
|
||||||
for (const auto &id : renamed) {
|
for (const auto &id : renamed) {
|
||||||
_myTagRenamed.fire_copy(id);
|
_myTagRenamed.fire_copy(id);
|
||||||
}
|
}
|
||||||
|
@ -946,7 +982,9 @@ void Reactions::customEmojiResolveDone(not_null<DocumentData*> document) {
|
||||||
const auto j = _unresolvedRecent.find(id);
|
const auto j = _unresolvedRecent.find(id);
|
||||||
const auto recent = (j != end(_unresolvedRecent));
|
const auto recent = (j != end(_unresolvedRecent));
|
||||||
const auto k = _unresolvedMyTags.find(id);
|
const auto k = _unresolvedMyTags.find(id);
|
||||||
const auto myTag = (k != end(_unresolvedMyTags));
|
const auto myTagSublists = (k != end(_unresolvedMyTags))
|
||||||
|
? base::take(k->second)
|
||||||
|
: base::flat_set<SavedSublist*>();
|
||||||
const auto l = _unresolvedTags.find(id);
|
const auto l = _unresolvedTags.find(id);
|
||||||
const auto tag = (l != end(_unresolvedTags));
|
const auto tag = (l != end(_unresolvedTags));
|
||||||
if (favorite) {
|
if (favorite) {
|
||||||
|
@ -961,9 +999,12 @@ void Reactions::customEmojiResolveDone(not_null<DocumentData*> document) {
|
||||||
_unresolvedRecent.erase(j);
|
_unresolvedRecent.erase(j);
|
||||||
_recent = resolveByIds(_recentIds, _unresolvedRecent);
|
_recent = resolveByIds(_recentIds, _unresolvedRecent);
|
||||||
}
|
}
|
||||||
if (myTag) {
|
if (!myTagSublists.empty()) {
|
||||||
_unresolvedMyTags.erase(k);
|
_unresolvedMyTags.erase(k);
|
||||||
_myTags = resolveByInfos(_myTagsInfo, _unresolvedMyTags);
|
for (const auto &sublist : myTagSublists) {
|
||||||
|
auto &my = _myTags[sublist];
|
||||||
|
my.tags = resolveByInfos(my.info, _unresolvedMyTags, sublist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tag) {
|
if (tag) {
|
||||||
_unresolvedTags.erase(l);
|
_unresolvedTags.erase(l);
|
||||||
|
@ -978,8 +1019,8 @@ void Reactions::customEmojiResolveDone(not_null<DocumentData*> document) {
|
||||||
if (recent) {
|
if (recent) {
|
||||||
_recentUpdated.fire({});
|
_recentUpdated.fire({});
|
||||||
}
|
}
|
||||||
if (myTag) {
|
for (const auto &sublist : myTagSublists) {
|
||||||
_myTagsUpdated.fire({});
|
_myTagsUpdated.fire_copy(sublist);
|
||||||
}
|
}
|
||||||
if (tag) {
|
if (tag) {
|
||||||
_tagsUpdated.fire({});
|
_tagsUpdated.fire({});
|
||||||
|
@ -1016,10 +1057,12 @@ std::vector<Reaction> Reactions::resolveByIds(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Reaction> Reactions::resolveByInfo(const MyTagInfo &info) {
|
std::optional<Reaction> Reactions::resolveByInfo(
|
||||||
|
const MyTagInfo &info,
|
||||||
|
SavedSublist *sublist) {
|
||||||
const auto withInfo = [&](Reaction reaction) {
|
const auto withInfo = [&](Reaction reaction) {
|
||||||
reaction.title = info.title;
|
|
||||||
reaction.count = info.count;
|
reaction.count = info.count;
|
||||||
|
reaction.title = sublist ? myTagTitle(reaction.id) : info.title;
|
||||||
return reaction;
|
return reaction;
|
||||||
};
|
};
|
||||||
if (const auto emoji = info.id.emoji(); !emoji.isEmpty()) {
|
if (const auto emoji = info.id.emoji(); !emoji.isEmpty()) {
|
||||||
|
@ -1038,13 +1081,20 @@ std::optional<Reaction> Reactions::resolveByInfo(const MyTagInfo &info) {
|
||||||
|
|
||||||
std::vector<Reaction> Reactions::resolveByInfos(
|
std::vector<Reaction> Reactions::resolveByInfos(
|
||||||
const std::vector<MyTagInfo> &infos,
|
const std::vector<MyTagInfo> &infos,
|
||||||
base::flat_set<ReactionId> &unresolved) {
|
base::flat_map<
|
||||||
|
ReactionId,
|
||||||
|
base::flat_set<SavedSublist*>> &unresolved,
|
||||||
|
SavedSublist *sublist) {
|
||||||
auto result = std::vector<Reaction>();
|
auto result = std::vector<Reaction>();
|
||||||
result.reserve(infos.size());
|
result.reserve(infos.size());
|
||||||
for (const auto &tag : infos) {
|
for (const auto &tag : infos) {
|
||||||
if (const auto resolved = resolveByInfo(tag)) {
|
if (auto resolved = resolveByInfo(tag, sublist)) {
|
||||||
result.push_back(*resolved);
|
result.push_back(*resolved);
|
||||||
} else if (unresolved.emplace(tag.id).second) {
|
} else if (const auto i = unresolved.find(tag.id)
|
||||||
|
; i != end(unresolved)) {
|
||||||
|
i->second.emplace(sublist);
|
||||||
|
} else {
|
||||||
|
unresolved[tag.id].emplace(sublist);
|
||||||
resolve(tag.id);
|
resolve(tag.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1180,6 +1230,20 @@ Reaction *Reactions::lookupTemporary(const ReactionId &id) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<std::vector<Reaction>> Reactions::myTagsValue(
|
||||||
|
SavedSublist *sublist) {
|
||||||
|
refreshMyTags(sublist);
|
||||||
|
const auto list = [=] {
|
||||||
|
return _myTags[sublist].tags;
|
||||||
|
};
|
||||||
|
return rpl::single(
|
||||||
|
list()
|
||||||
|
) | rpl::then(_myTagsUpdated.events(
|
||||||
|
) | rpl::filter(
|
||||||
|
rpl::mappers::_1 == sublist
|
||||||
|
) | rpl::map(list));
|
||||||
|
}
|
||||||
|
|
||||||
void Reactions::repaintCollected() {
|
void Reactions::repaintCollected() {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
auto closest = crl::time();
|
auto closest = crl::time();
|
||||||
|
@ -1282,7 +1346,8 @@ void MessageReactions::add(const ReactionId &id, bool addToRecent) {
|
||||||
auto my = 0;
|
auto my = 0;
|
||||||
const auto tags = _item->reactionsAreTags();
|
const auto tags = _item->reactionsAreTags();
|
||||||
if (tags) {
|
if (tags) {
|
||||||
history->owner().reactions().incrementMyTag(id);
|
const auto sublist = _item->savedSublist();
|
||||||
|
history->owner().reactions().incrementMyTag(id, sublist);
|
||||||
}
|
}
|
||||||
_list.erase(ranges::remove_if(_list, [&](MessageReaction &one) {
|
_list.erase(ranges::remove_if(_list, [&](MessageReaction &one) {
|
||||||
const auto removing = one.my && (my == myLimit || ++my == myLimit);
|
const auto removing = one.my && (my == myLimit || ++my == myLimit);
|
||||||
|
@ -1306,7 +1371,8 @@ void MessageReactions::add(const ReactionId &id, bool addToRecent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tags) {
|
if (tags) {
|
||||||
history->owner().reactions().decrementMyTag(one.id);
|
const auto sublist = _item->savedSublist();
|
||||||
|
history->owner().reactions().decrementMyTag(one.id, sublist);
|
||||||
}
|
}
|
||||||
return removed;
|
return removed;
|
||||||
}), end(_list));
|
}), end(_list));
|
||||||
|
@ -1365,7 +1431,8 @@ void MessageReactions::remove(const ReactionId &id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tags) {
|
if (tags) {
|
||||||
history->owner().reactions().decrementMyTag(id);
|
const auto sublist = _item->savedSublist();
|
||||||
|
history->owner().reactions().decrementMyTag(id, sublist);
|
||||||
}
|
}
|
||||||
auto &owner = history->owner();
|
auto &owner = history->owner();
|
||||||
owner.reactions().send(_item, false);
|
owner.reactions().send(_item, false);
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CustomEmoji;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
class SavedSublist;
|
||||||
class DocumentMedia;
|
class DocumentMedia;
|
||||||
class Session;
|
class Session;
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ public:
|
||||||
void refreshRecent();
|
void refreshRecent();
|
||||||
void refreshRecentDelayed();
|
void refreshRecentDelayed();
|
||||||
void refreshDefault();
|
void refreshDefault();
|
||||||
void refreshMyTags();
|
void refreshMyTags(SavedSublist *sublist = nullptr);
|
||||||
void refreshMyTagsDelayed();
|
void refreshMyTagsDelayed();
|
||||||
void refreshTags();
|
void refreshTags();
|
||||||
|
|
||||||
|
@ -97,8 +98,8 @@ public:
|
||||||
[[nodiscard]] ReactionId favoriteId() const;
|
[[nodiscard]] ReactionId favoriteId() const;
|
||||||
[[nodiscard]] const Reaction *favorite() const;
|
[[nodiscard]] const Reaction *favorite() const;
|
||||||
void setFavorite(const ReactionId &id);
|
void setFavorite(const ReactionId &id);
|
||||||
void incrementMyTag(const ReactionId &id);
|
void incrementMyTag(const ReactionId &id, SavedSublist *sublist);
|
||||||
void decrementMyTag(const ReactionId &id);
|
void decrementMyTag(const ReactionId &id, SavedSublist *sublist);
|
||||||
void renameTag(const ReactionId &id, const QString &name);
|
void renameTag(const ReactionId &id, const QString &name);
|
||||||
[[nodiscard]] DocumentData *chooseGenericAnimation(
|
[[nodiscard]] DocumentData *chooseGenericAnimation(
|
||||||
not_null<DocumentData*> custom) const;
|
not_null<DocumentData*> custom) const;
|
||||||
|
@ -131,6 +132,9 @@ public:
|
||||||
void clearTemporary();
|
void clearTemporary();
|
||||||
[[nodiscard]] Reaction *lookupTemporary(const ReactionId &id);
|
[[nodiscard]] Reaction *lookupTemporary(const ReactionId &id);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<std::vector<Reaction>> myTagsValue(
|
||||||
|
SavedSublist *sublist = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] static bool HasUnread(const MTPMessageReactions &data);
|
[[nodiscard]] static bool HasUnread(const MTPMessageReactions &data);
|
||||||
static void CheckUnknownForUnread(
|
static void CheckUnknownForUnread(
|
||||||
not_null<Session*> owner,
|
not_null<Session*> owner,
|
||||||
|
@ -144,6 +148,20 @@ private:
|
||||||
std::unique_ptr<Ui::AnimatedIcon> icon;
|
std::unique_ptr<Ui::AnimatedIcon> icon;
|
||||||
bool fromSelectAnimation = false;
|
bool fromSelectAnimation = false;
|
||||||
};
|
};
|
||||||
|
struct TagsBySublist {
|
||||||
|
TagsBySublist() = default;
|
||||||
|
TagsBySublist(TagsBySublist&&) = default;
|
||||||
|
TagsBySublist(const TagsBySublist&) = delete;
|
||||||
|
TagsBySublist &operator=(TagsBySublist&&) = default;
|
||||||
|
TagsBySublist &operator=(const TagsBySublist&) = delete;
|
||||||
|
|
||||||
|
std::vector<Reaction> tags;
|
||||||
|
std::vector<MyTagInfo> info;
|
||||||
|
uint64 hash = 0;
|
||||||
|
mtpRequestId requestId = 0;
|
||||||
|
bool requestScheduled = false;
|
||||||
|
bool updateScheduled = false;
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] not_null<CustomEmojiManager::Listener*> resolveListener();
|
[[nodiscard]] not_null<CustomEmojiManager::Listener*> resolveListener();
|
||||||
void customEmojiResolveDone(not_null<DocumentData*> document) override;
|
void customEmojiResolveDone(not_null<DocumentData*> document) override;
|
||||||
|
@ -152,14 +170,16 @@ private:
|
||||||
void requestRecent();
|
void requestRecent();
|
||||||
void requestDefault();
|
void requestDefault();
|
||||||
void requestGeneric();
|
void requestGeneric();
|
||||||
void requestMyTags();
|
void requestMyTags(SavedSublist *sublist = nullptr);
|
||||||
void requestTags();
|
void requestTags();
|
||||||
|
|
||||||
void updateTop(const MTPDmessages_reactions &data);
|
void updateTop(const MTPDmessages_reactions &data);
|
||||||
void updateRecent(const MTPDmessages_reactions &data);
|
void updateRecent(const MTPDmessages_reactions &data);
|
||||||
void updateDefault(const MTPDmessages_availableReactions &data);
|
void updateDefault(const MTPDmessages_availableReactions &data);
|
||||||
void updateGeneric(const MTPDmessages_stickerSet &data);
|
void updateGeneric(const MTPDmessages_stickerSet &data);
|
||||||
void updateMyTags(const MTPDmessages_savedReactionTags &data);
|
void updateMyTags(
|
||||||
|
SavedSublist *sublist,
|
||||||
|
const MTPDmessages_savedReactionTags &data);
|
||||||
void updateTags(const MTPDmessages_reactions &data);
|
void updateTags(const MTPDmessages_reactions &data);
|
||||||
|
|
||||||
void recentUpdated();
|
void recentUpdated();
|
||||||
|
@ -172,13 +192,17 @@ private:
|
||||||
const std::vector<ReactionId> &ids,
|
const std::vector<ReactionId> &ids,
|
||||||
base::flat_set<ReactionId> &unresolved);
|
base::flat_set<ReactionId> &unresolved);
|
||||||
[[nodiscard]] std::optional<Reaction> resolveByInfo(
|
[[nodiscard]] std::optional<Reaction> resolveByInfo(
|
||||||
const MyTagInfo &info);
|
const MyTagInfo &info,
|
||||||
|
SavedSublist *sublist);
|
||||||
[[nodiscard]] std::vector<Reaction> resolveByInfos(
|
[[nodiscard]] std::vector<Reaction> resolveByInfos(
|
||||||
const std::vector<MyTagInfo> &infos,
|
const std::vector<MyTagInfo> &infos,
|
||||||
base::flat_set<ReactionId> &unresolved);
|
base::flat_map<
|
||||||
|
ReactionId,
|
||||||
|
base::flat_set<SavedSublist*>> &unresolved,
|
||||||
|
SavedSublist *sublist);
|
||||||
void resolve(const ReactionId &id);
|
void resolve(const ReactionId &id);
|
||||||
void applyFavorite(const ReactionId &id);
|
void applyFavorite(const ReactionId &id);
|
||||||
void scheduleMyTagsUpdate();
|
void scheduleMyTagsUpdate(SavedSublist *sublist);
|
||||||
|
|
||||||
[[nodiscard]] std::optional<Reaction> parse(
|
[[nodiscard]] std::optional<Reaction> parse(
|
||||||
const MTPAvailableReaction &entry);
|
const MTPAvailableReaction &entry);
|
||||||
|
@ -201,9 +225,10 @@ private:
|
||||||
std::vector<Reaction> _recent;
|
std::vector<Reaction> _recent;
|
||||||
std::vector<ReactionId> _recentIds;
|
std::vector<ReactionId> _recentIds;
|
||||||
base::flat_set<ReactionId> _unresolvedRecent;
|
base::flat_set<ReactionId> _unresolvedRecent;
|
||||||
std::vector<Reaction> _myTags;
|
base::flat_map<SavedSublist*, TagsBySublist> _myTags;
|
||||||
std::vector<MyTagInfo> _myTagsInfo;
|
base::flat_map<
|
||||||
base::flat_set<ReactionId> _unresolvedMyTags;
|
ReactionId,
|
||||||
|
base::flat_set<SavedSublist*>> _unresolvedMyTags;
|
||||||
std::vector<Reaction> _tags;
|
std::vector<Reaction> _tags;
|
||||||
std::vector<ReactionId> _tagsIds;
|
std::vector<ReactionId> _tagsIds;
|
||||||
base::flat_set<ReactionId> _unresolvedTags;
|
base::flat_set<ReactionId> _unresolvedTags;
|
||||||
|
@ -224,7 +249,7 @@ private:
|
||||||
rpl::event_stream<> _recentUpdated;
|
rpl::event_stream<> _recentUpdated;
|
||||||
rpl::event_stream<> _defaultUpdated;
|
rpl::event_stream<> _defaultUpdated;
|
||||||
rpl::event_stream<> _favoriteUpdated;
|
rpl::event_stream<> _favoriteUpdated;
|
||||||
rpl::event_stream<> _myTagsUpdated;
|
rpl::event_stream<SavedSublist*> _myTagsUpdated;
|
||||||
rpl::event_stream<> _tagsUpdated;
|
rpl::event_stream<> _tagsUpdated;
|
||||||
rpl::event_stream<ReactionId> _myTagRenamed;
|
rpl::event_stream<ReactionId> _myTagRenamed;
|
||||||
|
|
||||||
|
@ -246,11 +271,6 @@ private:
|
||||||
|
|
||||||
mtpRequestId _genericRequestId = 0;
|
mtpRequestId _genericRequestId = 0;
|
||||||
|
|
||||||
mtpRequestId _myTagsRequestId = 0;
|
|
||||||
bool _myTagsRequestScheduled = false;
|
|
||||||
bool _myTagsUpdateScheduled = false;
|
|
||||||
uint64 _myTagsHash = 0;
|
|
||||||
|
|
||||||
mtpRequestId _tagsRequestId = 0;
|
mtpRequestId _tagsRequestId = 0;
|
||||||
uint64 _tagsHash = 0;
|
uint64 _tagsHash = 0;
|
||||||
|
|
||||||
|
|
|
@ -2987,16 +2987,9 @@ void InnerWidget::searchInChat(
|
||||||
|
|
||||||
if (peer->isSelf()) {
|
if (peer->isSelf()) {
|
||||||
const auto reactions = &peer->owner().reactions();
|
const auto reactions = &peer->owner().reactions();
|
||||||
const auto list = [=] {
|
|
||||||
return reactions->list(Data::Reactions::Type::MyTags);
|
|
||||||
};
|
|
||||||
_searchTags = std::make_unique<SearchTags>(
|
_searchTags = std::make_unique<SearchTags>(
|
||||||
&peer->owner(),
|
&peer->owner(),
|
||||||
rpl::single(
|
reactions->myTagsValue(sublist),
|
||||||
list()
|
|
||||||
) | rpl::then(
|
|
||||||
reactions->myTagsUpdates() | rpl::map(list)
|
|
||||||
),
|
|
||||||
tags);
|
tags);
|
||||||
|
|
||||||
_searchTags->selectedValue(
|
_searchTags->selectedValue(
|
||||||
|
|
Loading…
Add table
Reference in a new issue