mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-21 10:41:12 +00:00
Various improvements
This commit is contained in:
parent
9a14b076c6
commit
d166e32b3e
@ -1213,6 +1213,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32, storyItem: EngineStoryItem, fromStory: Bool) -> ViewController
|
func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32, storyItem: EngineStoryItem, fromStory: Bool) -> ViewController
|
||||||
|
|
||||||
func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController
|
func makeStarsTransactionsScreen(context: AccountContext, starsContext: StarsContext) -> ViewController
|
||||||
|
func makeTonTransactionsScreen(context: AccountContext, tonContext: StarsContext) -> ViewController
|
||||||
func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController
|
func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController
|
||||||
func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController
|
func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, extendedMedia: [TelegramExtendedMedia], inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, completion: @escaping (Bool) -> Void) -> ViewController
|
||||||
func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController
|
func makeStarsSubscriptionTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, link: String, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?, EnginePeer?)?, NoError>, navigateToPeer: @escaping (EnginePeer) -> Void) -> ViewController
|
||||||
|
BIN
submodules/PremiumUI/Resources/diamond.scn
Normal file
BIN
submodules/PremiumUI/Resources/diamond.scn
Normal file
Binary file not shown.
@ -280,9 +280,9 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
let itemLabel: NSAttributedString
|
let itemLabel: NSAttributedString
|
||||||
let labelString: String
|
let labelString: String
|
||||||
|
|
||||||
let absCount = StarsAmount(value: abs(item.transaction.count.value), nanos: abs(item.transaction.count.nanos))
|
let absCount = StarsAmount(value: abs(item.transaction.count.amount.value), nanos: abs(item.transaction.count.amount.nanos))
|
||||||
let formattedLabel = presentationStringsFormattedNumber(absCount, item.presentationData.dateTimeFormat.groupingSeparator)
|
let formattedLabel = presentationStringsFormattedNumber(absCount, item.presentationData.dateTimeFormat.groupingSeparator)
|
||||||
if item.transaction.count < StarsAmount.zero {
|
if item.transaction.count.amount < StarsAmount.zero {
|
||||||
labelString = "- \(formattedLabel)"
|
labelString = "- \(formattedLabel)"
|
||||||
} else {
|
} else {
|
||||||
labelString = "+ \(formattedLabel)"
|
labelString = "+ \(formattedLabel)"
|
||||||
|
@ -618,9 +618,9 @@ private final class StarsContextImpl {
|
|||||||
}
|
}
|
||||||
var transactions = state.transactions
|
var transactions = state.transactions
|
||||||
if addTransaction {
|
if addTransaction {
|
||||||
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil, floodskipNumber: nil, starrefCommissionPermille: nil, starrefPeerId: nil, starrefAmount: nil, paidMessageCount: nil, premiumGiftMonths: nil), at: 0)
|
let count = CurrencyAmount(amount: balance, currency: self.ton ? .ton : .stars)
|
||||||
|
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: count, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil, floodskipNumber: nil, starrefCommissionPermille: nil, starrefPeerId: nil, starrefAmount: nil, paidMessageCount: nil, premiumGiftMonths: nil), at: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: max(StarsAmount(value: 0, nanos: 0), state.balance + balance), subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
|
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: max(StarsAmount(value: 0, nanos: 0), state.balance + balance), subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +724,7 @@ private extension StarsContext.State.Transaction {
|
|||||||
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
|
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
|
||||||
let _ = subscriptionPeriod
|
let _ = subscriptionPeriod
|
||||||
|
|
||||||
self.init(flags: flags, id: id, count: StarsAmount(apiAmount: stars), date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) }, floodskipNumber: floodskipNumber, starrefCommissionPermille: starrefCommissionPermille, starrefPeerId: starrefPeer?.peerId, starrefAmount: starrefAmount.flatMap(StarsAmount.init(apiAmount:)), paidMessageCount: paidMessageCount, premiumGiftMonths: premiumGiftMonths)
|
self.init(flags: flags, id: id, count: CurrencyAmount(apiAmount: stars), date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) }, floodskipNumber: floodskipNumber, starrefCommissionPermille: starrefCommissionPermille, starrefPeerId: starrefPeer?.peerId, starrefAmount: starrefAmount.flatMap(StarsAmount.init(apiAmount:)), paidMessageCount: paidMessageCount, premiumGiftMonths: premiumGiftMonths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,7 +789,7 @@ public final class StarsContext {
|
|||||||
|
|
||||||
public let flags: Flags
|
public let flags: Flags
|
||||||
public let id: String
|
public let id: String
|
||||||
public let count: StarsAmount
|
public let count: CurrencyAmount
|
||||||
public let date: Int32
|
public let date: Int32
|
||||||
public let peer: Peer
|
public let peer: Peer
|
||||||
public let title: String?
|
public let title: String?
|
||||||
@ -812,7 +812,7 @@ public final class StarsContext {
|
|||||||
public init(
|
public init(
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
id: String,
|
id: String,
|
||||||
count: StarsAmount,
|
count: CurrencyAmount,
|
||||||
date: Int32,
|
date: Int32,
|
||||||
peer: Peer,
|
peer: Peer,
|
||||||
title: String?,
|
title: String?,
|
||||||
@ -1173,9 +1173,9 @@ private final class StarsTransactionsContextImpl {
|
|||||||
case .all:
|
case .all:
|
||||||
initialTransactions = currentTransactions
|
initialTransactions = currentTransactions
|
||||||
case .incoming:
|
case .incoming:
|
||||||
initialTransactions = currentTransactions.filter { $0.count > StarsAmount.zero }
|
initialTransactions = currentTransactions.filter { $0.count.amount > StarsAmount.zero }
|
||||||
case .outgoing:
|
case .outgoing:
|
||||||
initialTransactions = currentTransactions.filter { $0.count < StarsAmount.zero }
|
initialTransactions = currentTransactions.filter { $0.count.amount < StarsAmount.zero }
|
||||||
}
|
}
|
||||||
|
|
||||||
self._state = StarsTransactionsContext.State(transactions: initialTransactions, canLoadMore: true, isLoading: false)
|
self._state = StarsTransactionsContext.State(transactions: initialTransactions, canLoadMore: true, isLoading: false)
|
||||||
@ -1193,9 +1193,9 @@ private final class StarsTransactionsContextImpl {
|
|||||||
case .all:
|
case .all:
|
||||||
filteredTransactions = currentTransactions
|
filteredTransactions = currentTransactions
|
||||||
case .incoming:
|
case .incoming:
|
||||||
filteredTransactions = currentTransactions.filter { $0.count > StarsAmount.zero }
|
filteredTransactions = currentTransactions.filter { $0.count.amount > StarsAmount.zero }
|
||||||
case .outgoing:
|
case .outgoing:
|
||||||
filteredTransactions = currentTransactions.filter { $0.count < StarsAmount.zero }
|
filteredTransactions = currentTransactions.filter { $0.count.amount < StarsAmount.zero }
|
||||||
}
|
}
|
||||||
|
|
||||||
if !filteredTransactions.isEmpty && self._state.transactions.isEmpty && filteredTransactions != initialTransactions {
|
if !filteredTransactions.isEmpty && self._state.transactions.isEmpty && filteredTransactions != initialTransactions {
|
||||||
@ -1220,9 +1220,9 @@ private final class StarsTransactionsContextImpl {
|
|||||||
case .all:
|
case .all:
|
||||||
filteredTransactions = currentTransactions
|
filteredTransactions = currentTransactions
|
||||||
case .incoming:
|
case .incoming:
|
||||||
filteredTransactions = currentTransactions.filter { $0.count > StarsAmount.zero }
|
filteredTransactions = currentTransactions.filter { $0.count.amount > StarsAmount.zero }
|
||||||
case .outgoing:
|
case .outgoing:
|
||||||
filteredTransactions = currentTransactions.filter { $0.count < StarsAmount.zero }
|
filteredTransactions = currentTransactions.filter { $0.count.amount < StarsAmount.zero }
|
||||||
}
|
}
|
||||||
|
|
||||||
if filteredTransactions != initialTransactions {
|
if filteredTransactions != initialTransactions {
|
||||||
|
@ -93,6 +93,15 @@ public func formatStarsAmountText(_ amount: StarsAmount, dateTimeFormat: Present
|
|||||||
return balanceText
|
return balanceText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func formatCurrencyAmountText(_ amount: CurrencyAmount, dateTimeFormat: PresentationDateTimeFormat, showPlus: Bool = false) -> String {
|
||||||
|
switch amount.currency {
|
||||||
|
case .stars:
|
||||||
|
return formatStarsAmountText(amount.amount, dateTimeFormat: dateTimeFormat, showPlus: showPlus)
|
||||||
|
case .ton:
|
||||||
|
return formatTonAmountText(amount.amount.value, dateTimeFormat: dateTimeFormat, showPlus: showPlus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private let invalidAddressCharacters = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=").inverted
|
private let invalidAddressCharacters = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=").inverted
|
||||||
public func isValidTonAddress(_ address: String, exactLength: Bool = false) -> Bool {
|
public func isValidTonAddress(_ address: String, exactLength: Bool = false) -> Bool {
|
||||||
if address.count > walletAddressLength || address.rangeOfCharacter(from: invalidAddressCharacters) != nil {
|
if address.count > walletAddressLength || address.rangeOfCharacter(from: invalidAddressCharacters) != nil {
|
||||||
|
@ -381,6 +381,7 @@ final class PeerInfoScreenData {
|
|||||||
let hasBotPreviewItems: Bool
|
let hasBotPreviewItems: Bool
|
||||||
let isPremiumRequiredForStoryPosting: Bool
|
let isPremiumRequiredForStoryPosting: Bool
|
||||||
let personalChannel: PeerInfoPersonalChannelData?
|
let personalChannel: PeerInfoPersonalChannelData?
|
||||||
|
let tonState: StarsContext.State?
|
||||||
let starsState: StarsContext.State?
|
let starsState: StarsContext.State?
|
||||||
let starsRevenueStatsState: StarsRevenueStats?
|
let starsRevenueStatsState: StarsRevenueStats?
|
||||||
let starsRevenueStatsContext: StarsRevenueStatsContext?
|
let starsRevenueStatsContext: StarsRevenueStatsContext?
|
||||||
@ -432,6 +433,7 @@ final class PeerInfoScreenData {
|
|||||||
hasBotPreviewItems: Bool,
|
hasBotPreviewItems: Bool,
|
||||||
isPremiumRequiredForStoryPosting: Bool,
|
isPremiumRequiredForStoryPosting: Bool,
|
||||||
personalChannel: PeerInfoPersonalChannelData?,
|
personalChannel: PeerInfoPersonalChannelData?,
|
||||||
|
tonState: StarsContext.State?,
|
||||||
starsState: StarsContext.State?,
|
starsState: StarsContext.State?,
|
||||||
starsRevenueStatsState: StarsRevenueStats?,
|
starsRevenueStatsState: StarsRevenueStats?,
|
||||||
starsRevenueStatsContext: StarsRevenueStatsContext?,
|
starsRevenueStatsContext: StarsRevenueStatsContext?,
|
||||||
@ -471,6 +473,7 @@ final class PeerInfoScreenData {
|
|||||||
self.hasBotPreviewItems = hasBotPreviewItems
|
self.hasBotPreviewItems = hasBotPreviewItems
|
||||||
self.isPremiumRequiredForStoryPosting = isPremiumRequiredForStoryPosting
|
self.isPremiumRequiredForStoryPosting = isPremiumRequiredForStoryPosting
|
||||||
self.personalChannel = personalChannel
|
self.personalChannel = personalChannel
|
||||||
|
self.tonState = tonState
|
||||||
self.starsState = starsState
|
self.starsState = starsState
|
||||||
self.starsRevenueStatsState = starsRevenueStatsState
|
self.starsRevenueStatsState = starsRevenueStatsState
|
||||||
self.starsRevenueStatsContext = starsRevenueStatsContext
|
self.starsRevenueStatsContext = starsRevenueStatsContext
|
||||||
@ -752,7 +755,7 @@ private func peerInfoPersonalOrLinkedChannel(context: AccountContext, peerId: En
|
|||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
}
|
}
|
||||||
|
|
||||||
func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id, accountsAndPeers: Signal<[(AccountContext, EnginePeer, Int32)], NoError>, activeSessionsContextAndCount: Signal<(ActiveSessionsContext, Int, WebSessionsContext)?, NoError>, notificationExceptions: Signal<NotificationExceptionsList?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, hasPassport: Signal<Bool, NoError>, starsContext: StarsContext?) -> Signal<PeerInfoScreenData, NoError> {
|
func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id, accountsAndPeers: Signal<[(AccountContext, EnginePeer, Int32)], NoError>, activeSessionsContextAndCount: Signal<(ActiveSessionsContext, Int, WebSessionsContext)?, NoError>, notificationExceptions: Signal<NotificationExceptionsList?, NoError>, privacySettings: Signal<AccountPrivacySettings?, NoError>, archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError>, hasPassport: Signal<Bool, NoError>, starsContext: StarsContext?, tonContext: StarsContext?) -> Signal<PeerInfoScreenData, NoError> {
|
||||||
let preferences = context.sharedContext.accountManager.sharedData(keys: [
|
let preferences = context.sharedContext.accountManager.sharedData(keys: [
|
||||||
SharedDataKeys.proxySettings,
|
SharedDataKeys.proxySettings,
|
||||||
ApplicationSpecificSharedDataKeys.inAppNotificationSettings,
|
ApplicationSpecificSharedDataKeys.inAppNotificationSettings,
|
||||||
@ -846,6 +849,13 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tonState: Signal<StarsContext.State?, NoError>
|
||||||
|
if let tonContext {
|
||||||
|
tonState = tonContext.state
|
||||||
|
} else {
|
||||||
|
tonState = .single(nil)
|
||||||
|
}
|
||||||
|
|
||||||
let starsState: Signal<StarsContext.State?, NoError>
|
let starsState: Signal<StarsContext.State?, NoError>
|
||||||
if let starsContext {
|
if let starsContext {
|
||||||
starsState = starsContext.state
|
starsState = starsContext.state
|
||||||
@ -879,9 +889,10 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
hasStories,
|
hasStories,
|
||||||
bots,
|
bots,
|
||||||
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
||||||
starsState
|
starsState,
|
||||||
|
tonState
|
||||||
)
|
)
|
||||||
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories, bots, personalChannel, starsState -> PeerInfoScreenData in
|
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories, bots, personalChannel, starsState, tonState -> PeerInfoScreenData in
|
||||||
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
||||||
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
||||||
|
|
||||||
@ -959,6 +970,7 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||||||
hasBotPreviewItems: false,
|
hasBotPreviewItems: false,
|
||||||
isPremiumRequiredForStoryPosting: true,
|
isPremiumRequiredForStoryPosting: true,
|
||||||
personalChannel: personalChannel,
|
personalChannel: personalChannel,
|
||||||
|
tonState: tonState,
|
||||||
starsState: starsState,
|
starsState: starsState,
|
||||||
starsRevenueStatsState: nil,
|
starsRevenueStatsState: nil,
|
||||||
starsRevenueStatsContext: nil,
|
starsRevenueStatsContext: nil,
|
||||||
@ -1009,6 +1021,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasBotPreviewItems: false,
|
hasBotPreviewItems: false,
|
||||||
isPremiumRequiredForStoryPosting: true,
|
isPremiumRequiredForStoryPosting: true,
|
||||||
personalChannel: nil,
|
personalChannel: nil,
|
||||||
|
tonState: nil,
|
||||||
starsState: nil,
|
starsState: nil,
|
||||||
starsRevenueStatsState: nil,
|
starsRevenueStatsState: nil,
|
||||||
starsRevenueStatsContext: nil,
|
starsRevenueStatsContext: nil,
|
||||||
@ -1468,6 +1481,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasBotPreviewItems: hasBotPreviewItems,
|
hasBotPreviewItems: hasBotPreviewItems,
|
||||||
isPremiumRequiredForStoryPosting: false,
|
isPremiumRequiredForStoryPosting: false,
|
||||||
personalChannel: personalChannel,
|
personalChannel: personalChannel,
|
||||||
|
tonState: nil,
|
||||||
starsState: nil,
|
starsState: nil,
|
||||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||||
@ -1699,6 +1713,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasBotPreviewItems: false,
|
hasBotPreviewItems: false,
|
||||||
isPremiumRequiredForStoryPosting: isPremiumRequiredForStoryPosting,
|
isPremiumRequiredForStoryPosting: isPremiumRequiredForStoryPosting,
|
||||||
personalChannel: personalChannel,
|
personalChannel: personalChannel,
|
||||||
|
tonState: nil,
|
||||||
starsState: nil,
|
starsState: nil,
|
||||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||||
@ -2031,6 +2046,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
hasBotPreviewItems: false,
|
hasBotPreviewItems: false,
|
||||||
isPremiumRequiredForStoryPosting: isPremiumRequiredForStoryPosting,
|
isPremiumRequiredForStoryPosting: isPremiumRequiredForStoryPosting,
|
||||||
personalChannel: nil,
|
personalChannel: nil,
|
||||||
|
tonState: nil,
|
||||||
starsState: nil,
|
starsState: nil,
|
||||||
starsRevenueStatsState: starsRevenueContextAndState.1,
|
starsRevenueStatsState: starsRevenueContextAndState.1,
|
||||||
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
starsRevenueStatsContext: starsRevenueContextAndState.0,
|
||||||
|
@ -538,6 +538,7 @@ private enum PeerInfoSettingsSection {
|
|||||||
case profile
|
case profile
|
||||||
case premiumManagement
|
case premiumManagement
|
||||||
case stars
|
case stars
|
||||||
|
case ton
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum PeerInfoReportType {
|
private enum PeerInfoReportType {
|
||||||
@ -1035,14 +1036,31 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let tonState = data.tonState {
|
||||||
|
if abs(tonState.balance.value) > 0 {
|
||||||
|
let balanceText: NSAttributedString
|
||||||
|
if abs(tonState.balance.value) > 0 {
|
||||||
|
let formattedLabel = formatTonAmountText(tonState.balance.value, dateTimeFormat: presentationData.dateTimeFormat)
|
||||||
|
let smallLabelFont = Font.regular(floor(presentationData.listsFontSize.itemListBaseFontSize / 17.0 * 13.0))
|
||||||
|
let labelFont = Font.regular(presentationData.listsFontSize.itemListBaseFontSize)
|
||||||
|
let labelColor = presentationData.theme.list.itemSecondaryTextColor
|
||||||
|
balanceText = tonAmountAttributedString(formattedLabel, integralFont: labelFont, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator)
|
||||||
|
} else {
|
||||||
|
balanceText = NSAttributedString()
|
||||||
|
}
|
||||||
|
items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 103, label: .attributedText(balanceText), text: "My TON", icon: PresentationResourcesSettings.ton, action: {
|
||||||
|
interaction.openSettings(.ton)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
if !isPremiumDisabled || context.isPremium {
|
if !isPremiumDisabled || context.isPremium {
|
||||||
items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 103, label: .text(""), additionalBadgeLabel: nil, text: presentationData.strings.Settings_Business, icon: PresentationResourcesSettings.business, action: {
|
items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 104, label: .text(""), additionalBadgeLabel: nil, text: presentationData.strings.Settings_Business, icon: PresentationResourcesSettings.business, action: {
|
||||||
interaction.openSettings(.businessSetup)
|
interaction.openSettings(.businessSetup)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if let starsState = data.starsState {
|
if let starsState = data.starsState {
|
||||||
if !isPremiumDisabled || starsState.balance > StarsAmount.zero {
|
if !isPremiumDisabled || starsState.balance > StarsAmount.zero {
|
||||||
items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 104, label: .text(""), text: presentationData.strings.Settings_SendGift, icon: PresentationResourcesSettings.premiumGift, action: {
|
items[.payment]!.append(PeerInfoScreenDisclosureItem(id: 105, label: .text(""), text: presentationData.strings.Settings_SendGift, icon: PresentationResourcesSettings.premiumGift, action: {
|
||||||
interaction.openSettings(.premiumGift)
|
interaction.openSettings(.premiumGift)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -3011,7 +3029,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
private var didSetReady = false
|
private var didSetReady = false
|
||||||
|
|
||||||
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, isMyProfile: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, profileGiftsContext: ProfileGiftsContext?, starsContext: StarsContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, initialPaneKey: PeerInfoPaneKey?) {
|
init(controller: PeerInfoScreenImpl, context: AccountContext, peerId: PeerId, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, nearbyPeerDistance: Int32?, reactionSourceMessageId: MessageId?, callMessages: [Message], isSettings: Bool, isMyProfile: Bool, hintGroupInCommon: PeerId?, requestsContext: PeerInvitationImportersContext?, profileGiftsContext: ProfileGiftsContext?, starsContext: StarsContext?, tonContext: StarsContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, initialPaneKey: PeerInfoPaneKey?) {
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
@ -4676,7 +4694,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
|
|
||||||
self.cachedFaq.set(.single(nil) |> then(cachedFaqInstantPage(context: self.context) |> map(Optional.init)))
|
self.cachedFaq.set(.single(nil) |> then(cachedFaqInstantPage(context: self.context) |> map(Optional.init)))
|
||||||
|
|
||||||
screenData = peerInfoScreenSettingsData(context: context, peerId: peerId, accountsAndPeers: self.accountsAndPeers.get(), activeSessionsContextAndCount: self.activeSessionsContextAndCount.get(), notificationExceptions: self.notificationExceptions.get(), privacySettings: self.privacySettings.get(), archivedStickerPacks: self.archivedPacks.get(), hasPassport: hasPassport, starsContext: starsContext)
|
screenData = peerInfoScreenSettingsData(context: context, peerId: peerId, accountsAndPeers: self.accountsAndPeers.get(), activeSessionsContextAndCount: self.activeSessionsContextAndCount.get(), notificationExceptions: self.notificationExceptions.get(), privacySettings: self.privacySettings.get(), archivedStickerPacks: self.archivedPacks.get(), hasPassport: hasPassport, starsContext: starsContext, tonContext: tonContext)
|
||||||
|
|
||||||
|
|
||||||
self.headerNode.displayCopyContextMenu = { [weak self] node, copyPhone, copyUsername in
|
self.headerNode.displayCopyContextMenu = { [weak self] node, copyPhone, copyUsername in
|
||||||
@ -10649,6 +10667,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
if let starsContext = self.controller?.starsContext {
|
if let starsContext = self.controller?.starsContext {
|
||||||
push(self.context.sharedContext.makeStarsTransactionsScreen(context: self.context, starsContext: starsContext))
|
push(self.context.sharedContext.makeStarsTransactionsScreen(context: self.context, starsContext: starsContext))
|
||||||
}
|
}
|
||||||
|
case .ton:
|
||||||
|
if let tonContext = self.controller?.tonContext {
|
||||||
|
push(self.context.sharedContext.makeTonTransactionsScreen(context: self.context, tonContext: tonContext))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12846,6 +12868,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||||||
private weak var requestsContext: PeerInvitationImportersContext?
|
private weak var requestsContext: PeerInvitationImportersContext?
|
||||||
private weak var profileGiftsContext: ProfileGiftsContext?
|
private weak var profileGiftsContext: ProfileGiftsContext?
|
||||||
fileprivate let starsContext: StarsContext?
|
fileprivate let starsContext: StarsContext?
|
||||||
|
fileprivate let tonContext: StarsContext?
|
||||||
private let switchToRecommendedChannels: Bool
|
private let switchToRecommendedChannels: Bool
|
||||||
private let switchToGifts: Bool
|
private let switchToGifts: Bool
|
||||||
private let switchToGroupsInCommon: Bool
|
private let switchToGroupsInCommon: Bool
|
||||||
@ -12947,12 +12970,23 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||||||
self.chatLocation = .peer(id: peerId)
|
self.chatLocation = .peer(id: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isSettings, let starsContext = context.starsContext {
|
if isSettings {
|
||||||
|
if let starsContext = context.starsContext {
|
||||||
self.starsContext = starsContext
|
self.starsContext = starsContext
|
||||||
starsContext.load(force: true)
|
starsContext.load(force: true)
|
||||||
} else {
|
} else {
|
||||||
self.starsContext = nil
|
self.starsContext = nil
|
||||||
}
|
}
|
||||||
|
if let tonContext = context.tonContext {
|
||||||
|
self.tonContext = tonContext
|
||||||
|
tonContext.load(force: true)
|
||||||
|
} else {
|
||||||
|
self.tonContext = nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.starsContext = nil
|
||||||
|
self.tonContext = nil
|
||||||
|
}
|
||||||
|
|
||||||
if isMyProfile, let profileGiftsContext {
|
if isMyProfile, let profileGiftsContext {
|
||||||
profileGiftsContext.updateFilter(.All)
|
profileGiftsContext.updateFilter(.All)
|
||||||
@ -13294,7 +13328,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
|
|||||||
} else if self.switchToGroupsInCommon {
|
} else if self.switchToGroupsInCommon {
|
||||||
initialPaneKey = .groupsInCommon
|
initialPaneKey = .groupsInCommon
|
||||||
}
|
}
|
||||||
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, isMyProfile: self.isMyProfile, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, profileGiftsContext: self.profileGiftsContext, starsContext: self.starsContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, initialPaneKey: initialPaneKey)
|
self.displayNode = PeerInfoScreenNode(controller: self, context: self.context, peerId: self.peerId, avatarInitiallyExpanded: self.avatarInitiallyExpanded, isOpenedFromChat: self.isOpenedFromChat, nearbyPeerDistance: self.nearbyPeerDistance, reactionSourceMessageId: self.reactionSourceMessageId, callMessages: self.callMessages, isSettings: self.isSettings, isMyProfile: self.isMyProfile, hintGroupInCommon: self.hintGroupInCommon, requestsContext: self.requestsContext, profileGiftsContext: self.profileGiftsContext, starsContext: self.starsContext, tonContext: self.tonContext, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, initialPaneKey: initialPaneKey)
|
||||||
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
|
self.controllerNode.accountsAndPeers.set(self.accountsAndPeers.get() |> map { $0.1 })
|
||||||
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
|
self.controllerNode.activeSessionsContextAndCount.set(self.activeSessionsContextAndCount.get())
|
||||||
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())
|
self.cachedDataPromise.set(self.controllerNode.cachedDataPromise.get())
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "PremiumDiamondComponent",
|
||||||
|
module_name = "PremiumDiamondComponent",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/AsyncDisplayKit",
|
||||||
|
"//submodules/Display",
|
||||||
|
"//submodules/SSignalKit/SwiftSignalKit",
|
||||||
|
"//submodules/ComponentFlow",
|
||||||
|
"//submodules/AccountContext",
|
||||||
|
"//submodules/AppBundle",
|
||||||
|
"//submodules/GZip",
|
||||||
|
"//submodules/LegacyComponents",
|
||||||
|
"//submodules/Components/MultilineTextComponent:MultilineTextComponent",
|
||||||
|
"//submodules/TelegramUI/Components/Premium/PremiumStarComponent",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,309 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import ComponentFlow
|
||||||
|
import SwiftSignalKit
|
||||||
|
import SceneKit
|
||||||
|
import GZip
|
||||||
|
import AppBundle
|
||||||
|
import LegacyComponents
|
||||||
|
import PremiumStarComponent
|
||||||
|
|
||||||
|
private let sceneVersion: Int = 5
|
||||||
|
|
||||||
|
private func deg2rad(_ number: Float) -> Float {
|
||||||
|
return number * .pi / 180
|
||||||
|
}
|
||||||
|
|
||||||
|
private func rad2deg(_ number: Float) -> Float {
|
||||||
|
return number * 180.0 / .pi
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class PremiumDiamondComponent: Component {
|
||||||
|
public init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: PremiumDiamondComponent, rhs: PremiumDiamondComponent) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class View: UIView, SCNSceneRendererDelegate, ComponentTaggedView {
|
||||||
|
public final class Tag {
|
||||||
|
public init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func matches(tag: Any) -> Bool {
|
||||||
|
if let _ = tag as? Tag {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private var _ready = Promise<Bool>()
|
||||||
|
public var ready: Signal<Bool, NoError> {
|
||||||
|
return self._ready.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
weak var animateFrom: UIView?
|
||||||
|
weak var containerView: UIView?
|
||||||
|
|
||||||
|
private let sceneView: SCNView
|
||||||
|
|
||||||
|
private var timer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
|
private var component: PremiumDiamondComponent?
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
self.sceneView = SCNView(frame: CGRect(origin: .zero, size: CGSize(width: 64.0, height: 64.0)))
|
||||||
|
self.sceneView.backgroundColor = .clear
|
||||||
|
self.sceneView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
|
||||||
|
self.sceneView.isUserInteractionEnabled = false
|
||||||
|
self.sceneView.preferredFramesPerSecond = 60
|
||||||
|
self.sceneView.isJitteringEnabled = true
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.addSubview(self.sceneView)
|
||||||
|
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
let panGestureRecoginzer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(_:)))
|
||||||
|
self.addGestureRecognizer(panGestureRecoginzer)
|
||||||
|
|
||||||
|
self.disablesInteractiveModalDismiss = true
|
||||||
|
self.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.timer?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var previousYaw: Float = 0.0
|
||||||
|
@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
|
||||||
|
guard let scene = self.sceneView.scene, let node = scene.rootNode.childNode(withName: "star", recursively: false) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let keys = [
|
||||||
|
"rotate",
|
||||||
|
"tapRotate",
|
||||||
|
"continuousRotation"
|
||||||
|
]
|
||||||
|
|
||||||
|
for key in keys {
|
||||||
|
node.removeAnimation(forKey: key)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch gesture.state {
|
||||||
|
case .began:
|
||||||
|
self.previousYaw = 0.0
|
||||||
|
case .changed:
|
||||||
|
let translation = gesture.translation(in: gesture.view)
|
||||||
|
let yawPan = deg2rad(Float(translation.x))
|
||||||
|
|
||||||
|
func rubberBandingOffset(offset: CGFloat, bandingStart: CGFloat) -> CGFloat {
|
||||||
|
let bandedOffset = offset - bandingStart
|
||||||
|
let range: CGFloat = 60.0
|
||||||
|
let coefficient: CGFloat = 0.4
|
||||||
|
return bandingStart + (1.0 - (1.0 / ((bandedOffset * coefficient / range) + 1.0))) * range
|
||||||
|
}
|
||||||
|
|
||||||
|
var pitchTranslation = rubberBandingOffset(offset: abs(translation.y), bandingStart: 0.0)
|
||||||
|
if translation.y < 0.0 {
|
||||||
|
pitchTranslation *= -1.0
|
||||||
|
}
|
||||||
|
let pitchPan = deg2rad(Float(pitchTranslation))
|
||||||
|
|
||||||
|
self.previousYaw = yawPan
|
||||||
|
// Maintain the initial tilt while adding pan gestures
|
||||||
|
let initialTiltX: Float = deg2rad(-15.0)
|
||||||
|
let initialTiltZ: Float = deg2rad(5.0)
|
||||||
|
node.eulerAngles = SCNVector3(initialTiltX + pitchPan, yawPan, initialTiltZ)
|
||||||
|
case .ended:
|
||||||
|
let velocity = gesture.velocity(in: gesture.view)
|
||||||
|
|
||||||
|
var smallAngle = false
|
||||||
|
if (self.previousYaw < .pi / 2 && self.previousYaw > -.pi / 2) && abs(velocity.x) < 200 {
|
||||||
|
smallAngle = true
|
||||||
|
}
|
||||||
|
|
||||||
|
self.playAppearanceAnimation(velocity: velocity.x, smallAngle: smallAngle, explode: !smallAngle && abs(velocity.x) > 600)
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setup() {
|
||||||
|
guard let scene = loadCompressedScene(name: "diamond", version: sceneVersion) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sceneView.scene = scene
|
||||||
|
self.sceneView.delegate = self
|
||||||
|
|
||||||
|
let _ = self.sceneView.snapshot()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var didSetReady = false
|
||||||
|
public func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
|
||||||
|
if !self.didSetReady {
|
||||||
|
self.didSetReady = true
|
||||||
|
|
||||||
|
Queue.mainQueue().justDispatch {
|
||||||
|
self._ready.set(.single(true))
|
||||||
|
self.onReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func onReady() {
|
||||||
|
self.playAppearanceAnimation(mirror: true, explode: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func playAppearanceAnimation(velocity: CGFloat? = nil, smallAngle: Bool = false, mirror: Bool = false, explode: Bool = false) {
|
||||||
|
guard let scene = self.sceneView.scene else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if explode, let node = scene.rootNode.childNode(withName: "swirl", recursively: false), let particlesLeft = scene.rootNode.childNode(withName: "particles_left", recursively: false), let particlesRight = scene.rootNode.childNode(withName: "particles_right", recursively: false), let particlesBottomLeft = scene.rootNode.childNode(withName: "particles_left_bottom", recursively: false), let particlesBottomRight = scene.rootNode.childNode(withName: "particles_right_bottom", recursively: false) {
|
||||||
|
if let leftParticleSystem = particlesLeft.particleSystems?.first, let rightParticleSystem = particlesRight.particleSystems?.first, let leftBottomParticleSystem = particlesBottomLeft.particleSystems?.first, let rightBottomParticleSystem = particlesBottomRight.particleSystems?.first {
|
||||||
|
leftParticleSystem.speedFactor = 2.0
|
||||||
|
leftParticleSystem.particleVelocity = 1.6
|
||||||
|
leftParticleSystem.birthRate = 60.0
|
||||||
|
leftParticleSystem.particleLifeSpan = 4.0
|
||||||
|
|
||||||
|
rightParticleSystem.speedFactor = 2.0
|
||||||
|
rightParticleSystem.particleVelocity = 1.6
|
||||||
|
rightParticleSystem.birthRate = 60.0
|
||||||
|
rightParticleSystem.particleLifeSpan = 4.0
|
||||||
|
|
||||||
|
leftBottomParticleSystem.particleVelocity = 1.6
|
||||||
|
leftBottomParticleSystem.birthRate = 24.0
|
||||||
|
leftBottomParticleSystem.particleLifeSpan = 7.0
|
||||||
|
|
||||||
|
rightBottomParticleSystem.particleVelocity = 1.6
|
||||||
|
rightBottomParticleSystem.birthRate = 24.0
|
||||||
|
rightBottomParticleSystem.particleLifeSpan = 7.0
|
||||||
|
|
||||||
|
node.physicsField?.isActive = true
|
||||||
|
Queue.mainQueue().after(1.0) {
|
||||||
|
node.physicsField?.isActive = false
|
||||||
|
|
||||||
|
leftParticleSystem.birthRate = 15.0
|
||||||
|
leftParticleSystem.particleVelocity = 1.0
|
||||||
|
leftParticleSystem.particleLifeSpan = 3.0
|
||||||
|
|
||||||
|
rightParticleSystem.birthRate = 15.0
|
||||||
|
rightParticleSystem.particleVelocity = 1.0
|
||||||
|
rightParticleSystem.particleLifeSpan = 3.0
|
||||||
|
|
||||||
|
leftBottomParticleSystem.particleVelocity = 1.0
|
||||||
|
leftBottomParticleSystem.birthRate = 10.0
|
||||||
|
leftBottomParticleSystem.particleLifeSpan = 5.0
|
||||||
|
|
||||||
|
rightBottomParticleSystem.particleVelocity = 1.0
|
||||||
|
rightBottomParticleSystem.birthRate = 10.0
|
||||||
|
rightBottomParticleSystem.particleLifeSpan = 5.0
|
||||||
|
|
||||||
|
let leftAnimation = POPBasicAnimation()
|
||||||
|
leftAnimation.property = (POPAnimatableProperty.property(withName: "speedFactor", initializer: { property in
|
||||||
|
property?.readBlock = { particleSystem, values in
|
||||||
|
values?.pointee = (particleSystem as! SCNParticleSystem).speedFactor
|
||||||
|
}
|
||||||
|
property?.writeBlock = { particleSystem, values in
|
||||||
|
(particleSystem as! SCNParticleSystem).speedFactor = values!.pointee
|
||||||
|
}
|
||||||
|
property?.threshold = 0.01
|
||||||
|
}) as! POPAnimatableProperty)
|
||||||
|
leftAnimation.fromValue = 1.2 as NSNumber
|
||||||
|
leftAnimation.toValue = 0.85 as NSNumber
|
||||||
|
leftAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
||||||
|
leftAnimation.duration = 0.5
|
||||||
|
leftParticleSystem.pop_add(leftAnimation, forKey: "speedFactor")
|
||||||
|
|
||||||
|
let rightAnimation = POPBasicAnimation()
|
||||||
|
rightAnimation.property = (POPAnimatableProperty.property(withName: "speedFactor", initializer: { property in
|
||||||
|
property?.readBlock = { particleSystem, values in
|
||||||
|
values?.pointee = (particleSystem as! SCNParticleSystem).speedFactor
|
||||||
|
}
|
||||||
|
property?.writeBlock = { particleSystem, values in
|
||||||
|
(particleSystem as! SCNParticleSystem).speedFactor = values!.pointee
|
||||||
|
}
|
||||||
|
property?.threshold = 0.01
|
||||||
|
}) as! POPAnimatableProperty)
|
||||||
|
rightAnimation.fromValue = 1.2 as NSNumber
|
||||||
|
rightAnimation.toValue = 0.85 as NSNumber
|
||||||
|
rightAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
||||||
|
rightAnimation.duration = 0.5
|
||||||
|
rightParticleSystem.pop_add(rightAnimation, forKey: "speedFactor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// var from = node.presentation.eulerAngles
|
||||||
|
// if abs(from.y - .pi * 2.0) < 0.001 {
|
||||||
|
// from.y = 0.0
|
||||||
|
// }
|
||||||
|
// node.removeAnimation(forKey: "tapRotate")
|
||||||
|
//
|
||||||
|
// var toValue: Float = smallAngle ? 0.0 : .pi * 2.0
|
||||||
|
// if let velocity = velocity, !smallAngle && abs(velocity) > 200 && velocity < 0.0 {
|
||||||
|
// toValue *= -1
|
||||||
|
// }
|
||||||
|
// if mirror {
|
||||||
|
// toValue *= -1
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// let to = SCNVector3(x: from.x, y: toValue, z: from.z)
|
||||||
|
// let distance = rad2deg(to.y - from.y)
|
||||||
|
//
|
||||||
|
// guard !distance.isZero else {
|
||||||
|
// Queue.mainQueue().after(0.1) { [weak self] in
|
||||||
|
// self?.setupContinuousRotation()
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let springAnimation = CASpringAnimation(keyPath: "eulerAngles")
|
||||||
|
// springAnimation.fromValue = NSValue(scnVector3: from)
|
||||||
|
// springAnimation.toValue = NSValue(scnVector3: to)
|
||||||
|
// springAnimation.mass = 1.0
|
||||||
|
// springAnimation.stiffness = 21.0
|
||||||
|
// springAnimation.damping = 5.8
|
||||||
|
// springAnimation.duration = springAnimation.settlingDuration * 0.75
|
||||||
|
// springAnimation.initialVelocity = velocity.flatMap { abs($0 / CGFloat(distance)) } ?? 1.7
|
||||||
|
// springAnimation.completion = { [weak self] finished in
|
||||||
|
// if finished {
|
||||||
|
// self?.setupContinuousRotation()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// node.addAnimation(springAnimation, forKey: "rotate")
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(component: PremiumDiamondComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
||||||
|
self.component = component
|
||||||
|
|
||||||
|
self.sceneView.bounds = CGRect(origin: .zero, size: CGSize(width: availableSize.width * 2.0, height: availableSize.height * 2.0))
|
||||||
|
if self.sceneView.superview == self {
|
||||||
|
self.sceneView.center = CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func makeView() -> View {
|
||||||
|
return View(frame: CGRect())
|
||||||
|
}
|
||||||
|
|
||||||
|
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
@ -376,7 +376,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
titleText = gift.title
|
titleText = gift.title
|
||||||
descriptionText = "\(strings.Gift_Unique_Collectible) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))"
|
descriptionText = "\(strings.Gift_Unique_Collectible) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))"
|
||||||
}
|
}
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
if case let .peer(peer) = transaction.peer {
|
if case let .peer(peer) = transaction.peer {
|
||||||
@ -395,7 +395,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
} else if let giveawayMessageIdValue = transaction.giveawayMessageId {
|
} else if let giveawayMessageIdValue = transaction.giveawayMessageId {
|
||||||
titleText = strings.Stars_Transaction_Giveaway_Title
|
titleText = strings.Stars_Transaction_Giveaway_Title
|
||||||
descriptionText = ""
|
descriptionText = ""
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
giveawayMessageId = giveawayMessageIdValue
|
giveawayMessageId = giveawayMessageIdValue
|
||||||
@ -406,7 +406,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
} else if let _ = transaction.subscriptionPeriod {
|
} else if let _ = transaction.subscriptionPeriod {
|
||||||
titleText = strings.Stars_Transaction_SubscriptionFee
|
titleText = strings.Stars_Transaction_SubscriptionFee
|
||||||
descriptionText = ""
|
descriptionText = ""
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
if case let .peer(peer) = transaction.peer {
|
if case let .peer(peer) = transaction.peer {
|
||||||
@ -417,7 +417,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
} else if transaction.flags.contains(.isGift) {
|
} else if transaction.flags.contains(.isGift) {
|
||||||
titleText = strings.Stars_Gift_Received_Title
|
titleText = strings.Stars_Gift_Received_Title
|
||||||
descriptionText = strings.Stars_Gift_Received_Text
|
descriptionText = strings.Stars_Gift_Received_Text
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
countOnTop = true
|
countOnTop = true
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
@ -446,7 +446,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
countOnTop = false
|
countOnTop = false
|
||||||
descriptionText = ""
|
descriptionText = ""
|
||||||
}
|
}
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
transactionPeer = transaction.peer
|
transactionPeer = transaction.peer
|
||||||
@ -457,7 +457,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
titleText = strings.Stars_Transaction_Reaction_Title
|
titleText = strings.Stars_Transaction_Reaction_Title
|
||||||
descriptionText = ""
|
descriptionText = ""
|
||||||
messageId = transaction.paidMessageId
|
messageId = transaction.paidMessageId
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
if case let .peer(peer) = transaction.peer {
|
if case let .peer(peer) = transaction.peer {
|
||||||
@ -490,7 +490,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
via = strings.Stars_Transaction_PremiumBotTopUp_Subtitle
|
via = strings.Stars_Transaction_PremiumBotTopUp_Subtitle
|
||||||
case .fragment:
|
case .fragment:
|
||||||
if parentPeer.id == component.context.account.peerId {
|
if parentPeer.id == component.context.account.peerId {
|
||||||
if (transaction.count.value < 0 && !transaction.flags.contains(.isRefund)) || (transaction.count.value > 0 && transaction.flags.contains(.isRefund)) {
|
if (transaction.count.amount.value < 0 && !transaction.flags.contains(.isRefund)) || (transaction.count.amount.value > 0 && transaction.flags.contains(.isRefund)) {
|
||||||
titleText = strings.Stars_Transaction_FragmentWithdrawal_Title
|
titleText = strings.Stars_Transaction_FragmentWithdrawal_Title
|
||||||
via = strings.Stars_Transaction_FragmentWithdrawal_Subtitle
|
via = strings.Stars_Transaction_FragmentWithdrawal_Subtitle
|
||||||
} else {
|
} else {
|
||||||
@ -545,7 +545,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
|
|
||||||
messageId = transaction.paidMessageId
|
messageId = transaction.paidMessageId
|
||||||
|
|
||||||
count = transaction.count
|
count = transaction.count.amount
|
||||||
transactionId = transaction.id
|
transactionId = transaction.id
|
||||||
date = transaction.date
|
date = transaction.date
|
||||||
if case let .peer(peer) = transaction.peer {
|
if case let .peer(peer) = transaction.peer {
|
||||||
@ -1173,7 +1173,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
if let starrefCommissionPermille = transaction.starrefCommissionPermille, transaction.starrefPeerId != nil {
|
if let starrefCommissionPermille = transaction.starrefCommissionPermille, transaction.starrefPeerId != nil {
|
||||||
if transaction.flags.contains(.isPaidMessage) || transaction.flags.contains(.isStarGiftResale) {
|
if transaction.flags.contains(.isPaidMessage) || transaction.flags.contains(.isStarGiftResale) {
|
||||||
var totalStars = transaction.count
|
var totalStars = transaction.count.amount
|
||||||
if let starrefCount = transaction.starrefAmount {
|
if let starrefCount = transaction.starrefAmount {
|
||||||
totalStars = totalStars + starrefCount
|
totalStars = totalStars + starrefCount
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,8 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/LottieComponent",
|
"//submodules/TelegramUI/Components/LottieComponent",
|
||||||
"//submodules/TelegramUI/Components/LottieComponentResourceContent",
|
"//submodules/TelegramUI/Components/LottieComponentResourceContent",
|
||||||
"//submodules/TelegramUI/Components/Gifts/GiftAnimationComponent",
|
"//submodules/TelegramUI/Components/Gifts/GiftAnimationComponent",
|
||||||
|
"//submodules/TelegramUI/Components/Premium/PremiumCoinComponent",
|
||||||
|
"//submodules/TelegramUI/Components/Premium/PremiumDiamondComponent",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -17,6 +17,7 @@ final class StarsBalanceComponent: Component {
|
|||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
let dateTimeFormat: PresentationDateTimeFormat
|
let dateTimeFormat: PresentationDateTimeFormat
|
||||||
let count: StarsAmount
|
let count: StarsAmount
|
||||||
|
let isTon: Bool
|
||||||
let rate: Double?
|
let rate: Double?
|
||||||
let actionTitle: String
|
let actionTitle: String
|
||||||
let actionAvailable: Bool
|
let actionAvailable: Bool
|
||||||
@ -35,6 +36,7 @@ final class StarsBalanceComponent: Component {
|
|||||||
strings: PresentationStrings,
|
strings: PresentationStrings,
|
||||||
dateTimeFormat: PresentationDateTimeFormat,
|
dateTimeFormat: PresentationDateTimeFormat,
|
||||||
count: StarsAmount,
|
count: StarsAmount,
|
||||||
|
isTon: Bool = false,
|
||||||
rate: Double?,
|
rate: Double?,
|
||||||
actionTitle: String,
|
actionTitle: String,
|
||||||
actionAvailable: Bool,
|
actionAvailable: Bool,
|
||||||
@ -52,6 +54,7 @@ final class StarsBalanceComponent: Component {
|
|||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.dateTimeFormat = dateTimeFormat
|
self.dateTimeFormat = dateTimeFormat
|
||||||
self.count = count
|
self.count = count
|
||||||
|
self.isTon = isTon
|
||||||
self.rate = rate
|
self.rate = rate
|
||||||
self.actionTitle = actionTitle
|
self.actionTitle = actionTitle
|
||||||
self.actionAvailable = actionAvailable
|
self.actionAvailable = actionAvailable
|
||||||
@ -97,6 +100,9 @@ final class StarsBalanceComponent: Component {
|
|||||||
if lhs.count != rhs.count {
|
if lhs.count != rhs.count {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.isTon != rhs.isTon {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.rate != rhs.rate {
|
if lhs.rate != rhs.rate {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -120,8 +126,6 @@ final class StarsBalanceComponent: Component {
|
|||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
self.icon.image = UIImage(bundleImageName: "Premium/Stars/BalanceStar")
|
|
||||||
|
|
||||||
self.addSubview(self.icon)
|
self.addSubview(self.icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +134,14 @@ final class StarsBalanceComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(component: StarsBalanceComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
func update(component: StarsBalanceComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||||
|
if self.component == nil {
|
||||||
|
if component.isTon {
|
||||||
|
self.icon.image = generateTintedImage(image: UIImage(bundleImageName: "Ads/TonBig"), color: component.theme.list.itemAccentColor)
|
||||||
|
} else {
|
||||||
|
self.icon.image = UIImage(bundleImageName: "Premium/Stars/BalanceStar")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.component = component
|
self.component = component
|
||||||
self.state = state
|
self.state = state
|
||||||
|
|
||||||
@ -164,7 +176,12 @@ final class StarsBalanceComponent: Component {
|
|||||||
let sideInset: CGFloat = 16.0
|
let sideInset: CGFloat = 16.0
|
||||||
var contentHeight: CGFloat = sideInset
|
var contentHeight: CGFloat = sideInset
|
||||||
|
|
||||||
let formattedLabel = formatStarsAmountText(component.count, dateTimeFormat: component.dateTimeFormat)
|
let formattedLabel: String
|
||||||
|
if component.isTon {
|
||||||
|
formattedLabel = formatTonAmountText(component.count.value, dateTimeFormat: component.dateTimeFormat)
|
||||||
|
} else {
|
||||||
|
formattedLabel = formatStarsAmountText(component.count, dateTimeFormat: component.dateTimeFormat)
|
||||||
|
}
|
||||||
let labelFont: UIFont
|
let labelFont: UIFont
|
||||||
if formattedLabel.contains(component.dateTimeFormat.decimalSeparator) {
|
if formattedLabel.contains(component.dateTimeFormat.decimalSeparator) {
|
||||||
labelFont = Font.with(size: 48.0, design: .round, weight: .semibold)
|
labelFont = Font.with(size: 48.0, design: .round, weight: .semibold)
|
||||||
@ -188,13 +205,13 @@ final class StarsBalanceComponent: Component {
|
|||||||
self.addSubview(titleView)
|
self.addSubview(titleView)
|
||||||
}
|
}
|
||||||
if let icon = self.icon.image {
|
if let icon = self.icon.image {
|
||||||
let spacing: CGFloat = 3.0
|
let spacing: CGFloat = 4.0
|
||||||
let totalWidth = titleSize.width + icon.size.width + spacing
|
let totalWidth = titleSize.width + icon.size.width + spacing
|
||||||
let origin = floorToScreenPixels((availableSize.width - totalWidth) / 2.0)
|
let origin = floorToScreenPixels((availableSize.width - totalWidth) / 2.0)
|
||||||
let titleFrame = CGRect(origin: CGPoint(x: origin + icon.size.width + spacing, y: contentHeight - 3.0), size: titleSize)
|
let titleFrame = CGRect(origin: CGPoint(x: origin + icon.size.width + spacing, y: contentHeight - 3.0), size: titleSize)
|
||||||
titleView.frame = titleFrame
|
titleView.frame = titleFrame
|
||||||
|
|
||||||
self.icon.frame = CGRect(origin: CGPoint(x: origin, y: contentHeight), size: icon.size)
|
self.icon.frame = CGRect(origin: CGPoint(x: origin, y: floorToScreenPixels(titleFrame.midY - icon.size.height / 2.0)), size: icon.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentHeight += titleSize.height
|
contentHeight += titleSize.height
|
||||||
|
@ -21,7 +21,7 @@ import TelegramStringFormatting
|
|||||||
|
|
||||||
private extension StarsContext.State.Transaction {
|
private extension StarsContext.State.Transaction {
|
||||||
var extendedId: String {
|
var extendedId: String {
|
||||||
if self.count > StarsAmount.zero {
|
if self.count.amount > StarsAmount.zero {
|
||||||
return "\(id)_in"
|
return "\(id)_in"
|
||||||
} else {
|
} else {
|
||||||
return "\(id)_out"
|
return "\(id)_out"
|
||||||
@ -320,7 +320,7 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
switch starGift {
|
switch starGift {
|
||||||
case let .generic(gift):
|
case let .generic(gift):
|
||||||
itemFile = gift.file
|
itemFile = gift.file
|
||||||
itemSubtitle = item.count > StarsAmount.zero ? environment.strings.Stars_Intro_Transaction_ConvertedGift : environment.strings.Stars_Intro_Transaction_Gift
|
itemSubtitle = item.count.amount > StarsAmount.zero ? environment.strings.Stars_Intro_Transaction_ConvertedGift : environment.strings.Stars_Intro_Transaction_Gift
|
||||||
case let .unique(gift):
|
case let .unique(gift):
|
||||||
for attribute in gift.attributes {
|
for attribute in gift.attributes {
|
||||||
if case let .model(_, file, _) = attribute {
|
if case let .model(_, file, _) = attribute {
|
||||||
@ -328,7 +328,7 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if item.count > StarsAmount.zero {
|
if item.count.amount > StarsAmount.zero {
|
||||||
itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftSale
|
itemSubtitle = environment.strings.Stars_Intro_Transaction_GiftSale
|
||||||
} else {
|
} else {
|
||||||
if item.flags.contains(.isStarGiftResale) {
|
if item.flags.contains(.isStarGiftResale) {
|
||||||
@ -373,7 +373,7 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
itemSubtitle = environment.strings.Stars_Intro_Transaction_Gift_Title
|
itemSubtitle = environment.strings.Stars_Intro_Transaction_Gift_Title
|
||||||
itemPeer = .fragment
|
itemPeer = .fragment
|
||||||
} else {
|
} else {
|
||||||
if (item.count.value < 0 && !item.flags.contains(.isRefund)) || (item.count.value > 0 && item.flags.contains(.isRefund)) {
|
if (item.count.amount.value < 0 && !item.flags.contains(.isRefund)) || (item.count.amount.value > 0 && item.flags.contains(.isRefund)) {
|
||||||
itemTitle = environment.strings.Stars_Intro_Transaction_FragmentWithdrawal_Title
|
itemTitle = environment.strings.Stars_Intro_Transaction_FragmentWithdrawal_Title
|
||||||
itemSubtitle = environment.strings.Stars_Intro_Transaction_FragmentWithdrawal_Subtitle
|
itemSubtitle = environment.strings.Stars_Intro_Transaction_FragmentWithdrawal_Subtitle
|
||||||
} else {
|
} else {
|
||||||
@ -382,7 +382,7 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if item.count > StarsAmount.zero && !item.flags.contains(.isRefund) {
|
if item.count.amount > StarsAmount.zero && !item.flags.contains(.isRefund) {
|
||||||
itemTitle = environment.strings.Stars_Intro_Transaction_FragmentTopUp_Title
|
itemTitle = environment.strings.Stars_Intro_Transaction_FragmentTopUp_Title
|
||||||
itemSubtitle = environment.strings.Stars_Intro_Transaction_FragmentTopUp_Subtitle
|
itemSubtitle = environment.strings.Stars_Intro_Transaction_FragmentTopUp_Subtitle
|
||||||
} else {
|
} else {
|
||||||
@ -409,13 +409,24 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let itemLabel: NSAttributedString
|
let itemLabel: NSAttributedString
|
||||||
let formattedLabel = formatStarsAmountText(item.count, dateTimeFormat: environment.dateTimeFormat, showPlus: true)
|
let formattedLabel = formatCurrencyAmountText(item.count, dateTimeFormat: environment.dateTimeFormat, showPlus: true)
|
||||||
|
|
||||||
let smallLabelFont = Font.with(size: floor(fontBaseDisplaySize / 17.0 * 13.0))
|
let smallLabelFont = Font.with(size: floor(fontBaseDisplaySize / 17.0 * 13.0))
|
||||||
let labelFont = Font.medium(fontBaseDisplaySize)
|
let labelFont = Font.medium(fontBaseDisplaySize)
|
||||||
let labelColor = formattedLabel.hasPrefix("-") ? environment.theme.list.itemDestructiveColor : environment.theme.list.itemDisclosureActions.constructive.fillColor
|
let labelColor = formattedLabel.hasPrefix("-") ? environment.theme.list.itemDestructiveColor : environment.theme.list.itemDisclosureActions.constructive.fillColor
|
||||||
itemLabel = tonAmountAttributedString(formattedLabel, integralFont: labelFont, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: environment.dateTimeFormat.decimalSeparator)
|
itemLabel = tonAmountAttributedString(formattedLabel, integralFont: labelFont, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: environment.dateTimeFormat.decimalSeparator)
|
||||||
|
|
||||||
|
let itemIconName: String
|
||||||
|
let itemIconColor: UIColor?
|
||||||
|
switch item.count.currency {
|
||||||
|
case .stars:
|
||||||
|
itemIconName = "Premium/Stars/StarMedium"
|
||||||
|
itemIconColor = nil
|
||||||
|
case .ton:
|
||||||
|
itemIconName = "Ads/TonAbout"
|
||||||
|
itemIconColor = labelColor
|
||||||
|
}
|
||||||
|
|
||||||
var itemDateColor = environment.theme.list.itemSecondaryTextColor
|
var itemDateColor = environment.theme.list.itemSecondaryTextColor
|
||||||
itemDate = stringForMediumCompactDate(timestamp: item.date, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat)
|
itemDate = stringForMediumCompactDate(timestamp: item.date, strings: environment.strings, dateTimeFormat: environment.dateTimeFormat)
|
||||||
if item.flags.contains(.isRefund) {
|
if item.flags.contains(.isRefund) {
|
||||||
@ -496,7 +507,7 @@ final class StarsTransactionsListPanelComponent: Component {
|
|||||||
contentInsets: UIEdgeInsets(top: 9.0, left: environment.containerInsets.left, bottom: 8.0, right: environment.containerInsets.right),
|
contentInsets: UIEdgeInsets(top: 9.0, left: environment.containerInsets.left, bottom: 8.0, right: environment.containerInsets.right),
|
||||||
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: itemPeer, photo: item.photo, media: item.media, uniqueGift: uniqueGift, backgroundColor: environment.theme.list.plainBackgroundColor))), false),
|
leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: component.context, theme: environment.theme, peer: itemPeer, photo: item.photo, media: item.media, uniqueGift: uniqueGift, backgroundColor: environment.theme.list.plainBackgroundColor))), false),
|
||||||
icon: nil,
|
icon: nil,
|
||||||
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
|
accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))),
|
||||||
action: { [weak self] _ in
|
action: { [weak self] _ in
|
||||||
guard let self, let component = self.component else {
|
guard let self, let component = self.component else {
|
||||||
return
|
return
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,11 @@ func openWebAppImpl(
|
|||||||
skipTermsOfService: Bool,
|
skipTermsOfService: Bool,
|
||||||
payload: String?
|
payload: String?
|
||||||
) {
|
) {
|
||||||
|
if context.isFrozen {
|
||||||
|
parentController.push(context.sharedContext.makeAccountFreezeInfoScreen(context: context))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let presentationData: PresentationData
|
let presentationData: PresentationData
|
||||||
if let parentController = parentController as? ChatControllerImpl {
|
if let parentController = parentController as? ChatControllerImpl {
|
||||||
presentationData = parentController.presentationData
|
presentationData = parentController.presentationData
|
||||||
|
@ -3687,6 +3687,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
return StarsTransactionsScreen(context: context, starsContext: starsContext)
|
return StarsTransactionsScreen(context: context, starsContext: starsContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func makeTonTransactionsScreen(context: AccountContext, tonContext: StarsContext) -> ViewController {
|
||||||
|
return TonTransactionsScreen(context: context, tonContext: tonContext)
|
||||||
|
}
|
||||||
|
|
||||||
public func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController {
|
public func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [Any], purpose: StarsPurchasePurpose, completion: @escaping (Int64) -> Void) -> ViewController {
|
||||||
return StarsPurchaseScreen(context: context, starsContext: starsContext, options: options, purpose: purpose, completion: completion)
|
return StarsPurchaseScreen(context: context, starsContext: starsContext, options: options, purpose: purpose, completion: completion)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user