Group boosts

This commit is contained in:
Ilya Laktyushin 2024-02-07 15:14:18 +04:00
parent 0fce018dbf
commit 9d2fb9f8e3
5 changed files with 95 additions and 59 deletions

View File

@ -11109,8 +11109,6 @@ Sorry for the inconvenience.";
"Chat.Giveaway.Info.Group.OngoingIntro" = "The giveaway is sponsored by the admins of **%1$@**, who acquired %2$@ for %3$@ for its members.";
"Chat.Giveaway.Info.Group.EndedIntro" = "The giveaway was sponsored by the admins of **%1$@**, who acquired %2$@ for %3$@ for its members.";
"ChannelBoost.EnableGroupEmojiPackLevelText" = "Your group needs **Level %1$@** to set emoji pack.";
"Premium.LastSeen" = "Last Seen Times";
"Premium.LastSeenInfo" = "View the last seen and read times of others even if you hide yours.";
"Premium.LastSeen.Proceed" = "About Telegram Premium";
@ -11192,3 +11190,21 @@ Sorry for the inconvenience.";
"Group.Emoji.NotFound" = "Emoji pack not found";
"Group.Emoji.NotFoundHelp" = "Try again or choose from the list below";
"GroupBoost.ProfileColor" = "Set Cover Color";
"GroupBoost.EnableProfileColorLevelText" = "Your group needs **Level %1$@** to change group cover color.";
"GroupBoost.ProfileIcon" = "Set Cover Icon";
"GroupBoost.EnableProfileIconLevelText" = "Your group needs **Level %1$@** to change group cover icon.";
"GroupBoost.EmojiStatus" = "Use Emoji Statuses";
"GroupBoost.EnableEmojiStatusLevelText" = "Your group needs **Level %1$@** to use emoji statuses.";
"GroupBoost.Wallpaper" = "Set Group Wallpaper";
"GroupBoost.EnableWallpaperLevelText" = "Your group needs **Level %1$@** to set group wallpaper.";
"GroupBoost.CustomWallpaper" = "Set Custom Group Wallpaper";
"GroupBoost.EnableCustomWallpaperLevelText" = "Your group needs **Level %1$@** to set custom group wallpaper.";
"GroupBoost.EnableEmojiPackLevelText" = "Your group needs **Level %1$@** to set emoji pack.";

View File

