2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Added support of custom promo suggestions.

This commit is contained in:
23rd
2025-05-06 12:13:55 +03:00
parent c2e887a86e
commit 197f6b05ae
5 changed files with 83 additions and 7 deletions

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/components/promo_suggestions.h"
#include "api/api_text_entities.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "core/application.h"
@@ -23,6 +24,19 @@ namespace {
constexpr auto kTopPromotionInterval = TimeId(60 * 60);
constexpr auto kTopPromotionMinDelay = TimeId(10);
[[nodiscard]] CustomSuggestion CustomFromTL(
not_null<Main::Session*> session,
const MTPPendingSuggestion &r) {
return CustomSuggestion({
.suggestion = qs(r.data().vsuggestion()),
.title = Api::ParseTextWithEntities(session, r.data().vtitle()),
.description = Api::ParseTextWithEntities(
session,
r.data().vdescription()),
.url = qs(r.data().vurl()),
});
}
} // namespace
PromoSuggestions::PromoSuggestions(not_null<Main::Session*> session)
@@ -112,10 +126,6 @@ void PromoSuggestions::topPromotionDone(const MTPhelp_PromoData &proxy) {
|= _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);
@@ -126,6 +136,22 @@ void PromoSuggestions::topPromotionDone(const MTPhelp_PromoData &proxy) {
} else {
setTopPromoted(nullptr, QString(), QString());
}
auto changedCustom = false;
auto custom = data.vcustom_pending_suggestion()
? std::make_optional(
CustomFromTL(_session, *data.vcustom_pending_suggestion()))
: std::nullopt;
if (_custom != custom) {
_custom = std::move(custom);
changedCustom = true;
}
if (changedPendingSuggestions
|| changedDismissedSuggestions
|| changedCustom) {
_refreshed.fire({});
}
});
}
@@ -194,4 +220,16 @@ void PromoSuggestions::dismiss(const QString &key) {
)).send();
}
void PromoSuggestions::invalidate() {
if (_topPromotionRequestId) {
_session->api().request(_topPromotionRequestId).cancel();
}
_topPromotionNextRequestTime = 0;
_topPromotionTimer.callOnce(crl::time(200));
}
std::optional<CustomSuggestion> PromoSuggestions::custom() const {
return _custom;
}
} // namespace Data

View File

@@ -17,18 +17,31 @@ class Session;
namespace Data {
struct CustomSuggestion final {
QString suggestion;
TextWithEntities title;
TextWithEntities description;
QString url;
friend inline auto operator<=>(
const CustomSuggestion &,
const CustomSuggestion &) = default;
};
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;
[[nodiscard]] std::optional<CustomSuggestion> custom() const;
[[nodiscard]] rpl::producer<> requested(const QString &key) const;
void dismiss(const QString &key);
void refreshTopPromotion();
void invalidate();
rpl::producer<> value() const;
// Create rpl::producer<> refreshed() const; on memand.
@@ -44,6 +57,7 @@ private:
const not_null<Main::Session*> _session;
base::flat_set<QString> _dismissedSuggestions;
std::vector<QString> _pendingSuggestions;
std::optional<CustomSuggestion> _custom;
History *_topPromoted = nullptr;