Chat wallpaper improvements

This commit is contained in:
Ilya Laktyushin
2023-04-11 22:25:41 +04:00
parent eb7ad97b3a
commit 62470a424f
37 changed files with 974 additions and 169 deletions

View File

@@ -20,27 +20,7 @@ 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
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor(rgb: 0x808084, alpha: 0.1).cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
context.setLineWidth(2.0)
context.setLineCap(.round)
context.setStrokeColor(theme.actionSheet.inputClearButtonColor.cgColor)
context.move(to: CGPoint(x: 10.0, y: 10.0))
context.addLine(to: CGPoint(x: 20.0, y: 20.0))
context.strokePath()
context.move(to: CGPoint(x: 20.0, y: 10.0))
context.addLine(to: CGPoint(x: 10.0, y: 20.0))
context.strokePath()
})
}
import WebUI
private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
let index: Int
@@ -745,7 +725,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
private let contentBackgroundNode: ASDisplayNode
private let titleNode: ASTextNode
private let textNode: ImmediateTextNode
private let cancelButton: HighlightableButtonNode
private let cancelButtonNode: WebAppCancelButtonNode
private let switchThemeButton: HighlightTrackingButtonNode
private let animationContainerNode: ASDisplayNode
private var animationNode: AnimationNode
@@ -830,13 +810,13 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.contentBackgroundNode.backgroundColor = backgroundColor
self.titleNode = ASTextNode()
self.titleNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Title, font: Font.semibold(16.0), textColor: textColor)
self.titleNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Title, font: Font.semibold(17.0), textColor: textColor)
self.textNode = ImmediateTextNode()
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Subtitle(peerName).string, font: Font.regular(12.0), textColor: secondaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Subtitle(peerName).string, font: Font.regular(15.0), textColor: secondaryTextColor)
self.textNode.isHidden = true
self.cancelButton = HighlightableButtonNode()
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
self.cancelButtonNode = WebAppCancelButtonNode(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.switchThemeButton = HighlightTrackingButtonNode()
self.animationContainerNode = ASDisplayNode()
@@ -845,7 +825,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.animationNode = AnimationNode(animation: self.isDarkAppearance ? "anim_sun_reverse" : "anim_sun", colors: iconColors(theme: self.presentationData.theme), scale: 1.0)
self.animationNode.isUserInteractionEnabled = false
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
self.otherButton = HighlightableButtonNode()
@@ -872,7 +852,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.backgroundNode.addSubnode(self.effectNode)
self.backgroundNode.addSubnode(self.contentBackgroundNode)
self.contentContainerNode.addSubnode(self.titleNode)
self.contentContainerNode.addSubnode(self.textNode)
self.buttonsContentContainerNode.addSubnode(self.textNode)
self.buttonsContentContainerNode.addSubnode(self.doneButton)
self.buttonsContentContainerNode.addSubnode(self.otherButton)
@@ -880,10 +860,10 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.animationContainerNode.addSubnode(self.animationNode)
self.topContentContainerNode.addSubnode(self.switchThemeButton)
self.topContentContainerNode.addSubnode(self.listNode)
self.topContentContainerNode.addSubnode(self.cancelButton)
self.topContentContainerNode.addSubnode(self.cancelButtonNode)
self.switchThemeButton.addTarget(self, action: #selector(self.switchThemePressed), forControlEvents: .touchUpInside)
self.cancelButton.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
self.cancelButtonNode.buttonNode.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
self.doneButton.pressed = { [weak self] in
if let strongSelf = self {
strongSelf.doneButton.isUserInteractionEnabled = false
@@ -970,6 +950,8 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
}
}
self.updateCancelButton()
}
private func enqueueTransition(_ transition: ThemeSettingsThemeItemNodeTransition) {
@@ -1018,6 +1000,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
UIView.transition(with: self.buttonsContentContainerNode.view, duration: ChatThemeScreen.themeCrossfadeDuration, options: [.transitionCrossDissolve, .curveLinear]) {
self.updateButtons()
}
self.updateCancelButton()
self.skipButtonsUpdate = false
self.themeSelectionsCount += 1
@@ -1027,23 +1010,17 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
private func updateButtons() {
let canResetWallpaper = self.controller?.canResetWallpaper ?? false
let doneButtonTitle: String
let otherButtonTitle: String
var accentButtonTheme = true
var destructiveOtherButton = false
var otherIsEnabled = false
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
otherIsEnabled = self.controller?.canResetWallpaper == true
accentButtonTheme = false
destructiveOtherButton = canResetWallpaper
} else if self.selectedEmoticon == nil && self.initiallySelectedEmoticon != nil {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_Reset
otherButtonTitle = self.presentationData.strings.Conversation_Theme_OtherOptions
} else {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_ApplyBackground
otherButtonTitle = self.presentationData.strings.Conversation_Theme_OtherOptions
doneButtonTitle = self.presentationData.strings.Conversation_Theme_Apply
}
let buttonTheme: SolidRoundedButtonTheme
@@ -1058,7 +1035,25 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
self.doneButton.updateTheme(buttonTheme)
self.otherButton.setTitle(otherButtonTitle, with: Font.regular(17.0), with: destructiveOtherButton ? self.presentationData.theme.actionSheet.destructiveActionTextColor : self.presentationData.theme.actionSheet.controlAccentColor, for: .normal)
self.otherButton.setTitle(self.presentationData.strings.Conversation_Theme_ResetWallpaper, with: Font.regular(17.0), with: self.presentationData.theme.actionSheet.destructiveActionTextColor, for: .normal)
self.otherButton.isHidden = !otherIsEnabled
self.textNode.isHidden = !accentButtonTheme || self.controller?.canResetWallpaper == false
if let (layout, navigationBarHeight) = self.containerLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
}
}
private func updateCancelButton() {
var cancelButtonState: WebAppCancelButtonNode.State = .cancel
if self.selectedEmoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji {
} else if self.selectedEmoticon == nil && self.initiallySelectedEmoticon != nil {
cancelButtonState = .back
} else {
cancelButtonState = .back
}
self.cancelButtonNode.setState(cancelButtonState, animated: true)
}
private var switchThemeIconAnimator: DisplayLinkAnimator?
@@ -1069,14 +1064,14 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let previousTheme = self.presentationData.theme
self.presentationData = presentationData
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.semibold(16.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(12.0), textColor: self.presentationData.theme.actionSheet.secondaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.semibold(17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(15.0), textColor: self.presentationData.theme.actionSheet.secondaryTextColor)
if previousTheme !== presentationData.theme, let (layout, navigationBarHeight) = self.containerLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
}
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
self.cancelButtonNode.theme = presentationData.theme
let previousIconColors = iconColors(theme: previousTheme)
let newIconColors = iconColors(theme: self.presentationData.theme)
@@ -1113,7 +1108,11 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
@objc func cancelButtonPressed() {
self.cancel?()
if self.cancelButtonNode.state == .back {
self.setEmoticon(self.initiallySelectedEmoticon)
} else {
self.cancel?()
}
}
@objc func otherButtonPressed() {
@@ -1317,7 +1316,10 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let bottomInset: CGFloat = 10.0 + cleanInsets.bottom
let titleHeight: CGFloat = 54.0
let contentHeight = titleHeight + bottomInset + 188.0 + 50.0
var contentHeight = titleHeight + bottomInset + 168.0
if self.controller?.canResetWallpaper == true {
contentHeight += 50.0
}
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
@@ -1336,29 +1338,38 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size))
let titleSize = self.titleNode.measure(CGSize(width: width - 90.0, height: titleHeight))
let titleFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - titleSize.width) / 2.0), y: 11.0 + UIScreenPixel), size: titleSize)
let titleFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - titleSize.width) / 2.0), y: 18.0 + UIScreenPixel), size: titleSize)
transition.updateFrame(node: self.titleNode, frame: titleFrame)
let textSize = self.textNode.updateLayout(CGSize(width: width - 90.0, height: titleHeight))
let textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: 31.0), size: textSize)
transition.updateFrame(node: self.textNode, frame: textFrame)
let switchThemeSize = CGSize(width: 44.0, height: 44.0)
let switchThemeFrame = CGRect(origin: CGPoint(x: 3.0, y: 6.0), size: switchThemeSize)
let switchThemeFrame = CGRect(origin: CGPoint(x: contentFrame.width - switchThemeSize.width - 3.0, y: 6.0), size: switchThemeSize)
transition.updateFrame(node: self.switchThemeButton, frame: switchThemeFrame)
transition.updateFrame(node: self.animationContainerNode, frame: switchThemeFrame.insetBy(dx: 9.0, dy: 9.0))
transition.updateFrameAsPositionAndBounds(node: self.animationNode, frame: CGRect(origin: .zero, size: self.animationContainerNode.frame.size))
let cancelSize = CGSize(width: 44.0, height: 44.0)
let cancelFrame = CGRect(origin: CGPoint(x: contentFrame.width - cancelSize.width - 3.0, y: 6.0), size: cancelSize)
transition.updateFrame(node: self.cancelButton, frame: cancelFrame)
let cancelSize = self.cancelButtonNode.calculateSizeThatFits(CGSize(width: layout.size.width, height: 56.0))
let cancelFrame = CGRect(origin: CGPoint(x: 16.0, y: 0.0), size: cancelSize)
transition.updateFrame(node: self.cancelButtonNode, frame: cancelFrame)
let buttonInset: CGFloat = 16.0
let doneButtonHeight = self.doneButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - 50.0 - insets.bottom - 6.0, width: contentFrame.width, height: doneButtonHeight))
var doneY = contentHeight - doneButtonHeight - 2.0 - insets.bottom
if self.controller?.canResetWallpaper == true {
doneY = contentHeight - doneButtonHeight - 52.0 - insets.bottom
}
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: doneY, width: contentFrame.width, height: doneButtonHeight))
let colorButtonSize = self.otherButton.measure(CGSize(width: contentFrame.width - buttonInset * 2.0, height: .greatestFiniteMagnitude))
transition.updateFrame(node: self.otherButton, frame: CGRect(origin: CGPoint(x: floor((contentFrame.width - colorButtonSize.width) / 2.0), y: contentHeight - colorButtonSize.height - insets.bottom - 6.0 - 9.0), size: colorButtonSize))
let otherButtonSize = self.otherButton.measure(CGSize(width: contentFrame.width - buttonInset * 2.0, height: .greatestFiniteMagnitude))
self.otherButton.frame = CGRect(origin: CGPoint(x: floor((contentFrame.width - otherButtonSize.width) / 2.0), y: contentHeight - otherButtonSize.height - insets.bottom - 15.0), size: otherButtonSize)
let textSize = self.textNode.updateLayout(CGSize(width: width - 90.0, height: titleHeight))
let textFrame: CGRect
if self.controller?.canResetWallpaper == true {
textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: contentHeight - textSize.height - insets.bottom - 17.0), size: textSize)
} else {
textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: contentHeight - textSize.height - insets.bottom - 15.0), size: textSize)
}
transition.updateFrame(node: self.textNode, frame: textFrame)
transition.updateFrame(node: self.contentContainerNode, frame: contentContainerFrame)
transition.updateFrame(node: self.topContentContainerNode, frame: contentContainerFrame)
@@ -1371,7 +1382,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let contentSize = CGSize(width: contentFrame.width, height: 120.0)
self.listNode.bounds = CGRect(x: 0.0, y: 0.0, width: contentSize.height, height: contentSize.width)
self.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + titleHeight + 6.0)
self.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + titleHeight - 4.0)
self.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 })
}
}