From a8cff5c5e0bcd2b6d4a8abd4bd7fd8d69745fa0a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 7 Feb 2024 17:03:02 +0400 Subject: [PATCH] Group boosts --- .../Telegram-iOS/en.lproj/Localizable.strings | 6 + .../Sources/PeerNameColors.swift | 9 ++ .../Sources/PremiumBoostLevelsScreen.swift | 137 +++++++++--------- 3 files changed, 85 insertions(+), 67 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 0ed59c07cc..022093d1bb 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -11207,4 +11207,10 @@ Sorry for the inconvenience."; "GroupBoost.CustomWallpaper" = "Set Custom Group Wallpaper"; "GroupBoost.EnableCustomWallpaperLevelText" = "Your group needs **Level %1$@** to set custom group wallpaper."; +"GroupBoost.EmojiPack" = "Set Group Emoji Pack"; "GroupBoost.EnableEmojiPackLevelText" = "Your group needs **Level %1$@** to set emoji pack."; + +"GroupBoost.AudioTranscription" = "Audio Transcription"; + +"GroupBoost.AdditionalFeatures" = "Additional Features"; +"GroupBoost.AdditionalFeaturesText" = "By gaining **boosts**, your group reaches higher levels and unlocks more features."; diff --git a/submodules/AccountContext/Sources/PeerNameColors.swift b/submodules/AccountContext/Sources/PeerNameColors.swift index 7724bb1e97..0bca8e2346 100644 --- a/submodules/AccountContext/Sources/PeerNameColors.swift +++ b/submodules/AccountContext/Sources/PeerNameColors.swift @@ -88,6 +88,7 @@ public class PeerNameColors: Equatable { profileStoryDarkColors: [:], profileDisplayOrder: [], nameColorsChannelMinRequiredBoostLevel: [:], + profileColorsChannelMinRequiredBoostLevel: [:], profileColorsGroupMinRequiredBoostLevel: [:] ) } @@ -105,6 +106,7 @@ public class PeerNameColors: Equatable { public let profileDisplayOrder: [Int32] public let nameColorsChannelMinRequiredBoostLevel: [Int32: Int32] + public let profileColorsChannelMinRequiredBoostLevel: [Int32: Int32] public let profileColorsGroupMinRequiredBoostLevel: [Int32: Int32] public func get(_ color: PeerNameColor, dark: Bool = false) -> Colors { @@ -158,6 +160,7 @@ public class PeerNameColors: Equatable { profileStoryDarkColors: [Int32: Colors], profileDisplayOrder: [Int32], nameColorsChannelMinRequiredBoostLevel: [Int32: Int32], + profileColorsChannelMinRequiredBoostLevel: [Int32: Int32], profileColorsGroupMinRequiredBoostLevel: [Int32: Int32] ) { self.colors = colors @@ -171,6 +174,7 @@ public class PeerNameColors: Equatable { self.profileStoryDarkColors = profileStoryDarkColors self.profileDisplayOrder = profileDisplayOrder self.nameColorsChannelMinRequiredBoostLevel = nameColorsChannelMinRequiredBoostLevel + self.profileColorsChannelMinRequiredBoostLevel = profileColorsChannelMinRequiredBoostLevel self.profileColorsGroupMinRequiredBoostLevel = profileColorsGroupMinRequiredBoostLevel } @@ -187,6 +191,7 @@ public class PeerNameColors: Equatable { var profileDisplayOrder: [Int32] = [] var nameColorsChannelMinRequiredBoostLevel: [Int32: Int32] = [:] + var profileColorsChannelMinRequiredBoostLevel: [Int32: Int32] = [:] var profileColorsGroupMinRequiredBoostLevel: [Int32: Int32] = [:] if !availableReplyColors.options.isEmpty { @@ -216,6 +221,9 @@ public class PeerNameColors: Equatable { if !availableProfileColors.options.isEmpty { for option in availableProfileColors.options { + if let requiredChannelMinBoostLevel = option.value.requiredChannelMinBoostLevel { + profileColorsChannelMinRequiredBoostLevel[option.key] = requiredChannelMinBoostLevel + } if let requiredGroupMinBoostLevel = option.value.requiredGroupMinBoostLevel { profileColorsGroupMinRequiredBoostLevel[option.key] = requiredGroupMinBoostLevel } @@ -257,6 +265,7 @@ public class PeerNameColors: Equatable { profileStoryDarkColors: profileStoryDarkColors, profileDisplayOrder: profileDisplayOrder, nameColorsChannelMinRequiredBoostLevel: nameColorsChannelMinRequiredBoostLevel, + profileColorsChannelMinRequiredBoostLevel: profileColorsChannelMinRequiredBoostLevel, profileColorsGroupMinRequiredBoostLevel: profileColorsGroupMinRequiredBoostLevel ) } diff --git a/submodules/PremiumUI/Sources/PremiumBoostLevelsScreen.swift b/submodules/PremiumUI/Sources/PremiumBoostLevelsScreen.swift index f7764b1112..95fdc69d6f 100644 --- a/submodules/PremiumUI/Sources/PremiumBoostLevelsScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumBoostLevelsScreen.swift @@ -398,6 +398,7 @@ private final class SheetContent: CombinedComponent { let insets: UIEdgeInsets let peerId: EnginePeer.Id + let isGroup: Bool let mode: PremiumBoostLevelsScreen.Mode let status: ChannelBoostStatus? let boostState: InternalBoostState.DisplayData? @@ -414,6 +415,7 @@ private final class SheetContent: CombinedComponent { strings: PresentationStrings, insets: UIEdgeInsets, peerId: EnginePeer.Id, + isGroup: Bool, mode: PremiumBoostLevelsScreen.Mode, status: ChannelBoostStatus?, boostState: InternalBoostState.DisplayData?, @@ -429,6 +431,7 @@ private final class SheetContent: CombinedComponent { self.strings = strings self.insets = insets self.peerId = peerId + self.isGroup = isGroup self.mode = mode self.status = status self.boostState = boostState @@ -453,6 +456,9 @@ private final class SheetContent: CombinedComponent { if lhs.peerId != rhs.peerId { return false } + if lhs.isGroup != rhs.isGroup { + return false + } if lhs.mode != rhs.mode { return false } @@ -547,10 +553,7 @@ private final class SheetContent: CombinedComponent { let iconName = "Premium/Boost" let peerName = state.peer?.compactDisplayTitle ?? "" - var isGroup = false - if let peer = state.peer, case let .channel(channel) = peer, case .group = channel.info { - isGroup = true - } + let isGroup = component.isGroup let level: Int let boosts: Int @@ -681,7 +684,7 @@ private final class SheetContent: CombinedComponent { isCurrent = mode == .current } case .features: - textString = "By gaining **boosts**, your group reaches higher levels and unlocks more features." + textString = strings.GroupBoost_AdditionalFeaturesText } let defaultTitle = strings.ChannelBoost_Level("\(level)").string @@ -1062,7 +1065,7 @@ private final class SheetContent: CombinedComponent { var profileColorsAtLevel: [(Int32, Int32)] = [] var profileColorsCountMap: [Int32: Int32] = [:] for color in context.component.context.peerNameColors.profileDisplayOrder { - if let level = context.component.context.peerNameColors.profileColorsGroupMinRequiredBoostLevel[color] { + if let level = isGroup ? context.component.context.peerNameColors.profileColorsGroupMinRequiredBoostLevel[color] : context.component.context.peerNameColors.profileColorsChannelMinRequiredBoostLevel[color] { if let current = profileColorsCountMap[level] { profileColorsCountMap[level] = current + 1 } else { @@ -1103,11 +1106,6 @@ private final class SheetContent: CombinedComponent { perks.append(.audioTranscription) } -// if level >= premiumConfiguration.minChannelProfileColorLevel { -// let delta = min(level - premiumConfiguration.minChannelProfileColorLevel + 1, 2) -// perks.append(.profileColor(8 * delta)) -// } - var profileColorsCount: Int32 = 0 for (colorLevel, count) in profileColorsAtLevel { if level >= colorLevel { @@ -1301,56 +1299,63 @@ private final class BoostLevelsContainerComponent: CombinedComponent { let component = context.component - var isGroup = false - if let peer = state.peer, case let .channel(channel) = peer, case .group = channel.info { - isGroup = true + var isGroup: Bool? + if let peer = state.peer { + if case let .channel(channel) = peer, case .group = channel.info { + isGroup = true + } else { + isGroup = false + } } - let scroll = scroll.update( - component: ScrollComponent( - content: AnyComponent( - SheetContent( - context: component.context, - theme: component.theme, - strings: component.strings, - insets: .zero, - peerId: component.peerId, - mode: component.mode, - status: component.status, - boostState: component.boostState, - boost: component.boost, - copyLink: component.copyLink, - dismiss: component.dismiss, - openStats: component.openStats, - openGift: component.openGift, - openPeer: component.openPeer - ) + if let isGroup { + let scroll = scroll.update( + component: ScrollComponent( + content: AnyComponent( + SheetContent( + context: component.context, + theme: component.theme, + strings: component.strings, + insets: .zero, + peerId: component.peerId, + isGroup: isGroup, + mode: component.mode, + status: component.status, + boostState: component.boostState, + boost: component.boost, + copyLink: component.copyLink, + dismiss: component.dismiss, + openStats: component.openStats, + openGift: component.openGift, + openPeer: component.openPeer + ) + ), + contentInsets: UIEdgeInsets(top: topInset, left: 0.0, bottom: 0.0, right: 0.0), + contentOffsetUpdated: { [weak state] topContentOffset, _ in + state?.topContentOffset = topContentOffset + Queue.mainQueue().justDispatch { + state?.updated(transition: .immediate) + } + }, + contentOffsetWillCommit: { _ in } ), - contentInsets: UIEdgeInsets(top: topInset, left: 0.0, bottom: 34.0, right: 0.0), - contentOffsetUpdated: { [weak state] topContentOffset, _ in - state?.topContentOffset = topContentOffset - Queue.mainQueue().justDispatch { - state?.updated(transition: .immediate) - } - }, - contentOffsetWillCommit: { _ in } - ), - availableSize: context.availableSize, - transition: context.transition - ) - - let background = background.update( - component: Rectangle(color: theme.overallDarkAppearance ? theme.list.blocksBackgroundColor : theme.list.plainBackgroundColor), - availableSize: scroll.size, - transition: context.transition - ) - context.add(background - .position(CGPoint(x: context.availableSize.width / 2.0, y: background.size.height / 2.0)) - ) - - context.add(scroll - .position(CGPoint(x: context.availableSize.width / 2.0, y: scroll.size.height / 2.0)) - ) + availableSize: context.availableSize, + transition: context.transition + ) + + let background = background.update( + component: Rectangle(color: theme.overallDarkAppearance ? theme.list.blocksBackgroundColor : theme.list.plainBackgroundColor), + availableSize: scroll.size, + transition: context.transition + ) + context.add(background + .position(CGPoint(x: context.availableSize.width / 2.0, y: background.size.height / 2.0)) + ) + + context.add(scroll + .position(CGPoint(x: context.availableSize.width / 2.0, y: scroll.size.height / 2.0)) + ) + } let topPanel = topPanel.update( component: BlurredBackgroundComponent( @@ -1399,13 +1404,12 @@ private final class BoostLevelsContainerComponent: CombinedComponent { case .customWallpaper: titleString = strings.ChannelBoost_CustomWallpaper case .audioTranscription: - //TODO:localize - titleString = "Audio Transcription" + titleString = strings.GroupBoost_AudioTranscription case .emojiPack: - titleString = "Set Group Emoji Pack" + titleString = strings.GroupBoost_EmojiPack } } else { - titleString = isGroup ? strings.GroupBoost_Title_Current : strings.ChannelBoost_Title_Current + titleString = isGroup == true ? strings.GroupBoost_Title_Current : strings.ChannelBoost_Title_Current } } else { titleString = strings.ChannelBoost_MaxLevelReached @@ -1418,16 +1422,15 @@ private final class BoostLevelsContainerComponent: CombinedComponent { if let _ = remaining { if case .current = mode { - titleString = isGroup ? strings.GroupBoost_Title_Current : strings.ChannelBoost_Title_Current + titleString = isGroup == true ? strings.GroupBoost_Title_Current : strings.ChannelBoost_Title_Current } else { - titleString = isGroup ? strings.GroupBoost_Title_Other : strings.ChannelBoost_Title_Other + titleString = isGroup == true ? strings.GroupBoost_Title_Other : strings.ChannelBoost_Title_Other } } else { titleString = strings.ChannelBoost_MaxLevelReached } case .features: - //TODO:localize - titleString = "Additional Features" + titleString = strings.GroupBoost_AdditionalFeatures titleFont = Font.semibold(20.0) } @@ -1523,7 +1526,7 @@ private final class BoostLevelsContainerComponent: CombinedComponent { .position(CGPoint(x: context.availableSize.width - closeButton.size.width, y: 28.0)) ) - return scroll.size + return context.availableSize } } }