| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- 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/credits.h"
- #include "api/api_credits.h"
- #include "data/data_user.h"
- #include "main/main_app_config.h"
- #include "main/main_session.h"
- namespace Data {
- namespace {
- constexpr auto kReloadThreshold = 60 * crl::time(1000);
- } // namespace
- StarsAmount FromTL(const MTPStarsAmount &value) {
- const auto &data = value.data();
- return StarsAmount(data.vamount().v, data.vnanos().v);
- }
- Credits::Credits(not_null<Main::Session*> session)
- : _session(session)
- , _reload([=] { load(true); }) {
- }
- Credits::~Credits() = default;
- void Credits::apply(const MTPDupdateStarsBalance &data) {
- apply(FromTL(data.vbalance()));
- }
- rpl::producer<float64> Credits::rateValue(
- not_null<PeerData*> ownedBotOrChannel) {
- return rpl::single(_session->appConfig().starsWithdrawRate());
- }
- void Credits::load(bool force) {
- if (_loader
- || (!force
- && _lastLoaded
- && _lastLoaded + kReloadThreshold > crl::now())) {
- return;
- }
- _loader = std::make_unique<Api::CreditsStatus>(_session->user());
- _loader->request({}, [=](Data::CreditsStatusSlice slice) {
- _loader = nullptr;
- apply(slice.balance);
- });
- }
- bool Credits::loaded() const {
- return _lastLoaded != 0;
- }
- rpl::producer<bool> Credits::loadedValue() const {
- if (loaded()) {
- return rpl::single(true);
- }
- return rpl::single(
- false
- ) | rpl::then(_loadedChanges.events() | rpl::map_to(true));
- }
- StarsAmount Credits::balance() const {
- return _nonLockedBalance.current();
- }
- StarsAmount Credits::balance(PeerId peerId) const {
- const auto it = _cachedPeerBalances.find(peerId);
- return (it != _cachedPeerBalances.end()) ? it->second : StarsAmount();
- }
- uint64 Credits::balanceCurrency(PeerId peerId) const {
- const auto it = _cachedPeerCurrencyBalances.find(peerId);
- return (it != _cachedPeerCurrencyBalances.end()) ? it->second : 0;
- }
- rpl::producer<StarsAmount> Credits::balanceValue() const {
- return _nonLockedBalance.value();
- }
- void Credits::updateNonLockedValue() {
- _nonLockedBalance = (_balance >= _locked)
- ? (_balance - _locked)
- : StarsAmount();
- }
- void Credits::lock(StarsAmount count) {
- Expects(loaded());
- Expects(count >= StarsAmount(0));
- Expects(_locked + count <= _balance);
- _locked += count;
- updateNonLockedValue();
- }
- void Credits::unlock(StarsAmount count) {
- Expects(count >= StarsAmount(0));
- Expects(_locked >= count);
- _locked -= count;
- updateNonLockedValue();
- }
- void Credits::withdrawLocked(StarsAmount count) {
- Expects(count >= StarsAmount(0));
- Expects(_locked >= count);
- _locked -= count;
- apply(_balance >= count ? (_balance - count) : StarsAmount(0));
- invalidate();
- }
- void Credits::invalidate() {
- _reload.call();
- }
- void Credits::apply(StarsAmount balance) {
- _balance = balance;
- updateNonLockedValue();
- const auto was = std::exchange(_lastLoaded, crl::now());
- if (!was) {
- _loadedChanges.fire({});
- }
- }
- void Credits::apply(PeerId peerId, StarsAmount balance) {
- _cachedPeerBalances[peerId] = balance;
- }
- void Credits::applyCurrency(PeerId peerId, uint64 balance) {
- _cachedPeerCurrencyBalances[peerId] = balance;
- }
- } // namespace Data
|