mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Use available reactions list from the server.
This commit is contained in:
parent
be74f8f2bc
commit
b1668afdf1
11 changed files with 212 additions and 18 deletions
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_location.h"
|
#include "data/data_location.h"
|
||||||
#include "data/data_histories.h"
|
#include "data/data_histories.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
|
#include "data/data_message_reactions.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/session/send_as_peers.h"
|
#include "main/session/send_as_peers.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
@ -760,6 +761,14 @@ PeerId ChannelData::groupCallDefaultJoinAs() const {
|
||||||
return _callDefaultJoinAs;
|
return _callDefaultJoinAs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelData::setAllowedReactions(std::vector<QString> list) {
|
||||||
|
_allowedReactions = std::move(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<QString> &ChannelData::allowedReactions() const {
|
||||||
|
return _allowedReactions;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
void ApplyMigration(
|
void ApplyMigration(
|
||||||
|
@ -903,6 +912,8 @@ void ApplyChannelUpdate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
channel->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
channel->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
||||||
|
channel->setAllowedReactions(
|
||||||
|
Data::Reactions::ParseAllowed(update.vavailable_reactions()));
|
||||||
channel->fullUpdated();
|
channel->fullUpdated();
|
||||||
channel->setPendingRequestsCount(
|
channel->setPendingRequestsCount(
|
||||||
update.vrequests_pending().value_or_empty(),
|
update.vrequests_pending().value_or_empty(),
|
||||||
|
|
|
@ -410,6 +410,9 @@ public:
|
||||||
void setGroupCallDefaultJoinAs(PeerId peerId);
|
void setGroupCallDefaultJoinAs(PeerId peerId);
|
||||||
[[nodiscard]] PeerId groupCallDefaultJoinAs() const;
|
[[nodiscard]] PeerId groupCallDefaultJoinAs() const;
|
||||||
|
|
||||||
|
void setAllowedReactions(std::vector<QString> list);
|
||||||
|
[[nodiscard]] const std::vector<QString> &allowedReactions() const;
|
||||||
|
|
||||||
// Still public data members.
|
// Still public data members.
|
||||||
uint64 access = 0;
|
uint64 access = 0;
|
||||||
|
|
||||||
|
@ -457,6 +460,8 @@ private:
|
||||||
QString _inviteLink;
|
QString _inviteLink;
|
||||||
std::optional<ChannelData*> _linkedChat;
|
std::optional<ChannelData*> _linkedChat;
|
||||||
|
|
||||||
|
std::vector<QString> _allowedReactions;
|
||||||
|
|
||||||
std::unique_ptr<Data::GroupCall> _call;
|
std::unique_ptr<Data::GroupCall> _call;
|
||||||
PeerId _callDefaultJoinAs = 0;
|
PeerId _callDefaultJoinAs = 0;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
|
#include "data/data_message_reactions.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -286,6 +287,14 @@ void ChatData::setPendingRequestsCount(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatData::setAllowedReactions(std::vector<QString> list) {
|
||||||
|
_allowedReactions = std::move(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<QString> &ChatData::allowedReactions() const {
|
||||||
|
return _allowedReactions;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
void ApplyChatUpdate(
|
void ApplyChatUpdate(
|
||||||
|
@ -457,6 +466,8 @@ void ApplyChatUpdate(not_null<ChatData*> chat, const MTPDchatFull &update) {
|
||||||
}
|
}
|
||||||
chat->checkFolder(update.vfolder_id().value_or_empty());
|
chat->checkFolder(update.vfolder_id().value_or_empty());
|
||||||
chat->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
chat->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
||||||
|
chat->setAllowedReactions(
|
||||||
|
Data::Reactions::ParseAllowed(update.vavailable_reactions()));
|
||||||
chat->fullUpdated();
|
chat->fullUpdated();
|
||||||
chat->setAbout(qs(update.vabout()));
|
chat->setAbout(qs(update.vabout()));
|
||||||
chat->setPendingRequestsCount(
|
chat->setPendingRequestsCount(
|
||||||
|
|
|
@ -175,6 +175,9 @@ public:
|
||||||
int count,
|
int count,
|
||||||
std::vector<UserId> recentRequesters);
|
std::vector<UserId> recentRequesters);
|
||||||
|
|
||||||
|
void setAllowedReactions(std::vector<QString> list);
|
||||||
|
[[nodiscard]] const std::vector<QString> &allowedReactions() const;
|
||||||
|
|
||||||
// Still public data members.
|
// Still public data members.
|
||||||
const MTPlong inputChat;
|
const MTPlong inputChat;
|
||||||
|
|
||||||
|
@ -199,6 +202,8 @@ private:
|
||||||
int _pendingRequestsCount = 0;
|
int _pendingRequestsCount = 0;
|
||||||
std::vector<UserId> _recentRequesters;
|
std::vector<UserId> _recentRequesters;
|
||||||
|
|
||||||
|
std::vector<QString> _allowedReactions;
|
||||||
|
|
||||||
std::unique_ptr<Data::GroupCall> _call;
|
std::unique_ptr<Data::GroupCall> _call;
|
||||||
PeerId _callDefaultJoinAs = 0;
|
PeerId _callDefaultJoinAs = 0;
|
||||||
base::flat_map<UserId, std::vector<BotCommand>> _botCommands;
|
base::flat_map<UserId, std::vector<BotCommand>> _botCommands;
|
||||||
|
|
|
@ -11,9 +11,119 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_chat.h"
|
||||||
|
#include "base/timer_rpl.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kRefreshEach = 60 * 60 * crl::time(1000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Reactions::Reactions(not_null<Session*> owner) : _owner(owner) {
|
||||||
|
request();
|
||||||
|
|
||||||
|
base::timer_each(
|
||||||
|
kRefreshEach
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
request();
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<Reaction> &Reactions::list() const {
|
||||||
|
return _available;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Reaction> Reactions::list(not_null<PeerData*> peer) const {
|
||||||
|
if (const auto chat = peer->asChat()) {
|
||||||
|
return filtered(chat->allowedReactions());
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
return filtered(channel->allowedReactions());
|
||||||
|
} else {
|
||||||
|
return list();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Reaction> Reactions::Filtered(
|
||||||
|
const std::vector<Reaction> &reactions,
|
||||||
|
const std::vector<QString> &emoji) {
|
||||||
|
auto result = std::vector<Reaction>();
|
||||||
|
result.reserve(emoji.size());
|
||||||
|
for (const auto &single : emoji) {
|
||||||
|
const auto i = ranges::find(reactions, single, &Reaction::emoji);
|
||||||
|
if (i != end(reactions)) {
|
||||||
|
result.push_back(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Reaction> Reactions::filtered(
|
||||||
|
const std::vector<QString> &emoji) const {
|
||||||
|
return Filtered(list(), emoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<QString> Reactions::ParseAllowed(
|
||||||
|
const MTPVector<MTPstring> *list) {
|
||||||
|
if (!list) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return list->v | ranges::view::transform([](const MTPstring &string) {
|
||||||
|
return qs(string);
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reactions::request() {
|
||||||
|
auto &api = _owner->session().api();
|
||||||
|
_requestId = api.request(MTPmessages_GetAvailableReactions(
|
||||||
|
MTP_int(_hash)
|
||||||
|
)).done([=](const MTPmessages_AvailableReactions &result) {
|
||||||
|
_requestId = 0;
|
||||||
|
result.match([&](const MTPDmessages_availableReactions &data) {
|
||||||
|
_hash = data.vhash().v;
|
||||||
|
|
||||||
|
const auto &list = data.vreactions().v;
|
||||||
|
_available.clear();
|
||||||
|
_available.reserve(data.vreactions().v.size());
|
||||||
|
for (const auto &reaction : list) {
|
||||||
|
if (const auto parsed = parse(reaction)) {
|
||||||
|
_available.push_back(*parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_updated.fire({});
|
||||||
|
}, [&](const MTPDmessages_availableReactionsNotModified &) {
|
||||||
|
});
|
||||||
|
}).fail([=] {
|
||||||
|
_requestId = 0;
|
||||||
|
_hash = 0;
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Reaction> Reactions::parse(const MTPAvailableReaction &entry) {
|
||||||
|
return entry.match([&](const MTPDavailableReaction &data) {
|
||||||
|
const auto emoji = qs(data.vreaction());
|
||||||
|
const auto known = (Ui::Emoji::Find(emoji) != nullptr);
|
||||||
|
if (!known) {
|
||||||
|
LOG(("API Error: Unknown emoji in reactions: %1").arg(emoji));
|
||||||
|
}
|
||||||
|
return known
|
||||||
|
? std::make_optional(Reaction{
|
||||||
|
.emoji = emoji,
|
||||||
|
.title = qs(data.vtitle()),
|
||||||
|
.staticIcon = _owner->processDocument(data.vstatic_icon()),
|
||||||
|
.selectAnimation = _owner->processDocument(
|
||||||
|
data.vselect_animation()),
|
||||||
|
.activateAnimation = _owner->processDocument(
|
||||||
|
data.vactivate_animation()),
|
||||||
|
.activateEffects = _owner->processDocument(
|
||||||
|
data.veffect_animation()),
|
||||||
|
})
|
||||||
|
: std::nullopt;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<QString> MessageReactions::SuggestList() {
|
std::vector<QString> MessageReactions::SuggestList() {
|
||||||
constexpr auto utf = [](const char *utf) {
|
constexpr auto utf = [](const char *utf) {
|
||||||
|
|
|
@ -9,6 +9,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
class Session;
|
||||||
|
|
||||||
|
struct Reaction {
|
||||||
|
QString emoji;
|
||||||
|
QString title;
|
||||||
|
not_null<DocumentData*> staticIcon;
|
||||||
|
not_null<DocumentData*> selectAnimation;
|
||||||
|
not_null<DocumentData*> activateAnimation;
|
||||||
|
not_null<DocumentData*> activateEffects;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Reactions final {
|
||||||
|
public:
|
||||||
|
explicit Reactions(not_null<Session*> owner);
|
||||||
|
|
||||||
|
[[nodiscard]] const std::vector<Reaction> &list() const;
|
||||||
|
[[nodiscard]] std::vector<Reaction> list(not_null<PeerData*> peer) const;
|
||||||
|
|
||||||
|
[[nodiscard]] static std::vector<Reaction> Filtered(
|
||||||
|
const std::vector<Reaction> &reactions,
|
||||||
|
const std::vector<QString> &emoji);
|
||||||
|
[[nodiscard]] std::vector<Reaction> filtered(
|
||||||
|
const std::vector<QString> &emoji) const;
|
||||||
|
|
||||||
|
[[nodiscard]] static std::vector<QString> ParseAllowed(
|
||||||
|
const MTPVector<MTPstring> *list);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<> updates() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void request();
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<Reaction> parse(
|
||||||
|
const MTPAvailableReaction &entry);
|
||||||
|
|
||||||
|
const not_null<Session*> _owner;
|
||||||
|
|
||||||
|
std::vector<Reaction> _available;
|
||||||
|
rpl::event_stream<> _updated;
|
||||||
|
|
||||||
|
mtpRequestId _requestId = 0;
|
||||||
|
int32 _hash = 0;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class MessageReactions final {
|
class MessageReactions final {
|
||||||
public:
|
public:
|
||||||
static std::vector<QString> SuggestList();
|
static std::vector<QString> SuggestList();
|
||||||
|
|
|
@ -54,6 +54,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
#include "data/data_send_action.h"
|
#include "data/data_send_action.h"
|
||||||
#include "data/data_sponsored_messages.h"
|
#include "data/data_sponsored_messages.h"
|
||||||
|
#include "data/data_message_reactions.h"
|
||||||
#include "data/data_cloud_themes.h"
|
#include "data/data_cloud_themes.h"
|
||||||
#include "data/data_streaming.h"
|
#include "data/data_streaming.h"
|
||||||
#include "data/data_media_rotation.h"
|
#include "data/data_media_rotation.h"
|
||||||
|
@ -241,7 +242,8 @@ Session::Session(not_null<Main::Session*> session)
|
||||||
, _mediaRotation(std::make_unique<MediaRotation>())
|
, _mediaRotation(std::make_unique<MediaRotation>())
|
||||||
, _histories(std::make_unique<Histories>(this))
|
, _histories(std::make_unique<Histories>(this))
|
||||||
, _stickers(std::make_unique<Stickers>(this))
|
, _stickers(std::make_unique<Stickers>(this))
|
||||||
, _sponsoredMessages(std::make_unique<SponsoredMessages>(this)) {
|
, _sponsoredMessages(std::make_unique<SponsoredMessages>(this))
|
||||||
|
, _reactions(std::make_unique<Reactions>(this)) {
|
||||||
_cache->open(_session->local().cacheKey());
|
_cache->open(_session->local().cacheKey());
|
||||||
_bigFileCache->open(_session->local().cacheBigFileKey());
|
_bigFileCache->open(_session->local().cacheBigFileKey());
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class WallPaper;
|
||||||
class ScheduledMessages;
|
class ScheduledMessages;
|
||||||
class SendActionManager;
|
class SendActionManager;
|
||||||
class SponsoredMessages;
|
class SponsoredMessages;
|
||||||
|
class Reactions;
|
||||||
class ChatFilters;
|
class ChatFilters;
|
||||||
class CloudThemes;
|
class CloudThemes;
|
||||||
class Streaming;
|
class Streaming;
|
||||||
|
@ -113,6 +114,10 @@ public:
|
||||||
[[nodiscard]] SponsoredMessages &sponsoredMessages() const {
|
[[nodiscard]] SponsoredMessages &sponsoredMessages() const {
|
||||||
return *_sponsoredMessages;
|
return *_sponsoredMessages;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] Reactions &reactions() const {
|
||||||
|
return *_reactions;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] MsgId nextNonHistoryEntryId() {
|
[[nodiscard]] MsgId nextNonHistoryEntryId() {
|
||||||
return ++_nonHistoryEntryId;
|
return ++_nonHistoryEntryId;
|
||||||
}
|
}
|
||||||
|
@ -962,15 +967,17 @@ private:
|
||||||
uint64 _wallpapersHash = 0;
|
uint64 _wallpapersHash = 0;
|
||||||
|
|
||||||
Groups _groups;
|
Groups _groups;
|
||||||
std::unique_ptr<ChatFilters> _chatsFilters;
|
const std::unique_ptr<ChatFilters> _chatsFilters;
|
||||||
std::unique_ptr<ScheduledMessages> _scheduledMessages;
|
std::unique_ptr<ScheduledMessages> _scheduledMessages;
|
||||||
std::unique_ptr<CloudThemes> _cloudThemes;
|
const std::unique_ptr<CloudThemes> _cloudThemes;
|
||||||
std::unique_ptr<SendActionManager> _sendActionManager;
|
const std::unique_ptr<SendActionManager> _sendActionManager;
|
||||||
std::unique_ptr<Streaming> _streaming;
|
const std::unique_ptr<Streaming> _streaming;
|
||||||
std::unique_ptr<MediaRotation> _mediaRotation;
|
const std::unique_ptr<MediaRotation> _mediaRotation;
|
||||||
std::unique_ptr<Histories> _histories;
|
const std::unique_ptr<Histories> _histories;
|
||||||
std::unique_ptr<Stickers> _stickers;
|
const std::unique_ptr<Stickers> _stickers;
|
||||||
std::unique_ptr<SponsoredMessages> _sponsoredMessages;
|
std::unique_ptr<SponsoredMessages> _sponsoredMessages;
|
||||||
|
const std::unique_ptr<Reactions> _reactions;
|
||||||
|
|
||||||
MsgId _nonHistoryEntryId = ServerMaxMsgId;
|
MsgId _nonHistoryEntryId = ServerMaxMsgId;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
|
@ -1698,9 +1698,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
auto reactionMenu = std::make_unique<Ui::PopupMenu>(
|
auto reactionMenu = std::make_unique<Ui::PopupMenu>(
|
||||||
this,
|
this,
|
||||||
st::reactionMenu);
|
st::reactionMenu);
|
||||||
for (const auto &text : Data::MessageReactions::SuggestList()) {
|
auto &reactions = item->history()->owner().reactions();
|
||||||
reactionMenu->addAction(text, [=] {
|
for (const auto &entry : reactions.list(item->history()->peer)) {
|
||||||
item->addReaction(text);
|
reactionMenu->addAction(entry.emoji, [=] {
|
||||||
|
item->addReaction(entry.emoji);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_menu->addAction("Reaction", std::move(reactionMenu));
|
_menu->addAction("Reaction", std::move(reactionMenu));
|
||||||
|
@ -3789,7 +3790,7 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
|
||||||
Instance->elementShowReactions(view);
|
Instance->elementShowReactions(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Result result;
|
static Result result;
|
||||||
|
|
|
@ -745,7 +745,7 @@ bool HistoryItem::suggestDeleteAllReport() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryItem::canReact() const {
|
bool HistoryItem::canReact() const {
|
||||||
return IsServerMsgId(id) && !out() && !_history->peer->isSelf();
|
return isRegular();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryItem::addReaction(const QString &reaction) {
|
void HistoryItem::addReaction(const QString &reaction) {
|
||||||
|
|
|
@ -213,11 +213,6 @@ int BottomInfo::resizeToWidth(int newWidth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BottomInfo::layout() {
|
void BottomInfo::layout() {
|
||||||
//const auto good = ::Data::MessageReactions::SuggestList();
|
|
||||||
//for (const auto &item : good) {
|
|
||||||
// _data.reactions.emplace(item, rand_value<uint8>() + 1);
|
|
||||||
//}
|
|
||||||
|
|
||||||
layoutDateText();
|
layoutDateText();
|
||||||
layoutViewsText();
|
layoutViewsText();
|
||||||
layoutRepliesText();
|
layoutRepliesText();
|
||||||
|
|
Loading…
Add table
Reference in a new issue