diff --git a/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift b/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift index 09cf65e4c7..eb19271570 100644 --- a/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift +++ b/submodules/TelegramCore/Sources/Statistics/StarsRevenueStatistics.swift @@ -4,13 +4,65 @@ import Postbox import TelegramApi import MtProtoKit -public struct StarsRevenueStats: Equatable { - public struct Balances: Equatable { +public struct StarsRevenueStats: Equatable, Codable { + private enum CodingKeys: String, CodingKey { + case revenueGraph + case balances + case usdRate + } + + static func key(peerId: PeerId) -> ValueBoxKey { + let key = ValueBoxKey(length: 8 + 4) + key.setInt64(0, value: peerId.toInt64()) + return key + } + + public struct Balances: Equatable, Codable { + private enum CodingKeys: String, CodingKey { + case currentBalance + case availableBalance + case overallRevenue + case withdrawEnabled + case nextWithdrawalTimestamp + } + public let currentBalance: Int64 public let availableBalance: Int64 public let overallRevenue: Int64 public let withdrawEnabled: Bool public let nextWithdrawalTimestamp: Int32? + + public init( + currentBalance: Int64, + availableBalance: Int64, + overallRevenue: Int64, + withdrawEnabled: Bool, + nextWithdrawalTimestamp: Int32? + ) { + self.currentBalance = currentBalance + self.availableBalance = availableBalance + self.overallRevenue = overallRevenue + self.withdrawEnabled = withdrawEnabled + self.nextWithdrawalTimestamp = nextWithdrawalTimestamp + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.currentBalance = try container.decode(Int64.self, forKey: .currentBalance) + self.availableBalance = try container.decode(Int64.self, forKey: .availableBalance) + self.overallRevenue = try container.decode(Int64.self, forKey: .overallRevenue) + self.withdrawEnabled = try container.decode(Bool.self, forKey: .withdrawEnabled) + self.nextWithdrawalTimestamp = try container.decodeIfPresent(Int32.self, forKey: .nextWithdrawalTimestamp) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(self.currentBalance, forKey: .currentBalance) + try container.encode(self.availableBalance, forKey: .availableBalance) + try container.encode(self.overallRevenue, forKey: .overallRevenue) + try container.encode(self.withdrawEnabled, forKey: .withdrawEnabled) + try container.encodeIfPresent(self.nextWithdrawalTimestamp, forKey: .nextWithdrawalTimestamp) + } } public let revenueGraph: StatsGraph @@ -23,6 +75,20 @@ public struct StarsRevenueStats: Equatable { self.usdRate = usdRate } + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.revenueGraph = try container.decode(StatsGraph.self, forKey: .revenueGraph) + self.balances = try container.decode(Balances.self, forKey: .balances) + self.usdRate = try container.decode(Double.self, forKey: .usdRate) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(self.revenueGraph, forKey: .revenueGraph) + try container.encode(self.balances, forKey: .balances) + try container.encode(self.usdRate, forKey: .usdRate) + } + public static func == (lhs: StarsRevenueStats, rhs: StarsRevenueStats) -> Bool { if lhs.revenueGraph != rhs.revenueGraph { return false @@ -121,6 +187,17 @@ private final class StarsRevenueStatsContextImpl { self._statePromise.set(.single(self._state)) self.load() + + let _ = (account.postbox.transaction { transaction -> StarsRevenueStats? in + return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStarsRevenueStats, key: StarsRevenueStats.key(peerId: peerId)))?.get(StarsRevenueStats.self) + } + |> deliverOnMainQueue).start(next: { [weak self] cachedResult in + guard let self, let cachedResult else { + return + } + self._state = StarsRevenueStatsContextState(stats: cachedResult) + self._statePromise.set(.single(self._state)) + }) } deinit { @@ -163,9 +240,17 @@ private final class StarsRevenueStatsContextImpl { self.disposable.set((signal |> deliverOnMainQueue).start(next: { [weak self] stats in - if let strongSelf = self { - strongSelf._state = StarsRevenueStatsContextState(stats: stats) - strongSelf._statePromise.set(.single(strongSelf._state)) + if let self { + self._state = StarsRevenueStatsContextState(stats: stats) + self._statePromise.set(.single(self._state)) + + if let stats { + let _ = (self.account.postbox.transaction { transaction in + if let entry = CodableEntry(stats) { + transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStarsRevenueStats, key: StarsRevenueStats.key(peerId: peerId)), entry: entry) + } + }).start() + } } })) } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift index 4c07120c5e..66e2542d89 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_Namespaces.swift @@ -126,6 +126,7 @@ public struct Namespaces { public static let savedMessageTags: Int8 = 35 public static let applicationIcons: Int8 = 36 public static let availableMessageEffects: Int8 = 37 + public static let cachedStarsRevenueStats: Int8 = 38 } public struct UnorderedItemList {