Chat wallpaper improvements

This commit is contained in:
Ilya Laktyushin 2023-04-09 16:03:17 +04:00
parent 8d7566afec
commit 32de4a1bc7
5 changed files with 143 additions and 30 deletions

View File

@ -314,6 +314,123 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.action?()
}
private func switchTheme() {
if let messageNodes = self.messageNodes {
for messageNode in messageNodes.prefix(2) {
if let snapshotView = messageNode.view.snapshotContentTree() {
messageNode.view.addSubview(snapshotView)
snapshotView.frame = messageNode.bounds
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.35, removeOnCompletion: false, completion: { [weak snapshotView] _ in
snapshotView?.removeFromSuperview()
})
}
}
}
let themeSettings = self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings])
|> map { sharedData -> PresentationThemeSettings in
let themeSettings: PresentationThemeSettings
if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) {
themeSettings = current
} else {
themeSettings = PresentationThemeSettings.defaultSettings
}
return themeSettings
}
let _ = (themeSettings
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] themeSettings in
guard let strongSelf = self else {
return
}
var presentationData = strongSelf.presentationData
let lightTheme: PresentationTheme
let lightWallpaper: TelegramWallpaper
let darkTheme: PresentationTheme
let darkWallpaper: TelegramWallpaper
if !strongSelf.isDarkAppearance {
darkTheme = presentationData.theme
darkWallpaper = presentationData.chatWallpaper
var currentColors = themeSettings.themeSpecificAccentColors[themeSettings.theme.index]
if let colors = currentColors, colors.baseColor == .theme {
currentColors = nil
}
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: themeSettings.theme, accentColor: currentColors)] ?? themeSettings.themeSpecificChatWallpapers[themeSettings.theme.index])
if let themeSpecificWallpaper = themeSpecificWallpaper {
lightWallpaper = themeSpecificWallpaper
} else {
let theme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeSettings.theme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, preview: true) ?? defaultPresentationTheme
lightWallpaper = theme.chat.defaultWallpaper
}
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[themeSettings.theme.index], [.classic, .day].contains(baseTheme) {
preferredBaseTheme = baseTheme
}
lightTheme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeSettings.theme, baseTheme: preferredBaseTheme, accentColor: currentColors?.color, bubbleColors: currentColors?.customBubbleColors ?? [], wallpaper: currentColors?.wallpaper, baseColor: currentColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
} else {
lightTheme = presentationData.theme
lightWallpaper = presentationData.chatWallpaper
let automaticTheme = themeSettings.automaticThemeSwitchSetting.theme
let effectiveColors = themeSettings.themeSpecificAccentColors[automaticTheme.index]
let themeSpecificWallpaper = (themeSettings.themeSpecificChatWallpapers[coloredThemeIndex(reference: automaticTheme, accentColor: effectiveColors)] ?? themeSettings.themeSpecificChatWallpapers[automaticTheme.index])
var preferredBaseTheme: TelegramBaseTheme?
if let baseTheme = themeSettings.themePreferredBaseTheme[automaticTheme.index], [.night, .tinted].contains(baseTheme) {
preferredBaseTheme = baseTheme
} else {
preferredBaseTheme = .night
}
darkTheme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: automaticTheme, baseTheme: preferredBaseTheme, accentColor: effectiveColors?.color, bubbleColors: effectiveColors?.customBubbleColors ?? [], wallpaper: effectiveColors?.wallpaper, baseColor: effectiveColors?.baseColor, serviceBackgroundColor: defaultServiceBackgroundColor) ?? defaultPresentationTheme
if let themeSpecificWallpaper = themeSpecificWallpaper {
darkWallpaper = themeSpecificWallpaper
} else {
switch lightWallpaper {
case .builtin, .color, .gradient:
darkWallpaper = darkTheme.chat.defaultWallpaper
case .file:
if lightWallpaper.isPattern {
darkWallpaper = darkTheme.chat.defaultWallpaper
} else {
darkWallpaper = lightWallpaper
}
default:
darkWallpaper = lightWallpaper
}
}
}
if strongSelf.isDarkAppearance {
darkTheme.forceSync = true
Queue.mainQueue().after(1.0, {
darkTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: darkTheme).withUpdated(chatWallpaper: darkWallpaper)
} else {
lightTheme.forceSync = true
Queue.mainQueue().after(1.0, {
lightTheme.forceSync = false
})
presentationData = presentationData.withUpdated(theme: lightTheme).withUpdated(chatWallpaper: lightWallpaper)
}
strongSelf.presentationData = presentationData
if let (layout, _) = strongSelf.validLayout {
strongSelf.updateMessagesLayout(layout: layout, offset: CGPoint(), transition: .animated(duration: 0.3, curve: .easeInOut))
}
})
}
@objc private func dayNightPressed() {
self.isDarkAppearance = !self.isDarkAppearance
@ -332,6 +449,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.updateIntensity(transition: .animated(duration: 0.3, curve: .easeInOut))
}
}
self.switchTheme()
}
private func animateIntensityChange(delay: Double) {
@ -1278,7 +1397,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
}
let theme = self.presentationData.theme.withUpdated(preview: false)
let theme = self.presentationData.theme
let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil)
items.append(self.context.sharedContext.makeChatMessagePreviewItem(context: self.context, messages: [message1], theme: theme, strings: self.presentationData.strings, wallpaper: currentWallpaper, fontSize: self.presentationData.chatFontSize, chatBubbleCorners: self.presentationData.chatBubbleCorners, dateTimeFormat: self.presentationData.dateTimeFormat, nameOrder: self.presentationData.nameDisplayOrder, forcedResourceStatus: nil, tapMessage: nil, clickThroughMessage: nil, backgroundNode: self.nativeNode, availableReactions: nil, isCentered: false))
@ -1296,18 +1415,15 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, availableHeight: layout.size.height)
if let messageNodes = self.messageNodes {
if self.validMessages != [topMessageText, bottomMessageText] {
self.validMessages = [topMessageText, bottomMessageText]
for i in 0 ..< items.count {
items[i].updateNode(async: { f in f() }, node: { return messageNodes[i] }, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None) { layout, apply in
let nodeFrame = CGRect(origin: messageNodes[i].frame.origin, size: CGSize(width: layout.size.width, height: layout.size.height))
for i in 0 ..< items.count {
items[i].updateNode(async: { f in f() }, node: { return messageNodes[i] }, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None) { layout, apply in
let nodeFrame = CGRect(origin: messageNodes[i].frame.origin, size: CGSize(width: layout.size.width, height: layout.size.height))
messageNodes[i].contentSize = layout.contentSize
messageNodes[i].insets = layout.insets
messageNodes[i].frame = nodeFrame
messageNodes[i].contentSize = layout.contentSize
messageNodes[i].insets = layout.insets
messageNodes[i].frame = nodeFrame
apply(ListViewItemApply(isOnScreen: true))
}
apply(ListViewItemApply(isOnScreen: true))
}
}
} else {

View File

@ -147,7 +147,7 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
case let .dayNight(isNight):
title = ""
let animationNode = AnimationNode(animation: isNight ? "anim_sun_reverse" : "anim_sun", colors: [:], scale: 1.0)
animationNode.speed = 1.5
animationNode.speed = 1.66
animationNode.isUserInteractionEnabled = false
self.animationNode = animationNode
}
@ -202,10 +202,8 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
func setIsNight(_ isNight: Bool) {
self.animationNode?.setAnimation(name: !isNight ? "anim_sun_reverse" : "anim_sun", colors: [:])
self.animationNode?.speed = 1.5
Queue.mainQueue().after(0.01) {
self.animationNode?.playOnce()
}
self.animationNode?.speed = 1.66
self.animationNode?.playOnce()
}
var buttonColor: UIColor = UIColor(rgb: 0x000000, alpha: 0.3) {

View File

@ -18556,9 +18556,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let selectedEmoticon: String? = themeEmoticon
var canResetWallpaper = false
if let cachedUserData = strongSelf.peerView?.cachedData as? CachedUserData {
canResetWallpaper = cachedUserData.wallpaper != nil
@ -18568,7 +18565,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
context: context,
updatedPresentationData: strongSelf.updatedPresentationData,
animatedEmojiStickers: animatedEmojiStickers,
initiallySelectedEmoticon: selectedEmoticon,
initiallySelectedEmoticon: themeEmoticon,
peerName: strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer.flatMap(EnginePeer.init)?.compactDisplayTitle ?? "",
canResetWallpaper: canResetWallpaper,
previewTheme: { [weak self] emoticon, dark in
@ -18596,7 +18593,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
navigationController.setViewControllers(controllers, animated: true)
}
}
var openWallpaperPickerImpl: (() -> Void)?
let openWallpaperPicker = {
let controller = wallpaperMediaPickerController(
@ -18677,7 +18673,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
controller?.dimTapped()
}
strongSelf.push(controller)
//strongSelf.present(controller, in: .window(.root))
strongSelf.themeScreen = controller
})
}
@ -18711,7 +18706,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}) {
let isEmoji = actions[0].0.id.namespace == Namespaces.ItemCollection.CloudEmojiPacks
strongSelf.presentInGlobalOverlay(UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: isEmoji ? presentationData.strings.EmojiPackActionInfo_RemovedTitle : presentationData.strings.StickerPackActionInfo_RemovedTitle, text: isEmoji ? presentationData.strings.EmojiPackActionInfo_MultipleRemovedText(Int32(actions.count)) : presentationData.strings.StickerPackActionInfo_MultipleRemovedText(Int32(actions.count)), undo: true, info: actions[0].0, topItem: actions[0].1.first, context: context), elevatedLayout: true, animateInAsReplacement: false, action: { action in
if case .undo = action {
var itemsAndIndices: [(StickerPackCollectionInfo, [StickerPackItem], Int)] = actions.compactMap { action -> (StickerPackCollectionInfo, [StickerPackItem], Int)? in
@ -18731,7 +18725,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
} else if let (info, items, action) = actions.first {
let isEmoji = info.id.namespace == Namespaces.ItemCollection.CloudEmojiPacks
switch action {
case .add:
strongSelf.presentInGlobalOverlay(UndoOverlayController(presentationData: presentationData, content: .stickersModified(title: isEmoji ? presentationData.strings.EmojiPackActionInfo_AddedTitle : presentationData.strings.StickerPackActionInfo_AddedTitle, text: isEmoji ? presentationData.strings.EmojiPackActionInfo_AddedText(info.title).string : presentationData.strings.StickerPackActionInfo_AddedText(info.title).string, undo: false, info: info, topItem: items.first, context: context), elevatedLayout: true, animateInAsReplacement: false, action: { _ in

View File

@ -901,6 +901,8 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
return
}
let selectedEmoticon = selectedEmoticon?.strippedEmoji
let isFirstTime = strongSelf.entries == nil
let presentationData = strongSelf.presentationData
@ -910,7 +912,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
guard let emoticon = theme.emoticon else {
continue
}
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file, themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
entries.append(ThemeSettingsThemeEntry(index: entries.count, emoticon: emoticon, emojiFile: animatedEmojiStickers[emoticon]?.first?.file, themeReference: .cloud(PresentationCloudTheme(theme: theme, resolvedWallpaper: nil, creatorAccountId: nil)), nightMode: isDarkAppearance, selected: selectedEmoticon == theme.emoticon?.strippedEmoji, theme: presentationData.theme, strings: presentationData.strings, wallpaper: nil))
}
let action: (String?) -> Void = { [weak self] emoticon in
@ -993,7 +995,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
var scrollToItem: ListViewScrollToItem?
if !self.initialized {
if let index = transition.entries.firstIndex(where: { entry in
return entry.emoticon == self.initiallySelectedEmoticon
return entry.emoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji
}) {
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-57.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
self.initialized = true
@ -1031,7 +1033,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let otherButtonTitle: String
var accentButtonTheme = true
var destructiveOtherButton = false
if self.selectedEmoticon == self.initiallySelectedEmoticon {
if self.selectedEmoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_SetPhotoWallpaper
otherButtonTitle = canResetWallpaper ? self.presentationData.strings.Conversation_Theme_ResetWallpaper : self.presentationData.strings.Common_Cancel
accentButtonTheme = false
@ -1115,7 +1117,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
@objc func otherButtonPressed() {
if self.selectedEmoticon != self.initiallySelectedEmoticon {
if self.selectedEmoticon?.strippedEmoji != self.initiallySelectedEmoticon?.strippedEmoji {
self.setEmoticon(self.initiallySelectedEmoticon)
} else {
if self.controller?.canResetWallpaper == true {
@ -1128,7 +1130,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
func dimTapped() {
if self.selectedEmoticon == self.initiallySelectedEmoticon {
if self.selectedEmoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji {
self.cancelButtonPressed()
} else {
let alertController = textAlertController(context: self.context, updatedPresentationData: (self.presentationData, .single(self.presentationData)), title: nil, text: self.presentationData.strings.Conversation_Theme_DismissAlert, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Conversation_Theme_DismissAlertApply, action: { [weak self] in

View File

@ -144,7 +144,11 @@ public func wallpaperDatas(account: Account, accountManager: AccountManager<Tele
return (thumbnailData, betterFullSizeData ?? fullSizeData, complete)
})
} else {
return .single((thumbnailData, fullSizeData, complete))
if thumbnailData == nil, let decodedThumbnailData = decodedThumbnailData {
return .single((decodedThumbnailData, fullSizeData, complete))
} else {
return .single((thumbnailData, fullSizeData, complete))
}
}
}
}