Merge commit '46917eaaf33fbcd409d0dfc11121c72d0bd1de85'

This commit is contained in:
Ali 2021-08-17 21:21:49 +02:00
commit aee4dcda79
8 changed files with 262 additions and 196 deletions

View File

@ -155,11 +155,11 @@ final class ThemeAccentColorController: ViewController {
var coloredWallpaper: TelegramWallpaper?
if !state.backgroundColors.isEmpty {
if let patternWallpaper = state.patternWallpaper {
coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: state.backgroundColors, intensity: state.patternIntensity, rotation: state.rotation))
coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: state.backgroundColors.map { $0.rgb }, intensity: state.patternIntensity, rotation: state.rotation))
} else if state.backgroundColors.count >= 2 {
coloredWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: state.backgroundColors, settings: WallpaperSettings(rotation: state.rotation)))
coloredWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: state.backgroundColors.map { $0.rgb }, settings: WallpaperSettings(rotation: state.rotation)))
} else {
coloredWallpaper = .color(state.backgroundColors[0])
coloredWallpaper = .color(state.backgroundColors[0].rgb)
}
}
@ -201,13 +201,13 @@ final class ThemeAccentColorController: ViewController {
}
if let themeReference = generalThemeReference {
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: coloredWallpaper ?? state.initialWallpaper, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: state.accentColor.color, backgroundColors: state.backgroundColors.map { $0.rgb }, bubbleColors: state.messagesColors.map { $0.rgb }, wallpaper: coloredWallpaper ?? state.initialWallpaper, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme
} else {
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: state.initialWallpaper ?? coloredWallpaper)
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor.color, backgroundColors: state.backgroundColors.map { $0.rgb }, bubbleColors: state.messagesColors.map { $0.rgb }, wallpaper: state.initialWallpaper ?? coloredWallpaper)
}
if hasSettings, let baseTheme = baseTheme {
settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor, messageColors: state.messagesColors, wallpaper: coloredWallpaper)
settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor.color, messageColors: state.messagesColors.map { $0.rgb }, wallpaper: coloredWallpaper)
}
completion(updatedTheme, settings)
@ -226,12 +226,12 @@ final class ThemeAccentColorController: ViewController {
let wallpaper = coloredWallpaper ?? state.initialWallpaper
let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor, messageColors: state.messagesColors, wallpaper: wallpaper)
let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor.rgb, messageColors: state.messagesColors.map { $0.rgb }, wallpaper: wallpaper)
let baseThemeReference = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme))
let apply: Signal<Void, CreateThemeError>
if create {
apply = (prepareWallpaper |> then(createTheme(account: context.account, title: generateThemeName(accentColor: state.accentColor), resource: nil, thumbnailData: nil, settings: settings)))
apply = (prepareWallpaper |> then(createTheme(account: context.account, title: generateThemeName(accentColor: state.accentColor.color), resource: nil, thumbnailData: nil, settings: settings)))
|> mapToSignal { next -> Signal<Void, CreateThemeError> in
if case let .result(resultTheme) = next {
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: resultTheme).start()
@ -552,7 +552,7 @@ final class ThemeAccentColorController: ViewController {
messageColors = []
}
let initialState = ThemeColorState(section: strongSelf.section, accentColor: accentColor, initialWallpaper: initialWallpaper, backgroundColors: backgroundColors, patternWallpaper: patternWallpaper, patternIntensity: patternIntensity, defaultMessagesColor: defaultMessagesColor, messagesColors: messageColors, rotation: rotation)
let initialState = ThemeColorState(section: strongSelf.section, accentColor: HSBColor(color: accentColor), initialWallpaper: initialWallpaper, backgroundColors: backgroundColors.map { HSBColor(rgb: $0) }, patternWallpaper: patternWallpaper, patternIntensity: patternIntensity, defaultMessagesColor: defaultMessagesColor.flatMap { HSBColor(color: $0) }, messagesColors: messageColors.map { HSBColor(rgb: $0) }, rotation: rotation)
strongSelf.controllerNode.updateState({ _ in
return initialState

View File

@ -39,17 +39,17 @@ struct ThemeColorState {
fileprivate var colorPanelCollapsed: Bool
fileprivate var displayPatternPanel: Bool
var accentColor: UIColor
var accentColor: HSBColor
var initialWallpaper: TelegramWallpaper?
var backgroundColors: [UInt32]
var backgroundColors: [HSBColor]
fileprivate var preview: Bool
fileprivate var previousPatternWallpaper: TelegramWallpaper?
var patternWallpaper: TelegramWallpaper?
var patternIntensity: Int32
var defaultMessagesColor: UIColor?
var messagesColors: [UInt32]
var defaultMessagesColor: HSBColor?
var messagesColors: [HSBColor]
var rotation: Int32
@ -57,7 +57,7 @@ struct ThemeColorState {
self.section = nil
self.colorPanelCollapsed = false
self.displayPatternPanel = false
self.accentColor = .clear
self.accentColor = HSBColor(hue: 0.0, saturation: 0.0, brightness: 1.0)
self.initialWallpaper = nil
self.backgroundColors = []
self.preview = false
@ -69,7 +69,7 @@ struct ThemeColorState {
self.rotation = 0
}
init(section: ThemeColorSection, accentColor: UIColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [UInt32], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, defaultMessagesColor: UIColor?, messagesColors: [UInt32], rotation: Int32 = 0) {
init(section: ThemeColorSection, accentColor: HSBColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [HSBColor], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, defaultMessagesColor: HSBColor?, messagesColors: [HSBColor], rotation: Int32 = 0) {
self.section = section
self.colorPanelCollapsed = false
self.displayPatternPanel = false
@ -116,9 +116,9 @@ struct ThemeColorState {
private func calcPatternColors(for state: ThemeColorState) -> [UIColor] {
if state.backgroundColors.count >= 1 {
let patternIntensity = CGFloat(state.patternIntensity) / 100.0
let topPatternColor = UIColor(rgb: state.backgroundColors[0]).withAlphaComponent(patternIntensity)
let topPatternColor = state.backgroundColors[0].color.withAlphaComponent(patternIntensity)
if state.backgroundColors.count >= 2 {
let bottomPatternColor = UIColor(rgb: state.backgroundColors[1]).withAlphaComponent(patternIntensity)
let bottomPatternColor = state.backgroundColors[1].color.withAlphaComponent(patternIntensity)
return [topPatternColor, bottomPatternColor]
} else {
return [topPatternColor, topPatternColor]
@ -176,7 +176,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
private let serviceBackgroundColorPromise = Promise<UIColor>()
private var wallpaperDisposable = MetaDisposable()
private var currentBackgroundColors: ([UInt32], Int32?, Int32?)?
private var currentBackgroundColors: ([HSBColor], Int32?, Int32?)?
private var currentBackgroundPromise = Promise<(UIColor, UIColor?)?>()
private var patternWallpaper: TelegramWallpaper?
@ -332,7 +332,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
switch section {
case .accent:
if let firstColor = colors.first {
updated.accentColor = UIColor(rgb: firstColor)
updated.accentColor = firstColor
}
case .background:
updated.backgroundColors = colors
@ -420,7 +420,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|> mapToThrottled { next -> Signal<ThemeColorState, NoError> in
return .single(next) |> then(.complete() |> delay(0.0166667, queue: self.queue))
}
|> map { state -> (PresentationTheme?, TelegramWallpaper, UIColor, [UInt32], Int32, PatternWallpaperArguments, Bool) in
|> map { state -> (PresentationTheme?, TelegramWallpaper, UIColor, [HSBColor], Int32, PatternWallpaperArguments, Bool) in
let accentColor = state.accentColor
var backgroundColors = state.backgroundColors
let messagesColors = state.messagesColors
@ -434,7 +434,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if !backgroundColors.isEmpty {
if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper {
wallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: backgroundColors, intensity: state.patternIntensity, rotation: state.rotation))
wallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: backgroundColors.map { $0.rgb }, intensity: state.patternIntensity, rotation: state.rotation))
let dimensions = file.file.dimensions ?? PixelDimensions(width: 100, height: 100)
var convertedRepresentations: [ImageRepresentationWithReference] = []
@ -443,22 +443,22 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
} else if backgroundColors.count >= 2 {
wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors, settings: WallpaperSettings(rotation: state.rotation)))
wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors.map { $0.rgb }, settings: WallpaperSettings(rotation: state.rotation)))
} else {
wallpaper = .color(backgroundColors.first ?? 0xffffff)
wallpaper = .color(backgroundColors.first?.rgb ?? 0xffffff)
}
} else if let themeReference = mode.themeReference, case let .builtin(theme) = themeReference, state.initialWallpaper == nil {
var suggestedWallpaper: TelegramWallpaper
switch theme {
case .dayClassic:
let topColor = accentColor.withMultiplied(hue: 1.010, saturation: 0.414, brightness: 0.957)
let bottomColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965)
let topColor = HSBColor(color: accentColor.color.withMultiplied(hue: 1.010, saturation: 0.414, brightness: 0.957))
let bottomColor = HSBColor(color: accentColor.color.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965))
suggestedWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: [topColor.rgb, bottomColor.rgb], settings: WallpaperSettings()))
backgroundColors = [topColor.rgb, bottomColor.rgb]
backgroundColors = [topColor, bottomColor]
case .nightAccent:
let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18)
let color = HSBColor(color: accentColor.color.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18))
suggestedWallpaper = .color(color.rgb)
backgroundColors = [color.rgb]
backgroundColors = [color]
default:
suggestedWallpaper = .builtin(WallpaperSettings())
}
@ -472,9 +472,9 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if !updateOnlyWallpaper {
if let themeReference = mode.themeReference {
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: messagesColors, serviceBackgroundColor: serviceBackgroundColor, preview: true) ?? defaultPresentationTheme
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: accentColor.color, backgroundColors: backgroundColors.map { $0.rgb }, bubbleColors: messagesColors.map { $0.rgb }, serviceBackgroundColor: serviceBackgroundColor, preview: true) ?? defaultPresentationTheme
} else if case let .edit(theme, _, _, _, _, _) = mode {
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: messagesColors)
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: accentColor.color, backgroundColors: backgroundColors.map { $0.rgb }, bubbleColors: messagesColors.map { $0.rgb })
} else {
updatedTheme = theme
}
@ -516,7 +516,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
strongSelf.wallpaper = wallpaper
strongSelf.patternArguments = patternArguments
strongSelf.colorsButtonNode.colors = backgroundColors.map(UIColor.init(rgb:))
strongSelf.colorsButtonNode.colors = backgroundColors.map { $0.color }
if !preview {
if !backgroundColors.isEmpty {
@ -573,6 +573,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
override func didLoad() {
super.didLoad()
self.view.disablesInteractiveModalDismiss = true
self.scrollNode.view.bounces = false
self.scrollNode.view.disablesInteractiveTransitionGestureRecognizer = true
self.scrollNode.view.showsHorizontalScrollIndicator = false
@ -619,18 +621,18 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if sectionChanged, let section = self.state.section {
self.view.endEditing(true)
var colors: [UInt32]
var defaultColor: UIColor?
var colors: [HSBColor]
var defaultColor: HSBColor?
switch section {
case .accent:
colors = [self.state.accentColor.rgb]
colors = [self.state.accentColor]
case .background:
if let themeReference = self.mode.themeReference, case let .builtin(theme) = themeReference {
switch theme {
case .dayClassic:
defaultColor = self.state.accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965)
defaultColor = HSBColor(color: self.state.accentColor.color.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965))
case .nightAccent:
defaultColor = self.state.accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18)
defaultColor = HSBColor(color: self.state.accentColor.color.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18))
default:
break
}
@ -644,7 +646,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if let defaultMessagesColor = self.state.defaultMessagesColor {
defaultColor = defaultMessagesColor
} else if let themeReference = self.mode.themeReference, case let .builtin(theme) = themeReference, theme == .nightAccent {
defaultColor = self.state.accentColor.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59)
defaultColor = HSBColor(color: self.state.accentColor.color.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59))
} else {
defaultColor = self.state.accentColor
}
@ -656,7 +658,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}
if colors.isEmpty, let defaultColor = defaultColor {
colors = [defaultColor.rgb]
colors = [defaultColor]
}
let maximumNumberOfColors: Int

