mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'd592c8a0f3713ec888f785c8574f0b8f5391c9b7'
This commit is contained in:
commit
bc0aefc32e
@ -104,7 +104,8 @@
|
||||
"PUSH_ALBUM" = "%1$@|sent you an album";
|
||||
"PUSH_MESSAGE_FILES_TEXT_1" = "sent you a file";
|
||||
"PUSH_MESSAGE_FILES_TEXT_any" = "sent you %d files";
|
||||
"PUSH_MESSAGE_THEME" = "%1$@|changed theme to %2$@";
|
||||
"PUSH_MESSAGE_THEME" = "%1$@|changed chat theme to %2$@";
|
||||
"PUSH_MESSAGE_NOTHEME" = "%1$@|disabled chat theme";
|
||||
|
||||
"PUSH_CHANNEL_MESSAGE_TEXT" = "%1$@|%2$@";
|
||||
"PUSH_CHANNEL_MESSAGE_NOTEXT" = "%1$@|posted a message";
|
||||
@ -178,6 +179,7 @@
|
||||
"PUSH_CHAT_MESSAGE_DOCS_TEXT_1" = "{author} sent a file";
|
||||
"PUSH_CHAT_MESSAGE_DOCS_TEXT_any" = "{author} sent %d files";
|
||||
"PUSH_CHAT_MESSAGE_THEME" = "%1$@|set theme to %3$@ in the group %2$@";
|
||||
"PUSH_CHAT_MESSAGE_NOTHEME" = "%1$@|disabled theme in the group %2$@";
|
||||
|
||||
"PUSH_PINNED_TEXT" = "%1$@|pinned \"%2$@\" ";
|
||||
"PUSH_PINNED_NOTEXT" = "%1$@|pinned a message";
|
||||
|
@ -288,8 +288,11 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let iconApply = iconLayout(TransformImageArguments(corners: ImageCorners(), imageSize: CGSize(width: iconSize, height: iconSize), boundingSize: CGSize(width: iconSize, height: iconSize), intrinsicInsets: UIEdgeInsets()))
|
||||
iconApply()
|
||||
|
||||
let placeholderBackgroundColor: UIColor
|
||||
|
||||
switch item.style {
|
||||
case .plain:
|
||||
placeholderBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
if strongSelf.backgroundNode.supernode != nil {
|
||||
strongSelf.backgroundNode.removeFromSupernode()
|
||||
}
|
||||
@ -297,7 +300,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
|
||||
strongSelf.topStripeNode.removeFromSupernode()
|
||||
}
|
||||
if strongSelf.bottomStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 0)
|
||||
strongSelf.addSubnode(strongSelf.bottomStripeNode)
|
||||
}
|
||||
if strongSelf.maskNode.supernode != nil {
|
||||
strongSelf.maskNode.removeFromSupernode()
|
||||
@ -312,6 +315,7 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: stripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - stripeInset, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.isHidden = last
|
||||
case .blocks:
|
||||
placeholderBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
if strongSelf.backgroundNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.backgroundNode, at: 0)
|
||||
}
|
||||
@ -395,8 +399,8 @@ public class ItemListVenueItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let subtitleFrame = strongSelf.addressNode.frame
|
||||
shapes.append(.roundedRectLine(startPoint: CGPoint(x: subtitleFrame.minX, y: subtitleFrame.minY + floor((subtitleFrame.height - lineDiameter) / 2.0)), width: subtitleLineWidth, diameter: lineDiameter))
|
||||
|
||||
shimmerNode.update(backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: layout.contentSize)
|
||||
|
||||
shimmerNode.update(backgroundColor: placeholderBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: layout.contentSize)
|
||||
} else if let shimmerNode = strongSelf.placeholderNode {
|
||||
strongSelf.placeholderNode = nil
|
||||
shimmerNode.removeFromSupernode()
|
||||
|
@ -35,7 +35,7 @@ public let defaultServiceBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.2)
|
||||
public let defaultPresentationTheme = makeDefaultDayPresentationTheme(serviceBackgroundColor: defaultServiceBackgroundColor, day: false, preview: false)
|
||||
public let defaultDayAccentColor = UIColor(rgb: 0x007ee5)
|
||||
|
||||
public func customizeDefaultDayTheme(theme: PresentationTheme, specialMode: Bool = false, editing: Bool, title: String?, accentColor: UIColor?, outgoingAccentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], animateBubbleColors: Bool?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme {
|
||||
public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, outgoingAccentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], animateBubbleColors: Bool?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme {
|
||||
if (theme.referenceTheme != .day && theme.referenceTheme != .dayClassic) {
|
||||
return theme
|
||||
}
|
||||
@ -51,85 +51,35 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, specialMode: Bool
|
||||
var outgoingAccent: UIColor?
|
||||
var suggestedWallpaper: TelegramWallpaper?
|
||||
|
||||
var bubbleColors = bubbleColors
|
||||
if specialMode, outgoingAccentColor == nil, bubbleColors.count < 3, let color = bubbleColors.first.flatMap({ UIColor(rgb: $0) }) {
|
||||
let colorHSB = color.hsb
|
||||
if colorHSB.b > 0.9 {
|
||||
let bubbleColor = color.withMultiplied(hue: 0.9, saturation: 1.3, brightness: 1.0)
|
||||
bubbleColors = [bubbleColor.rgb]
|
||||
|
||||
let colorPairs: [(UInt32, UInt32)] = [
|
||||
(0xe5f9d7, 0x6cd516),
|
||||
(0xe7f5ff, 0x43b6f9),
|
||||
(0xe3f7f5, 0x4ccbb8),
|
||||
(0xfff6cf, 0xe8b816),
|
||||
(0xfffac9, 0xe2c714),
|
||||
(0xc5a61e, 0xd6b534)
|
||||
]
|
||||
|
||||
func generateAccentColor(color: UIColor) -> UIColor {
|
||||
var nearest: (color: (UInt32, UInt32), distance: Int32)?
|
||||
for (sample, accentSample) in colorPairs {
|
||||
let distance = color.distance(to: UIColor(rgb: sample))
|
||||
if let currentNearest = nearest {
|
||||
if distance < currentNearest.distance {
|
||||
nearest = ((sample, accentSample), distance)
|
||||
}
|
||||
var bubbleColors = bubbleColors
|
||||
if bubbleColors.isEmpty, editing {
|
||||
if day {
|
||||
let accentColor = accentColor ?? defaultDayAccentColor
|
||||
bubbleColors = [accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98).rgb, accentColor.rgb]
|
||||
outgoingAccent = outgoingAccentColor
|
||||
} else {
|
||||
if let accentColor = accentColor, !accentColor.alpha.isZero {
|
||||
let hsb = accentColor.hsb
|
||||
bubbleColors = [UIColor(hue: hsb.0, saturation: (hsb.1 > 0.0 && hsb.2 > 0.0) ? 0.14 : 0.0, brightness: 0.79 + hsb.2 * 0.21, alpha: 1.0).rgb]
|
||||
if let outgoingAccentColor = outgoingAccentColor {
|
||||
outgoingAccent = outgoingAccentColor
|
||||
} else {
|
||||
if accentColor.lightness > 0.705 {
|
||||
outgoingAccent = UIColor(hue: hsb.0, saturation: min(1.0, hsb.1 * 1.1), brightness: min(hsb.2, 0.6), alpha: 1.0)
|
||||
} else {
|
||||
nearest = ((sample, accentSample), distance)
|
||||
outgoingAccent = accentColor
|
||||
}
|
||||
}
|
||||
|
||||
if let colors = nearest?.color {
|
||||
let colorHsb = color.hsb
|
||||
let similarColorHsb = UIColor(rgb: colors.0).hsb
|
||||
let accentColorHsb = UIColor(rgb: colors.1).hsb
|
||||
|
||||
let correction = (similarColorHsb.0 > 0.0 ? colorHsb.0 / similarColorHsb.0 : 1.0, similarColorHsb.1 > 0.0 ? colorHsb.1 / similarColorHsb.1 : 1.0, similarColorHsb.2 > 0.0 ? colorHsb.2 / similarColorHsb.2 : 1.0)
|
||||
let correctedComplementingColor = UIColor(hue: min(1.0, accentColorHsb.0 * correction.0), saturation: min(1.0, accentColorHsb.1 * correction.1), brightness: min(1.0, accentColorHsb.2 * correction.2), alpha: 1.0)
|
||||
return correctedComplementingColor
|
||||
} else {
|
||||
return color
|
||||
}
|
||||
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
} else {
|
||||
bubbleColors = [UIColor(rgb: 0xe1ffc7).rgb]
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
outgoingAccent = outgoingAccentColor
|
||||
}
|
||||
|
||||
outgoingAccent = generateAccentColor(color: color)
|
||||
} else {
|
||||
let bubbleColor = color.withMultiplied(hue: 1.014, saturation: 0.12, brightness: 1.29)
|
||||
bubbleColors = [bubbleColor.rgb]
|
||||
|
||||
outgoingAccent = color
|
||||
}
|
||||
} else {
|
||||
if bubbleColors.isEmpty, editing {
|
||||
if day {
|
||||
let accentColor = accentColor ?? defaultDayAccentColor
|
||||
bubbleColors = [accentColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98).rgb, accentColor.rgb]
|
||||
outgoingAccent = outgoingAccentColor
|
||||
} else {
|
||||
if let accentColor = accentColor, !accentColor.alpha.isZero {
|
||||
let hsb = accentColor.hsb
|
||||
bubbleColors = [UIColor(hue: hsb.0, saturation: (hsb.1 > 0.0 && hsb.2 > 0.0) ? 0.14 : 0.0, brightness: 0.79 + hsb.2 * 0.21, alpha: 1.0).rgb]
|
||||
if let outgoingAccentColor = outgoingAccentColor {
|
||||
outgoingAccent = outgoingAccentColor
|
||||
} else {
|
||||
if accentColor.lightness > 0.705 {
|
||||
outgoingAccent = UIColor(hue: hsb.0, saturation: min(1.0, hsb.1 * 1.1), brightness: min(hsb.2, 0.6), alpha: 1.0)
|
||||
} else {
|
||||
outgoingAccent = accentColor
|
||||
}
|
||||
}
|
||||
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
} else {
|
||||
bubbleColors = [UIColor(rgb: 0xe1ffc7).rgb]
|
||||
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: defaultBuiltinWallpaperGradientColors.map(\.rgb), settings: WallpaperSettings()))
|
||||
outgoingAccent = outgoingAccentColor
|
||||
}
|
||||
}
|
||||
} else {
|
||||
outgoingAccent = outgoingAccentColor
|
||||
}
|
||||
outgoingAccent = outgoingAccentColor
|
||||
}
|
||||
|
||||
var accentColor = accentColor
|
||||
|
@ -19,13 +19,13 @@ public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeRefe
|
||||
return theme
|
||||
}
|
||||
|
||||
public func customizePresentationTheme(_ theme: PresentationTheme, specialMode: Bool = false, editing: Bool, title: String? = nil, accentColor: UIColor?, outgoingAccentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], animateBubbleColors: Bool?, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, title: String? = nil, accentColor: UIColor?, outgoingAccentColor: UIColor?, backgroundColors: [UInt32], bubbleColors: [UInt32], animateBubbleColors: Bool?, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil) -> PresentationTheme {
|
||||
if accentColor == nil && bubbleColors.isEmpty && backgroundColors.isEmpty && wallpaper == nil {
|
||||
return theme
|
||||
}
|
||||
switch theme.referenceTheme {
|
||||
case .day, .dayClassic:
|
||||
return customizeDefaultDayTheme(theme: theme, specialMode: specialMode, editing: editing, title: title, accentColor: accentColor, outgoingAccentColor: outgoingAccentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors ?? false, wallpaper: wallpaper, serviceBackgroundColor: nil)
|
||||
return customizeDefaultDayTheme(theme: theme, editing: editing, title: title, accentColor: accentColor, outgoingAccentColor: outgoingAccentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors ?? false, wallpaper: wallpaper, serviceBackgroundColor: nil)
|
||||
case .night:
|
||||
return customizeDefaultDarkPresentationTheme(theme: theme, editing: editing, title: title, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors ?? false, wallpaper: wallpaper, baseColor: baseColor)
|
||||
case .nightAccent:
|
||||
@ -33,17 +33,25 @@ public func customizePresentationTheme(_ theme: PresentationTheme, specialMode:
|
||||
}
|
||||
}
|
||||
|
||||
public func makePresentationTheme(settings: TelegramThemeSettings, specialMode: Bool = false, title: String? = nil, serviceBackgroundColor: UIColor? = nil) -> PresentationTheme? {
|
||||
public func makePresentationTheme(settings: TelegramThemeSettings, title: String? = nil, serviceBackgroundColor: UIColor? = nil) -> PresentationTheme? {
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: settings.baseTheme), extendingThemeReference: nil, serviceBackgroundColor: serviceBackgroundColor, preview: false)
|
||||
return customizePresentationTheme(defaultTheme, specialMode: specialMode, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), outgoingAccentColor: settings.outgoingAccentColor.flatMap { UIColor(argb: $0) }, backgroundColors: [], bubbleColors: settings.messageColors, animateBubbleColors: settings.animateMessageColors, wallpaper: settings.wallpaper)
|
||||
return customizePresentationTheme(defaultTheme, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), outgoingAccentColor: settings.outgoingAccentColor.flatMap { UIColor(argb: $0) }, backgroundColors: [], bubbleColors: settings.messageColors, animateBubbleColors: settings.animateMessageColors, wallpaper: settings.wallpaper)
|
||||
}
|
||||
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, outgoingAccentColor: UIColor? = nil, backgroundColors: [UInt32] = [], bubbleColors: [UInt32] = [], animateBubbleColors: Bool? = nil, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil, serviceBackgroundColor: UIColor? = nil, specialMode: Bool = false, preview: Bool = false) -> PresentationTheme? {
|
||||
public func makePresentationTheme(cloudTheme: TelegramTheme) -> PresentationTheme? {
|
||||
guard let settings = cloudTheme.settings else {
|
||||
return nil
|
||||
}
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: settings.baseTheme), extendingThemeReference: nil, serviceBackgroundColor: nil, preview: false)
|
||||
return customizePresentationTheme(defaultTheme, editing: true, accentColor: UIColor(argb: settings.accentColor), outgoingAccentColor: settings.outgoingAccentColor.flatMap { UIColor(argb: $0) }, backgroundColors: [], bubbleColors: settings.messageColors, animateBubbleColors: settings.animateMessageColors, wallpaper: settings.wallpaper)
|
||||
}
|
||||
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, outgoingAccentColor: UIColor? = nil, backgroundColors: [UInt32] = [], bubbleColors: [UInt32] = [], animateBubbleColors: Bool? = nil, wallpaper: TelegramWallpaper? = nil, baseColor: PresentationThemeBaseColor? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? {
|
||||
let theme: PresentationTheme
|
||||
switch themeReference {
|
||||
case let .builtin(reference):
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: reference, extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, preview: preview)
|
||||
theme = customizePresentationTheme(defaultTheme, specialMode: specialMode, editing: true, accentColor: accentColor, outgoingAccentColor: outgoingAccentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors, wallpaper: wallpaper, baseColor: baseColor)
|
||||
theme = customizePresentationTheme(defaultTheme, editing: true, accentColor: accentColor, outgoingAccentColor: outgoingAccentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors, wallpaper: wallpaper, baseColor: baseColor)
|
||||
case let .local(info):
|
||||
if let path = mediaBox.completedResourcePath(info.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, themeReference: themeReference, resolvedWallpaper: info.resolvedWallpaper) {
|
||||
theme = customizePresentationTheme(loadedTheme, editing: false, accentColor: accentColor, outgoingAccentColor: outgoingAccentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, animateBubbleColors: animateBubbleColors, wallpaper: wallpaper)
|
||||
|
@ -3926,6 +3926,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
let accountManager = context.sharedContext.accountManager
|
||||
let currentThemeEmoticon = Atomic<(String?, Bool)?>(value: nil)
|
||||
self.presentationDataDisposable = combineLatest(queue: Queue.mainQueue(), context.sharedContext.presentationData, themeSettings, context.engine.themes.getChatThemes(accountManager: accountManager, onlyCached: false), themeEmoticon, self.themeEmoticonAndDarkAppearancePreviewPromise.get()).start(next: { [weak self] presentationData, themeSettings, chatThemes, themeEmoticon, themeEmoticonAndDarkAppearance in
|
||||
if let strongSelf = self {
|
||||
let (themeEmoticonPreview, darkAppearancePreview) = themeEmoticonAndDarkAppearance
|
||||
@ -3944,17 +3945,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
var presentationData = presentationData
|
||||
var useDarkAppearance = presentationData.theme.overallDarkAppearance
|
||||
|
||||
if let themeEmoticon = themeEmoticon, let theme = chatThemes.first(where: { $0.emoji == themeEmoticon }) {
|
||||
var useDarkAppearance = presentationData.theme.overallDarkAppearance
|
||||
if let darkAppearancePreview = darkAppearancePreview {
|
||||
useDarkAppearance = darkAppearancePreview
|
||||
}
|
||||
let customTheme = useDarkAppearance ? theme.darkTheme : theme.theme
|
||||
if let settings = customTheme.settings, let theme = makePresentationTheme(settings: settings) {
|
||||
presentationData = presentationData.withUpdated(theme: theme)
|
||||
presentationData = presentationData.withUpdated(chatWallpaper: theme.chat.defaultWallpaper)
|
||||
presentationData = presentationData.withUpdated(theme: theme).withUpdated(chatWallpaper: theme.chat.defaultWallpaper)
|
||||
}
|
||||
} else if let darkAppearancePreview = darkAppearancePreview {
|
||||
useDarkAppearance = darkAppearancePreview
|
||||
let lightTheme: PresentationTheme
|
||||
let lightWallpaper: TelegramWallpaper
|
||||
|
||||
@ -4009,24 +4011,24 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
if darkAppearancePreview {
|
||||
presentationData = presentationData.withUpdated(theme: darkTheme)
|
||||
presentationData = presentationData.withUpdated(chatWallpaper: darkWallpaper)
|
||||
presentationData = presentationData.withUpdated(theme: darkTheme).withUpdated(chatWallpaper: darkWallpaper)
|
||||
} else {
|
||||
presentationData = presentationData.withUpdated(theme: lightTheme)
|
||||
presentationData = presentationData.withUpdated(chatWallpaper: lightWallpaper)
|
||||
presentationData = presentationData.withUpdated(theme: lightTheme).withUpdated(chatWallpaper: lightWallpaper)
|
||||
}
|
||||
}
|
||||
let isFirstTime = !strongSelf.didSetPresentationData
|
||||
strongSelf.presentationData = presentationData
|
||||
strongSelf.didSetPresentationData = true
|
||||
|
||||
if isFirstTime || previousTheme !== presentationData.theme || previousStrings !== presentationData.strings || presentationData.chatWallpaper != previousChatWallpaper {
|
||||
let previousThemeEmoticon = currentThemeEmoticon.swap((themeEmoticon, useDarkAppearance))
|
||||
|
||||
if isFirstTime || previousTheme != presentationData.theme || previousStrings !== presentationData.strings || presentationData.chatWallpaper != previousChatWallpaper {
|
||||
strongSelf.themeAndStringsUpdated()
|
||||
|
||||
controllerInteraction.updatedPresentationData = strongSelf.updatedPresentationData
|
||||
strongSelf.presentationDataPromise.set(.single(strongSelf.presentationData))
|
||||
|
||||
if !isFirstTime && previousTheme !== presentationData.theme {
|
||||
if !isFirstTime && (previousThemeEmoticon?.0 != themeEmoticon || previousThemeEmoticon?.1 != useDarkAppearance) {
|
||||
strongSelf.presentCrossfadeSnapshot(delay: 0.2)
|
||||
}
|
||||
}
|
||||
@ -5932,7 +5934,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|> deliverOnMainQueue).start(next: { [weak self] searchResult in
|
||||
if let strongSelf = self, let (searchResult, searchState, searchLocation) = searchResult {
|
||||
|
||||
let controller = ChatSearchResultsController(context: strongSelf.context, location: searchLocation, searchQuery: searchData.query, searchResult: searchResult, searchState: searchState, navigateToMessageIndex: { index in
|
||||
let controller = ChatSearchResultsController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, location: searchLocation, searchQuery: searchData.query, searchResult: searchResult, searchState: searchState, navigateToMessageIndex: { index in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -13365,9 +13367,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return updated
|
||||
})
|
||||
|
||||
let _ = (self.cachedDataPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] cachedData in
|
||||
let animatedEmojiStickers = context.engine.stickers.loadedStickerPack(reference: .animatedEmoji, forceActualized: false)
|
||||
|> map { animatedEmoji -> [String: [StickerPackItem]] in
|
||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||
switch animatedEmoji {
|
||||
case let .result(_, items, _):
|
||||
for case let item as StickerPackItem in items {
|
||||
if let emoji = item.getStringRepresentationsOfIndexKeys().first {
|
||||
animatedEmojiStickers[emoji.basicEmoji.0] = [item]
|
||||
let strippedEmoji = emoji.basicEmoji.0.strippedEmoji
|
||||
if animatedEmojiStickers[strippedEmoji] == nil {
|
||||
animatedEmojiStickers[strippedEmoji] = [item]
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return animatedEmojiStickers
|
||||
}
|
||||
|
||||
let _ = (combineLatest(queue: Queue.mainQueue(), self.cachedDataPromise.get(), animatedEmojiStickers)
|
||||
|> take(1)).start(next: { [weak self] cachedData, animatedEmojiStickers in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -13383,14 +13404,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
selectedEmoticon = nil
|
||||
}
|
||||
|
||||
let controller = ChatThemeScreen(context: context, updatedPresentationData: strongSelf.updatedPresentationData, initiallySelectedEmoticon: selectedEmoticon, previewTheme: { [weak self] emoticon, dark in
|
||||
let controller = ChatThemeScreen(context: context, updatedPresentationData: strongSelf.updatedPresentationData, animatedEmojiStickers: animatedEmojiStickers, initiallySelectedEmoticon: selectedEmoticon, previewTheme: { [weak self] emoticon, dark in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentCrossfadeSnapshot(delay: 0.2)
|
||||
strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((emoticon, dark)))
|
||||
}
|
||||
}, completion: { [weak self] emoticon in
|
||||
strongSelf.presentCrossfadeSnapshot(delay: 0.2)
|
||||
strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((emoticon, nil)))
|
||||
strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((emoticon ?? "", nil)))
|
||||
let _ = context.engine.themes.setChatTheme(peerId: peerId, emoticon: emoticon).start(completed: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.themeEmoticonAndDarkAppearancePreviewPromise.set(.single((nil, nil)))
|
||||
|
@ -25,9 +25,9 @@ final class ChatSearchResultsController: ViewController {
|
||||
|
||||
private var presentationDataDisposable: Disposable?
|
||||
|
||||
init(context: AccountContext, location: SearchMessagesLocation, searchQuery: String, searchResult: SearchMessagesResult, searchState: SearchMessagesState, navigateToMessageIndex: @escaping (Int) -> Void, resultsUpdated: @escaping (SearchMessagesResult, SearchMessagesState) -> Void) {
|
||||
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, location: SearchMessagesLocation, searchQuery: String, searchResult: SearchMessagesResult, searchState: SearchMessagesState, navigateToMessageIndex: @escaping (Int) -> Void, resultsUpdated: @escaping (SearchMessagesResult, SearchMessagesState) -> Void) {
|
||||
self.context = context
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.location = location
|
||||
self.searchQuery = searchQuery
|
||||
self.navigateToMessageIndex = navigateToMessageIndex
|
||||
@ -39,7 +39,7 @@ final class ChatSearchResultsController: ViewController {
|
||||
|
||||
self.navigationPresentation = .modal
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentationData = presentationData
|
||||
|
@ -14,8 +14,12 @@ import PresentationDataUtils
|
||||
import AnimationUI
|
||||
import MergeLists
|
||||
import MediaResources
|
||||
import StickerResources
|
||||
import WallpaperResources
|
||||
import TooltipUI
|
||||
import AnimatedStickerNode
|
||||
import TelegramAnimatedStickerNode
|
||||
import ShimmerEffect
|
||||
|
||||
private func closeButtonImage(theme: PresentationTheme) -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
||||
@ -41,6 +45,7 @@ private func closeButtonImage(theme: PresentationTheme) -> UIImage? {
|
||||
private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
|
||||
let index: Int
|
||||
let emoticon: String?
|
||||
let emojiFile: TelegramMediaFile?
|
||||
let themeReference: PresentationThemeReference?
|
||||
var selected: Bool
|
||||
let theme: PresentationTheme
|
||||
@ -58,6 +63,7 @@ private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
|
||||
if lhs.emoticon != rhs.emoticon {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.themeReference?.index != rhs.themeReference?.index {
|
||||
return false
|
||||
}
|
||||
@ -81,7 +87,7 @@ private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
|
||||
}
|
||||
|
||||
func item(context: AccountContext, action: @escaping (String?) -> Void) -> ListViewItem {
|
||||
return ThemeSettingsThemeIconItem(context: context, emoticon: self.emoticon, themeReference: self.themeReference, selected: self.selected, theme: self.theme, strings: self.strings, wallpaper: self.wallpaper, action: action)
|
||||
return ThemeSettingsThemeIconItem(context: context, emoticon: self.emoticon, emojiFile: self.emojiFile, themeReference: self.themeReference, selected: self.selected, theme: self.theme, strings: self.strings, wallpaper: self.wallpaper, action: action)
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +95,7 @@ private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
|
||||
private class ThemeSettingsThemeIconItem: ListViewItem {
|
||||
let context: AccountContext
|
||||
let emoticon: String?
|
||||
let emojiFile: TelegramMediaFile?
|
||||
let themeReference: PresentationThemeReference?
|
||||
let selected: Bool
|
||||
let theme: PresentationTheme
|
||||
@ -96,9 +103,10 @@ private class ThemeSettingsThemeIconItem: ListViewItem {
|
||||
let wallpaper: TelegramWallpaper?
|
||||
let action: (String?) -> Void
|
||||
|
||||
public init(context: AccountContext, emoticon: String?, themeReference: PresentationThemeReference?, selected: Bool, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper?, action: @escaping (String?) -> Void) {
|
||||
public init(context: AccountContext, emoticon: String?, emojiFile: TelegramMediaFile?, themeReference: PresentationThemeReference?, selected: Bool, theme: PresentationTheme, strings: PresentationStrings, wallpaper: TelegramWallpaper?, action: @escaping (String?) -> Void) {
|
||||
self.context = context
|
||||
self.emoticon = emoticon
|
||||
self.emojiFile = emojiFile
|
||||
self.themeReference = themeReference
|
||||
self.selected = selected
|
||||
self.theme = theme
|
||||
@ -231,16 +239,37 @@ private func generateBorderImage(theme: PresentationTheme, bordered: Bool, selec
|
||||
|
||||
private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
private let containerNode: ASDisplayNode
|
||||
private let emojiContainerNode: ASDisplayNode
|
||||
private let imageNode: TransformImageNode
|
||||
private let overlayNode: ASImageNode
|
||||
private let textNode: TextNode
|
||||
private let emojiNode: TextNode
|
||||
private let emojiImageNode: TransformImageNode
|
||||
private var animatedStickerNode: AnimatedStickerNode?
|
||||
private var placeholderNode: StickerShimmerEffectNode
|
||||
var snapshotView: UIView?
|
||||
|
||||
var item: ThemeSettingsThemeIconItem?
|
||||
|
||||
override var visibility: ListViewItemNodeVisibility {
|
||||
didSet {
|
||||
self.visibilityStatus = self.visibility != .none
|
||||
}
|
||||
}
|
||||
|
||||
private var visibilityStatus: Bool = false {
|
||||
didSet {
|
||||
if self.visibilityStatus != oldValue {
|
||||
self.animatedStickerNode?.visibility = self.visibilityStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let stickerFetchedDisposable = MetaDisposable()
|
||||
|
||||
init() {
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.emojiContainerNode = ASDisplayNode()
|
||||
|
||||
self.imageNode = TransformImageNode()
|
||||
self.imageNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 82.0, height: 108.0))
|
||||
@ -257,6 +286,10 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
|
||||
self.emojiNode = TextNode()
|
||||
self.emojiNode.isUserInteractionEnabled = false
|
||||
|
||||
self.emojiImageNode = TransformImageNode()
|
||||
|
||||
self.placeholderNode = StickerShimmerEffectNode()
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false, rotated: false, seeThrough: false)
|
||||
|
||||
@ -264,9 +297,47 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
self.containerNode.addSubnode(self.imageNode)
|
||||
self.containerNode.addSubnode(self.overlayNode)
|
||||
self.containerNode.addSubnode(self.textNode)
|
||||
self.containerNode.addSubnode(self.emojiNode)
|
||||
|
||||
self.addSubnode(self.emojiContainerNode)
|
||||
self.emojiContainerNode.addSubnode(self.emojiNode)
|
||||
self.emojiContainerNode.addSubnode(self.emojiImageNode)
|
||||
self.emojiContainerNode.addSubnode(self.placeholderNode)
|
||||
|
||||
var firstTime = true
|
||||
self.emojiImageNode.imageUpdated = { [weak self] image in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if image != nil {
|
||||
strongSelf.removePlaceholder(animated: !firstTime)
|
||||
if firstTime {
|
||||
strongSelf.emojiImageNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
firstTime = false
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.stickerFetchedDisposable.dispose()
|
||||
}
|
||||
|
||||
private func removePlaceholder(animated: Bool) {
|
||||
if !animated {
|
||||
self.placeholderNode.removeFromSupernode()
|
||||
} else {
|
||||
self.placeholderNode.alpha = 0.0
|
||||
self.placeholderNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
|
||||
self?.placeholderNode.removeFromSupernode()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {
|
||||
let emojiFrame = CGRect(origin: CGPoint(x: 33.0, y: 79.0), size: CGSize(width: 24.0, height: 24.0))
|
||||
self.placeholderNode.updateAbsoluteRect(CGRect(origin: CGPoint(x: rect.minX + emojiFrame.minX, y: rect.minY + emojiFrame.minY), size: emojiFrame.size), within: containerSize)
|
||||
}
|
||||
|
||||
func asyncLayout() -> (ThemeSettingsThemeIconItem, ListViewItemLayoutParams) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let makeTextLayout = TextNode.asyncLayout(self.textNode)
|
||||
let makeEmojiLayout = TextNode.asyncLayout(self.emojiNode)
|
||||
@ -275,11 +346,15 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
let currentItem = self.item
|
||||
|
||||
return { [weak self] item, params in
|
||||
var updatedEmoticon = false
|
||||
var updatedThemeReference = false
|
||||
var updatedTheme = false
|
||||
var updatedWallpaper = false
|
||||
var updatedSelected = false
|
||||
|
||||
if currentItem?.emoticon != item.emoticon {
|
||||
updatedEmoticon = true
|
||||
}
|
||||
if currentItem?.themeReference != item.themeReference {
|
||||
updatedThemeReference = true
|
||||
}
|
||||
@ -296,7 +371,13 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
let text = NSAttributedString(string: item.strings.Conversation_Theme_NoTheme, 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()))
|
||||
|
||||
let title = NSAttributedString(string: item.emoticon ?? "❌", font: Font.regular(22.0), textColor: .black)
|
||||
var emoticon = item.emoticon
|
||||
if emoticon == "🦁" {
|
||||
emoticon = "🌳"
|
||||
} else if emoticon == "🔮" {
|
||||
emoticon = "🎆"
|
||||
}
|
||||
let title = NSAttributedString(string: emoticon != nil ? "" : "❌", font: Font.regular(22.0), textColor: .black)
|
||||
let (_, emojiApply) = makeEmojiLayout(TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let itemLayout = ListViewItemNodeLayout(contentSize: CGSize(width: 120.0, height: 90.0), insets: UIEdgeInsets())
|
||||
@ -324,6 +405,9 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
strongSelf.containerNode.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
strongSelf.containerNode.frame = CGRect(origin: CGPoint(x: 15.0, y: -15.0), size: CGSize(width: 90.0, height: 120.0))
|
||||
|
||||
strongSelf.emojiContainerNode.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
strongSelf.emojiContainerNode.frame = CGRect(origin: CGPoint(x: 15.0, y: -15.0), size: CGSize(width: 90.0, height: 120.0))
|
||||
|
||||
let _ = textApply()
|
||||
let _ = emojiApply()
|
||||
|
||||
@ -334,14 +418,50 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
|
||||
strongSelf.overlayNode.frame = strongSelf.imageNode.frame.insetBy(dx: -1.0, dy: -1.0)
|
||||
strongSelf.emojiNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 79.0), size: CGSize(width: 90.0, height: 30.0))
|
||||
|
||||
let emojiFrame = CGRect(origin: CGPoint(x: 33.0, y: 79.0), size: CGSize(width: 24.0, height: 24.0))
|
||||
if let file = item.emojiFile, updatedEmoticon {
|
||||
let imageApply = strongSelf.emojiImageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: emojiFrame.size, boundingSize: emojiFrame.size, intrinsicInsets: UIEdgeInsets()))
|
||||
imageApply()
|
||||
strongSelf.emojiImageNode.setSignal(chatMessageStickerPackThumbnail(postbox: item.context.account.postbox, resource: file.resource, animated: true, nilIfEmpty: true))
|
||||
strongSelf.emojiImageNode.frame = emojiFrame
|
||||
|
||||
let animatedStickerNode: AnimatedStickerNode
|
||||
if let current = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.emojiImageNode.isHidden = true
|
||||
}
|
||||
strongSelf.animatedStickerNode = animatedStickerNode
|
||||
strongSelf.emojiContainerNode.insertSubnode(animatedStickerNode, belowSubnode: strongSelf.placeholderNode)
|
||||
let pathPrefix = item.context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(file.resource.id)
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: item.context.account, resource: file.resource), width: 96, height: 96, mode: .direct(cachePathPrefix: pathPrefix))
|
||||
}
|
||||
animatedStickerNode.visibility = strongSelf.visibilityStatus
|
||||
|
||||
strongSelf.stickerFetchedDisposable.set(fetchedMediaResource(mediaBox: item.context.account.postbox.mediaBox, reference: MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)).start())
|
||||
|
||||
let thumbnailDimensions = PixelDimensions(width: 512, height: 512)
|
||||
strongSelf.placeholderNode.update(backgroundColor: nil, foregroundColor: UIColor(rgb: 0xffffff, alpha: 0.2), shimmeringColor: UIColor(rgb: 0xffffff, alpha: 0.3), data: file.immediateThumbnailData, size: emojiFrame.size, imageSize: thumbnailDimensions.cgSize)
|
||||
strongSelf.placeholderNode.frame = emojiFrame
|
||||
}
|
||||
|
||||
if let animatedStickerNode = strongSelf.animatedStickerNode {
|
||||
animatedStickerNode.frame = emojiFrame
|
||||
animatedStickerNode.updateLayout(size: emojiFrame.size)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crossfade() {
|
||||
if let snapshotView = self.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.view.addSubview(snapshotView)
|
||||
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.transform = self.containerNode.view.transform
|
||||
snapshotView.frame = self.containerNode.view.frame
|
||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, delay: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
@ -376,6 +496,7 @@ final class ChatThemeScreen: ViewController {
|
||||
private var animatedIn = false
|
||||
|
||||
private let context: AccountContext
|
||||
private let animatedEmojiStickers: [String: [StickerPackItem]]
|
||||
private let initiallySelectedEmoticon: String?
|
||||
private let dismissByTapOutside: Bool
|
||||
private let previewTheme: (String?, Bool?) -> Void
|
||||
@ -392,9 +513,10 @@ final class ChatThemeScreen: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), initiallySelectedEmoticon: String?, dismissByTapOutside: Bool = true, previewTheme: @escaping (String?, Bool?) -> Void, completion: @escaping (String?) -> Void) {
|
||||
init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), animatedEmojiStickers: [String: [StickerPackItem]], initiallySelectedEmoticon: String?, dismissByTapOutside: Bool = true, previewTheme: @escaping (String?, Bool?) -> Void, completion: @escaping (String?) -> Void) {
|
||||
self.context = context
|
||||
self.presentationData = updatedPresentationData.initial
|
||||
self.animatedEmojiStickers = animatedEmojiStickers
|
||||
self.initiallySelectedEmoticon = initiallySelectedEmoticon
|
||||
self.dismissByTapOutside = dismissByTapOutside
|
||||
self.previewTheme = previewTheme
|
||||
@ -426,7 +548,7 @@ final class ChatThemeScreen: ViewController {
|
||||
}
|
||||
|
||||
override public func loadDisplayNode() {
|
||||
self.displayNode = ChatThemeScreenNode(context: self.context, presentationData: self.presentationData, initiallySelectedEmoticon: self.initiallySelectedEmoticon, dismissByTapOutside: self.dismissByTapOutside)
|
||||
self.displayNode = ChatThemeScreenNode(context: self.context, presentationData: self.presentationData, animatedEmojiStickers: self.animatedEmojiStickers, initiallySelectedEmoticon: self.initiallySelectedEmoticon, dismissByTapOutside: self.dismissByTapOutside)
|
||||
self.controllerNode.passthroughHitTestImpl = self.passthroughHitTestImpl
|
||||
self.controllerNode.previewTheme = { [weak self] emoticon, dark in
|
||||
guard let strongSelf = self else {
|
||||
@ -558,7 +680,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
var dismiss: (() -> Void)?
|
||||
var cancel: (() -> Void)?
|
||||
|
||||
init(context: AccountContext, presentationData: PresentationData, initiallySelectedEmoticon: String?, dismissByTapOutside: Bool) {
|
||||
init(context: AccountContext, presentationData: PresentationData, animatedEmojiStickers: [String: [StickerPackItem]], initiallySelectedEmoticon: String?, dismissByTapOutside: Bool) {
|
||||
self.context = context
|
||||
self.initiallySelectedEmoticon = initiallySelectedEmoticon
|
||||
self.selectedEmoticon = initiallySelectedEmoticon
|
||||
@ -662,18 +784,24 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
|
||||
|
||||
var entries: [ThemeSettingsThemeEntry] = []
|
||||
if strongSelf.initiallySelectedEmoticon != nil {
|
||||
entries.append(ThemeSettingsThemeEntry(index: 0, emoticon: nil, themeReference: nil, selected: selectedEmoticon == nil, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
|
||||
entries.append(ThemeSettingsThemeEntry(index: 0, emoticon: nil, emojiFile: nil, themeReference: nil, selected: selectedEmoticon == nil, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
|
||||
}
|
||||
for theme in themes {
|
||||
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: theme.emoji, themeReference: .cloud(PresentationCloudTheme(theme: isDarkAppearance ? theme.darkTheme : theme.theme, resolvedWallpaper: nil, creatorAccountId: nil)), selected: selectedEmoticon == theme.emoji, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
|
||||
var emoticon = theme.emoji
|
||||
if emoticon == "🦁" {
|
||||
emoticon = "🌳"
|
||||
} else if emoticon == "🔮" {
|
||||
emoticon = "🎆"
|
||||
}
|
||||
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: theme.emoji, emojiFile: animatedEmojiStickers[emoticon]?.first?.file, themeReference: .cloud(PresentationCloudTheme(theme: isDarkAppearance ? theme.darkTheme : theme.theme, resolvedWallpaper: nil, creatorAccountId: nil)), selected: selectedEmoticon == theme.emoji, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
|
||||
}
|
||||
|
||||
let action: (String?) -> Void = { [weak self] emoticon in
|
||||
if let strongSelf = self, strongSelf.selectedEmoticon != emoticon {
|
||||
strongSelf.animateCrossfade(animateBackground: strongSelf.presentationData.theme.overallDarkAppearance, updateSunIcon: true)
|
||||
|
||||
strongSelf.selectedEmoticon = emoticon
|
||||
strongSelf.previewTheme?(emoticon, strongSelf.isDarkAppearance)
|
||||
strongSelf.selectedEmoticon = emoticon
|
||||
let _ = ensureThemeVisible(listNode: strongSelf.listNode, emoticon: emoticon, animated: true)
|
||||
|
||||
strongSelf.doneButton.title = emoticon == nil ? strongSelf.presentationData.strings.Conversation_Theme_Reset : strongSelf.presentationData.strings.Conversation_Theme_Apply
|
||||
|
@ -3489,20 +3489,9 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
|
||||
let filteredButtons = allHeaderButtons.subtracting(headerButtons)
|
||||
|
||||
var canChangeColors = true
|
||||
// if let peer = peer as? TelegramUser, self.data?.encryptionKeyFingerprint == nil {
|
||||
// canChangeColors = true
|
||||
// }
|
||||
if let peer = peer as? TelegramChannel {
|
||||
if case .broadcast = peer.info {
|
||||
canChangeColors = false
|
||||
} else {
|
||||
canChangeColors = peer.hasPermission(.changeInfo)
|
||||
}
|
||||
} else if let peer = peer as? TelegramGroup, case .member = peer.role {
|
||||
canChangeColors = !peer.hasBannedPermission(.banChangeInfo)
|
||||
} else if self.data?.encryptionKeyFingerprint != nil {
|
||||
canChangeColors = false
|
||||
var canChangeColors = false
|
||||
if peer is TelegramUser, self.data?.encryptionKeyFingerprint == nil {
|
||||
canChangeColors = true
|
||||
}
|
||||
|
||||
if canChangeColors {
|
||||
@ -6799,7 +6788,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
|
||||
}
|
||||
}
|
||||
|
||||
self.presentationDataDisposable = ((updatedPresentationData?.signal ?? context.sharedContext.presentationData)
|
||||
self.presentationDataDisposable = (presentationDataSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
let previousTheme = strongSelf.presentationData.theme
|
||||
|
@ -78,6 +78,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
var displayUndo = true
|
||||
var undoText = presentationData.strings.Undo_Undo
|
||||
var undoTextColor = UIColor(rgb: 0x5ac8fa)
|
||||
undoTextColor = presentationData.theme.list.itemAccentColor.withMultiplied(hue: 1.0, saturation: 0.64, brightness: 1.08)
|
||||
|
||||
if presentationData.theme.overallDarkAppearance {
|
||||
self.animationBackgroundColor = presentationData.theme.rootController.tabBar.backgroundColor
|
||||
|
Loading…
x
Reference in New Issue
Block a user