mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Show cloud stickers by emoji.
This commit is contained in:
parent
c3ff5f2603
commit
f0a95032a5
5 changed files with 120 additions and 40 deletions
|
@ -59,6 +59,7 @@ constexpr auto kFeedMessagesLimit = 50;
|
|||
constexpr auto kReadFeaturedSetsTimeout = TimeMs(1000);
|
||||
constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000);
|
||||
constexpr auto kFeedReadTimeout = TimeMs(1000);
|
||||
constexpr auto kStickersByEmojiInvalidateTimeout = TimeMs(60 * 60 * 1000);
|
||||
|
||||
bool IsSilentPost(not_null<HistoryItem*> item, bool silent) {
|
||||
const auto history = item->history();
|
||||
|
@ -2199,11 +2200,60 @@ void ApiWrap::updateStickers() {
|
|||
|
||||
void ApiWrap::setGroupStickerSet(not_null<ChannelData*> megagroup, const MTPInputStickerSet &set) {
|
||||
Expects(megagroup->mgInfo != nullptr);
|
||||
|
||||
megagroup->mgInfo->stickerSet = set;
|
||||
request(MTPchannels_SetStickers(megagroup->inputChannel, set)).send();
|
||||
_session->data().notifyStickersUpdated();
|
||||
}
|
||||
|
||||
std::vector<not_null<DocumentData*>> *ApiWrap::stickersByEmoji(
|
||||
not_null<EmojiPtr> emoji) {
|
||||
const auto it = _stickersByEmoji.find(emoji);
|
||||
const auto sendRequest = [&] {
|
||||
if (it == _stickersByEmoji.end()) {
|
||||
return true;
|
||||
}
|
||||
const auto received = it->second.received;
|
||||
const auto now = getms(true);
|
||||
return (received > 0)
|
||||
&& (received + kStickersByEmojiInvalidateTimeout) <= now;
|
||||
}();
|
||||
if (sendRequest) {
|
||||
const auto hash = (it != _stickersByEmoji.end())
|
||||
? it->second.hash
|
||||
: QString();
|
||||
request(MTPmessages_GetStickers(
|
||||
MTP_flags(MTPmessages_GetStickers::Flag::f_exclude_featured),
|
||||
MTP_string(emoji->text()),
|
||||
MTP_string(hash)
|
||||
)).done([=](const MTPmessages_Stickers &result) {
|
||||
if (result.type() == mtpc_messages_stickersNotModified) {
|
||||
return;
|
||||
}
|
||||
Assert(result.type() == mtpc_messages_stickers);
|
||||
const auto &data = result.c_messages_stickers();
|
||||
auto &entry = _stickersByEmoji[emoji];
|
||||
entry.list.clear();
|
||||
entry.list.reserve(data.vstickers.v.size());
|
||||
for (const auto &sticker : data.vstickers.v) {
|
||||
const auto document = Auth().data().document(sticker);
|
||||
if (document->sticker()) {
|
||||
entry.list.push_back(document);
|
||||
}
|
||||
}
|
||||
entry.hash = qs(data.vhash);
|
||||
entry.received = getms(true);
|
||||
_session->data().notifyStickersUpdated();
|
||||
}).send();
|
||||
}
|
||||
if (it == _stickersByEmoji.end()) {
|
||||
_stickersByEmoji.emplace(emoji, StickersByEmoji());
|
||||
} else if (it->second.received > 0) {
|
||||
return &it->second.list;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ApiWrap::requestStickers(TimeId now) {
|
||||
if (!_session->data().stickersUpdateNeeded(now)
|
||||
|| _stickersUpdateRequest) {
|
||||
|
|
|
@ -129,6 +129,8 @@ public:
|
|||
void setGroupStickerSet(
|
||||
not_null<ChannelData*> megagroup,
|
||||
const MTPInputStickerSet &set);
|
||||
std::vector<not_null<DocumentData*>> *stickersByEmoji(
|
||||
not_null<EmojiPtr> emoji);
|
||||
|
||||
void joinChannel(ChannelData *channel);
|
||||
void leaveChannel(ChannelData *channel);
|
||||
|
@ -279,6 +281,12 @@ private:
|
|||
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
||||
using SharedMediaType = Storage::SharedMediaType;
|
||||
|
||||
struct StickersByEmoji {
|
||||
std::vector<not_null<DocumentData*>> list;
|
||||
QString hash;
|
||||
TimeMs received = 0;
|
||||
};
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
|
@ -489,6 +497,8 @@ private:
|
|||
base::Timer _featuredSetsReadTimer;
|
||||
base::flat_set<uint64> _featuredSetsRead;
|
||||
|
||||
base::flat_map<not_null<EmojiPtr>, StickersByEmoji> _stickersByEmoji;
|
||||
|
||||
base::flat_map<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
|
||||
mtpRequestId _contactsRequestId = 0;
|
||||
|
|
|
@ -324,6 +324,7 @@ void FieldAutocomplete::rowsUpdated(const internal::MentionRows &mrows, const in
|
|||
if (!isHidden()) {
|
||||
hideAnimated();
|
||||
}
|
||||
_scroll->scrollToY(0);
|
||||
_mrows.clear();
|
||||
_hrows.clear();
|
||||
_brows.clear();
|
||||
|
|
|
@ -670,34 +670,53 @@ Pack GetListByEmoji(not_null<EmojiPtr> emoji) {
|
|||
result = faved;
|
||||
}
|
||||
}
|
||||
auto &order = Auth().data().stickerSetsOrder();
|
||||
for (auto i = 0, l = order.size(); i != l; ++i) {
|
||||
auto it = sets.find(order[i]);
|
||||
if (it != sets.cend()) {
|
||||
const auto addList = [&](const Order &order, MTPDstickerSet::Flag skip) {
|
||||
for (const auto setId : order) {
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend() || (it->flags & skip)) {
|
||||
continue;
|
||||
}
|
||||
if (it->emoji.isEmpty()) {
|
||||
setsToRequest.insert(it->id, it->access);
|
||||
it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded;
|
||||
} else if (!(it->flags & MTPDstickerSet::Flag::f_archived)) {
|
||||
continue;
|
||||
}
|
||||
auto i = it->emoji.constFind(original);
|
||||
if (i != it->emoji.cend()) {
|
||||
if (i == it->emoji.cend()) {
|
||||
continue;
|
||||
}
|
||||
result.reserve(result.size() + i->size());
|
||||
for_const (auto sticker, *i) {
|
||||
if (!faved.contains(sticker)) {
|
||||
result.push_back(sticker);
|
||||
}
|
||||
}
|
||||
}
|
||||
for_const (const auto document, *i) {
|
||||
if (!faved.contains(document)) {
|
||||
result.push_back(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addList(
|
||||
Auth().data().stickerSetsOrder(),
|
||||
MTPDstickerSet::Flag::f_archived);
|
||||
addList(
|
||||
Auth().data().featuredStickerSetsOrder(),
|
||||
MTPDstickerSet::Flag::f_installed_date);
|
||||
|
||||
if (!setsToRequest.isEmpty()) {
|
||||
for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
||||
Auth().api().scheduleStickerSetRequest(i.key(), i.value());
|
||||
}
|
||||
Auth().api().requestStickerSets();
|
||||
}
|
||||
if (const auto pack = Auth().api().stickersByEmoji(original)) {
|
||||
for (const auto document : *pack) {
|
||||
if (!base::contains(result, document)) {
|
||||
result.push_back(document);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Pack();
|
||||
}
|
||||
|
||||
base::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
|
||||
not_null<DocumentData*> document) {
|
||||
|
|
|
@ -43,13 +43,13 @@ public:
|
|||
return *_session;
|
||||
}
|
||||
|
||||
base::Variable<bool> &contactsLoaded() {
|
||||
[[nodiscard]] base::Variable<bool> &contactsLoaded() {
|
||||
return _contactsLoaded;
|
||||
}
|
||||
base::Variable<bool> &allChatsLoaded() {
|
||||
[[nodiscard]] base::Variable<bool> &allChatsLoaded() {
|
||||
return _allChatsLoaded;
|
||||
}
|
||||
base::Observable<void> &moreChatsLoaded() {
|
||||
[[nodiscard]] base::Observable<void> &moreChatsLoaded() {
|
||||
return _moreChatsLoaded;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
not_null<HistoryItem*> item;
|
||||
not_null<bool*> isVisible;
|
||||
};
|
||||
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
||||
[[nodiscard]] base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
||||
return _queryItemVisibility;
|
||||
}
|
||||
struct IdChange {
|
||||
|
@ -65,32 +65,32 @@ public:
|
|||
MsgId oldId = 0;
|
||||
};
|
||||
void notifyItemIdChange(IdChange event);
|
||||
rpl::producer<IdChange> itemIdChanged() const;
|
||||
[[nodiscard]] rpl::producer<IdChange> itemIdChanged() const;
|
||||
void notifyItemLayoutChange(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
||||
void notifyViewLayoutChange(not_null<const ViewElement*> view);
|
||||
rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
|
||||
void requestItemRepaint(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||
void requestViewRepaint(not_null<const ViewElement*> view);
|
||||
rpl::producer<not_null<const ViewElement*>> viewRepaintRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewRepaintRequest() const;
|
||||
void requestItemResize(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const;
|
||||
void requestViewResize(not_null<ViewElement*> view);
|
||||
rpl::producer<not_null<ViewElement*>> viewResizeRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<ViewElement*>> viewResizeRequest() const;
|
||||
void requestItemViewRefresh(not_null<HistoryItem*> item);
|
||||
rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const;
|
||||
void requestAnimationPlayInline(not_null<HistoryItem*> item);
|
||||
rpl::producer<not_null<HistoryItem*>> animationPlayInlineRequest() const;
|
||||
[[nodiscard]] rpl::producer<not_null<HistoryItem*>> animationPlayInlineRequest() const;
|
||||
void notifyHistoryUnloaded(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyUnloaded() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const History*>> historyUnloaded() const;
|
||||
|
||||
void notifyItemRemoved(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
|
||||
void notifyHistoryCleared(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyCleared() const;
|
||||
[[nodiscard]] rpl::producer<not_null<const History*>> historyCleared() const;
|
||||
void notifyHistoryChangeDelayed(not_null<History*> history);
|
||||
rpl::producer<not_null<History*>> historyChanged() const;
|
||||
[[nodiscard]] rpl::producer<not_null<History*>> historyChanged() const;
|
||||
void sendHistoryChangeNotifications();
|
||||
|
||||
using MegagroupParticipant = std::tuple<
|
||||
|
@ -99,23 +99,23 @@ public:
|
|||
void removeMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
||||
[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
||||
[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
||||
not_null<ChannelData*> channel) const;
|
||||
void addNewMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
||||
[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
||||
[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
||||
not_null<ChannelData*> channel) const;
|
||||
|
||||
void notifyFeedUpdated(not_null<Feed*> feed, FeedUpdateFlag update);
|
||||
rpl::producer<FeedUpdate> feedUpdated() const;
|
||||
[[nodiscard]] rpl::producer<FeedUpdate> feedUpdated() const;
|
||||
|
||||
void notifyStickersUpdated();
|
||||
rpl::producer<> stickersUpdated() const;
|
||||
[[nodiscard]] rpl::producer<> stickersUpdated() const;
|
||||
void notifySavedGifsUpdated();
|
||||
rpl::producer<> savedGifsUpdated() const;
|
||||
[[nodiscard]] rpl::producer<> savedGifsUpdated() const;
|
||||
|
||||
bool stickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastStickersUpdate, now);
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
void setFeaturedStickerSetsUnreadCount(int count) {
|
||||
_featuredStickerSetsUnreadCount = count;
|
||||
}
|
||||
rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
||||
[[nodiscard]] rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
||||
return _featuredStickerSetsUnreadCount.value();
|
||||
}
|
||||
const Stickers::Sets &stickerSets() const {
|
||||
|
|
Loading…
Add table
Reference in a new issue