/* 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 "data/data_subscription_option.h" #include "mtproto/sender.h" class History; class ApiWrap; namespace Main { class Session; } // namespace Main namespace Payments { struct InvoicePremiumGiftCode; } // namespace Payments namespace Api { struct GiftCode { PeerId from = 0; PeerId to = 0; MsgId giveawayId = 0; TimeId date = 0; TimeId used = 0; // 0 if not used. int months = 0; bool giveaway = false; explicit operator bool() const { return months != 0; } friend inline bool operator==( const GiftCode&, const GiftCode&) = default; }; enum class GiveawayState { Invalid, Running, Preparing, Finished, Refunded, }; struct GiveawayInfo { QString giftCode; QString disallowedCountry; ChannelId adminChannelId = 0; GiveawayState state = GiveawayState::Invalid; TimeId tooEarlyDate = 0; TimeId finishDate = 0; TimeId startDate = 0; int winnersCount = 0; int activatedCount = 0; bool participating = false; explicit operator bool() const { return state != GiveawayState::Invalid; } }; class Premium final { public: explicit Premium(not_null api); void reload(); [[nodiscard]] rpl::producer statusTextValue() const; [[nodiscard]] auto videos() const -> const base::flat_map> &; [[nodiscard]] rpl::producer<> videosUpdated() const; [[nodiscard]] auto stickers() const -> const std::vector> &; [[nodiscard]] rpl::producer<> stickersUpdated() const; [[nodiscard]] auto cloudSet() const -> const std::vector> &; [[nodiscard]] rpl::producer<> cloudSetUpdated() const; [[nodiscard]] auto helloStickers() const -> const std::vector> &; [[nodiscard]] rpl::producer<> helloStickersUpdated() const; [[nodiscard]] int64 monthlyAmount() const; [[nodiscard]] QString monthlyCurrency() const; void checkGiftCode( const QString &slug, Fn done); GiftCode updateGiftCode(const QString &slug, const GiftCode &code); [[nodiscard]] rpl::producer giftCodeValue( const QString &slug) const; void applyGiftCode(const QString &slug, Fn done); void resolveGiveawayInfo( not_null peer, MsgId messageId, Fn done); [[nodiscard]] auto subscriptionOptions() const -> const Data::SubscriptionOptions &; [[nodiscard]] rpl::producer<> somePremiumRequiredResolved() const; void resolvePremiumRequired(not_null user); private: void reloadPromo(); void reloadStickers(); void reloadCloudSet(); void reloadHelloStickers(); void requestPremiumRequiredSlice(); const not_null _session; MTP::Sender _api; mtpRequestId _promoRequestId = 0; std::optional _statusText; rpl::event_stream _statusTextUpdates; base::flat_map> _videos; rpl::event_stream<> _videosUpdated; mtpRequestId _stickersRequestId = 0; uint64 _stickersHash = 0; std::vector> _stickers; rpl::event_stream<> _stickersUpdated; mtpRequestId _cloudSetRequestId = 0; uint64 _cloudSetHash = 0; std::vector> _cloudSet; rpl::event_stream<> _cloudSetUpdated; mtpRequestId _helloStickersRequestId = 0; uint64 _helloStickersHash = 0; std::vector> _helloStickers; rpl::event_stream<> _helloStickersUpdated; int64 _monthlyAmount = 0; QString _monthlyCurrency; mtpRequestId _giftCodeRequestId = 0; QString _giftCodeSlug; base::flat_map _giftCodes; rpl::event_stream _giftCodeUpdated; mtpRequestId _giveawayInfoRequestId = 0; PeerData *_giveawayInfoPeer = nullptr; MsgId _giveawayInfoMessageId = 0; Fn _giveawayInfoDone; Data::SubscriptionOptions _subscriptionOptions; rpl::event_stream<> _somePremiumRequiredResolved; base::flat_set> _resolvePremiumRequiredUsers; base::flat_set> _resolvePremiumRequestedUsers; bool _premiumRequiredRequestScheduled = false; }; class PremiumGiftCodeOptions final { public: PremiumGiftCodeOptions(not_null peer); [[nodiscard]] rpl::producer request(); [[nodiscard]] Data::SubscriptionOptions options(int amount); [[nodiscard]] const std::vector &availablePresets() const; [[nodiscard]] int monthsFromPreset(int monthsIndex); [[nodiscard]] Payments::InvoicePremiumGiftCode invoice( int users, int months); [[nodiscard]] rpl::producer applyPrepaid( const Payments::InvoicePremiumGiftCode &invoice, uint64 prepaidId); [[nodiscard]] int giveawayBoostsPerPremium() const; [[nodiscard]] int giveawayCountriesMax() const; [[nodiscard]] int giveawayAddPeersMax() const; [[nodiscard]] int giveawayPeriodMax() const; [[nodiscard]] bool giveawayGiftsPurchaseAvailable() const; private: struct Token final { int users = 0; int months = 0; friend inline constexpr auto operator<=>(Token, Token) = default; }; struct Store final { uint64 amount = 0; QString product; int quantity = 0; }; using Amount = int; const not_null _peer; base::flat_map _subscriptionOptions; struct { std::vector months; std::vector totalCosts; QString currency; } _optionsForOnePerson; std::vector _availablePresets; base::flat_map _stores; MTP::Sender _api; }; enum class RequirePremiumState { Unknown, Yes, No, }; [[nodiscard]] RequirePremiumState ResolveRequiresPremiumToWrite( not_null peer, History *maybeHistory); [[nodiscard]] rpl::producer RandomHelloStickerValue( not_null session); } // namespace Api