mirror of https://github.com/procxx/kepka.git
Show cloud stickers by emoji.
This commit is contained in:
parent
c3ff5f2603
commit
f0a95032a5
|
@ -59,6 +59,7 @@ constexpr auto kFeedMessagesLimit = 50;
|
||||||
constexpr auto kReadFeaturedSetsTimeout = TimeMs(1000);
|
constexpr auto kReadFeaturedSetsTimeout = TimeMs(1000);
|
||||||
constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000);
|
constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000);
|
||||||
constexpr auto kFeedReadTimeout = TimeMs(1000);
|
constexpr auto kFeedReadTimeout = TimeMs(1000);
|
||||||
|
constexpr auto kStickersByEmojiInvalidateTimeout = TimeMs(60 * 60 * 1000);
|
||||||
|
|
||||||
bool IsSilentPost(not_null<HistoryItem*> item, bool silent) {
|
bool IsSilentPost(not_null<HistoryItem*> item, bool silent) {
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
|
@ -2199,11 +2200,60 @@ void ApiWrap::updateStickers() {
|
||||||
|
|
||||||
void ApiWrap::setGroupStickerSet(not_null<ChannelData*> megagroup, const MTPInputStickerSet &set) {
|
void ApiWrap::setGroupStickerSet(not_null<ChannelData*> megagroup, const MTPInputStickerSet &set) {
|
||||||
Expects(megagroup->mgInfo != nullptr);
|
Expects(megagroup->mgInfo != nullptr);
|
||||||
|
|
||||||
megagroup->mgInfo->stickerSet = set;
|
megagroup->mgInfo->stickerSet = set;
|
||||||
request(MTPchannels_SetStickers(megagroup->inputChannel, set)).send();
|
request(MTPchannels_SetStickers(megagroup->inputChannel, set)).send();
|
||||||
_session->data().notifyStickersUpdated();
|
_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) {
|
void ApiWrap::requestStickers(TimeId now) {
|
||||||
if (!_session->data().stickersUpdateNeeded(now)
|
if (!_session->data().stickersUpdateNeeded(now)
|
||||||
|| _stickersUpdateRequest) {
|
|| _stickersUpdateRequest) {
|
||||||
|
|
|
@ -129,6 +129,8 @@ public:
|
||||||
void setGroupStickerSet(
|
void setGroupStickerSet(
|
||||||
not_null<ChannelData*> megagroup,
|
not_null<ChannelData*> megagroup,
|
||||||
const MTPInputStickerSet &set);
|
const MTPInputStickerSet &set);
|
||||||
|
std::vector<not_null<DocumentData*>> *stickersByEmoji(
|
||||||
|
not_null<EmojiPtr> emoji);
|
||||||
|
|
||||||
void joinChannel(ChannelData *channel);
|
void joinChannel(ChannelData *channel);
|
||||||
void leaveChannel(ChannelData *channel);
|
void leaveChannel(ChannelData *channel);
|
||||||
|
@ -279,6 +281,12 @@ private:
|
||||||
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
||||||
using SharedMediaType = Storage::SharedMediaType;
|
using SharedMediaType = Storage::SharedMediaType;
|
||||||
|
|
||||||
|
struct StickersByEmoji {
|
||||||
|
std::vector<not_null<DocumentData*>> list;
|
||||||
|
QString hash;
|
||||||
|
TimeMs received = 0;
|
||||||
|
};
|
||||||
|
|
||||||
void updatesReceived(const MTPUpdates &updates);
|
void updatesReceived(const MTPUpdates &updates);
|
||||||
void checkQuitPreventFinished();
|
void checkQuitPreventFinished();
|
||||||
|
|
||||||
|
@ -489,6 +497,8 @@ private:
|
||||||
base::Timer _featuredSetsReadTimer;
|
base::Timer _featuredSetsReadTimer;
|
||||||
base::flat_set<uint64> _featuredSetsRead;
|
base::flat_set<uint64> _featuredSetsRead;
|
||||||
|
|
||||||
|
base::flat_map<not_null<EmojiPtr>, StickersByEmoji> _stickersByEmoji;
|
||||||
|
|
||||||
base::flat_map<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
base::flat_map<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||||
|
|
||||||
mtpRequestId _contactsRequestId = 0;
|
mtpRequestId _contactsRequestId = 0;
|
||||||
|
|
|
@ -324,6 +324,7 @@ void FieldAutocomplete::rowsUpdated(const internal::MentionRows &mrows, const in
|
||||||
if (!isHidden()) {
|
if (!isHidden()) {
|
||||||
hideAnimated();
|
hideAnimated();
|
||||||
}
|
}
|
||||||
|
_scroll->scrollToY(0);
|
||||||
_mrows.clear();
|
_mrows.clear();
|
||||||
_hrows.clear();
|
_hrows.clear();
|
||||||
_brows.clear();
|
_brows.clear();
|
||||||
|
|
|
@ -670,33 +670,52 @@ Pack GetListByEmoji(not_null<EmojiPtr> emoji) {
|
||||||
result = faved;
|
result = faved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto &order = Auth().data().stickerSetsOrder();
|
const auto addList = [&](const Order &order, MTPDstickerSet::Flag skip) {
|
||||||
for (auto i = 0, l = order.size(); i != l; ++i) {
|
for (const auto setId : order) {
|
||||||
auto it = sets.find(order[i]);
|
auto it = sets.find(setId);
|
||||||
if (it != sets.cend()) {
|
if (it == sets.cend() || (it->flags & skip)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (it->emoji.isEmpty()) {
|
if (it->emoji.isEmpty()) {
|
||||||
setsToRequest.insert(it->id, it->access);
|
setsToRequest.insert(it->id, it->access);
|
||||||
it->flags |= MTPDstickerSet_ClientFlag::f_not_loaded;
|
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()) {
|
auto i = it->emoji.constFind(original);
|
||||||
result.reserve(result.size() + i->size());
|
if (i == it->emoji.cend()) {
|
||||||
for_const (auto sticker, *i) {
|
continue;
|
||||||
if (!faved.contains(sticker)) {
|
}
|
||||||
result.push_back(sticker);
|
result.reserve(result.size() + i->size());
|
||||||
}
|
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()) {
|
if (!setsToRequest.isEmpty()) {
|
||||||
for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
for (auto i = setsToRequest.cbegin(), e = setsToRequest.cend(); i != e; ++i) {
|
||||||
Auth().api().scheduleStickerSetRequest(i.key(), i.value());
|
Auth().api().scheduleStickerSetRequest(i.key(), i.value());
|
||||||
}
|
}
|
||||||
Auth().api().requestStickerSets();
|
Auth().api().requestStickerSets();
|
||||||
}
|
}
|
||||||
return result;
|
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(
|
base::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
|
||||||
|
|
|
@ -43,13 +43,13 @@ public:
|
||||||
return *_session;
|
return *_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Variable<bool> &contactsLoaded() {
|
[[nodiscard]] base::Variable<bool> &contactsLoaded() {
|
||||||
return _contactsLoaded;
|
return _contactsLoaded;
|
||||||
}
|
}
|
||||||
base::Variable<bool> &allChatsLoaded() {
|
[[nodiscard]] base::Variable<bool> &allChatsLoaded() {
|
||||||
return _allChatsLoaded;
|
return _allChatsLoaded;
|
||||||
}
|
}
|
||||||
base::Observable<void> &moreChatsLoaded() {
|
[[nodiscard]] base::Observable<void> &moreChatsLoaded() {
|
||||||
return _moreChatsLoaded;
|
return _moreChatsLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public:
|
||||||
not_null<HistoryItem*> item;
|
not_null<HistoryItem*> item;
|
||||||
not_null<bool*> isVisible;
|
not_null<bool*> isVisible;
|
||||||
};
|
};
|
||||||
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
[[nodiscard]] base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
||||||
return _queryItemVisibility;
|
return _queryItemVisibility;
|
||||||
}
|
}
|
||||||
struct IdChange {
|
struct IdChange {
|
||||||
|
@ -65,32 +65,32 @@ public:
|
||||||
MsgId oldId = 0;
|
MsgId oldId = 0;
|
||||||
};
|
};
|
||||||
void notifyItemIdChange(IdChange event);
|
void notifyItemIdChange(IdChange event);
|
||||||
rpl::producer<IdChange> itemIdChanged() const;
|
[[nodiscard]] rpl::producer<IdChange> itemIdChanged() const;
|
||||||
void notifyItemLayoutChange(not_null<const HistoryItem*> item);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
void notifyHistoryChangeDelayed(not_null<History*> history);
|
||||||
rpl::producer<not_null<History*>> historyChanged() const;
|
[[nodiscard]] rpl::producer<not_null<History*>> historyChanged() const;
|
||||||
void sendHistoryChangeNotifications();
|
void sendHistoryChangeNotifications();
|
||||||
|
|
||||||
using MegagroupParticipant = std::tuple<
|
using MegagroupParticipant = std::tuple<
|
||||||
|
@ -99,23 +99,23 @@ public:
|
||||||
void removeMegagroupParticipant(
|
void removeMegagroupParticipant(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
||||||
rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
||||||
not_null<ChannelData*> channel) const;
|
not_null<ChannelData*> channel) const;
|
||||||
void addNewMegagroupParticipant(
|
void addNewMegagroupParticipant(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
||||||
rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
||||||
not_null<ChannelData*> channel) const;
|
not_null<ChannelData*> channel) const;
|
||||||
|
|
||||||
void notifyFeedUpdated(not_null<Feed*> feed, FeedUpdateFlag update);
|
void notifyFeedUpdated(not_null<Feed*> feed, FeedUpdateFlag update);
|
||||||
rpl::producer<FeedUpdate> feedUpdated() const;
|
[[nodiscard]] rpl::producer<FeedUpdate> feedUpdated() const;
|
||||||
|
|
||||||
void notifyStickersUpdated();
|
void notifyStickersUpdated();
|
||||||
rpl::producer<> stickersUpdated() const;
|
[[nodiscard]] rpl::producer<> stickersUpdated() const;
|
||||||
void notifySavedGifsUpdated();
|
void notifySavedGifsUpdated();
|
||||||
rpl::producer<> savedGifsUpdated() const;
|
[[nodiscard]] rpl::producer<> savedGifsUpdated() const;
|
||||||
|
|
||||||
bool stickersUpdateNeeded(TimeMs now) const {
|
bool stickersUpdateNeeded(TimeMs now) const {
|
||||||
return stickersUpdateNeeded(_lastStickersUpdate, now);
|
return stickersUpdateNeeded(_lastStickersUpdate, now);
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
void setFeaturedStickerSetsUnreadCount(int count) {
|
void setFeaturedStickerSetsUnreadCount(int count) {
|
||||||
_featuredStickerSetsUnreadCount = count;
|
_featuredStickerSetsUnreadCount = count;
|
||||||
}
|
}
|
||||||
rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
[[nodiscard]] rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
||||||
return _featuredStickerSetsUnreadCount.value();
|
return _featuredStickerSetsUnreadCount.value();
|
||||||
}
|
}
|
||||||
const Stickers::Sets &stickerSets() const {
|
const Stickers::Sets &stickerSets() const {
|
||||||
|
|
Loading…
Reference in New Issue