diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 32b0d260f6..dc4976bd6e 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -12456,6 +12456,7 @@ Sorry for the inconvenience."; "Monetization.StarsProceeds.Available" = "Available Balance"; "Monetization.StarsProceeds.Current" = "Total Balance"; "Monetization.StarsProceeds.Total" = "Lifetime Proceeds"; +"Monetization.StarsProceeds.Info" = "Funds from your total balance can be used for ads or withdrawn as rewards 21 days after they are earned."; "Premium.MessageEffects" = "Message Effects"; "Premium.MessageEffectsInfo" = "Add over 500 animated effects to private messages."; diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift index cf9bd1260a..bac3cdd995 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift @@ -153,9 +153,10 @@ class BarsComponentController: GeneralChartComponentController { func verticalLimitsLabels(verticalRange: ClosedRange, secondary: Bool) -> (ClosedRange, [LinesChartLabel]) { var (range, labels) = super.verticalLimitsLabels(verticalRange: verticalRange) if secondary { + let allowedChars = "0123456789\(self.verticalLimitsNumberFormatter.decimalSeparator ?? ".")" var updatedLabels: [LinesChartLabel] = [] for label in labels { - let convertedValue = (Double(label.text) ?? 0.0) * self.conversionRate + let convertedValue = (Double(label.text.filter(allowedChars.contains)) ?? 0.0) * self.conversionRate let text: String if convertedValue > 1.0 { text = String(format: "%0.1f", convertedValue) diff --git a/submodules/StatisticsUI/Sources/ChannelStatsController.swift b/submodules/StatisticsUI/Sources/ChannelStatsController.swift index 35985e5b8e..bf3c15d0bd 100644 --- a/submodules/StatisticsUI/Sources/ChannelStatsController.swift +++ b/submodules/StatisticsUI/Sources/ChannelStatsController.swift @@ -238,8 +238,9 @@ private enum StatsEntry: ItemListNodeEntry { case adsStarsRevenueGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType, Double) case adsProceedsTitle(PresentationTheme, String) - case adsProceedsOverview(PresentationTheme, RevenueStats, StarsRevenueStats?) - + case adsProceedsOverview(PresentationTheme, RevenueStats?, StarsRevenueStats?) + case adsProceedsInfo(PresentationTheme, String) + case adsTonBalanceTitle(PresentationTheme, String) case adsTonBalance(PresentationTheme, RevenueStats, Bool, Bool) case adsTonBalanceInfo(PresentationTheme, String) @@ -307,7 +308,7 @@ private enum StatsEntry: ItemListNodeEntry { return StatsSection.adsTonRevenue.rawValue case .adsStarsRevenueTitle, .adsStarsRevenueGraph: return StatsSection.adsStarsRevenue.rawValue - case .adsProceedsTitle, .adsProceedsOverview: + case .adsProceedsTitle, .adsProceedsOverview, .adsProceedsInfo: return StatsSection.adsProceeds.rawValue case .adsTonBalanceTitle, .adsTonBalance, .adsTonBalanceInfo: return StatsSection.adsTonBalance.rawValue @@ -430,24 +431,26 @@ private enum StatsEntry: ItemListNodeEntry { return 20007 case .adsProceedsOverview: return 20008 - case .adsTonBalanceTitle: + case .adsProceedsInfo: return 20009 - case .adsTonBalance: + case .adsTonBalanceTitle: return 20010 - case .adsTonBalanceInfo: + case .adsTonBalance: return 20011 - case .adsStarsBalanceTitle: + case .adsTonBalanceInfo: return 20012 - case .adsStarsBalance: + case .adsStarsBalanceTitle: return 20013 - case .adsStarsBalanceInfo: + case .adsStarsBalance: return 20014 - case .adsTransactionsTitle: + case .adsStarsBalanceInfo: return 20015 - case .adsTransactionsTabs: + case .adsTransactionsTitle: return 20016 + case .adsTransactionsTabs: + return 20017 case let .adsTransaction(index, _, _): - return 20017 + index + return 20018 + index case let .adsStarsTransaction(index, _, _): return 30017 + index case .adsTransactionsExpand: @@ -785,6 +788,12 @@ private enum StatsEntry: ItemListNodeEntry { } else { return false } + case let .adsProceedsInfo(lhsTheme, lhsText): + if case let .adsProceedsInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { + return true + } else { + return false + } case let .adsTonBalanceTitle(lhsTheme, lhsText): if case let .adsTonBalanceTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { return true @@ -904,7 +913,8 @@ private enum StatsEntry: ItemListNodeEntry { let .boostersInfo(_, text), let .boostLinkInfo(_, text), let .boostGiftsInfo(_, text), - let .adsCpmInfo(_, text): + let .adsCpmInfo(_, text), + let .adsProceedsInfo(_, text): return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section) case let .overview(_, stats): return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: false, stats: stats, sectionId: self.section, style: .blocks) @@ -1046,7 +1056,7 @@ private enum StatsEntry: ItemListNodeEntry { arguments.openMonetizationIntro() }) case let .adsProceedsOverview(_, stats, starsStats): - return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: false, stats: stats, additionalStats: starsStats, sectionId: self.section, style: .blocks) + return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: false, stats: stats ?? starsStats, additionalStats: stats != nil ? starsStats : nil, sectionId: self.section, style: .blocks) case let .adsTonBalance(_, stats, canWithdraw, isEnabled): return MonetizationBalanceItem( context: arguments.context, @@ -1542,8 +1552,9 @@ private func monetizationEntries( } } - entries.append(.adsProceedsTitle(presentationData.theme, presentationData.strings.Monetization_OverviewTitle)) - entries.append(.adsProceedsOverview(presentationData.theme, data, starsData)) + entries.append(.adsProceedsTitle(presentationData.theme, presentationData.strings.Monetization_StarsProceeds_Title)) + entries.append(.adsProceedsOverview(presentationData.theme, canViewRevenue ? data : nil, canViewStarsRevenue ? starsData : nil)) + entries.append(.adsProceedsInfo(presentationData.theme, presentationData.strings.Monetization_StarsProceeds_Info)) var isCreator = false if let peer, case let .channel(channel) = peer, channel.flags.contains(.isCreator) { diff --git a/submodules/StatisticsUI/Sources/MessageStatsController.swift b/submodules/StatisticsUI/Sources/MessageStatsController.swift index aacc3daa49..b2d5f1fb80 100644 --- a/submodules/StatisticsUI/Sources/MessageStatsController.swift +++ b/submodules/StatisticsUI/Sources/MessageStatsController.swift @@ -160,7 +160,7 @@ private enum StatsEntry: ItemListNodeEntry { let .publicForwardsTitle(_, text): return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) case let .overview(_, stats, storyViews, publicShares): - return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: false, stats: stats as! Stats, storyViews: storyViews, publicShares: publicShares, sectionId: self.section, style: .blocks) + return StatsOverviewItem(context: arguments.context, presentationData: presentationData, isGroup: false, stats: stats as? Stats, storyViews: storyViews, publicShares: publicShares, sectionId: self.section, style: .blocks) case let .interactionsGraph(_, _, _, graph, type, noInitialZoom), let .reactionsGraph(_, _, _, graph, type, noInitialZoom): return StatsGraphItem(presentationData: presentationData, graph: graph, type: type, noInitialZoom: noInitialZoom, getDetailsData: { date, completion in let _ = arguments.loadDetailedGraph(graph, Int64(date.timeIntervalSince1970) * 1000).start(next: { graph in diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index 8e72379fdf..747b814c84 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -47,14 +47,14 @@ class StatsOverviewItem: ListViewItem, ItemListItem { let context: AccountContext let presentationData: ItemListPresentationData let isGroup: Bool - let stats: Stats + let stats: Stats? let additionalStats: Stats? let storyViews: EngineStoryItem.Views? let publicShares: Int32? let sectionId: ItemListSectionId let style: ItemListStyle - init(context: AccountContext, presentationData: ItemListPresentationData, isGroup: Bool, stats: Stats, additionalStats: Stats? = nil, storyViews: EngineStoryItem.Views? = nil, publicShares: Int32? = nil, sectionId: ItemListSectionId, style: ItemListStyle) { + init(context: AccountContext, presentationData: ItemListPresentationData, isGroup: Bool, stats: Stats?, additionalStats: Stats? = nil, storyViews: EngineStoryItem.Views? = nil, publicShares: Int32? = nil, sectionId: ItemListSectionId, style: ItemListStyle) { self.context = context self.presentationData = presentationData self.isGroup = isGroup @@ -863,6 +863,40 @@ class StatsOverviewItemNode: ListViewItemNode { height += topLeftItemLayoutAndApply!.0.height * 3.0 + verticalSpacing * 2.0 } + } else if let stats = item.stats as? StarsRevenueStats { + twoColumnLayout = false + + topLeftItemLayoutAndApply = makeTopLeftItemLayout( + item.context, + params.width, + item.presentationData, + presentationStringsFormattedNumber(Int32(stats.balances.availableBalance), item.presentationData.dateTimeFormat.groupingSeparator), + item.presentationData.strings.Monetization_StarsProceeds_Available, + (stats.balances.availableBalance == 0 ? "" : "≈\(formatUsdValue(stats.balances.availableBalance, rate: stats.usdRate))", .generic), + .stars + ) + + topRightItemLayoutAndApply = makeTopRightItemLayout( + item.context, + params.width, + item.presentationData, + presentationStringsFormattedNumber(Int32(stats.balances.currentBalance), item.presentationData.dateTimeFormat.groupingSeparator), + item.presentationData.strings.Monetization_StarsProceeds_Current, + (stats.balances.currentBalance == 0 ? "" : "≈\(formatUsdValue(stats.balances.currentBalance, rate: stats.usdRate))", .generic), + .stars + ) + + middle1LeftItemLayoutAndApply = makeMiddle1LeftItemLayout( + item.context, + params.width, + item.presentationData, + presentationStringsFormattedNumber(Int32(stats.balances.overallRevenue), item.presentationData.dateTimeFormat.groupingSeparator), + item.presentationData.strings.Monetization_StarsProceeds_Total, + (stats.balances.overallRevenue == 0 ? "" : "≈\(formatUsdValue(stats.balances.overallRevenue, rate: stats.usdRate))", .generic), + .stars + ) + + height += topLeftItemLayoutAndApply!.0.height * 3.0 + verticalSpacing * 2.0 } let contentSize = CGSize(width: params.width, height: height)