View File

@ -312,7 +312,7 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate {
struct WallpaperColorPanelNodeState: Equatable {
var selection: Int?
var colors: [UInt32]
var colors: [HSBColor]
var maximumNumberOfColors: Int
var rotateAvailable: Bool
var rotation: Int32
@ -390,7 +390,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
private var sampleItemNodes: [ColorSampleItemNode] = []
private let multiColorFieldNode: ColorInputFieldNode
var colorsChanged: (([UInt32], Bool) -> Void)?
var colorsChanged: (([HSBColor], Bool) -> Void)?
var colorSelected: (() -> Void)?
var rotate: (() -> Void)?
@ -456,7 +456,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updated = current
updated.preview = !ended
if let index = strongSelf.state.selection {
updated.colors[index] = color.rgb
updated.colors[index] = HSBColor(color: color)
}
return updated
})
@ -486,7 +486,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updated = current
updated.preview = true
if let index = strongSelf.state.selection {
updated.colors[index] = color.rgb
updated.colors[index] = color
}
return updated
}, updateLayout: false)
@ -498,7 +498,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var updated = current
updated.preview = false
if let index = strongSelf.state.selection {
updated.colors[index] = color.rgb
updated.colors[index] = color
}
return updated
}, updateLayout: false)
@ -528,7 +528,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
if let index = self.state.selection {
if self.state.colors.count > index {
self.colorPickerNode.color = UIColor(rgb: self.state.colors[index])
self.colorPickerNode.color = self.state.colors[index]
}
}
@ -536,15 +536,15 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.updateLayout(size: size, transition: animated ? .animated(duration: 0.3, curve: .easeInOut) : .immediate)
}
if let index = state.selection {
if let index = self.state.selection {
if self.state.colors.count > index {
self.multiColorFieldNode.setColor(UIColor(rgb: self.state.colors[index]), update: false)
self.multiColorFieldNode.setColor(self.state.colors[index].color, update: false)
}
}
for i in 0 ..< state.colors.count {
for i in 0 ..< self.state.colors.count {
if i < self.sampleItemNodes.count {
self.sampleItemNodes[i].update(size: self.sampleItemNodes[i].bounds.size, color: UIColor(rgb: state.colors[i]), isSelected: state.selection == i)
self.sampleItemNodes[i].update(size: self.sampleItemNodes[i].bounds.size, color: self.state.colors[i].color, isSelected: state.selection == i)
}
}
@ -658,7 +658,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
}
itemNode.frame = CGRect(origin: CGPoint(x: nextSampleX, y: (topPanelHeight - sampleItemSize) / 2.0), size: CGSize(width: sampleItemSize, height: sampleItemSize))
nextSampleX += sampleItemSize
itemNode.update(size: itemNode.bounds.size, color: UIColor(rgb: self.state.colors[i]), isSelected: self.state.selection == i)
itemNode.update(size: itemNode.bounds.size, color: self.state.colors[i].color, isSelected: self.state.selection == i)
if animateIn {
transition.animateTransformScale(node: itemNode, from: 0.1)
@ -722,9 +722,9 @@ final class WallpaperColorPanelNode: ASDisplayNode {
var current = current
if current.colors.count < current.maximumNumberOfColors {
if current.colors.isEmpty {
current.colors.append(0xffffff)
current.colors.append(HSBColor(rgb: 0xffffff))
} else if current.simpleGradientGeneration {
var hsb = UIColor(rgb: current.colors[0]).hsb
var hsb = current.colors[0].values
if hsb.1 > 0.5 {
hsb.1 -= 0.15
} else {
@ -735,7 +735,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
} else {
hsb.0 += 0.05
}
current.colors.append(UIColor(hue: hsb.0, saturation: hsb.1, brightness: hsb.2, alpha: 1.0).rgb)
current.colors.append(HSBColor(values: hsb))
} else {
current.colors.append(current.colors[current.colors.count - 1])
}
@ -743,38 +743,6 @@ final class WallpaperColorPanelNode: ASDisplayNode {
}
return current
})
/*self.firstColorFieldNode.setSkipEndEditingIfNeeded()
self.updateState({ current in
var updated = current
updated.selection = .index(1)
let firstColor = current.firstColor ?? current.defaultColor
if let color = firstColor {
updated.firstColor = color
let secondColor: UIColor
if updated.simpleGradientGeneration {
var hsb = color.hsb
if hsb.1 > 0.5 {
hsb.1 -= 0.15
} else {
hsb.1 += 0.15
}
if hsb.0 > 0.5 {
hsb.0 -= 0.05
} else {
hsb.0 += 0.05
}
updated.secondColor = UIColor(hue: hsb.0, saturation: hsb.1, brightness: hsb.2, alpha: 1.0)
} else {
updated.secondColor = generateGradientColors(color: color).1
}
}
return updated
})*/
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

View File

@ -89,11 +89,10 @@ private final class HSBParameter: NSObject {
}
private final class WallpaperColorKnobNode: ASDisplayNode {
var hsb: (CGFloat, CGFloat, CGFloat) = (0.0, 0.0, 1.0) {
var color: HSBColor = HSBColor(hue: 0.0, saturation: 0.0, brightness: 1.0) {
didSet {
if self.hsb != oldValue {
let color = UIColor(hue: hsb.0, saturation: hsb.1, brightness: hsb.2, alpha: 1.0)
self.colorNode.backgroundColor = color
if self.color != oldValue {
self.colorNode.backgroundColor = self.color.color
}
}
}
@ -166,6 +165,64 @@ private final class WallpaperColorHueSaturationNode: ASDisplayNode {
context.setFillColor(UIColor(rgb: 0x000000, alpha: 1.0 - parameters.value).cgColor)
context.fill(bounds)
}
var tap: ((CGPoint) -> Void)?
var panBegan: ((CGPoint) -> Void)?
var panChanged: ((CGPoint, Bool) -> Void)?
var initialTouchLocation: CGPoint?
var touchMoved = false
var previousTouchLocation: CGPoint?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let touchLocation = touches.first?.location(in: self.view) {
self.touchMoved = false
self.initialTouchLocation = touchLocation
self.previousTouchLocation = nil
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if let touchLocation = touches.first?.location(in: self.view), let initialLocation = self.initialTouchLocation {
let dX = touchLocation.x - initialLocation.x
let dY = touchLocation.y - initialLocation.y
if !self.touchMoved && dX * dX + dY * dY > 3.0 {
self.touchMoved = true
self.panBegan?(touchLocation)
self.previousTouchLocation = touchLocation
} else if let previousTouchLocation = self.previousTouchLocation {
let dX = touchLocation.x - previousTouchLocation.x
let dY = touchLocation.y - previousTouchLocation.y
let translation = CGPoint(x: dX, y: dY)
self.panChanged?(translation, false)
self.previousTouchLocation = touchLocation
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
if self.touchMoved {
if let touchLocation = touches.first?.location(in: self.view), let previousTouchLocation = self.previousTouchLocation {
let dX = touchLocation.x - previousTouchLocation.x
let dY = touchLocation.y - previousTouchLocation.y
let translation = CGPoint(x: dX, y: dY)
self.panChanged?(translation, true)
}
} else if let touchLocation = self.initialTouchLocation {
self.tap?(touchLocation)
}
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
}
}
private final class WallpaperColorBrightnessNode: ASDisplayNode {
@ -209,6 +266,50 @@ private final class WallpaperColorBrightnessNode: ASDisplayNode {
}
}
struct HSBColor: Equatable {
static func == (lhs: HSBColor, rhs: HSBColor) -> Bool {
return lhs.values.h == rhs.values.h && lhs.values.s == rhs.values.s && lhs.values.b == rhs.values.b
}
let values: (h: CGFloat, s: CGFloat, b: CGFloat)
var hue: CGFloat {
return self.values.h
}
var saturation: CGFloat {
return self.values.s
}
var brightness: CGFloat {
return self.values.b
}
var rgb: UInt32 {
return self.color.rgb
}
init(values: (h: CGFloat, s: CGFloat, b: CGFloat)) {
self.values = values
}
init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat) {
self.values = (h: hue, s: saturation, b: brightness)
}
init(color: UIColor) {
self.values = color.hsb
}
init(rgb: UInt32) {
self.init(color: UIColor(rgb: rgb))
}
var color: UIColor {
return UIColor(hue: self.values.h, saturation: self.values.s, brightness: self.values.b, alpha: 1.0)
}
}
final class WallpaperColorPickerNode: ASDisplayNode {
private let brightnessNode: WallpaperColorBrightnessNode
private let brightnessKnobNode: ASImageNode
@ -217,21 +318,16 @@ final class WallpaperColorPickerNode: ASDisplayNode {
private var validLayout: CGSize?
var colorHsb: (CGFloat, CGFloat, CGFloat) = (0.0, 1.0, 1.0)
var color: UIColor {
get {
return UIColor(hue: self.colorHsb.0, saturation: self.colorHsb.1, brightness: self.colorHsb.2, alpha: 1.0)
}
set {
let newHsb = newValue.hsb
if newHsb != self.colorHsb {
self.colorHsb = newHsb
var color: HSBColor = HSBColor(hue: 0.0, saturation: 1.0, brightness: 1.0) {
didSet {
if self.color != oldValue {
self.update()
}
}
}
var colorChanged: ((UIColor) -> Void)?
var colorChangeEnded: ((UIColor) -> Void)?
var colorChanged: ((HSBColor) -> Void)?
var colorChangeEnded: ((HSBColor) -> Void)?
init(strings: PresentationStrings) {
self.brightnessNode = WallpaperColorBrightnessNode()
@ -253,16 +349,79 @@ final class WallpaperColorPickerNode: ASDisplayNode {
self.addSubnode(self.colorKnobNode)
self.update()
self.colorNode.tap = { [weak self] location in
guard let strongSelf = self, let size = strongSelf.validLayout else {
return
}
let colorHeight = size.height - 66.0
let newHue = max(0.0, min(1.0, location.x / size.width))
let newSaturation = max(0.0, min(1.0, (1.0 - location.y / colorHeight)))
strongSelf.color = HSBColor(hue: newHue, saturation: newSaturation, brightness: strongSelf.color.brightness)
strongSelf.updateKnobLayout(size: size, panningColor: false, transition: .immediate)
strongSelf.update()
strongSelf.colorChangeEnded?(strongSelf.color)
}
self.colorNode.panBegan = { [weak self] location in
guard let strongSelf = self, let size = strongSelf.validLayout else {
return
}
let previousColor = strongSelf.color
let colorHeight = size.height - 66.0
let newHue = max(0.0, min(1.0, location.x / size.width))
let newSaturation = max(0.0, min(1.0, (1.0 - location.y / colorHeight)))
strongSelf.color = HSBColor(hue: newHue, saturation: newSaturation, brightness: strongSelf.color.brightness)
strongSelf.updateKnobLayout(size: size, panningColor: true, transition: .immediate)
if strongSelf.color != previousColor {
strongSelf.colorChanged?(strongSelf.color)
}
}
self.colorNode.panChanged = { [weak self] translation, ended in
guard let strongSelf = self, let size = strongSelf.validLayout else {
return
}
let previousColor = strongSelf.color
let colorHeight = size.height - 66.0
let newHue = max(0.0, min(1.0, strongSelf.color.hue + translation.x / size.width))
let newSaturation = max(0.0, min(1.0, strongSelf.color.saturation - translation.y / colorHeight))
strongSelf.color = HSBColor(hue: newHue, saturation: newSaturation, brightness: strongSelf.color.brightness)
if ended {
strongSelf.updateKnobLayout(size: size, panningColor: false, transition: .animated(duration: 0.3, curve: .easeInOut))
} else {
strongSelf.updateKnobLayout(size: size, panningColor: true, transition: .immediate)
}
if strongSelf.color != previousColor || ended {
strongSelf.update()
if ended {
strongSelf.colorChangeEnded?(strongSelf.color)
} else {
strongSelf.colorChanged?(strongSelf.color)
}
}
}
}
override func didLoad() {
super.didLoad()
let colorPanRecognizer = UIPanGestureRecognizer(target: self, action: #selector(WallpaperColorPickerNode.colorPan))
self.colorNode.view.addGestureRecognizer(colorPanRecognizer)
let colorTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(WallpaperColorPickerNode.colorTap))
self.colorNode.view.addGestureRecognizer(colorTapRecognizer)
self.view.disablesInteractiveTransitionGestureRecognizer = true
self.view.disablesInteractiveModalDismiss = true
let brightnessPanRecognizer = UIPanGestureRecognizer(target: self, action: #selector(WallpaperColorPickerNode.brightnessPan))
self.brightnessNode.view.addGestureRecognizer(brightnessPanRecognizer)
@ -270,16 +429,16 @@ final class WallpaperColorPickerNode: ASDisplayNode {
private func update() {
self.backgroundColor = .white
self.colorNode.value = self.colorHsb.2
self.brightnessNode.hsb = self.colorHsb
self.colorKnobNode.hsb = self.colorHsb
self.colorNode.value = self.color.brightness
self.brightnessNode.hsb = self.color.values
self.colorKnobNode.color = self.color
}
private func updateKnobLayout(size: CGSize, panningColor: Bool, transition: ContainedViewLayoutTransition) {
let knobSize = CGSize(width: 45.0, height: 45.0)
let colorHeight = size.height - 66.0
var colorKnobFrame = CGRect(x: floorToScreenPixels(-knobSize.width / 2.0 + size.width * self.colorHsb.0), y: floorToScreenPixels(-knobSize.height / 2.0 + (colorHeight * (1.0 - self.colorHsb.1))), width: knobSize.width, height: knobSize.height)
var colorKnobFrame = CGRect(x: floorToScreenPixels(-knobSize.width / 2.0 + size.width * self.color.hue), y: floorToScreenPixels(-knobSize.height / 2.0 + (colorHeight * (1.0 - self.color.saturation))), width: knobSize.width, height: knobSize.height)
var origin = colorKnobFrame.origin
if !panningColor {
origin = CGPoint(x: max(0.0, min(origin.x, size.width - knobSize.width)), y: max(0.0, min(origin.y, colorHeight - knobSize.height)))
@ -291,7 +450,7 @@ final class WallpaperColorPickerNode: ASDisplayNode {
let inset: CGFloat = 15.0
let brightnessKnobSize = CGSize(width: 12.0, height: 55.0)
let brightnessKnobFrame = CGRect(x: inset - brightnessKnobSize.width / 2.0 + (size.width - inset * 2.0) * (1.0 - self.colorHsb.2), y: size.height - 65.0, width: brightnessKnobSize.width, height: brightnessKnobSize.height)
let brightnessKnobFrame = CGRect(x: inset - brightnessKnobSize.width / 2.0 + (size.width - inset * 2.0) * (1.0 - self.color.brightness), y: size.height - 65.0, width: brightnessKnobSize.width, height: brightnessKnobSize.height)
transition.updateFrame(node: self.brightnessKnobNode, frame: brightnessKnobFrame)
}
@ -307,72 +466,6 @@ final class WallpaperColorPickerNode: ASDisplayNode {
self.updateKnobLayout(size: size, panningColor: false, transition: .immediate)
}
@objc private func colorTap(_ recognizer: UITapGestureRecognizer) {
guard let size = self.validLayout, recognizer.state == .recognized else {
return
}
let colorHeight = size.height - 66.0
let location = recognizer.location(in: recognizer.view)
let newHue = max(0.0, min(1.0, location.x / size.width))
let newSaturation = max(0.0, min(1.0, (1.0 - location.y / colorHeight)))
self.colorHsb.0 = newHue
self.colorHsb.1 = newSaturation
self.updateKnobLayout(size: size, panningColor: false, transition: .immediate)
self.update()
self.colorChangeEnded?(self.color)
}
@objc private func colorPan(_ recognizer: UIPanGestureRecognizer) {
guard let size = self.validLayout else {
return
}
let previousColor = self.color
let colorHeight = size.height - 66.0
let location = recognizer.location(in: recognizer.view)
let transition = recognizer.translation(in: recognizer.view)
if recognizer.state == .began {
let newHue = max(0.0, min(1.0, location.x / size.width))
let newSaturation = max(0.0, min(1.0, (1.0 - location.y / colorHeight)))
self.colorHsb.0 = newHue
self.colorHsb.1 = newSaturation
} else {
let newHue = max(0.0, min(1.0, self.colorHsb.0 + transition.x / size.width))
let newSaturation = max(0.0, min(1.0, self.colorHsb.1 - transition.y / (size.height - 66.0)))
self.colorHsb.0 = newHue
self.colorHsb.1 = newSaturation
}
var ended = false
switch recognizer.state {
case .began:
self.updateKnobLayout(size: size, panningColor: true, transition: .immediate)
case .changed:
self.updateKnobLayout(size: size, panningColor: true, transition: .immediate)
recognizer.setTranslation(CGPoint(), in: recognizer.view)
case .ended:
self.updateKnobLayout(size: size, panningColor: false, transition: .animated(duration: 0.3, curve: .easeInOut))
ended = true
default:
break
}
if self.color != previousColor || ended {
self.update()
if ended {
self.colorChangeEnded?(self.color)
} else {
self.colorChanged?(self.color)
}
}
}
@objc private func brightnessPan(_ recognizer: UIPanGestureRecognizer) {
guard let size = self.validLayout else {
return
@ -382,9 +475,9 @@ final class WallpaperColorPickerNode: ASDisplayNode {
let transition = recognizer.translation(in: recognizer.view)
let brightnessWidth: CGFloat = size.width - 42.0 * 2.0
let newValue = max(0.0, min(1.0, self.colorHsb.2 - transition.x / brightnessWidth))
self.colorHsb.2 = newValue
let newValue = max(0.0, min(1.0, self.color.brightness - transition.x / brightnessWidth))
self.color = HSBColor(hue: self.color.hue, saturation: self.color.saturation, brightness: newValue)
var ended = false
switch recognizer.state {
case .changed:

View File

@ -631,11 +631,11 @@ public class WallpaperGalleryController: ViewController {
strongSelf.patternInitialWallpaper = enabled ? initialWallpaper : nil
switch initialWallpaper {
case let .color(color):
strongSelf.patternPanelNode?.backgroundColors = ([color], nil, nil)
strongSelf.patternPanelNode?.backgroundColors = ([HSBColor(rgb: color)], nil, nil)
case let .gradient(gradient):
strongSelf.patternPanelNode?.backgroundColors = (gradient.colors, gradient.settings.rotation, nil)
strongSelf.patternPanelNode?.backgroundColors = (gradient.colors.map { HSBColor(rgb: $0) }, gradient.settings.rotation, nil)
case let .file(file) where file.isPattern:
strongSelf.patternPanelNode?.backgroundColors = (file.settings.colors, file.settings.rotation, file.settings.intensity)
strongSelf.patternPanelNode?.backgroundColors = (file.settings.colors.map { HSBColor(rgb: $0) }, file.settings.rotation, file.settings.intensity)
default:
break
}
@ -678,7 +678,7 @@ public class WallpaperGalleryController: ViewController {
strongSelf.colorsPanelNode?.updateState({ _ in
return WallpaperColorPanelNodeState(
selection: 0,
colors: colors.map(\.rgb),
colors: colors.map { HSBColor(color: $0) },
maximumNumberOfColors: 4,
rotateAvailable: false,
rotation: 0,
@ -863,7 +863,7 @@ public class WallpaperGalleryController: ViewController {
break
}
strongSelf.patternPanelNode?.backgroundColors = (colors, rotation, intensity)
strongSelf.patternPanelNode?.backgroundColors = (colors.map { HSBColor(rgb: $0) }, rotation, intensity)
}
}
self.patternPanelNode = patternPanelNode
@ -888,10 +888,10 @@ public class WallpaperGalleryController: ViewController {
return
}
var wallpaper: TelegramWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: colors, settings: WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil)))
var wallpaper: TelegramWallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: colors.map { $0.rgb }, settings: WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil)))
if case let .file(file) = currentWallpaper {
wallpaper = currentWallpaper.withUpdatedSettings(WallpaperSettings(blur: false, motion: false, colors: colors, intensity: file.settings.intensity, rotation: file.settings.rotation))
wallpaper = currentWallpaper.withUpdatedSettings(WallpaperSettings(blur: false, motion: false, colors: colors.map { $0.rgb }, intensity: file.settings.intensity, rotation: file.settings.rotation))
}
strongSelf.updateEntries(wallpaper: wallpaper)

View File

@ -200,7 +200,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
}
}
var backgroundColors: ([UInt32], Int32?, Int32?)? = nil {
var backgroundColors: ([HSBColor], Int32?, Int32?)? = nil {
didSet {
var updated = false
if oldValue?.0 != self.backgroundColors?.0 || oldValue?.1 != self.backgroundColors?.1 {
@ -329,7 +329,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
node.removeFromSupernode()
}
let backgroundColors = self.backgroundColors ?? ([0xd6e2ee], nil, nil)
let backgroundColors = self.backgroundColors.flatMap { ($0.0.map({ $0.rgb }), $0.1, $0.2) } ?? ([0xd6e2ee], nil, nil)
let intensity: Int32 = backgroundColors.2.flatMap { value in
if value < 0 {
return -80

View File

@ -162,11 +162,14 @@ func preparedChatMediaInputGridEntryTransition(account: Account, view: ItemColle
return ChatMediaInputGridTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: firstIndexInSectionOffset, stationaryItems: stationaryItems, scrollToItem: scrollToItem, updateOpaqueState: opaqueState, animated: animated)
}
func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, temporaryPackOrder: [ItemCollectionId]? = nil, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false) -> [ChatMediaInputPanelEntry] {
func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, temporaryPackOrder: [ItemCollectionId]? = nil, trendingIsDismissed: Bool = false, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false) -> [ChatMediaInputPanelEntry] {
var entries: [ChatMediaInputPanelEntry] = []
if hasGifs {
entries.append(.recentGifs(theme, expanded))
}
if trendingIsDismissed {
entries.append(.trending(true, theme, expanded))
}
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
entries.append(.savedStickers(theme, expanded))
}
@ -251,7 +254,7 @@ func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, reactions: [Str
return entries
}
func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], dismissedTrendingStickerPacks: [ItemCollectionId.Id]? = nil, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme) -> [ChatMediaInputGridEntry] {
func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], trendingIsDismissed: Bool = false, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme) -> [ChatMediaInputGridEntry] {
var entries: [ChatMediaInputGridEntry] = []
if hasSearch && view.lower == nil {
@ -279,10 +282,6 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
}
}
var trendingIsDismissed = false
if let dismissedTrendingStickerPacks = dismissedTrendingStickerPacks, Set(trendingPacks.map({ $0.info.id.id })) == Set(dismissedTrendingStickerPacks) {
trendingIsDismissed = true
}
if !trendingIsDismissed {
entries.append(.trendingList(theme: theme, strings: strings, packs: trendingPacks))
}
@ -1106,10 +1105,15 @@ final class ChatMediaInputNode: ChatInputNode {
for info in view.collectionInfos {
installedPacks.insert(info.0)
}
var trendingIsDismissed = false
if let dismissedTrendingStickerPacks = dismissedTrendingStickerPacks, Set(trendingPacks.map({ $0.info.id.id })) == Set(dismissedTrendingStickerPacks) {
trendingIsDismissed = true
}
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, expanded: panelExpanded)
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, trendingIsDismissed: trendingIsDismissed, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, expanded: panelExpanded)
let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, reactions: reactions, animatedEmojiStickers: animatedEmojiStickers, expanded: panelExpanded)
var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, dismissedTrendingStickerPacks: dismissedTrendingStickerPacks, strings: strings, theme: theme)
var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, trendingIsDismissed: trendingIsDismissed, strings: strings, theme: theme)
if view.higher == nil {
var hasTopSeparator = true

View File

@ -133,7 +133,6 @@ final class ChatMediaInputTrendingItemNode: ListViewItemNode {
if self.elevated != elevated {
self.elevated = elevated
self.badgeBackground.isHidden = !self.elevated
}
self.containerNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: expandedBoundingSize)