@ -88,7 +88,7 @@ public class PeerNameColors: Equatable {
profileStoryDarkColors: [:],
profileDisplayOrder: [],
nameColorsChannelMinRequiredBoostLevel: [:],
nameColorsGroupMinRequiredBoostLevel: [:]
profileColorsGroupMinRequiredBoostLevel: [:]
)
}
@ -105,7 +105,7 @@ public class PeerNameColors: Equatable {
public let profileDisplayOrder: [Int32]
public let nameColorsChannelMinRequiredBoostLevel: [Int32: Int32]
public let nameColorsGroupMinRequiredBoostLevel: [Int32: Int32]
public let profileColorsGroupMinRequiredBoostLevel: [Int32: Int32]
public func get(_ color: PeerNameColor, dark: Bool = false) -> Colors {
if dark, let colors = self.darkColors[color.rawValue] {
@ -158,7 +158,7 @@ public class PeerNameColors: Equatable {
profileStoryDarkColors: [Int32: Colors],
profileDisplayOrder: [Int32],
nameColorsChannelMinRequiredBoostLevel: [Int32: Int32],
nameColorsGroupMinRequiredBoostLevel: [Int32: Int32]
profileColorsGroupMinRequiredBoostLevel: [Int32: Int32]
) {
self.colors = colors
self.darkColors = darkColors
@ -171,7 +171,7 @@ public class PeerNameColors: Equatable {
self.profileStoryDarkColors = profileStoryDarkColors
self.profileDisplayOrder = profileDisplayOrder
self.nameColorsChannelMinRequiredBoostLevel = nameColorsChannelMinRequiredBoostLevel
self.nameColorsGroupMinRequiredBoostLevel = nameColorsGroupMinRequiredBoostLevel
self.profileColorsGroupMinRequiredBoostLevel = profileColorsGroupMinRequiredBoostLevel
}
public static func with(availableReplyColors: EngineAvailableColorOptions, availableProfileColors: EngineAvailableColorOptions) -> PeerNameColors {
@ -187,17 +187,13 @@ public class PeerNameColors: Equatable {
var profileDisplayOrder: [Int32] = []
var nameColorsChannelMinRequiredBoostLevel: [Int32: Int32] = [:]
var nameColorsGroupMinRequiredBoostLevel: [Int32: Int32] = [:]
var profileColorsGroupMinRequiredBoostLevel: [Int32: Int32] = [:]
if !availableReplyColors.options.isEmpty {
for option in availableReplyColors.options {
if let requiredChannelMinBoostLevel = option.value.requiredChannelMinBoostLevel {
nameColorsChannelMinRequiredBoostLevel[option.key] = requiredChannelMinBoostLevel
}
if let requiredGroupMinBoostLevel = option.value.requiredGroupMinBoostLevel {
nameColorsGroupMinRequiredBoostLevel[option.key] = requiredGroupMinBoostLevel
}
if let parsedLight = PeerNameColors.Colors(colors: option.value.light.background) {
colors[option.key] = parsedLight
}
@ -220,6 +216,9 @@ public class PeerNameColors: Equatable {
if !availableProfileColors.options.isEmpty {
for option in availableProfileColors.options {
if let requiredGroupMinBoostLevel = option.value.requiredGroupMinBoostLevel {
profileColorsGroupMinRequiredBoostLevel[option.key] = requiredGroupMinBoostLevel
}
if let parsedLight = PeerNameColors.Colors(colors: option.value.light.background) {
profileColors[option.key] = parsedLight
}
@ -258,7 +257,7 @@ public class PeerNameColors: Equatable {
profileStoryDarkColors: profileStoryDarkColors,
profileDisplayOrder: profileDisplayOrder,
nameColorsChannelMinRequiredBoostLevel: nameColorsChannelMinRequiredBoostLevel,
nameColorsGroupMinRequiredBoostLevel: nameColorsGroupMinRequiredBoostLevel
profileColorsGroupMinRequiredBoostLevel: profileColorsGroupMinRequiredBoostLevel
)
}

View File

@ -28,20 +28,21 @@ func requiredBoostSubjectLevel(subject: BoostSubject, group: Bool, context: Acco
case let .channelReactions(reactionCount):
return reactionCount
case let .nameColors(colors):
if group {
if let value = context.peerNameColors.nameColorsGroupMinRequiredBoostLevel[colors.rawValue] {
return value
}
} else {
if let value = context.peerNameColors.nameColorsChannelMinRequiredBoostLevel[colors.rawValue] {
return value
}
if let value = context.peerNameColors.nameColorsChannelMinRequiredBoostLevel[colors.rawValue] {
return value
}
return 1
case .nameIcon:
return configuration.minChannelNameIconLevel
case .profileColors:
return configuration.minChannelProfileColorLevel
case let .profileColors(colors):
if group {
if let value = context.peerNameColors.profileColorsGroupMinRequiredBoostLevel[colors.rawValue] {
return value
}
} else {
return configuration.minChannelProfileColorLevel
}
return 1
case .profileIcon:
return group ? configuration.minGroupProfileIconLevel : configuration.minChannelProfileIconLevel
case .emojiStatus:
@ -62,7 +63,7 @@ public enum BoostSubject: Equatable {
case channelReactions(reactionCount: Int32)
case nameColors(colors: PeerNameColor)
case nameIcon
case profileColors
case profileColors(colors: PeerNameColor)
case profileIcon
case emojiStatus
case wallpaper
@ -616,19 +617,19 @@ private final class SheetContent: CombinedComponent {
case .nameIcon:
textString = strings.ChannelBoost_EnableNameIconLevelText("\(premiumConfiguration.minChannelNameIconLevel)").string
case .profileColors:
textString = strings.ChannelBoost_EnableProfileColorLevelText("\(premiumConfiguration.minChannelProfileColorLevel)").string
textString = isGroup ? strings.GroupBoost_EnableProfileColorLevelText("\(premiumConfiguration.minChannelProfileColorLevel)").string : strings.ChannelBoost_EnableProfileColorLevelText("\(premiumConfiguration.minChannelProfileColorLevel)").string
case .profileIcon:
textString = strings.ChannelBoost_EnableProfileIconLevelText("\(premiumConfiguration.minChannelProfileIconLevel)").string
textString = isGroup ? strings.GroupBoost_EnableProfileIconLevelText("\(premiumConfiguration.minChannelProfileIconLevel)").string : strings.ChannelBoost_EnableProfileIconLevelText("\(premiumConfiguration.minChannelProfileIconLevel)").string
case .emojiStatus:
textString = strings.ChannelBoost_EnableEmojiStatusLevelText("\(premiumConfiguration.minChannelEmojiStatusLevel)").string
textString = isGroup ? strings.GroupBoost_EnableEmojiStatusLevelText("\(premiumConfiguration.minChannelEmojiStatusLevel)").string : strings.ChannelBoost_EnableEmojiStatusLevelText("\(premiumConfiguration.minChannelEmojiStatusLevel)").string
case .wallpaper:
textString = strings.ChannelBoost_EnableWallpaperLevelText("\(premiumConfiguration.minChannelWallpaperLevel)").string
textString = isGroup ? strings.GroupBoost_EnableWallpaperLevelText("\(premiumConfiguration.minChannelWallpaperLevel)").string : strings.ChannelBoost_EnableWallpaperLevelText("\(premiumConfiguration.minChannelWallpaperLevel)").string
case .customWallpaper:
textString = strings.ChannelBoost_EnableCustomWallpaperLevelText("\(premiumConfiguration.minChannelCustomWallpaperLevel)").string
textString = isGroup ? strings.GroupBoost_EnableCustomWallpaperLevelText("\(premiumConfiguration.minChannelCustomWallpaperLevel)").string : strings.ChannelBoost_EnableCustomWallpaperLevelText("\(premiumConfiguration.minChannelCustomWallpaperLevel)").string
case .audioTranscription:
textString = ""
case .emojiPack:
textString = strings.ChannelBoost_EnableGroupEmojiPackLevelText("\(premiumConfiguration.minGroupEmojiPackLevel)").string
textString = strings.GroupBoost_EnableEmojiPackLevelText("\(premiumConfiguration.minGroupEmojiPackLevel)").string
}
} else {
let boostsString = strings.ChannelBoost_MoreBoostsNeeded_Boosts(Int32(remaining))
@ -1058,6 +1059,21 @@ private final class SheetContent: CombinedComponent {
nameColorsAtLevel.append((key, value))
}
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 current = profileColorsCountMap[level] {
profileColorsCountMap[level] = current + 1
} else {
profileColorsCountMap[level] = 1
}
}
}
for (key, value) in profileColorsCountMap {
profileColorsAtLevel.append((key, value))
}
var isFeatures = false
if case .features = component.mode {
isFeatures = true
@ -1083,19 +1099,30 @@ private final class SheetContent: CombinedComponent {
perks.append(.nameColor(nameColorsCount))
}
if isGroup && level >= premiumConfiguration.minGroupAudioTranscriptionLevel {
if isGroup && level >= requiredBoostSubjectLevel(subject: .audioTranscription, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.audioTranscription)
}
if level >= premiumConfiguration.minChannelProfileColorLevel {
let delta = min(level - premiumConfiguration.minChannelProfileColorLevel + 1, 2)
perks.append(.profileColor(8 * delta))
// 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 {
profileColorsCount += count
}
}
if level >= premiumConfiguration.minChannelProfileIconLevel {
if profileColorsCount > 0 {
perks.append(.profileColor(profileColorsCount))
}
if level >= requiredBoostSubjectLevel(subject: .profileIcon, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.profileIcon)
}
if isGroup && level >= premiumConfiguration.minGroupAudioTranscriptionLevel {
if isGroup && level >= requiredBoostSubjectLevel(subject: .audioTranscription, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.emojiPack)
}
@ -1109,16 +1136,16 @@ private final class SheetContent: CombinedComponent {
perks.append(.linkColor(linkColorsCount))
}
if !isGroup && level >= premiumConfiguration.minChannelNameIconLevel {
if !isGroup && level >= requiredBoostSubjectLevel(subject: .nameIcon, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.linkIcon)
}
if level >= premiumConfiguration.minChannelEmojiStatusLevel {
if level >= requiredBoostSubjectLevel(subject: .emojiStatus, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.emojiStatus)
}
if level >= premiumConfiguration.minChannelWallpaperLevel {
if level >= requiredBoostSubjectLevel(subject: .wallpaper, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.wallpaper(8))
}
if level >= premiumConfiguration.minChannelCustomWallpaperLevel {
if level >= requiredBoostSubjectLevel(subject: .customWallpaper, group: isGroup, context: component.context, configuration: premiumConfiguration) {
perks.append(.customWallpaper)
}

View File

@ -129,26 +129,20 @@ func _internal_applyChannelBoost(account: Account, peerId: PeerId, slots: [Int32
|> mapToSignal { result -> Signal<MyBoostStatus?, NoError> in
if let result = result {
return account.postbox.transaction { transaction -> MyBoostStatus? in
let myBoostStatus = MyBoostStatus(apiMyBoostStatus: result, accountPeerId: account.peerId, transaction: transaction)
var appliedBoosts: Int32 = 0
for boost in myBoostStatus.boosts {
if boost.peer?.id == peerId {
appliedBoosts += 1
let myStatus = MyBoostStatus(apiMyBoostStatus: result, accountPeerId: account.peerId, transaction: transaction)
let peerIds = myStatus.boosts.reduce(Set<PeerId>(), { current, value in
var current = current
if let peerId = value.peer?.id {
current.insert(peerId)
}
}
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
var cachedData: CachedChannelData
if let current = current as? CachedChannelData {
cachedData = current
} else {
cachedData = CachedChannelData()
}
return cachedData.withUpdatedAppliedBoosts(appliedBoosts)
return current
})
return myBoostStatus
transaction.updatePeerCachedData(peerIds: peerIds, update: { peerId, cachedData in
let cachedData = cachedData as? CachedChannelData ?? CachedChannelData()
let count = myStatus.boosts.filter { $0.peer?.id == peerId }.count
return cachedData.withUpdatedAppliedBoosts(count != 0 ? Int32(count) : nil)
})
return myStatus
}
} else {
return .single(nil)

View File

@ -945,8 +945,8 @@ final class ChannelAppearanceScreenComponent: Component {
}
let profileColor = resolvedState.profileColor
if profileColor != nil {
requiredBoostSubjects.append(.profileColors)
if let profileColor {
requiredBoostSubjects.append(.profileColors(colors: profileColor))
}
let backgroundFileId = resolvedState.backgroundFileId