2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Allow editing tag names in Saved Messages.

This commit is contained in:
John Preston
2024-01-26 13:38:38 +04:00
parent 32462fca9b
commit d116c8fea0
13 changed files with 289 additions and 15 deletions

View File

@@ -356,6 +356,15 @@ const std::vector<MyTagInfo> &Reactions::myTagsInfo() const {
return _myTagsInfo;
}
const QString &Reactions::myTagTitle(const ReactionId &id) const {
const auto i = ranges::find(_myTagsInfo, id, &::Data::MyTagInfo::id);
if (i != end(_myTagsInfo)) {
return i->title;
}
static const auto kEmpty = QString();
return kEmpty;
}
ReactionId Reactions::favoriteId() const {
return _favoriteId;
}
@@ -415,6 +424,23 @@ void Reactions::decrementMyTag(const ReactionId &id) {
scheduleMyTagsUpdate();
}
void Reactions::renameTag(const ReactionId &id, const QString &name) {
auto i = ranges::find(_myTagsInfo, id, &MyTagInfo::id);
if (i == end(_myTagsInfo) || i->title == name) {
return;
}
i->title = name;
scheduleMyTagsUpdate();
_myTagRenamed.fire_copy(id);
using Flag = MTPmessages_UpdateSavedReactionTag::Flag;
_owner->session().api().request(MTPmessages_UpdateSavedReactionTag(
MTP_flags(name.isEmpty() ? Flag(0) : Flag::f_title),
ReactionToMTP(id),
MTP_string(name)
)).send();
}
void Reactions::scheduleMyTagsUpdate() {
_myTagsUpdateScheduled = true;
crl::on_main(&session(), [=] {
@@ -496,6 +522,10 @@ rpl::producer<> Reactions::tagsUpdates() const {
return _tagsUpdated.events();
}
rpl::producer<ReactionId> Reactions::myTagRenamed() const {
return _myTagRenamed.events();
}
void Reactions::preloadImageFor(const ReactionId &id) {
if (_images.contains(id) || id.emoji().isEmpty()) {
return;
@@ -850,9 +880,21 @@ void Reactions::updateGeneric(const MTPDmessages_stickerSet &data) {
void Reactions::updateMyTags(const MTPDmessages_savedReactionTags &data) {
_myTagsHash = data.vhash().v;
_myTagsInfo = ListFromMTP(data);
auto list = ListFromMTP(data);
auto renamed = base::flat_set<ReactionId>();
for (const auto &info : list) {
const auto j = ranges::find(_myTagsInfo, info.id, &MyTagInfo::id);
const auto was = (j != end(_myTagsInfo)) ? j->title : QString();
if (info.title != was) {
renamed.emplace(info.id);
}
}
_myTagsInfo = std::move(list);
_myTags = resolveByInfos(_myTagsInfo, _unresolvedMyTags);
_myTagsUpdated.fire({});
for (const auto &id : renamed) {
_myTagRenamed.fire_copy(id);
}
}
void Reactions::updateTags(const MTPDmessages_reactions &data) {
@@ -1304,6 +1346,7 @@ void MessageReactions::remove(const ReactionId &id) {
return;
}
i->my = false;
const auto tags = _item->reactionsAreTags();
const auto removed = !--i->count;
if (removed) {
_list.erase(i);
@@ -1321,6 +1364,9 @@ void MessageReactions::remove(const ReactionId &id) {
}
}
}
if (tags) {
history->owner().reactions().decrementMyTag(id);
}
auto &owner = history->owner();
owner.reactions().send(_item, false);
owner.notifyItemDataChange(_item);

View File

@@ -93,11 +93,13 @@ public:
};
[[nodiscard]] const std::vector<Reaction> &list(Type type) const;
[[nodiscard]] const std::vector<MyTagInfo> &myTagsInfo() const;
[[nodiscard]] const QString &myTagTitle(const ReactionId &id) const;
[[nodiscard]] ReactionId favoriteId() const;
[[nodiscard]] const Reaction *favorite() const;
void setFavorite(const ReactionId &id);
void incrementMyTag(const ReactionId &id);
void decrementMyTag(const ReactionId &id);
void renameTag(const ReactionId &id, const QString &name);
[[nodiscard]] DocumentData *chooseGenericAnimation(
not_null<DocumentData*> custom) const;
@@ -107,6 +109,7 @@ public:
[[nodiscard]] rpl::producer<> favoriteUpdates() const;
[[nodiscard]] rpl::producer<> myTagsUpdates() const;
[[nodiscard]] rpl::producer<> tagsUpdates() const;
[[nodiscard]] rpl::producer<ReactionId> myTagRenamed() const;
enum class ImageSize {
BottomInfo,
@@ -223,6 +226,7 @@ private:
rpl::event_stream<> _favoriteUpdated;
rpl::event_stream<> _myTagsUpdated;
rpl::event_stream<> _tagsUpdated;
rpl::event_stream<ReactionId> _myTagRenamed;
// We need &i->second stay valid while inserting new items.
// So we use std::map instead of base::flat_map here.

View File

@@ -295,6 +295,16 @@ Session::Session(not_null<Main::Session*> session)
}
}, _lifetime);
_reactions->myTagRenamed(
) | rpl::start_with_next([=](const ReactionId &id) {
const auto i = _viewsByTag.find(id);
if (i != end(_viewsByTag)) {
for (const auto &view : i->second) {
notifyItemDataChange(view->data());
}
}
}, _lifetime);
Spellchecker::HighlightReady(
) | rpl::start_with_next([=](uint64 processId) {
highlightProcessDone(processId);
@@ -4608,6 +4618,28 @@ rpl::producer<not_null<PeerData*>> Session::peerDecorationsUpdated() const {
return _peerDecorationsUpdated.events();
}
void Session::viewTagsChanged(
not_null<ViewElement*> view,
std::vector<Data::ReactionId> &&was,
std::vector<Data::ReactionId> &&now) {
for (const auto &id : now) {
const auto i = ranges::remove(was, id);
if (i != end(was)) {
was.erase(i, end(was));
} else {
_viewsByTag[id].emplace(view);
}
}
for (const auto &id : was) {
const auto i = _viewsByTag.find(id);
if (i != end(_viewsByTag)
&& i->second.remove(view)
&& i->second.empty()) {
_viewsByTag.erase(i);
}
}
}
void Session::clearLocalStorage() {
_cache->close();
_cache->clear();

View File

@@ -62,6 +62,7 @@ class NotifySettings;
class CustomEmojiManager;
class Stories;
class SavedMessages;
struct ReactionId;
struct RepliesReadTillUpdate {
FullMsgId id;
@@ -742,6 +743,11 @@ public:
void applyStatsDcId(not_null<ChannelData*>, MTP::DcId);
[[nodiscard]] MTP::DcId statsDcId(not_null<ChannelData*>);
void viewTagsChanged(
not_null<ViewElement*> view,
std::vector<ReactionId> &&was,
std::vector<ReactionId> &&now);
void clearLocalStorage();
private:
@@ -1005,9 +1011,14 @@ private:
base::flat_map<uint64, not_null<GroupCall*>> _groupCalls;
rpl::event_stream<InviteToCall> _invitesToCalls;
base::flat_map<uint64, base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
base::flat_map<
uint64,
base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
base::flat_set<not_null<ViewElement*>> _shownSpoilers;
base::flat_map<
ReactionId,
base::flat_set<not_null<ViewElement*>>> _viewsByTag;
History *_topPromoted = nullptr;