mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Channel appearance
This commit is contained in:
parent
3fc9d37ba7
commit
2708aa0a41
@ -1388,7 +1388,8 @@ public class PeerNameColors: Equatable {
|
||||
profilePaletteDarkColors: [:],
|
||||
profileStoryColors: [:],
|
||||
profileStoryDarkColors: [:],
|
||||
profileDisplayOrder: []
|
||||
profileDisplayOrder: [],
|
||||
nameColorsChannelMinRequiredBoostLevel: [:]
|
||||
)
|
||||
}
|
||||
|
||||
@ -1404,6 +1405,8 @@ public class PeerNameColors: Equatable {
|
||||
public let profileStoryDarkColors: [Int32: Colors]
|
||||
public let profileDisplayOrder: [Int32]
|
||||
|
||||
public let nameColorsChannelMinRequiredBoostLevel: [Int32: Int32]
|
||||
|
||||
public func get(_ color: PeerNameColor, dark: Bool = false) -> Colors {
|
||||
if dark, let colors = self.darkColors[color.rawValue] {
|
||||
return colors
|
||||
@ -1453,7 +1456,8 @@ public class PeerNameColors: Equatable {
|
||||
profilePaletteDarkColors: [Int32: Colors],
|
||||
profileStoryColors: [Int32: Colors],
|
||||
profileStoryDarkColors: [Int32: Colors],
|
||||
profileDisplayOrder: [Int32]
|
||||
profileDisplayOrder: [Int32],
|
||||
nameColorsChannelMinRequiredBoostLevel: [Int32: Int32]
|
||||
) {
|
||||
self.colors = colors
|
||||
self.darkColors = darkColors
|
||||
@ -1465,6 +1469,7 @@ public class PeerNameColors: Equatable {
|
||||
self.profileStoryColors = profileStoryColors
|
||||
self.profileStoryDarkColors = profileStoryDarkColors
|
||||
self.profileDisplayOrder = profileDisplayOrder
|
||||
self.nameColorsChannelMinRequiredBoostLevel = nameColorsChannelMinRequiredBoostLevel
|
||||
}
|
||||
|
||||
public static func with(availableReplyColors: EngineAvailableColorOptions, availableProfileColors: EngineAvailableColorOptions) -> PeerNameColors {
|
||||
@ -1479,8 +1484,14 @@ public class PeerNameColors: Equatable {
|
||||
var profileStoryDarkColors: [Int32: Colors] = [:]
|
||||
var profileDisplayOrder: [Int32] = []
|
||||
|
||||
var nameColorsChannelMinRequiredBoostLevel: [Int32: Int32] = [:]
|
||||
|
||||
if !availableReplyColors.options.isEmpty {
|
||||
for option in availableReplyColors.options {
|
||||
if let requiredChannelMinBoostLevel = option.value.requiredChannelMinBoostLevel {
|
||||
nameColorsChannelMinRequiredBoostLevel[option.key] = requiredChannelMinBoostLevel
|
||||
}
|
||||
|
||||
if let parsedLight = PeerNameColors.Colors(colors: option.value.light.background) {
|
||||
colors[option.key] = parsedLight
|
||||
}
|
||||
@ -1539,7 +1550,8 @@ public class PeerNameColors: Equatable {
|
||||
profilePaletteDarkColors: profilePaletteDarkColors,
|
||||
profileStoryColors: profileStoryColors,
|
||||
profileStoryDarkColors: profileStoryDarkColors,
|
||||
profileDisplayOrder: profileDisplayOrder
|
||||
profileDisplayOrder: profileDisplayOrder,
|
||||
nameColorsChannelMinRequiredBoostLevel: nameColorsChannelMinRequiredBoostLevel
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -4739,7 +4739,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
if self.experimentalSnapScrollToItem {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.visible, animated: animated, curve: ListViewAnimationCurve.Default(duration: nil), directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
} else {
|
||||
if node.frame.minY < self.insets.top {
|
||||
if node.frame.minY < self.insets.top + overflow {
|
||||
if !allowIntersection || node.frame.maxY < self.insets.top {
|
||||
let position: ListViewScrollPosition
|
||||
if allowIntersection {
|
||||
@ -4749,7 +4749,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
}
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: position, animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
}
|
||||
} else if node.frame.maxY > self.visibleSize.height - self.insets.bottom {
|
||||
} else if node.frame.maxY > self.visibleSize.height - self.insets.bottom - overflow {
|
||||
if !allowIntersection || node.frame.minY > self.visibleSize.height - self.insets.bottom {
|
||||
let position: ListViewScrollPosition
|
||||
if allowIntersection {
|
||||
|
@ -20,10 +20,37 @@ import SolidRoundedButtonComponent
|
||||
import BlurredBackgroundComponent
|
||||
import UndoUI
|
||||
|
||||
func requiredBoostSubjectLevel(subject: BoostSubject, context: AccountContext, configuration: PremiumConfiguration) -> Int32 {
|
||||
switch subject {
|
||||
case .stories:
|
||||
return 1
|
||||
case let .channelReactions(reactionCount):
|
||||
return reactionCount
|
||||
case let .nameColors(colors):
|
||||
if let value = context.peerNameColors.nameColorsChannelMinRequiredBoostLevel[colors.rawValue] {
|
||||
return value
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
case .nameIcon:
|
||||
return configuration.minChannelNameIconLevel
|
||||
case .profileColors:
|
||||
return configuration.minChannelProfileColorLevel
|
||||
case .profileIcon:
|
||||
return configuration.minChannelProfileIconLevel
|
||||
case .emojiStatus:
|
||||
return configuration.minChannelEmojiStatusLevel
|
||||
case .wallpaper:
|
||||
return configuration.minChannelWallpaperLevel
|
||||
case .customWallpaper:
|
||||
return configuration.minChannelCustomWallpaperLevel
|
||||
}
|
||||
}
|
||||
|
||||
public enum BoostSubject: Equatable {
|
||||
case stories
|
||||
case channelReactions(reactionCount: Int32)
|
||||
case nameColors
|
||||
case nameColors(colors: PeerNameColor)
|
||||
case nameIcon
|
||||
case profileColors
|
||||
case profileIcon
|
||||
@ -31,27 +58,8 @@ public enum BoostSubject: Equatable {
|
||||
case wallpaper
|
||||
case customWallpaper
|
||||
|
||||
public func requiredLevel(_ configuration: PremiumConfiguration) -> Int32 {
|
||||
switch self {
|
||||
case .stories:
|
||||
return 1
|
||||
case let .channelReactions(reactionCount):
|
||||
return reactionCount
|
||||
case .nameColors:
|
||||
return configuration.minChannelNameColorLevel
|
||||
case .nameIcon:
|
||||
return configuration.minChannelNameIconLevel
|
||||
case .profileColors:
|
||||
return configuration.minChannelProfileColorLevel
|
||||
case .profileIcon:
|
||||
return configuration.minChannelProfileIconLevel
|
||||
case .emojiStatus:
|
||||
return configuration.minChannelEmojiStatusLevel
|
||||
case .wallpaper:
|
||||
return configuration.minChannelWallpaperLevel
|
||||
case .customWallpaper:
|
||||
return configuration.minChannelCustomWallpaperLevel
|
||||
}
|
||||
public func requiredLevel(context: AccountContext, configuration: PremiumConfiguration) -> Int32 {
|
||||
return requiredBoostSubjectLevel(subject: self, context: context, configuration: configuration)
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,7 +487,9 @@ private final class LimitSheetContent: CombinedComponent {
|
||||
textString = strings.ChannelBoost_CustomReactionsText("\(reactionCount)", "\(reactionCount)").string
|
||||
needsSecondParagraph = false
|
||||
case .nameColors:
|
||||
textString = strings.ChannelBoost_EnableNameColorLevelText("\(premiumConfiguration.minChannelNameColorLevel)").string
|
||||
let colorLevel = component.subject.requiredLevel(context: context.component.context, configuration: premiumConfiguration)
|
||||
|
||||
textString = strings.ChannelBoost_EnableNameColorLevelText("\(colorLevel)").string
|
||||
case .nameIcon:
|
||||
textString = strings.ChannelBoost_EnableNameIconLevelText("\(premiumConfiguration.minChannelNameIconLevel)").string
|
||||
case .profileColors:
|
||||
|
@ -1180,6 +1180,7 @@ private final class LimitSheetContent: CombinedComponent {
|
||||
if let remaining {
|
||||
let storiesString = strings.ChannelBoost_StoriesPerDay(level + 1)
|
||||
let valueString = strings.ChannelBoost_MoreBoosts(remaining)
|
||||
|
||||
switch boostSubject {
|
||||
case .stories:
|
||||
if level == 0 {
|
||||
@ -1189,9 +1190,12 @@ private final class LimitSheetContent: CombinedComponent {
|
||||
titleText = strings.ChannelBoost_IncreaseLimit
|
||||
string = strings.ChannelBoost_IncreaseLimitText(valueString, storiesString).string
|
||||
}
|
||||
case .nameColors:
|
||||
case let .nameColors(colors):
|
||||
titleText = strings.ChannelBoost_EnableColors
|
||||
string = strings.ChannelBoost_EnableColorsLevelText("\(premiumConfiguration.minChannelNameColorLevel)").string
|
||||
|
||||
let colorLevel = requiredBoostSubjectLevel(subject: .nameColors(colors: colors), context: component.context, configuration: premiumConfiguration)
|
||||
|
||||
string = strings.ChannelBoost_EnableColorsLevelText("\(colorLevel)").string
|
||||
case let .channelReactions(reactionCount):
|
||||
titleText = strings.ChannelBoost_CustomReactions
|
||||
string = strings.ChannelBoost_CustomReactionsText("\(reactionCount)", "\(reactionCount)").string
|
||||
@ -1778,7 +1782,7 @@ public class PremiumLimitScreen: ViewControllerComponentContainer {
|
||||
|
||||
public enum BoostSubject: Equatable {
|
||||
case stories
|
||||
case nameColors
|
||||
case nameColors(colors: PeerNameColor)
|
||||
case channelReactions(reactionCount: Int)
|
||||
}
|
||||
|
||||
|
@ -193,10 +193,14 @@ private final class ThemeGridThemeItemIconNode : ASDisplayNode {
|
||||
}
|
||||
|
||||
let string: String?
|
||||
if let _ = item.themeReference.emoticon {
|
||||
string = nil
|
||||
if let themeReference = item.themeReference {
|
||||
if let _ = themeReference.emoticon {
|
||||
string = nil
|
||||
} else {
|
||||
string = themeDisplayName(strings: item.strings, reference: themeReference)
|
||||
}
|
||||
} else {
|
||||
string = themeDisplayName(strings: item.strings, reference: item.themeReference)
|
||||
string = nil
|
||||
}
|
||||
|
||||
let text = NSAttributedString(string: string ?? item.strings.Conversation_Theme_NoTheme, font: Font.bold(14.0), textColor: .white)
|
||||
@ -207,16 +211,17 @@ private final class ThemeGridThemeItemIconNode : ASDisplayNode {
|
||||
let (_, emojiApply) = makeEmojiLayout(TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: size.width, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
if updatedThemeReference || updatedWallpaper || updatedNightMode || updatedSize {
|
||||
var themeReference = item.themeReference
|
||||
if case .builtin = themeReference, item.nightMode {
|
||||
themeReference = .builtin(.night)
|
||||
if var themeReference = item.themeReference {
|
||||
if case .builtin = themeReference, item.nightMode {
|
||||
themeReference = .builtin(.night)
|
||||
}
|
||||
|
||||
let color = item.themeSpecificAccentColors[themeReference.index]
|
||||
let wallpaper = item.themeSpecificChatWallpapers[themeReference.index]
|
||||
|
||||
self.imageNode.setSignal(themeIconImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, theme: themeReference, color: color, wallpaper: wallpaper ?? item.wallpaper, nightMode: item.nightMode, emoticon: true, large: true))
|
||||
self.imageNode.backgroundColor = nil
|
||||
}
|
||||
|
||||
let color = item.themeSpecificAccentColors[themeReference.index]
|
||||
let wallpaper = item.themeSpecificChatWallpapers[themeReference.index]
|
||||
|
||||
self.imageNode.setSignal(themeIconImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, theme: themeReference, color: color, wallpaper: wallpaper ?? item.wallpaper, nightMode: item.nightMode, emoticon: true, large: true))
|
||||
self.imageNode.backgroundColor = nil
|
||||
}
|
||||
|
||||
if updatedTheme || updatedSelected {
|
||||
@ -501,7 +506,9 @@ class ThemeGridThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let selected = item.currentTheme.index == theme.index
|
||||
|
||||
let iconItem = ThemeCarouselThemeIconItem(context: item.context, emojiFile: theme.emoticon.flatMap { item.animatedEmojiStickers[$0]?.first?.file }, themeReference: theme, nightMode: item.nightMode, channelMode: false, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil, action: { theme in
|
||||
item.updatedTheme(theme)
|
||||
if let theme {
|
||||
item.updatedTheme(theme)
|
||||
}
|
||||
}, contextAction: nil)
|
||||
|
||||
validIds.append(theme.index)
|
||||
|
@ -283,8 +283,10 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
case let .chatPreview(theme, wallpaper, fontSize, chatBubbleCorners, strings, dateTimeFormat, nameDisplayOrder, items):
|
||||
return ThemeSettingsChatPreviewItem(context: arguments.context, theme: theme, componentTheme: theme, strings: strings, sectionId: self.section, fontSize: fontSize, chatBubbleCorners: chatBubbleCorners, wallpaper: wallpaper, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, messageItems: items)
|
||||
case let .themes(theme, strings, chatThemes, currentTheme, nightMode, animatedEmojiStickers, themeSpecificAccentColors, themeSpecificChatWallpapers):
|
||||
return ThemeCarouselThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: chatThemes, animatedEmojiStickers: animatedEmojiStickers, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, nightMode: nightMode, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
arguments.selectTheme(theme)
|
||||
return ThemeCarouselThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: chatThemes, hasNoTheme: false, animatedEmojiStickers: animatedEmojiStickers, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, nightMode: nightMode, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
if let theme {
|
||||
arguments.selectTheme(theme)
|
||||
}
|
||||
}, contextAction: { theme, node, gesture in
|
||||
arguments.themeContextAction(false, theme, node, gesture)
|
||||
}, tag: ThemeSettingsEntryTag.theme)
|
||||
|
@ -628,6 +628,7 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP
|
||||
if abs(panGestureState.offsetFraction) > 0.6 || abs(velocity.y) >= 100.0 {
|
||||
self.panGestureState = PanGestureState(offsetFraction: panGestureState.offsetFraction < 0.0 ? -1.0 : 1.0)
|
||||
self.notifyDismissedInteractivelyOnPanGestureApply = true
|
||||
self.callScreen.beginPictureInPictureIfPossible()
|
||||
}
|
||||
|
||||
self.update(transition: .animated(duration: 0.4, curve: .spring))
|
||||
|
@ -94,16 +94,19 @@ public final class EngineAvailableColorOptions: Codable, Equatable {
|
||||
case light = "l"
|
||||
case dark = "d"
|
||||
case isHidden = "h"
|
||||
case requiredChannelMinBoostLevel = "rcmb"
|
||||
}
|
||||
|
||||
public let light: ColorOption
|
||||
public let dark: ColorOption?
|
||||
public let isHidden: Bool
|
||||
public let requiredChannelMinBoostLevel: Int32?
|
||||
|
||||
public init(light: ColorOption, dark: ColorOption?, isHidden: Bool) {
|
||||
public init(light: ColorOption, dark: ColorOption?, isHidden: Bool, requiredChannelMinBoostLevel: Int32?) {
|
||||
self.light = light
|
||||
self.dark = dark
|
||||
self.isHidden = isHidden
|
||||
self.requiredChannelMinBoostLevel = requiredChannelMinBoostLevel
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
@ -112,6 +115,7 @@ public final class EngineAvailableColorOptions: Codable, Equatable {
|
||||
self.light = try container.decode(ColorOption.self, forKey: .light)
|
||||
self.dark = try container.decodeIfPresent(ColorOption.self, forKey: .dark)
|
||||
self.isHidden = try container.decode(Bool.self, forKey: .isHidden)
|
||||
self.requiredChannelMinBoostLevel = try container.decodeIfPresent(Int32.self, forKey: .requiredChannelMinBoostLevel)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -120,6 +124,7 @@ public final class EngineAvailableColorOptions: Codable, Equatable {
|
||||
try container.encode(self.light, forKey: .light)
|
||||
try container.encodeIfPresent(self.dark, forKey: .dark)
|
||||
try container.encodeIfPresent(self.isHidden, forKey: .isHidden)
|
||||
try container.encodeIfPresent(self.requiredChannelMinBoostLevel, forKey: .requiredChannelMinBoostLevel)
|
||||
}
|
||||
|
||||
public static func ==(lhs: ColorOptionPack, rhs: ColorOptionPack) -> Bool {
|
||||
@ -135,6 +140,9 @@ public final class EngineAvailableColorOptions: Codable, Equatable {
|
||||
if lhs.isHidden != rhs.isHidden {
|
||||
return false
|
||||
}
|
||||
if lhs.requiredChannelMinBoostLevel != rhs.requiredChannelMinBoostLevel {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -262,14 +270,14 @@ private extension EngineAvailableColorOptions {
|
||||
var mappedOptions: [Option] = []
|
||||
for apiColor in apiColors {
|
||||
switch apiColor {
|
||||
case let .peerColorOption(flags, colorId, colors, darkColors, _):
|
||||
case let .peerColorOption(flags, colorId, colors, darkColors, requiredChannelMinBoostLevel):
|
||||
let isHidden = (flags & (1 << 0)) != 0
|
||||
|
||||
let mappedColors = colors.flatMap(EngineAvailableColorOptions.ColorOption.init(apiColors:))
|
||||
let mappedDarkColors = darkColors.flatMap(EngineAvailableColorOptions.ColorOption.init(apiColors:))
|
||||
|
||||
if let mappedColors = mappedColors {
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: mappedColors, dark: mappedDarkColors, isHidden: isHidden)))
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: mappedColors, dark: mappedDarkColors, isHidden: isHidden, requiredChannelMinBoostLevel: requiredChannelMinBoostLevel)))
|
||||
} else if colorId >= 0 && colorId <= 6 {
|
||||
let staticMap: [UInt32] = [
|
||||
0xcc5049,
|
||||
@ -282,7 +290,7 @@ private extension EngineAvailableColorOptions {
|
||||
]
|
||||
let colorPack = MultiColorPack(colors: [staticMap[Int(colorId)]])
|
||||
let defaultColors = EngineAvailableColorOptions.ColorOption(palette: colorPack, background: colorPack, stories: nil)
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: defaultColors, dark: nil, isHidden: isHidden)))
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: defaultColors, dark: nil, isHidden: isHidden, requiredChannelMinBoostLevel: requiredChannelMinBoostLevel)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
|
||||
let requiredLevel = requiredBoostSubject.requiredLevel(premiumConfiguration)
|
||||
let requiredLevel = requiredBoostSubject.requiredLevel(context: component.context, configuration: premiumConfiguration)
|
||||
if let boostLevel = self.boostLevel, requiredLevel > boostLevel {
|
||||
self.displayBoostLevels(subject: requiredBoostSubject)
|
||||
return
|
||||
@ -806,7 +806,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
return availableSize
|
||||
}
|
||||
|
||||
var requiredBoostSubject: BoostSubject = .nameColors
|
||||
var requiredBoostSubjects: [BoostSubject] = [.nameColors(colors: resolvedState.nameColor)]
|
||||
|
||||
let replyIconLevel = 5
|
||||
var profileIconLevel = 7
|
||||
@ -824,34 +824,27 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
|
||||
let replyFileId = resolvedState.replyFileId
|
||||
if replyFileId != nil {
|
||||
requiredBoostSubject = .nameIcon
|
||||
requiredBoostSubjects.append(.nameIcon)
|
||||
}
|
||||
|
||||
let profileColor = resolvedState.profileColor
|
||||
if profileColor != nil {
|
||||
requiredBoostSubject = .profileColors
|
||||
requiredBoostSubjects.append(.profileColors)
|
||||
}
|
||||
|
||||
let backgroundFileId = resolvedState.backgroundFileId
|
||||
if backgroundFileId != nil {
|
||||
requiredBoostSubject = .profileIcon
|
||||
requiredBoostSubjects.append(.profileIcon)
|
||||
}
|
||||
|
||||
let emojiStatus = resolvedState.emojiStatus
|
||||
if emojiStatus != nil {
|
||||
requiredBoostSubject = .emojiStatus
|
||||
requiredBoostSubjects.append(.emojiStatus)
|
||||
}
|
||||
let statusFileId = emojiStatus?.fileId
|
||||
|
||||
let cloudThemes: [PresentationThemeReference] = contentsData.availableThemes.map { .cloud(PresentationCloudTheme(theme: $0, resolvedWallpaper: nil, creatorAccountId: $0.isCreator ? component.context.account.id : nil)) }
|
||||
var chatThemes = cloudThemes.filter { $0.emoticon != nil }
|
||||
chatThemes.insert(.builtin(.dayClassic), at: 0)
|
||||
|
||||
if !chatThemes.isEmpty {
|
||||
if self.currentTheme == nil {
|
||||
self.currentTheme = chatThemes[0]
|
||||
}
|
||||
}
|
||||
let chatThemes = cloudThemes.filter { $0.emoticon != nil }
|
||||
|
||||
if let currentTheme = self.currentTheme, (self.resolvedCurrentTheme?.reference != currentTheme || self.resolvedCurrentTheme?.isDark != environment.theme.overallDarkAppearance), (self.resolvingCurrentTheme?.reference != currentTheme || self.resolvingCurrentTheme?.isDark != environment.theme.overallDarkAppearance) {
|
||||
self.resolvingCurrentTheme?.disposable.dispose()
|
||||
@ -891,8 +884,8 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
if self.currentTheme != nil && self.currentTheme != chatThemes.first {
|
||||
requiredBoostSubject = .wallpaper
|
||||
if self.currentTheme != nil {
|
||||
requiredBoostSubjects.append(.wallpaper)
|
||||
}
|
||||
|
||||
if case let .user(user) = peer {
|
||||
@ -913,6 +906,12 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
)
|
||||
}
|
||||
|
||||
let requiredBoostSubject: BoostSubject
|
||||
if let maxBoostSubject = requiredBoostSubjects.max(by: { $0.requiredLevel(context: component.context, configuration: premiumConfiguration) < $1.requiredLevel(context: component.context, configuration: premiumConfiguration) }) {
|
||||
requiredBoostSubject = maxBoostSubject
|
||||
} else {
|
||||
requiredBoostSubject = .nameColors(colors: resolvedState.nameColor)
|
||||
}
|
||||
self.requiredBoostSubject = requiredBoostSubject
|
||||
|
||||
let topInset: CGFloat = 24.0
|
||||
@ -951,7 +950,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
))))
|
||||
if replyFileId != nil, let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelNameIconLevel {
|
||||
if let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelNameIconLevel {
|
||||
replyLogoContents.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BoostLevelIconComponent(
|
||||
strings: environment.strings,
|
||||
level: replyIconLevel
|
||||
@ -1047,7 +1046,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
|
||||
contentHeight += sectionSpacing
|
||||
|
||||
if !chatThemes.isEmpty, let currentTheme {
|
||||
if !chatThemes.isEmpty {
|
||||
var wallpaperLogoContents: [AnyComponentWithIdentity<Empty>] = []
|
||||
wallpaperLogoContents.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
@ -1057,7 +1056,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
))))
|
||||
if currentTheme != chatThemes[0], let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelCustomWallpaperLevel {
|
||||
if let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelCustomWallpaperLevel {
|
||||
wallpaperLogoContents.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BoostLevelIconComponent(
|
||||
strings: environment.strings,
|
||||
level: themeLevel
|
||||
@ -1085,12 +1084,13 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
strings: environment.strings,
|
||||
sectionId: 0,
|
||||
themes: chatThemes,
|
||||
hasNoTheme: true,
|
||||
animatedEmojiStickers: component.context.animatedEmojiStickers,
|
||||
themeSpecificAccentColors: [:],
|
||||
themeSpecificChatWallpapers: [:],
|
||||
nightMode: environment.theme.overallDarkAppearance,
|
||||
channelMode: true,
|
||||
currentTheme: currentTheme,
|
||||
currentTheme: self.currentTheme,
|
||||
updatedTheme: { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
@ -1138,7 +1138,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
))))
|
||||
if backgroundFileId != nil, let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelProfileIconLevel {
|
||||
if let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelProfileIconLevel {
|
||||
profileLogoContents.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BoostLevelIconComponent(
|
||||
strings: environment.strings,
|
||||
level: profileIconLevel
|
||||
@ -1249,7 +1249,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
))))
|
||||
if emojiStatus != nil, let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelEmojiStatusLevel {
|
||||
if let boostLevel = self.boostLevel, boostLevel < premiumConfiguration.minChannelEmojiStatusLevel {
|
||||
emojiStatusContents.append(AnyComponentWithIdentity(id: 1, component: AnyComponent(BoostLevelIconComponent(
|
||||
strings: environment.strings,
|
||||
level: emojiStatusLevel
|
||||
@ -1361,7 +1361,7 @@ final class ChannelAppearanceScreenComponent: Component {
|
||||
Text(text: "Apply Changes", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||
)))
|
||||
|
||||
let requiredLevel = requiredBoostSubject.requiredLevel(premiumConfiguration)
|
||||
let requiredLevel = requiredBoostSubject.requiredLevel(context: component.context, configuration: premiumConfiguration)
|
||||
if let boostLevel = self.boostLevel, requiredLevel > boostLevel {
|
||||
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(1 as Int), component: AnyComponent(PremiumLockButtonSubtitleComponent(
|
||||
count: Int(requiredLevel),
|
||||
|
@ -416,7 +416,7 @@ private func ensureColorVisible(listNode: ListView, color: PeerNameColor, animat
|
||||
}
|
||||
}
|
||||
if let resultNode = resultNode {
|
||||
listNode.ensureItemNodeVisible(resultNode, animated: animated, overflow: 24.0)
|
||||
listNode.ensureItemNodeVisible(resultNode, animated: animated, overflow: 76.0)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
@ -891,7 +891,7 @@ public func PeerNameColorScreen(
|
||||
}
|
||||
|
||||
let link = status.url
|
||||
let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors, isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0, canBoostAgain: false), count: Int32(status.boosts), action: {
|
||||
let controller = PremiumLimitScreen(context: context, subject: .storiesChannelBoost(peer: peer, boostSubject: .nameColors(colors: .blue), isCurrent: true, level: Int32(status.level), currentLevelBoosts: Int32(status.currentLevelBoosts), nextLevelBoosts: status.nextLevelBoosts.flatMap(Int32.init), link: link, myBoostCount: 0, canBoostAgain: false), count: Int32(status.boosts), action: {
|
||||
UIPasteboard.general.string = link
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.ChannelBoost_BoostLinkCopied), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false }))
|
||||
|
@ -24,7 +24,7 @@ import HexColor
|
||||
private struct ThemeCarouselThemeEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
let emojiFile: TelegramMediaFile?
|
||||
let themeReference: PresentationThemeReference
|
||||
let themeReference: PresentationThemeReference?
|
||||
let nightMode: Bool
|
||||
let channelMode: Bool
|
||||
let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
@ -45,7 +45,7 @@ private struct ThemeCarouselThemeEntry: Comparable, Identifiable {
|
||||
if lhs.emojiFile?.fileId != rhs.emojiFile?.fileId {
|
||||
return false
|
||||
}
|
||||
if lhs.themeReference.index != rhs.themeReference.index {
|
||||
if lhs.themeReference?.index != rhs.themeReference?.index {
|
||||
return false
|
||||
}
|
||||
if lhs.nightMode != rhs.nightMode {
|
||||
@ -79,7 +79,7 @@ private struct ThemeCarouselThemeEntry: Comparable, Identifiable {
|
||||
return lhs.index < rhs.index
|
||||
}
|
||||
|
||||
func item(context: AccountContext, action: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?) -> ListViewItem {
|
||||
func item(context: AccountContext, action: @escaping (PresentationThemeReference?) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?) -> ListViewItem {
|
||||
return ThemeCarouselThemeIconItem(context: context, emojiFile: self.emojiFile, themeReference: self.themeReference, nightMode: self.nightMode, channelMode: self.channelMode, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, selected: self.selected, theme: self.theme, strings: self.strings, wallpaper: self.wallpaper, action: action, contextAction: contextAction)
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ private struct ThemeCarouselThemeEntry: Comparable, Identifiable {
|
||||
public class ThemeCarouselThemeIconItem: ListViewItem {
|
||||
public let context: AccountContext
|
||||
public let emojiFile: TelegramMediaFile?
|
||||
public let themeReference: PresentationThemeReference
|
||||
public let themeReference: PresentationThemeReference?
|
||||
public let nightMode: Bool
|
||||
public let channelMode: Bool
|
||||
public let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
@ -97,10 +97,10 @@ public class ThemeCarouselThemeIconItem: ListViewItem {
|
||||
public let theme: PresentationTheme
|
||||
public let strings: PresentationStrings
|
||||
public let wallpaper: TelegramWallpaper?
|
||||
public let action: (PresentationThemeReference) -> Void
|
||||
public let action: (PresentationThemeReference?) -> Void
|
||||
public let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
|
||||
public init(context: AccountContext, emojiFile: TelegramMediaFile?, themeReference: PresentationThemeReference, nightMode: Bool, channelMode: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], selected: Bool, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper?, action: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?) {
|
||||
public init(context: AccountContext, emojiFile: TelegramMediaFile?, themeReference: PresentationThemeReference?, nightMode: Bool, channelMode: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], selected: Bool, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper?, action: @escaping (PresentationThemeReference?) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?) {
|
||||
self.context = context
|
||||
self.emojiFile = emojiFile
|
||||
self.themeReference = themeReference
|
||||
@ -336,6 +336,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
|
||||
func asyncLayout() -> (ThemeCarouselThemeIconItem, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let makeTextLayout = TextNode.asyncLayout(self.textNode)
|
||||
let makeEmojiLayout = TextNode.asyncLayout(self.emojiNode)
|
||||
let makeImageLayout = self.imageNode.asyncLayout()
|
||||
|
||||
@ -368,9 +369,14 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
updatedSelected = true
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let text = NSAttributedString(string: "No\nWallpaper", font: Font.semibold(15.0), textColor: item.theme.actionSheet.controlAccentColor)
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: text, backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
var string: String?
|
||||
if let _ = item.themeReference.emoticon {
|
||||
if item.themeReference == nil {
|
||||
string = "❌"
|
||||
} else if let _ = item.themeReference?.emoticon {
|
||||
} else {
|
||||
string = "🎨"
|
||||
}
|
||||
@ -384,16 +390,19 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
strongSelf.item = item
|
||||
|
||||
if updatedThemeReference || updatedWallpaper || updatedNightMode || updatedChannelMode {
|
||||
var themeReference = item.themeReference
|
||||
if case .builtin = themeReference, item.nightMode {
|
||||
themeReference = .builtin(.night)
|
||||
if var themeReference = item.themeReference {
|
||||
if case .builtin = themeReference, item.nightMode {
|
||||
themeReference = .builtin(.night)
|
||||
}
|
||||
|
||||
let color = item.themeSpecificAccentColors[themeReference.index]
|
||||
let wallpaper = item.themeSpecificChatWallpapers[themeReference.index]
|
||||
|
||||
strongSelf.imageNode.setSignal(themeIconImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, theme: themeReference, color: color, wallpaper: wallpaper ?? item.wallpaper, nightMode: item.nightMode, channelMode: item.channelMode, emoticon: true))
|
||||
strongSelf.imageNode.backgroundColor = nil
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
let color = item.themeSpecificAccentColors[themeReference.index]
|
||||
let wallpaper = item.themeSpecificChatWallpapers[themeReference.index]
|
||||
|
||||
strongSelf.imageNode.setSignal(themeIconImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, theme: themeReference, color: color, wallpaper: wallpaper ?? item.wallpaper, nightMode: item.nightMode, channelMode: item.channelMode, emoticon: true))
|
||||
strongSelf.imageNode.backgroundColor = nil
|
||||
}
|
||||
|
||||
if updatedTheme || updatedSelected {
|
||||
@ -424,6 +433,10 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
strongSelf.emojiNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 78.0), size: CGSize(width: 90.0, height: 30.0))
|
||||
strongSelf.emojiNode.isHidden = string == nil
|
||||
|
||||
let _ = textApply()
|
||||
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((90.0 - textLayout.size.width) / 2.0), y: 24.0), size: textLayout.size)
|
||||
strongSelf.textNode.isHidden = item.themeReference != nil
|
||||
|
||||
let emojiFrame = CGRect(origin: CGPoint(x: 33.0, y: 79.0), size: CGSize(width: 24.0, height: 24.0))
|
||||
if let file = item.emojiFile, currentItem?.emojiFile == nil {
|
||||
let imageApply = strongSelf.emojiImageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: emojiFrame.size, boundingSize: emojiFrame.size, intrinsicInsets: UIEdgeInsets()))
|
||||
@ -462,7 +475,7 @@ private final class ThemeCarouselThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
|
||||
let presentationData = item.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.activateAreaNode.accessibilityLabel = item.themeReference.emoticon.flatMap { presentationData.strings.Appearance_VoiceOver_Theme($0).string }
|
||||
strongSelf.activateAreaNode.accessibilityLabel = item.themeReference?.emoticon.flatMap { presentationData.strings.Appearance_VoiceOver_Theme($0).string }
|
||||
if item.selected {
|
||||
strongSelf.activateAreaNode.accessibilityTraits = [.button, .selected]
|
||||
} else {
|
||||
@ -525,21 +538,23 @@ public class ThemeCarouselThemeItem: ListViewItem, ItemListItem, ListItemCompone
|
||||
public let theme: PresentationTheme
|
||||
public let strings: PresentationStrings
|
||||
public let themes: [PresentationThemeReference]
|
||||
public let hasNoTheme: Bool
|
||||
public let animatedEmojiStickers: [String: [StickerPackItem]]
|
||||
public let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
public let themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||
public let nightMode: Bool
|
||||
public let channelMode: Bool
|
||||
public let currentTheme: PresentationThemeReference
|
||||
public let updatedTheme: (PresentationThemeReference) -> Void
|
||||
public let currentTheme: PresentationThemeReference?
|
||||
public let updatedTheme: (PresentationThemeReference?) -> Void
|
||||
public let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
public let tag: ItemListItemTag?
|
||||
|
||||
public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], animatedEmojiStickers: [String: [StickerPackItem]], themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], nightMode: Bool, channelMode: Bool = false, currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
public init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], hasNoTheme: Bool, animatedEmojiStickers: [String: [StickerPackItem]], themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], nightMode: Bool, channelMode: Bool = false, currentTheme: PresentationThemeReference?, updatedTheme: @escaping (PresentationThemeReference?) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.themes = themes
|
||||
self.hasNoTheme = hasNoTheme
|
||||
self.animatedEmojiStickers = animatedEmojiStickers
|
||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
||||
@ -634,7 +649,7 @@ private struct ThemeCarouselThemeItemNodeTransition {
|
||||
let updatePosition: Bool
|
||||
}
|
||||
|
||||
private func preparedTransition(context: AccountContext, action: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, from fromEntries: [ThemeCarouselThemeEntry], to toEntries: [ThemeCarouselThemeEntry], crossfade: Bool, updatePosition: Bool) -> ThemeCarouselThemeItemNodeTransition {
|
||||
private func preparedTransition(context: AccountContext, action: @escaping (PresentationThemeReference?) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, from fromEntries: [ThemeCarouselThemeEntry], to toEntries: [ThemeCarouselThemeEntry], crossfade: Bool, updatePosition: Bool) -> ThemeCarouselThemeItemNodeTransition {
|
||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||
|
||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
@ -648,7 +663,7 @@ private func ensureThemeVisible(listNode: ListView, themeReference: Presentation
|
||||
var resultNode: ThemeCarouselThemeItemIconNode?
|
||||
listNode.forEachItemNode { node in
|
||||
if resultNode == nil, let node = node as? ThemeCarouselThemeItemIconNode {
|
||||
if node.item?.themeReference.index == themeReference.index {
|
||||
if node.item?.themeReference?.index == themeReference.index {
|
||||
resultNode = node
|
||||
}
|
||||
}
|
||||
@ -736,7 +751,7 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized || !self.tapping {
|
||||
if let index = transition.entries.firstIndex(where: { entry in
|
||||
return entry.themeReference.index == item.currentTheme.index
|
||||
return entry.themeReference?.index == item.currentTheme?.index
|
||||
}) {
|
||||
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-57.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
|
||||
self.initialized = true
|
||||
@ -836,8 +851,16 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
var index: Int = 0
|
||||
|
||||
var hasCurrentTheme = false
|
||||
if item.hasNoTheme {
|
||||
let selected = item.currentTheme == nil
|
||||
if selected {
|
||||
hasCurrentTheme = true
|
||||
}
|
||||
entries.append(ThemeCarouselThemeEntry(index: index, emojiFile: nil, themeReference: nil, nightMode: item.nightMode, channelMode: item.channelMode, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: selected, theme: item.theme, strings: item.strings, wallpaper: nil))
|
||||
index += 1
|
||||
}
|
||||
for theme in item.themes {
|
||||
let selected = item.currentTheme.index == theme.index
|
||||
let selected = item.currentTheme?.index == theme.index
|
||||
if selected {
|
||||
hasCurrentTheme = true
|
||||
}
|
||||
@ -850,11 +873,13 @@ public class ThemeCarouselThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
entries.append(ThemeCarouselThemeEntry(index: index, emojiFile: nil, themeReference: item.currentTheme, nightMode: false, channelMode: item.channelMode, themeSpecificAccentColors: item.themeSpecificAccentColors, themeSpecificChatWallpapers: item.themeSpecificChatWallpapers, selected: true, theme: item.theme, strings: item.strings, wallpaper: nil))
|
||||
}
|
||||
|
||||
let action: (PresentationThemeReference) -> Void = { [weak self] themeReference in
|
||||
let action: (PresentationThemeReference?) -> Void = { [weak self] themeReference in
|
||||
if let strongSelf = self {
|
||||
strongSelf.tapping = true
|
||||
strongSelf.item?.updatedTheme(themeReference)
|
||||
let _ = ensureThemeVisible(listNode: strongSelf.listNode, themeReference: themeReference, animated: true)
|
||||
if let themeReference {
|
||||
let _ = ensureThemeVisible(listNode: strongSelf.listNode, themeReference: themeReference, animated: true)
|
||||
}
|
||||
Queue.mainQueue().after(0.4) {
|
||||
strongSelf.tapping = false
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user