mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 13:17:08 +02:00
Update scheme, new sticker categories.
This commit is contained in:
parent
63e1731d7c
commit
bb6fd4bc4d
13 changed files with 238 additions and 30 deletions
|
@ -760,14 +760,14 @@ rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
|
|||
channel()->inputChannel
|
||||
)).done([=](const MTPstats_BroadcastRevenueStats &result) {
|
||||
const auto &data = result.data();
|
||||
|
||||
const auto &balances = data.vbalances().data();
|
||||
_data = Data::EarnStatistics{
|
||||
.topHoursGraph = StatisticalGraphFromTL(
|
||||
data.vtop_hours_graph()),
|
||||
.revenueGraph = StatisticalGraphFromTL(data.vrevenue_graph()),
|
||||
.currentBalance = data.vcurrent_balance().v,
|
||||
.availableBalance = data.vavailable_balance().v,
|
||||
.overallRevenue = data.voverall_revenue().v,
|
||||
.currentBalance = balances.vcurrent_balance().v,
|
||||
.availableBalance = balances.vavailable_balance().v,
|
||||
.overallRevenue = balances.voverall_revenue().v,
|
||||
.usdRate = data.vusd_rate().v,
|
||||
};
|
||||
|
||||
|
|
|
@ -573,12 +573,17 @@ EmojiListWidget::~EmojiListWidget() {
|
|||
|
||||
void EmojiListWidget::setupSearch() {
|
||||
const auto session = &_show->session();
|
||||
const auto type = (_mode == Mode::EmojiStatus)
|
||||
? TabbedSearchType::Status
|
||||
: (_mode == Mode::UserpicBuilder)
|
||||
? TabbedSearchType::ProfilePhoto
|
||||
: TabbedSearchType::Emoji;
|
||||
_search = MakeSearch(this, st(), [=](std::vector<QString> &&query) {
|
||||
_nextSearchQuery = std::move(query);
|
||||
InvokeQueued(this, [=] {
|
||||
applyNextSearchQuery();
|
||||
});
|
||||
}, session, (_mode == Mode::EmojiStatus), _mode == Mode::UserpicBuilder);
|
||||
}, session, type);
|
||||
}
|
||||
|
||||
void EmojiListWidget::applyNextSearchQuery() {
|
||||
|
|
|
@ -820,7 +820,7 @@ void GifsListWidget::setupSearch() {
|
|||
: SearchEmojiSectionSetId();
|
||||
refreshIcons();
|
||||
searchForGifs(accumulated);
|
||||
}, session);
|
||||
}, session, TabbedSearchType::Emoji);
|
||||
}
|
||||
|
||||
int32 GifsListWidget::showInlineRows(bool newResults) {
|
||||
|
|
|
@ -547,6 +547,15 @@ void StickersListWidget::sendSearchRequest() {
|
|||
}
|
||||
|
||||
_search->setLoading(true);
|
||||
|
||||
if (_searchQuery == Ui::PremiumGroupFakeEmoticon()) {
|
||||
_search->setLoading(false);
|
||||
_searchRequestId = 0;
|
||||
_searchCache.emplace(_searchQuery, std::vector<uint64>());
|
||||
showSearchResults();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto hash = uint64(0);
|
||||
_searchRequestId = _api.request(MTPmessages_SearchStickerSets(
|
||||
MTP_flags(0),
|
||||
|
@ -570,10 +579,14 @@ void StickersListWidget::searchForSets(
|
|||
return;
|
||||
}
|
||||
|
||||
_filteredStickers = session().data().stickers().getListByEmoji(
|
||||
std::move(emoji),
|
||||
0,
|
||||
true);
|
||||
if (query == Ui::PremiumGroupFakeEmoticon()) {
|
||||
_filteredStickers = session().data().stickers().getPremiumList(0);
|
||||
} else {
|
||||
_filteredStickers = session().data().stickers().getListByEmoji(
|
||||
std::move(emoji),
|
||||
0,
|
||||
true);
|
||||
}
|
||||
if (_searchQuery != cleaned) {
|
||||
_search->setLoading(false);
|
||||
if (const auto requestId = base::take(_searchRequestId)) {
|
||||
|
@ -2604,15 +2617,18 @@ void StickersListWidget::beforeHiding() {
|
|||
|
||||
void StickersListWidget::setupSearch() {
|
||||
const auto session = &_show->session();
|
||||
const auto type = (_mode == Mode::UserpicBuilder)
|
||||
? TabbedSearchType::ProfilePhoto
|
||||
: TabbedSearchType::Stickers;
|
||||
_search = MakeSearch(this, st(), [=](std::vector<QString> &&query) {
|
||||
auto set = base::flat_set<EmojiPtr>();
|
||||
auto text = ranges::accumulate(query, QString(), [](
|
||||
QString a,
|
||||
QString b) {
|
||||
QString a,
|
||||
QString b) {
|
||||
return a.isEmpty() ? b : (a + ' ' + b);
|
||||
});
|
||||
searchForSets(std::move(text), SearchEmoji(query, set));
|
||||
}, session, false, (_mode == Mode::UserpicBuilder));
|
||||
}, session, type);
|
||||
}
|
||||
|
||||
void StickersListWidget::displaySet(uint64 setId) {
|
||||
|
|
|
@ -307,16 +307,17 @@ std::unique_ptr<Ui::TabbedSearch> MakeSearch(
|
|||
const style::EmojiPan &st,
|
||||
Fn<void(std::vector<QString>&&)> callback,
|
||||
not_null<Main::Session*> session,
|
||||
bool statusCategories,
|
||||
bool profilePhotoCategories) {
|
||||
TabbedSearchType type) {
|
||||
using Descriptor = Ui::SearchDescriptor;
|
||||
const auto owner = &session->data();
|
||||
auto result = std::make_unique<Ui::TabbedSearch>(parent, st, Descriptor{
|
||||
.st = st.search,
|
||||
.groups = (profilePhotoCategories
|
||||
.groups = ((type == TabbedSearchType::ProfilePhoto)
|
||||
? owner->emojiStatuses().profilePhotoGroupsValue()
|
||||
: statusCategories
|
||||
: (type == TabbedSearchType::Status)
|
||||
? owner->emojiStatuses().statusGroupsValue()
|
||||
: (type == TabbedSearchType::Stickers)
|
||||
? owner->emojiStatuses().stickerGroupsValue()
|
||||
: owner->emojiStatuses().emojiGroupsValue()),
|
||||
.customEmojiFactory = owner->customEmojiManager().factory(
|
||||
Data::CustomEmojiManager::SizeTag::SetIcon,
|
||||
|
|
|
@ -98,13 +98,18 @@ struct TabbedSelectorDescriptor {
|
|||
ComposeFeatures features;
|
||||
};
|
||||
|
||||
enum class TabbedSearchType {
|
||||
Emoji,
|
||||
Status,
|
||||
ProfilePhoto,
|
||||
Stickers,
|
||||
};
|
||||
[[nodiscard]] std::unique_ptr<Ui::TabbedSearch> MakeSearch(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const style::EmojiPan &st,
|
||||
Fn<void(std::vector<QString>&&)> callback,
|
||||
not_null<Main::Session*> session,
|
||||
bool statusCategories = false,
|
||||
bool profilePhotoCategories = false);
|
||||
TabbedSearchType type);
|
||||
|
||||
class TabbedSelector : public Ui::RpWidget {
|
||||
public:
|
||||
|
|
|
@ -153,6 +153,11 @@ auto EmojiStatuses::statusGroupsValue() const -> rpl::producer<Groups> {
|
|||
return _statusGroups.data.value();
|
||||
}
|
||||
|
||||
auto EmojiStatuses::stickerGroupsValue() const -> rpl::producer<Groups> {
|
||||
const_cast<EmojiStatuses*>(this)->requestStickerGroups();
|
||||
return _stickerGroups.data.value();
|
||||
}
|
||||
|
||||
auto EmojiStatuses::profilePhotoGroupsValue() const
|
||||
-> rpl::producer<Groups> {
|
||||
const_cast<EmojiStatuses*>(this)->requestProfilePhotoGroups();
|
||||
|
@ -172,6 +177,12 @@ void EmojiStatuses::requestStatusGroups() {
|
|||
MTPmessages_GetEmojiStatusGroups(MTP_int(_statusGroups.hash)));
|
||||
}
|
||||
|
||||
void EmojiStatuses::requestStickerGroups() {
|
||||
requestGroups(
|
||||
&_stickerGroups,
|
||||
MTPmessages_GetEmojiStickerGroups(MTP_int(_stickerGroups.hash)));
|
||||
}
|
||||
|
||||
void EmojiStatuses::requestProfilePhotoGroups() {
|
||||
requestGroups(
|
||||
&_profilePhotoGroups,
|
||||
|
@ -185,15 +196,24 @@ void EmojiStatuses::requestProfilePhotoGroups() {
|
|||
auto result = std::vector<Ui::EmojiGroup>();
|
||||
result.reserve(list.size());
|
||||
for (const auto &group : list) {
|
||||
const auto &data = group.data();
|
||||
auto emoticons = ranges::views::all(
|
||||
data.vemoticons().v
|
||||
) | ranges::views::transform([](const MTPstring &emoticon) {
|
||||
return qs(emoticon);
|
||||
}) | ranges::to_vector;
|
||||
result.push_back({
|
||||
.iconId = QString::number(data.vicon_emoji_id().v),
|
||||
.emoticons = std::move(emoticons),
|
||||
group.match([&](const MTPDemojiGroupPremium &data) {
|
||||
result.push_back({
|
||||
.iconId = QString::number(data.vicon_emoji_id().v),
|
||||
.type = Ui::EmojiGroupType::Premium,
|
||||
});
|
||||
}, [&](const auto &data) {
|
||||
auto emoticons = ranges::views::all(
|
||||
data.vemoticons().v
|
||||
) | ranges::views::transform([](const MTPstring &emoticon) {
|
||||
return qs(emoticon);
|
||||
}) | ranges::to_vector;
|
||||
result.push_back({
|
||||
.iconId = QString::number(data.vicon_emoji_id().v),
|
||||
.emoticons = std::move(emoticons),
|
||||
.type = (MTPDemojiGroupGreeting::Is<decltype(data)>()
|
||||
? Ui::EmojiGroupType::Greeting
|
||||
: Ui::EmojiGroupType::Normal),
|
||||
});
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -60,9 +60,11 @@ public:
|
|||
using Groups = std::vector<Ui::EmojiGroup>;
|
||||
[[nodiscard]] rpl::producer<Groups> emojiGroupsValue() const;
|
||||
[[nodiscard]] rpl::producer<Groups> statusGroupsValue() const;
|
||||
[[nodiscard]] rpl::producer<Groups> stickerGroupsValue() const;
|
||||
[[nodiscard]] rpl::producer<Groups> profilePhotoGroupsValue() const;
|
||||
void requestEmojiGroups();
|
||||
void requestStatusGroups();
|
||||
void requestStickerGroups();
|
||||
void requestProfilePhotoGroups();
|
||||
|
||||
private:
|
||||
|
@ -124,6 +126,7 @@ private:
|
|||
|
||||
GroupsType _emojiGroups;
|
||||
GroupsType _statusGroups;
|
||||
GroupsType _stickerGroups;
|
||||
GroupsType _profilePhotoGroups;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
|
|
@ -1132,6 +1132,141 @@ void Stickers::gifsReceived(const QVector<MTPDocument> &items, uint64 hash) {
|
|||
notifySavedGifsUpdated();
|
||||
}
|
||||
|
||||
std::vector<not_null<DocumentData*>> Stickers::getPremiumList(uint64 seed) {
|
||||
struct StickerWithDate {
|
||||
not_null<DocumentData*> document;
|
||||
TimeId date = 0;
|
||||
};
|
||||
auto result = std::vector<StickerWithDate>();
|
||||
auto &sets = setsRef();
|
||||
auto setsToRequest = base::flat_map<uint64, uint64>();
|
||||
|
||||
const auto add = [&](not_null<DocumentData*> document, TimeId date) {
|
||||
if (ranges::find(result, document, [](const StickerWithDate &data) {
|
||||
return data.document;
|
||||
}) == result.end()) {
|
||||
result.push_back({ document, date });
|
||||
}
|
||||
};
|
||||
|
||||
constexpr auto kSlice = 65536;
|
||||
const auto CreateSortKey = [&](
|
||||
not_null<DocumentData*> document,
|
||||
int base) {
|
||||
if (document->sticker() && document->sticker()->isAnimated()) {
|
||||
base += kSlice;
|
||||
}
|
||||
return TimeId(base + int((document->id ^ seed) % kSlice));
|
||||
};
|
||||
const auto CreateRecentSortKey = [&](not_null<DocumentData*> document) {
|
||||
return CreateSortKey(document, kSlice * 6);
|
||||
};
|
||||
auto myCounter = 0;
|
||||
const auto CreateMySortKey = [&](not_null<DocumentData*> document) {
|
||||
auto base = kSlice * 6;
|
||||
if (!document->sticker() || !document->sticker()->isAnimated()) {
|
||||
base -= kSlice;
|
||||
}
|
||||
return (base - (++myCounter));
|
||||
};
|
||||
const auto CreateFeaturedSortKey = [&](not_null<DocumentData*> document) {
|
||||
return CreateSortKey(document, kSlice * 2);
|
||||
};
|
||||
const auto CreateOtherSortKey = [&](not_null<DocumentData*> document) {
|
||||
return CreateSortKey(document, 0);
|
||||
};
|
||||
const auto InstallDateAdjusted = [&](
|
||||
TimeId date,
|
||||
not_null<DocumentData*> document) {
|
||||
return (document->sticker() && document->sticker()->isAnimated())
|
||||
? date
|
||||
: date / 2;
|
||||
};
|
||||
const auto RecentInstallDate = [&](not_null<DocumentData*> document) {
|
||||
Expects(document->sticker() != nullptr);
|
||||
|
||||
const auto sticker = document->sticker();
|
||||
if (sticker->set.id) {
|
||||
const auto setIt = sets.find(sticker->set.id);
|
||||
if (setIt != sets.end()) {
|
||||
return InstallDateAdjusted(setIt->second->installDate, document);
|
||||
}
|
||||
}
|
||||
return TimeId(0);
|
||||
};
|
||||
|
||||
auto recentIt = sets.find(Stickers::CloudRecentSetId);
|
||||
if (recentIt != sets.cend()) {
|
||||
const auto recent = recentIt->second.get();
|
||||
const auto count = int(recent->stickers.size());
|
||||
result.reserve(count);
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto document = recent->stickers[i];
|
||||
auto index = i;
|
||||
if (!document->isPremiumSticker()) {
|
||||
continue;
|
||||
} else {
|
||||
index = recent->stickers.indexOf(document);
|
||||
}
|
||||
const auto usageDate = (recent->dates.empty() || index < 0)
|
||||
? 0
|
||||
: recent->dates[index];
|
||||
const auto date = usageDate
|
||||
? usageDate
|
||||
: RecentInstallDate(document);
|
||||
result.push_back({
|
||||
document,
|
||||
date ? date : CreateRecentSortKey(document) });
|
||||
}
|
||||
}
|
||||
const auto addList = [&](
|
||||
const StickersSetsOrder &order,
|
||||
SetFlag skip) {
|
||||
for (const auto setId : order) {
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend() || (it->second->flags & skip)) {
|
||||
continue;
|
||||
}
|
||||
const auto set = it->second.get();
|
||||
if (set->emoji.empty()) {
|
||||
setsToRequest.emplace(set->id, set->accessHash);
|
||||
set->flags |= SetFlag::NotLoaded;
|
||||
continue;
|
||||
}
|
||||
const auto my = (set->flags & SetFlag::Installed);
|
||||
result.reserve(result.size() + set->stickers.size());
|
||||
for (const auto document : set->stickers) {
|
||||
if (!document->isPremiumSticker()) {
|
||||
continue;
|
||||
}
|
||||
const auto installDate = my ? set->installDate : TimeId(0);
|
||||
const auto date = (installDate > 1)
|
||||
? InstallDateAdjusted(installDate, document)
|
||||
: my
|
||||
? CreateMySortKey(document)
|
||||
: CreateFeaturedSortKey(document);
|
||||
add(document, date);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
addList(setsOrder(), SetFlag::Archived);
|
||||
addList(featuredSetsOrder(), SetFlag::Installed);
|
||||
|
||||
if (!setsToRequest.empty()) {
|
||||
for (const auto &[setId, accessHash] : setsToRequest) {
|
||||
session().api().scheduleStickerSetRequest(setId, accessHash);
|
||||
}
|
||||
session().api().requestStickerSets();
|
||||
}
|
||||
|
||||
ranges::sort(result, std::greater<>(), &StickerWithDate::date);
|
||||
|
||||
return result
|
||||
| ranges::views::transform(&StickerWithDate::document)
|
||||
| ranges::to_vector;
|
||||
}
|
||||
|
||||
std::vector<not_null<DocumentData*>> Stickers::getListByEmoji(
|
||||
std::vector<EmojiPtr> emoji,
|
||||
uint64 seed,
|
||||
|
|
|
@ -235,6 +235,8 @@ public:
|
|||
const MTPmessages_FeaturedStickers &result);
|
||||
void gifsReceived(const QVector<MTPDocument> &items, uint64 hash);
|
||||
|
||||
[[nodiscard]] std::vector<not_null<DocumentData*>> getPremiumList(
|
||||
uint64 seed);
|
||||
[[nodiscard]] std::vector<not_null<DocumentData*>> getListByEmoji(
|
||||
std::vector<EmojiPtr> emoji,
|
||||
uint64 seed,
|
||||
|
|
|
@ -1519,6 +1519,8 @@ emojiListNotModified#481eadfa = EmojiList;
|
|||
emojiList#7a1e11d1 hash:long document_id:Vector<long> = EmojiList;
|
||||
|
||||
emojiGroup#7a9abda9 title:string icon_emoji_id:long emoticons:Vector<string> = EmojiGroup;
|
||||
emojiGroupGreeting#80d26cc7 title:string icon_emoji_id:long emoticons:Vector<string> = EmojiGroup;
|
||||
emojiGroupPremium#93bcf34 title:string icon_emoji_id:long = EmojiGroup;
|
||||
|
||||
messages.emojiGroupsNotModified#6fb4ad87 = messages.EmojiGroups;
|
||||
messages.emojiGroups#881fb94b hash:int groups:Vector<EmojiGroup> = messages.EmojiGroups;
|
||||
|
@ -1762,7 +1764,7 @@ channels.sponsoredMessageReportResultChooseOption#846f9e42 title:string options:
|
|||
channels.sponsoredMessageReportResultAdsHidden#3e3bcf2f = channels.SponsoredMessageReportResult;
|
||||
channels.sponsoredMessageReportResultReported#ad798849 = channels.SponsoredMessageReportResult;
|
||||
|
||||
stats.broadcastRevenueStats#d07b4bad top_hours_graph:StatsGraph revenue_graph:StatsGraph current_balance:long available_balance:long overall_revenue:long usd_rate:double = stats.BroadcastRevenueStats;
|
||||
stats.broadcastRevenueStats#5407e297 top_hours_graph:StatsGraph revenue_graph:StatsGraph balances:BroadcastRevenueBalances usd_rate:double = stats.BroadcastRevenueStats;
|
||||
|
||||
stats.broadcastRevenueWithdrawalUrl#ec659737 url:string = stats.BroadcastRevenueWithdrawalUrl;
|
||||
|
||||
|
@ -1777,6 +1779,8 @@ reactionNotificationsFromAll#4b9e22a0 = ReactionNotificationsFrom;
|
|||
|
||||
reactionsNotifySettings#56e34970 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings;
|
||||
|
||||
broadcastRevenueBalances#8438f1c6 current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
|
@ -2165,6 +2169,7 @@ messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vecto
|
|||
messages.deleteQuickReplyMessages#e105e910 shortcut_id:int id:Vector<int> = Updates;
|
||||
messages.toggleDialogFilterTags#fd2dda49 enabled:Bool = Bool;
|
||||
messages.getMyStickers#d0b5e1fc offset_id:long limit:int = messages.MyStickers;
|
||||
messages.getEmojiStickerGroups#1dd840f5 hash:int = messages.EmojiGroups;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
||||
|
|
|
@ -273,6 +273,11 @@ void GroupsStrip::fireChosenGroup() {
|
|||
|
||||
} // namespace
|
||||
|
||||
const QString &PremiumGroupFakeEmoticon() {
|
||||
static const auto result = u"*premium"_q;
|
||||
return result;
|
||||
}
|
||||
|
||||
SearchWithGroups::SearchWithGroups(
|
||||
QWidget *parent,
|
||||
SearchDescriptor descriptor)
|
||||
|
@ -359,7 +364,9 @@ void SearchWithGroups::initGroups() {
|
|||
widget->chosen(
|
||||
) | rpl::start_with_next([=](const GroupsStrip::Chosen &chosen) {
|
||||
_chosenGroup = chosen.group->iconId;
|
||||
_query = chosen.group->emoticons;
|
||||
_query = (chosen.group->type == EmojiGroupType::Premium)
|
||||
? std::vector{ PremiumGroupFakeEmoticon() }
|
||||
: chosen.group->emoticons;
|
||||
_debouncedQuery = chosen.group->emoticons;
|
||||
_debounceTimer.cancel();
|
||||
scrollGroupsToIcon(chosen.iconLeft, chosen.iconRight);
|
||||
|
|
|
@ -31,15 +31,24 @@ class RpWidget;
|
|||
template <typename Widget>
|
||||
class FadeWrap;
|
||||
|
||||
enum class EmojiGroupType {
|
||||
Normal,
|
||||
Greeting,
|
||||
Premium,
|
||||
};
|
||||
|
||||
struct EmojiGroup {
|
||||
QString iconId;
|
||||
std::vector<QString> emoticons;
|
||||
EmojiGroupType type = EmojiGroupType::Normal;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
const EmojiGroup &a,
|
||||
const EmojiGroup &b) = default;
|
||||
};
|
||||
|
||||
[[nodiscard]] const QString &PremiumGroupFakeEmoticon();
|
||||
|
||||
struct SearchDescriptor {
|
||||
const style::TabbedSearch &st;
|
||||
rpl::producer<std::vector<EmojiGroup>> groups;
|
||||
|
|
Loading…
Add table
Reference in a new issue