diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index dd4791e9b7..41bdcebf23 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -12418,5 +12418,10 @@ Sorry for the inconvenience."; "Monetization.Balance.StarsInfo" = "You can withdraw Stars using Fragment, or use Stars to advertise your channel. [Learn More >]()"; "Monetization.Balance.StarsInfo_URL" = "https://telegram.org"; +"Monetization.StarsProceeds.Title" = "Rewards Overview"; +"Monetization.StarsProceeds.Available" = "Available Balance"; +"Monetization.StarsProceeds.Current" = "Total Balance"; +"Monetization.StarsProceeds.Total" = "Lifetime Proceeds"; + "Premium.MessageEffects" = "Message Effects"; "Premium.MessageEffectsInfo" = "Add over 500 animated effects to private messages."; diff --git a/submodules/StatisticsUI/Sources/MonetizationUtils.swift b/submodules/StatisticsUI/Sources/MonetizationUtils.swift index 8c88627578..8abe34e85d 100644 --- a/submodules/StatisticsUI/Sources/MonetizationUtils.swift +++ b/submodules/StatisticsUI/Sources/MonetizationUtils.swift @@ -38,6 +38,11 @@ func formatBalanceText(_ value: Int64, decimalSeparator: String, showPlus: Bool } else if showPlus { balanceText.insert("+", at: balanceText.startIndex) } + + if let dec = balanceText.range(of: decimalSeparator) { + balanceText = String(balanceText[balanceText.startIndex ..< min(balanceText.endIndex, balanceText.index(dec.upperBound, offsetBy: 2))]) + } + return balanceText } diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index 28cb76aaa1..7b2251ac41 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -211,8 +211,26 @@ private final class ValueItemNode: ASDisplayNode { let (deltaLayout, deltaApply) = makeDeltaLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: delta?.0 ?? "", font: deltaFont, textColor: deltaColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: constrainedSize, alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + var valueOffset: CGFloat = 0.0 + let iconName: String? + var iconTinted = false + switch mode { + case .ton: + iconName = "Ads/TonMedium" + iconTinted = true + valueOffset = 17.0 + case .stars: + iconName = "Premium/Stars/StarMedium" + valueOffset = 19.0 + default: + iconName = nil + } + let horizontalSpacing: CGFloat = 4.0 - let size = CGSize(width: valueLayout.size.width + horizontalSpacing + deltaLayout.size.width, height: valueLayout.size.height + titleLayout.size.height) + let size = CGSize( + width: max(valueOffset + valueLayout.size.width + horizontalSpacing + deltaLayout.size.width, titleLayout.size.width), + height: valueLayout.size.height + titleLayout.size.height + ) return (size, { var themeUpdated = false if targetNode.currentTheme !== presentationData.theme { @@ -223,22 +241,7 @@ private final class ValueItemNode: ASDisplayNode { let _ = valueApply() let _ = titleApply() let _ = deltaApply() - - var valueOffset: CGFloat = 0.0 - let iconName: String? - var iconTinted = false - switch mode { - case .ton: - iconName = "Ads/TonMedium" - iconTinted = true - valueOffset = 17.0 - case .stars: - iconName = "Premium/Stars/StarMedium" - valueOffset = 19.0 - default: - iconName = nil - } - + var iconNameUpdated = false if targetNode.currentIconName != iconName { targetNode.currentIconName = iconName @@ -385,6 +388,7 @@ class StatsOverviewItemNode: ListViewItemNode { } var twoColumnLayout = true + var useMinLeftColumnWidth = true var topLeftItemLayoutAndApply: (CGSize, () -> ValueItemNode)? var topRightItemLayoutAndApply: (CGSize, () -> ValueItemNode)? @@ -761,13 +765,14 @@ class StatsOverviewItemNode: ListViewItemNode { } else if let stats = item.stats as? RevenueStats { if let additionalStats = item.additionalStats as? StarsRevenueStats, additionalStats.balances.overallRevenue > 0 { twoColumnLayout = true + useMinLeftColumnWidth = true topLeftItemLayoutAndApply = makeTopLeftItemLayout( item.context, params.width, item.presentationData, formatBalanceText(stats.balances.availableBalance, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator), - "Available Balance", //item.presentationData.strings.Monetization_Overview_Available, + item.presentationData.strings.Monetization_StarsProceeds_Available, (stats.balances.availableBalance == 0 ? "" : "≈\(formatUsdValue(stats.balances.availableBalance, rate: stats.usdRate))", .generic), .ton ) @@ -777,7 +782,7 @@ class StatsOverviewItemNode: ListViewItemNode { params.width, item.presentationData, formatBalanceText(stats.balances.currentBalance, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator), - "Current Balance", //item.presentationData.strings.Monetization_Overview_Current, + item.presentationData.strings.Monetization_StarsProceeds_Current, (stats.balances.currentBalance == 0 ? "" : "≈\(formatUsdValue(stats.balances.currentBalance, rate: stats.usdRate))", .generic), .ton ) @@ -787,7 +792,7 @@ class StatsOverviewItemNode: ListViewItemNode { params.width, item.presentationData, formatBalanceText(stats.balances.overallRevenue, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator), - "Lifetime Proceeds",//item.presentationData.strings.Monetization_Overview_Total, + item.presentationData.strings.Monetization_StarsProceeds_Total, (stats.balances.overallRevenue == 0 ? "" : "≈\(formatUsdValue(stats.balances.overallRevenue, rate: stats.usdRate))", .generic), .ton ) @@ -957,7 +962,11 @@ class StatsOverviewItemNode: ListViewItemNode { if let bottomLeftItemLayout = bottomLeftItemLayoutAndApply?.0 { maxLeftWidth = max(maxLeftWidth, bottomLeftItemLayout.width) } - secondColumnX = max(layout.size.width / 2.0, firstColumnX + maxLeftWidth + horizontalSpacing) + if useMinLeftColumnWidth { + secondColumnX = min(layout.size.width / 2.0, firstColumnX + maxLeftWidth + horizontalSpacing * 3.0) + } else { + secondColumnX = max(layout.size.width / 2.0, firstColumnX + maxLeftWidth + horizontalSpacing) + } } if let topLeftItemLayout = topLeftItemLayoutAndApply?.0 { diff --git a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift index 7c55781932..9cba0d586f 100644 --- a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift +++ b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift @@ -55,7 +55,6 @@ public enum MessageContentKind: Equatable { case invoice(String) case story case giveaway - case paidContent public func isSemanticallyEqual(to other: MessageContentKind) -> Bool { switch self { @@ -191,12 +190,6 @@ public enum MessageContentKind: Equatable { } else { return false } - case .paidContent: - if case .paidContent = other { - return true - } else { - return false - } } } @@ -246,8 +239,6 @@ public enum MessageContentKind: Equatable { return .story case .giveaway: return .giveaway - case .paidContent: - return .paidContent } } } @@ -396,6 +387,25 @@ public func mediaContentKind(_ media: EngineMedia, message: EngineMessage? = nil } else { return nil } + case let .paidContent(paidContent): + switch paidContent.extendedMedia.first { + case let .preview(_, _, videoDuration): + if let _ = videoDuration { + return .video + } else { + return .image + } + case let .full(media): + if media is TelegramMediaImage { + return .image + } else if media is TelegramMediaFile { + return .video + } else { + return nil + } + default: + return nil + } default: return nil } @@ -455,8 +465,6 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation return (NSAttributedString(string: strings.Message_Story), true) case .giveaway: return (NSAttributedString(string: strings.Message_Giveaway), true) - case .paidContent: - return (NSAttributedString(string: "Paid Media"), true) } } diff --git a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift index 26b94ef3a7..9b042d59b4 100644 --- a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift @@ -382,7 +382,13 @@ public final class StarsImageComponent: Component { largeParticlesView.update(size: availableSize) largeParticlesView.frame = CGRect(origin: .zero, size: availableSize) - let imageSize = CGSize(width: component.diameter, height: component.diameter) + var imageSize = CGSize(width: component.diameter, height: component.diameter) + if case let .media(media) = component.subject, media.count > 1 { + imageSize = CGSize(width: component.diameter - 6.0, height: component.diameter - 6.0) + } else if case let .extendedMedia(media) = component.subject, media.count > 1 { + imageSize = CGSize(width: component.diameter - 6.0, height: component.diameter - 6.0) + } + let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - imageSize.width) / 2.0), y: floorToScreenPixels((availableSize.height - imageSize.height) / 2.0)), size: imageSize) switch component.subject { diff --git a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift index d9f5bed1cd..cc283ed472 100644 --- a/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsWithdrawalScreen/Sources/StarsWithdrawalScreen.swift @@ -623,6 +623,7 @@ private final class AmountFieldComponent: Component { if let amount, let maxAmount = component.maxValue, amount > maxAmount { textField.text = "\(maxAmount)" + self.textChanged(self.textField) self.animateError() return false } diff --git a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift index 8cf3708fd0..77f9463ec8 100644 --- a/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPinnedMessageTitlePanelNode.swift @@ -654,9 +654,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode { } break } else if let file = fullMedia as? TelegramMediaFile { - if !file.isInstantVideo && !file.isSticker, let representation = largestImageRepresentation(file.previewRepresentations) { - imageDimensions = representation.dimensions.cgSize - } else if file.isAnimated, let dimensions = file.dimensions { + if let dimensions = file.dimensions { imageDimensions = dimensions.cgSize } break