Moved out top promo from api and suggestions from config to single file.

This commit is contained in:
23rd 2025-05-06 11:11:45 +03:00
parent dc1459438c
commit c2e887a86e
13 changed files with 288 additions and 205 deletions

View file

@ -501,6 +501,8 @@ PRIVATE
data/components/factchecks.h
data/components/location_pickers.cpp
data/components/location_pickers.h
data/components/promo_suggestions.cpp
data/components/promo_suggestions.h
data/components/recent_peers.cpp
data/components/recent_peers.h
data/components/scheduled_messages.cpp

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_global_privacy.h"
#include "apiwrap.h"
#include "data/components/promo_suggestions.h"
#include "data/data_user.h"
#include "main/main_session.h"
#include "main/main_app_config.h"
@ -101,13 +102,11 @@ rpl::producer<bool> GlobalPrivacy::showArchiveAndMute() const {
}
rpl::producer<> GlobalPrivacy::suggestArchiveAndMute() const {
return _session->appConfig().suggestionRequested(
u"AUTOARCHIVE_POPULAR"_q);
return _session->promoSuggestions().requested(u"AUTOARCHIVE_POPULAR"_q);
}
void GlobalPrivacy::dismissArchiveAndMuteSuggestion() {
_session->appConfig().dismissSuggestion(
u"AUTOARCHIVE_POPULAR"_q);
_session->promoSuggestions().dismiss(u"AUTOARCHIVE_POPULAR"_q);
}
void GlobalPrivacy::updateHideReadTime(bool hide) {

View file

@ -91,8 +91,6 @@ namespace {
// Save draft to the cloud with 1 sec extra delay.
constexpr auto kSaveCloudDraftTimeout = 1000;
constexpr auto kTopPromotionInterval = TimeId(60 * 60);
constexpr auto kTopPromotionMinDelay = TimeId(10);
constexpr auto kSmallDelayMs = 5;
constexpr auto kReadFeaturedSetsTimeout = crl::time(1000);
constexpr auto kFileLoaderQueueStopTimeout = crl::time(5000);
@ -163,7 +161,6 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _featuredSetsReadTimer([=] { readFeaturedSets(); })
, _dialogsLoadState(std::make_unique<DialogsLoadState>())
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
, _topPromotionTimer([=] { refreshTopPromotion(); })
, _updateNotifyTimer([=] { sendNotifySettingsUpdates(); })
, _statsSessionKillTimer([=] { checkStatsSessions(); })
, _authorizations(std::make_unique<Api::Authorizations>(this))
@ -199,11 +196,6 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
}, _session->lifetime());
setupSupportMode();
Core::App().settings().proxy().connectionTypeValue(
) | rpl::start_with_next([=] {
refreshTopPromotion();
}, _session->lifetime());
});
}
@ -243,77 +235,6 @@ void ApiWrap::requestChangelog(
//).send();
}
void ApiWrap::refreshTopPromotion() {
const auto now = base::unixtime::now();
const auto next = (_topPromotionNextRequestTime != 0)
? _topPromotionNextRequestTime
: now;
if (_topPromotionRequestId) {
getTopPromotionDelayed(now, next);
return;
}
const auto key = [&]() -> std::pair<QString, uint32> {
if (!Core::App().settings().proxy().isEnabled()) {
return {};
}
const auto &proxy = Core::App().settings().proxy().selected();
if (proxy.type != MTP::ProxyData::Type::Mtproto) {
return {};
}
return { proxy.host, proxy.port };
}();
if (_topPromotionKey == key && now < next) {
getTopPromotionDelayed(now, next);
return;
}
_topPromotionKey = key;
_topPromotionRequestId = request(MTPhelp_GetPromoData(
)).done([=](const MTPhelp_PromoData &result) {
_topPromotionRequestId = 0;
topPromotionDone(result);
}).fail([=] {
_topPromotionRequestId = 0;
const auto now = base::unixtime::now();
const auto next = _topPromotionNextRequestTime = now
+ kTopPromotionInterval;
if (!_topPromotionTimer.isActive()) {
getTopPromotionDelayed(now, next);
}
}).send();
}
void ApiWrap::getTopPromotionDelayed(TimeId now, TimeId next) {
_topPromotionTimer.callOnce(std::min(
std::max(next - now, kTopPromotionMinDelay),
kTopPromotionInterval) * crl::time(1000));
};
void ApiWrap::topPromotionDone(const MTPhelp_PromoData &proxy) {
_topPromotionNextRequestTime = proxy.match([&](const auto &data) {
return data.vexpires().v;
});
getTopPromotionDelayed(
base::unixtime::now(),
_topPromotionNextRequestTime);
proxy.match([&](const MTPDhelp_promoDataEmpty &data) {
_session->data().setTopPromoted(nullptr, QString(), QString());
}, [&](const MTPDhelp_promoData &data) {
_session->data().processChats(data.vchats());
_session->data().processUsers(data.vusers());
if (const auto peer = data.vpeer()) {
const auto peerId = peerFromMTP(*peer);
const auto history = _session->data().history(peerId);
_session->data().setTopPromoted(
history,
data.vpsa_type().value_or_empty(),
data.vpsa_message().value_or_empty());
} else {
_session->data().setTopPromoted(nullptr, QString(), QString());
}
});
}
void ApiWrap::requestDeepLinkInfo(
const QString &path,
Fn<void(TextWithEntities message, bool updateRequired)> callback) {

View file

@ -200,7 +200,6 @@ public:
void requestChangelog(
const QString &sinceVersion,
Fn<void(const MTPUpdates &result)> callback);
void refreshTopPromotion();
void requestDeepLinkInfo(
const QString &path,
Fn<void(TextWithEntities message, bool updateRequired)> callback);
@ -569,9 +568,6 @@ private:
not_null<SendingAlbum*> album,
Fn<void(bool)> done = nullptr);
void getTopPromotionDelayed(TimeId now, TimeId next);
void topPromotionDone(const MTPhelp_PromoData &proxy);
void sendNotifySettingsUpdates();
template <typename Request>
@ -709,11 +705,6 @@ private:
std::unique_ptr<TaskQueue> _fileLoader;
base::flat_map<uint64, std::shared_ptr<SendingAlbum>> _sendingAlbums;
mtpRequestId _topPromotionRequestId = 0;
std::pair<QString, uint32> _topPromotionKey;
TimeId _topPromotionNextRequestTime = TimeId(0);
base::Timer _topPromotionTimer;
base::flat_set<not_null<const Data::ForumTopic*>> _updateNotifyTopics;
base::flat_set<not_null<const PeerData*>> _updateNotifyPeers;
base::flat_set<Data::DefaultNotify> _updateNotifyDefaults;

