Fix theme preview crossfade

This commit is contained in:
Ilya Laktyushin
2019-12-19 20:53:44 +04:00
parent f1980e597d
commit 89b8804e42
4 changed files with 42 additions and 13 deletions

View File

@@ -264,6 +264,7 @@ private func editThemeControllerEntries(presentationData: PresentationData, stat
public func editThemeController(context: AccountContext, mode: EditThemeControllerMode, navigateToChat: ((PeerId) -> Void)? = nil) -> ViewController { public func editThemeController(context: AccountContext, mode: EditThemeControllerMode, navigateToChat: ((PeerId) -> Void)? = nil) -> ViewController {
let initialState: EditThemeControllerState let initialState: EditThemeControllerState
let previewThemePromise = Promise<PresentationTheme>() let previewThemePromise = Promise<PresentationTheme>()
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
switch mode { switch mode {
case let .create(existingTheme): case let .create(existingTheme):
let theme: PresentationTheme let theme: PresentationTheme
@@ -272,7 +273,6 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
theme = existingTheme theme = existingTheme
wallpaper = theme.chat.defaultWallpaper wallpaper = theme.chat.defaultWallpaper
} else { } else {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
theme = presentationData.theme theme = presentationData.theme
wallpaper = presentationData.chatWallpaper wallpaper = presentationData.chatWallpaper
} }
@@ -293,7 +293,8 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
previewThemePromise.set(.single(theme.withUpdated(name: nil, defaultWallpaper: info.resolvedWallpaper))) previewThemePromise.set(.single(theme.withUpdated(name: nil, defaultWallpaper: info.resolvedWallpaper)))
} }
} else { } else {
previewThemePromise.set(.single(context.sharedContext.currentPresentationData.with { $0 }.theme)) previewThemePromise.set(.single(presentationData.theme.withUpdated(name: "", defaultWallpaper: presentationData.chatWallpaper)))
} }
initialState = EditThemeControllerState(mode: mode, title: info.theme.title, slug: info.theme.slug, updatedTheme: nil, updating: false) initialState = EditThemeControllerState(mode: mode, title: info.theme.title, slug: info.theme.slug, updatedTheme: nil, updating: false)
} }

View File

@@ -49,15 +49,15 @@ private enum ThemeSettingsColorEntry: Comparable, Identifiable {
static func <(lhs: ThemeSettingsColorEntry, rhs: ThemeSettingsColorEntry) -> Bool { static func <(lhs: ThemeSettingsColorEntry, rhs: ThemeSettingsColorEntry) -> Bool {
switch lhs { switch lhs {
case .picker:
return true
case let .color(lhsIndex, _, _, _): case let .color(lhsIndex, _, _, _):
switch rhs { switch rhs {
case let .color(rhsIndex, _, _, _): case let .color(rhsIndex, _, _, _):
return lhsIndex < rhsIndex return lhsIndex < rhsIndex
case .picker: case .picker:
return true return false
} }
case .picker:
return false
} }
} }
@@ -460,7 +460,7 @@ private final class ThemeSettingsAccentColorPickerItemNode : ListViewItemNode {
if let strongSelf = self { if let strongSelf = self {
strongSelf.item = item strongSelf.item = item
strongSelf.imageNode.frame = CGRect(origin: CGPoint(x: 9.0, y: 9.0), size: CGSize(width: 42.0, height: 42.0)) strongSelf.imageNode.frame = CGRect(origin: CGPoint(x: 11.0, y: 9.0), size: CGSize(width: 42.0, height: 42.0))
} }
}) })
} }
@@ -701,7 +701,6 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.layoutParams = params strongSelf.layoutParams = params
if themeUpdated { if themeUpdated {
strongSelf.listNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor strongSelf.backgroundNode.backgroundColor = item.theme.list.itemBlocksBackgroundColor
strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor strongSelf.topStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor strongSelf.bottomStripeNode.backgroundColor = item.theme.list.itemBlocksSeparatorColor
@@ -760,6 +759,8 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
var entries: [ThemeSettingsColorEntry] = [] var entries: [ThemeSettingsColorEntry] = []
entries.append(.picker)
var index: Int = 0 var index: Int = 0
for color in item.colors { for color in item.colors {
switch color { switch color {
@@ -782,7 +783,6 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
index += 1 index += 1
} }
entries.append(.picker)
let action: (PresentationThemeAccentColor?, Bool) -> Void = { [weak self] color, selected in let action: (PresentationThemeAccentColor?, Bool) -> Void = { [weak self] color, selected in
if let strongSelf = self, let item = strongSelf.item { if let strongSelf = self, let item = strongSelf.item {
@@ -806,7 +806,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
} }
let previousEntries = strongSelf.entries ?? [] let previousEntries = strongSelf.entries ?? []
let crossfade = themeUpdated || previousEntries.count != entries.count let crossfade = previousEntries.count != entries.count || (currentItem != nil && currentItem?.themeReference.index != item.themeReference.index)
let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, crossfade: crossfade) let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, crossfade: crossfade)
strongSelf.enqueueTransition(transition) strongSelf.enqueueTransition(transition)

View File

@@ -343,10 +343,10 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
colorItems.append(contentsOf: colors.map { .color($0) }) colorItems.append(contentsOf: colors.map { .color($0) })
if let customColors = customColors { if let customColors = customColors {
colorItems.append(contentsOf: customColors.colors.map { .custom($0) }) colorItems.insert(contentsOf: customColors.colors.reversed().map { .custom($0) }, at: 0)
} else { } else {
if let currentColor = currentColor, currentColor.baseColor == .custom { if let currentColor = currentColor, currentColor.baseColor == .custom {
colorItems.append(.custom(currentColor)) colorItems.insert(.custom(currentColor), at: 0)
} }
} }
@@ -610,7 +610,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
wallpaper = settings.themeSpecificChatWallpapers[reference.index &+ Int64(accentColor.index)] wallpaper = settings.themeSpecificChatWallpapers[reference.index &+ Int64(accentColor.index)]
} }
if wallpaper == nil { if wallpaper == nil {
settings.themeSpecificChatWallpapers[reference.index] wallpaper = settings.themeSpecificChatWallpapers[reference.index]
} }
return (accentColor, wallpaper) return (accentColor, wallpaper)
} }
@@ -767,7 +767,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
wallpaper = settings.themeSpecificChatWallpapers[reference.index &+ Int64(accentColor.index)] wallpaper = settings.themeSpecificChatWallpapers[reference.index &+ Int64(accentColor.index)]
} }
if wallpaper == nil { if wallpaper == nil {
settings.themeSpecificChatWallpapers[reference.index] wallpaper = settings.themeSpecificChatWallpapers[reference.index]
} }
return (accentColor, wallpaper) return (accentColor, wallpaper)
} |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, TelegramWallpaper?), NoError> in } |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, TelegramWallpaper?), NoError> in

View File

@@ -200,6 +200,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
private let imageNode: TransformImageNode private let imageNode: TransformImageNode
private let overlayNode: ASImageNode private let overlayNode: ASImageNode
private let titleNode: TextNode private let titleNode: TextNode
private var snapshotView: UIView?
var item: ThemeSettingsThemeIconItem? var item: ThemeSettingsThemeIconItem?
@@ -303,6 +304,21 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
} }
} }
func prepareCrossfadeTransition() {
self.snapshotView?.removeFromSuperview()
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
self.snapshotView = snapshotView
}
}
func animateCrossfadeTransition() {
self.snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
self?.snapshotView?.removeFromSuperview()
})
}
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) { override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
super.animateInsertion(currentTimestamp, duration: duration, short: short) super.animateInsertion(currentTimestamp, duration: duration, short: short)
@@ -626,11 +642,23 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view) self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
self.snapshotView = snapshotView self.snapshotView = snapshotView
} }
self.listNode.forEachVisibleItemNode { node in
if let node = node as? ThemeSettingsThemeItemIconNode {
node.prepareCrossfadeTransition()
}
}
} }
func animateCrossfadeTransition() { func animateCrossfadeTransition() {
self.snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in self.snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
self?.snapshotView?.removeFromSuperview() self?.snapshotView?.removeFromSuperview()
}) })
self.listNode.forEachVisibleItemNode { node in
if let node = node as? ThemeSettingsThemeItemIconNode {
node.animateCrossfadeTransition()
}
}
} }
} }