View file

@ -0,0 +1,197 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/components/promo_suggestions.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "data/data_changes.h"
#include "data/data_histories.h"
#include "data/data_session.h"
#include "history/history.h"
#include "main/main_session.h"
namespace Data {
namespace {
constexpr auto kTopPromotionInterval = TimeId(60 * 60);
constexpr auto kTopPromotionMinDelay = TimeId(10);
} // namespace
PromoSuggestions::PromoSuggestions(not_null<Main::Session*> session)
: _session(session)
, _topPromotionTimer([=] { refreshTopPromotion(); }) {
Core::App().settings().proxy().connectionTypeValue(
) | rpl::start_with_next([=] {
refreshTopPromotion();
}, _lifetime);
}
PromoSuggestions::~PromoSuggestions() = default;
void PromoSuggestions::refreshTopPromotion() {
const auto now = base::unixtime::now();
const auto next = (_topPromotionNextRequestTime != 0)
? _topPromotionNextRequestTime
: now;
if (_topPromotionRequestId) {
getTopPromotionDelayed(now, next);
return;
}
const auto key = [&]() -> std::pair<QString, uint32> {
if (!Core::App().settings().proxy().isEnabled()) {
return {};
}
const auto &proxy = Core::App().settings().proxy().selected();
if (proxy.type != MTP::ProxyData::Type::Mtproto) {
return {};
}
return { proxy.host, proxy.port };
}();
if (_topPromotionKey == key && now < next) {
getTopPromotionDelayed(now, next);
return;
}
_topPromotionKey = key;
_topPromotionRequestId = _session->api().request(MTPhelp_GetPromoData(
)).done([=](const MTPhelp_PromoData &result) {
_topPromotionRequestId = 0;
topPromotionDone(result);
}).fail([=] {
_topPromotionRequestId = 0;
const auto now = base::unixtime::now();
const auto next = _topPromotionNextRequestTime = now
+ kTopPromotionInterval;
if (!_topPromotionTimer.isActive()) {
getTopPromotionDelayed(now, next);
}
}).send();
}
void PromoSuggestions::getTopPromotionDelayed(TimeId now, TimeId next) {
_topPromotionTimer.callOnce(std::min(
std::max(next - now, kTopPromotionMinDelay),
kTopPromotionInterval) * crl::time(1000));
};
void PromoSuggestions::topPromotionDone(const MTPhelp_PromoData &proxy) {
_topPromotionNextRequestTime = proxy.match([&](const auto &data) {
return data.vexpires().v;
});
getTopPromotionDelayed(
base::unixtime::now(),
_topPromotionNextRequestTime);
proxy.match([&](const MTPDhelp_promoDataEmpty &data) {
setTopPromoted(nullptr, QString(), QString());
}, [&](const MTPDhelp_promoData &data) {
_session->data().processChats(data.vchats());
_session->data().processUsers(data.vusers());
auto changedPendingSuggestions = false;
auto pendingSuggestions = ranges::views::all(
data.vpending_suggestions().v
) | ranges::views::transform([](const auto &suggestion) {
return qs(suggestion);
}) | ranges::to_vector;
if (!ranges::equal(_pendingSuggestions, pendingSuggestions)) {
_pendingSuggestions = std::move(pendingSuggestions);
changedPendingSuggestions = true;
}
auto changedDismissedSuggestions = false;
for (const auto &suggestion : data.vdismissed_suggestions().v) {
changedDismissedSuggestions
|= _dismissedSuggestions.emplace(qs(suggestion)).second;
}
if (changedPendingSuggestions || changedDismissedSuggestions) {
_refreshed.fire({});
}
if (const auto peer = data.vpeer()) {
const auto peerId = peerFromMTP(*peer);
const auto history = _session->data().history(peerId);
setTopPromoted(
history,
data.vpsa_type().value_or_empty(),
data.vpsa_message().value_or_empty());
} else {
setTopPromoted(nullptr, QString(), QString());
}
});
}
rpl::producer<> PromoSuggestions::value() const {
return _refreshed.events_starting_with({});
}
void PromoSuggestions::setTopPromoted(
History *promoted,
const QString &type,
const QString &message) {
const auto changed = (_topPromoted != promoted);
if (!changed
&& (!promoted || promoted->topPromotionMessage() == message)) {
return;
}
if (changed) {
if (_topPromoted) {
_topPromoted->cacheTopPromotion(false, QString(), QString());
}
}
const auto old = std::exchange(_topPromoted, promoted);
if (_topPromoted) {
_session->data().histories().requestDialogEntry(_topPromoted);
_topPromoted->cacheTopPromotion(true, type, message);
_topPromoted->requestChatListMessage();
_session->changes().historyUpdated(
_topPromoted,
HistoryUpdate::Flag::TopPromoted);
}
if (changed && old) {
_session->changes().historyUpdated(
old,
HistoryUpdate::Flag::TopPromoted);
}
}
bool PromoSuggestions::current(const QString &key) const {
if (key == u"BIRTHDAY_CONTACTS_TODAY"_q) {
if (_dismissedSuggestions.contains(key)) {
return false;
} else {
const auto known
= _session->data().knownBirthdaysToday();
if (!known) {
return true;
}
return !known->empty();
}
}
return !_dismissedSuggestions.contains(key)
&& ranges::contains(_pendingSuggestions, key);
}
rpl::producer<> PromoSuggestions::requested(const QString &key) const {
return value() | rpl::filter([=] { return current(key); });
}
void PromoSuggestions::dismiss(const QString &key) {
if (!_dismissedSuggestions.emplace(key).second) {
return;
}
_session->api().request(MTPhelp_DismissSuggestion(
MTP_inputPeerEmpty(),
MTP_string(key)
)).send();
}
} // namespace Data

View file

@ -0,0 +1,61 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/timer.h"
class History;
namespace Main {
class Session;
} // namespace Main
namespace Data {
class PromoSuggestions final {
public:
explicit PromoSuggestions(not_null<Main::Session*> session);
~PromoSuggestions();
[[nodiscard]] bool current(const QString &key) const;
[[nodiscard]] rpl::producer<> requested(
const QString &key) const;
void dismiss(const QString &key);
void refreshTopPromotion();
rpl::producer<> value() const;
// Create rpl::producer<> refreshed() const; on memand.
private:
void setTopPromoted(
History *promoted,
const QString &type,
const QString &message);
void getTopPromotionDelayed(TimeId now, TimeId next);
void topPromotionDone(const MTPhelp_PromoData &proxy);
const not_null<Main::Session*> _session;
base::flat_set<QString> _dismissedSuggestions;
std::vector<QString> _pendingSuggestions;
History *_topPromoted = nullptr;
mtpRequestId _topPromotionRequestId = 0;
std::pair<QString, uint32> _topPromotionKey;
TimeId _topPromotionNextRequestTime = TimeId(0);
base::Timer _topPromotionTimer;
rpl::event_stream<> _refreshed;
rpl::lifetime _lifetime;
};
} // namespace Data

View file

@ -4807,36 +4807,6 @@ MessageIdsList Session::takeMimeForwardIds() {
return std::move(_mimeForwardIds);
}
void Session::setTopPromoted(
History *promoted,
const QString &type,
const QString &message) {
const auto changed = (_topPromoted != promoted);
if (!changed
&& (!promoted || promoted->topPromotionMessage() == message)) {
return;
}
if (changed) {
if (_topPromoted) {
_topPromoted->cacheTopPromotion(false, QString(), QString());
}
}
const auto old = std::exchange(_topPromoted, promoted);
if (_topPromoted) {
histories().requestDialogEntry(_topPromoted);
_topPromoted->cacheTopPromotion(true, type, message);
_topPromoted->requestChatListMessage();
session().changes().historyUpdated(
_topPromoted,
HistoryUpdate::Flag::TopPromoted);
}
if (changed && old) {
session().changes().historyUpdated(
old,
HistoryUpdate::Flag::TopPromoted);
}
}
bool Session::updateWallpapers(const MTPaccount_WallPapers &data) {
return data.match([&](const MTPDaccount_wallPapers &data) {
setWallpapers(data.vwallpapers().v, data.vhash().v);

View file

@ -801,11 +801,6 @@ public:
void setMimeForwardIds(MessageIdsList &&list);
MessageIdsList takeMimeForwardIds();
void setTopPromoted(
History *promoted,
const QString &type,
const QString &message);
bool updateWallpapers(const MTPaccount_WallPapers &data);
void removeWallpaper(const WallPaper &paper);
const std::vector<WallPaper> &wallpapers() const;
@ -1129,8 +1124,6 @@ private:
ReactionId,
base::flat_set<not_null<ViewElement*>>> _viewsByTag;
History *_topPromoted = nullptr;
std::unordered_map<PeerId, std::unique_ptr<PeerData>> _peers;
MessageIdsList _mimeForwardIds;

View file

@ -23,7 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_group_call_bar.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "data/components/promo_suggestions.h"
#include "main/main_session.h"
#include "settings/settings_credits_graphics.h"
#include "settings/settings_premium.h"
@ -120,9 +120,9 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
const auto content = state->content;
const auto wrap = state->wrap;
using RightIcon = TopBarSuggestionContent::RightIcon;
const auto config = &session->appConfig();
const auto promo = &session->promoSuggestions();
if (session->premiumCanBuy()
&& config->suggestionCurrent(kSugPremiumGrace.utf8())) {
&& promo->current(kSugPremiumGrace.utf8())) {
content->setRightIcon(RightIcon::Close);
content->setClickedCallback([=] {
const auto controller = FindSessionController(parent);
@ -133,7 +133,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
}));
});
content->setHideCallback([=] {
config->dismissSuggestion(kSugPremiumGrace.utf8());
promo->dismiss(kSugPremiumGrace.utf8());
repeat(repeat);
});
content->setContent(
@ -147,7 +147,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
Toggle{ true, anim::type::normal });
return;
} else if (session->premiumCanBuy()
&& config->suggestionCurrent(kSugLowCreditsSubs.utf8())) {
&& promo->current(kSugLowCreditsSubs.utf8())) {
state->creditsHistory = std::make_unique<Api::CreditsHistory>(
session->user(),
false,
@ -165,13 +165,12 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
needed,
Settings::SmallBalanceSubscription{ peers },
[=] {
config->dismissSuggestion(
kSugLowCreditsSubs.utf8());
promo->dismiss(kSugLowCreditsSubs.utf8());
repeat(repeat);
}));
});
content->setHideCallback([=] {
config->dismissSuggestion(kSugLowCreditsSubs.utf8());
promo->dismiss(kSugLowCreditsSubs.utf8());
repeat(repeat);
});
content->setContent(
@ -219,7 +218,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
return;
} else if (session->premiumCanBuy()
&& config->suggestionCurrent(kSugBirthdayContacts.utf8())) {
&& promo->current(kSugBirthdayContacts.utf8())) {
session->data().contactBirthdays(
) | rpl::start_with_next(crl::guard(content, [=] {
const auto users = session->data()
@ -242,8 +241,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
}
});
content->setHideCallback([=] {
config->dismissSuggestion(
kSugBirthdayContacts.utf8());
promo->dismiss(kSugBirthdayContacts.utf8());
controller->showToast(
tr::lng_dialogs_suggestions_birthday_contact_dismiss(
tr::now));
@ -351,7 +349,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
Toggle{ true, anim::type::normal });
}), state->giftsLifetime);
return;
} else if (config->suggestionCurrent(kSugSetBirthday.utf8())
} else if (promo->current(kSugSetBirthday.utf8())
&& !Data::IsBirthdayToday(session->user()->birthday())) {
content->setRightIcon(RightIcon::Close);
content->setClickedCallback([=] {
@ -373,7 +371,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
});
});
content->setHideCallback([=] {
config->dismissSuggestion(kSugSetBirthday.utf8());
promo->dismiss(kSugSetBirthday.utf8());
repeat(repeat);
});
content->setContent(
@ -387,13 +385,13 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
Toggle{ true, anim::type::normal });
return;
} else if (session->premiumPossible() && !session->premium()) {
const auto isPremiumAnnual = config->suggestionCurrent(
const auto isPremiumAnnual = promo->current(
kSugPremiumAnnual.utf8());
const auto isPremiumRestore = !isPremiumAnnual
&& config->suggestionCurrent(kSugPremiumRestore.utf8());
&& promo->current(kSugPremiumRestore.utf8());
const auto isPremiumUpgrade = !isPremiumAnnual
&& !isPremiumRestore
&& config->suggestionCurrent(kSugPremiumUpgrade.utf8());
&& promo->current(kSugPremiumUpgrade.utf8());
const auto set = [=](QString discount) {
constexpr auto kMinus = QChar(0x2212);
const auto &title = isPremiumAnnual
@ -416,7 +414,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
content->setClickedCallback([=] {
const auto controller = FindSessionController(parent);
Settings::ShowPremium(controller, "dialogs_hint");
config->dismissSuggestion(isPremiumAnnual
promo->dismiss(isPremiumAnnual
? kSugPremiumAnnual.utf8()
: isPremiumRestore
? kSugPremiumRestore.utf8()
@ -442,7 +440,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
return;
}
}
if (config->suggestionCurrent(kSugSetUserpic.utf8())
if (promo->current(kSugSetUserpic.utf8())
&& !session->user()->userpicPhotoId()) {
const auto controller = FindSessionController(parent);
content->setRightIcon(RightIcon::Close);
@ -484,7 +482,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
});
content->setHideCallback([=] {
config->dismissSuggestion(kSugSetUserpic.utf8());
promo->dismiss(kSugSetUserpic.utf8());
repeat(repeat);
});
@ -541,7 +539,7 @@ rpl::producer<Ui::SlideWrap<Ui::RpWidget>*> TopBarSuggestionValue(
(was == now) ? toggle.type : anim::type::instant);
}, lifetime);
session->appConfig().value() | rpl::start_with_next([=] {
session->promoSuggestions().value() | rpl::start_with_next([=] {
const auto was = state->wrap;
processCurrentSuggestion(processCurrentSuggestion);
if (was != state->wrap) {

View file

@ -170,15 +170,6 @@ void AppConfig::refresh(bool force) {
}
updateIgnoredRestrictionReasons(std::move(was));
{
const auto dismissedSuggestions = get<std::vector<QString>>(
u"dismissed_suggestions"_q,
std::vector<QString>());
for (const auto &suggestion : dismissedSuggestions) {
_dismissedSuggestions.emplace(suggestion);
}
}
DEBUG_LOG(("getAppConfig result handled."));
_refreshed.fire({});
}, [](const MTPDhelp_appConfigNotModified &) {});
@ -331,47 +322,6 @@ std::vector<int> AppConfig::getIntArray(
});
}
bool AppConfig::suggestionCurrent(const QString &key) const {
if (key == u"BIRTHDAY_CONTACTS_TODAY"_q) {
if (_dismissedSuggestions.contains(key)
|| !_account->sessionExists()) {
return false;
} else {
const auto known
= _account->session().data().knownBirthdaysToday();
if (!known) {
return true;
}
return !known->empty();
}
}
return !_dismissedSuggestions.contains(key)
&& ranges::contains(
get<std::vector<QString>>(
u"pending_suggestions"_q,
std::vector<QString>()),
key);
}
rpl::producer<> AppConfig::suggestionRequested(const QString &key) const {
return value(
) | rpl::filter([=] {
return suggestionCurrent(key);
});
}
void AppConfig::dismissSuggestion(const QString &key) {
Expects(_api.has_value());
if (!_dismissedSuggestions.emplace(key).second) {
return;
}
_api->request(MTPhelp_DismissSuggestion(
MTP_inputPeerEmpty(),
MTP_string(key)
)).send();
}
bool AppConfig::newRequirePremiumFree() const {
return get<bool>(
u"new_noncontact_peers_require_premium_without_ownpremium"_q,

View file

@ -48,11 +48,6 @@ public:
[[nodiscard]] rpl::producer<> refreshed() const;
[[nodiscard]] rpl::producer<> value() const;
[[nodiscard]] bool suggestionCurrent(const QString &key) const;
[[nodiscard]] rpl::producer<> suggestionRequested(
const QString &key) const;
void dismissSuggestion(const QString &key);
[[nodiscard]] bool newRequirePremiumFree() const;
[[nodiscard]] auto ignoredRestrictionReasons() const
@ -125,7 +120,6 @@ private:
bool _pendingRefresh = false;
base::flat_map<QString, MTPJSONValue> _data;
rpl::event_stream<> _refreshed;
base::flat_set<QString> _dismissedSuggestions;
std::vector<QString> _ignoreRestrictionReasons;
rpl::event_stream<std::vector<QString>> _ignoreRestrictionChanges;

View file

@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/components/credits.h"
#include "data/components/factchecks.h"
#include "data/components/location_pickers.h"
#include "data/components/promo_suggestions.h"
#include "data/components/recent_peers.h"
#include "data/components/scheduled_messages.h"
#include "data/components/sponsored_messages.h"
@ -117,6 +118,7 @@ Session::Session(
, _factchecks(std::make_unique<Data::Factchecks>(this))
, _locationPickers(std::make_unique<Data::LocationPickers>())
, _credits(std::make_unique<Data::Credits>(this))
, _promoSuggestions(std::make_unique<Data::PromoSuggestions>(this))
, _cachedReactionIconFactory(std::make_unique<ReactionIconFactory>())
, _supportHelper(Support::Helper::Create(this))
, _fastButtonsBots(std::make_unique<Support::FastButtonsBots>(this))

View file

@ -39,6 +39,7 @@ class TopPeers;
class Factchecks;
class LocationPickers;
class Credits;
class PromoSuggestions;
} // namespace Data
namespace HistoryView::Reactions {
@ -189,6 +190,9 @@ public:
[[nodiscard]] InlineBots::AttachWebView &attachWebView() const {
return *_attachWebView;
}
[[nodiscard]] Data::PromoSuggestions &promoSuggestions() const {
return *_promoSuggestions;
}
[[nodiscard]] auto cachedReactionIconFactory() const
-> HistoryView::Reactions::CachedIconFactory & {
return *_cachedReactionIconFactory;
@ -290,6 +294,7 @@ private:
const std::unique_ptr<Data::Factchecks> _factchecks;
const std::unique_ptr<Data::LocationPickers> _locationPickers;
const std::unique_ptr<Data::Credits> _credits;
const std::unique_ptr<Data::PromoSuggestions> _promoSuggestions;
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
const std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;