Theme fixes

This commit is contained in:
Ali 2021-05-31 16:27:07 +04:00
parent 735ee8a54b
commit 7e52c6c345
12 changed files with 150 additions and 190 deletions

View File

@ -166,7 +166,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
if patternIntensity < 0.0 { if patternIntensity < 0.0 {
self.imageNode.alpha = 1.0 self.imageNode.alpha = 1.0
self.arguments = PatternWallpaperArguments(colors: [.black], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity)) self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity))
} else { } else {
self.imageNode.alpha = CGFloat(file.settings.intensity ?? 50) / 100.0 self.imageNode.alpha = CGFloat(file.settings.intensity ?? 50) / 100.0
self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0)) self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0))

View File

@ -156,9 +156,9 @@ final class ThemeAccentColorController: ViewController {
var coloredWallpaper: TelegramWallpaper? var coloredWallpaper: TelegramWallpaper?
if !state.backgroundColors.isEmpty { if !state.backgroundColors.isEmpty {
if let patternWallpaper = state.patternWallpaper { if let patternWallpaper = state.patternWallpaper {
coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(motion: state.motion, colors: state.backgroundColors, intensity: state.patternIntensity, rotation: state.rotation)) coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: state.backgroundColors, intensity: state.patternIntensity, rotation: state.rotation))
} else if state.backgroundColors.count >= 2 { } else if state.backgroundColors.count >= 2 {
coloredWallpaper = .gradient(state.backgroundColors, WallpaperSettings(motion: state.motion, rotation: state.rotation)) coloredWallpaper = .gradient(state.backgroundColors, WallpaperSettings(rotation: state.rotation))
} else { } else {
coloredWallpaper = .color(state.backgroundColors[0]) coloredWallpaper = .color(state.backgroundColors[0])
} }
@ -602,7 +602,7 @@ final class ThemeAccentColorController: ViewController {
messageColors = nil messageColors = nil
} }
let initialState = ThemeColorState(section: strongSelf.section, accentColor: accentColor, initialWallpaper: initialWallpaper, backgroundColors: backgroundColors, patternWallpaper: patternWallpaper, patternIntensity: patternIntensity, motion: motion, defaultMessagesColor: defaultMessagesColor, messagesColors: messageColors, rotation: rotation) let initialState = ThemeColorState(section: strongSelf.section, accentColor: accentColor, initialWallpaper: initialWallpaper, backgroundColors: backgroundColors, patternWallpaper: patternWallpaper, patternIntensity: patternIntensity, defaultMessagesColor: defaultMessagesColor, messagesColors: messageColors, rotation: rotation)
strongSelf.controllerNode.updateState({ _ in strongSelf.controllerNode.updateState({ _ in
return initialState return initialState

View File

@ -48,7 +48,6 @@ struct ThemeColorState {
fileprivate var previousPatternWallpaper: TelegramWallpaper? fileprivate var previousPatternWallpaper: TelegramWallpaper?
var patternWallpaper: TelegramWallpaper? var patternWallpaper: TelegramWallpaper?
var patternIntensity: Int32 var patternIntensity: Int32
var motion: Bool
var defaultMessagesColor: UIColor? var defaultMessagesColor: UIColor?
var messagesColors: (UIColor, UIColor?)? var messagesColors: (UIColor, UIColor?)?
@ -66,13 +65,12 @@ struct ThemeColorState {
self.previousPatternWallpaper = nil self.previousPatternWallpaper = nil
self.patternWallpaper = nil self.patternWallpaper = nil
self.patternIntensity = 50 self.patternIntensity = 50
self.motion = false
self.defaultMessagesColor = nil self.defaultMessagesColor = nil
self.messagesColors = nil self.messagesColors = nil
self.rotation = 0 self.rotation = 0
} }
init(section: ThemeColorSection, accentColor: UIColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [UInt32], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, motion: Bool, defaultMessagesColor: UIColor?, messagesColors: (UIColor, UIColor?)?, rotation: Int32 = 0) { init(section: ThemeColorSection, accentColor: UIColor, initialWallpaper: TelegramWallpaper?, backgroundColors: [UInt32], patternWallpaper: TelegramWallpaper?, patternIntensity: Int32, defaultMessagesColor: UIColor?, messagesColors: (UIColor, UIColor?)?, rotation: Int32 = 0) {
self.section = section self.section = section
self.colorPanelCollapsed = false self.colorPanelCollapsed = false
self.displayPatternPanel = false self.displayPatternPanel = false
@ -83,7 +81,6 @@ struct ThemeColorState {
self.previousPatternWallpaper = nil self.previousPatternWallpaper = nil
self.patternWallpaper = patternWallpaper self.patternWallpaper = patternWallpaper
self.patternIntensity = patternIntensity self.patternIntensity = patternIntensity
self.motion = motion
self.defaultMessagesColor = defaultMessagesColor self.defaultMessagesColor = defaultMessagesColor
self.messagesColors = messagesColors self.messagesColors = messagesColors
self.rotation = rotation self.rotation = rotation
@ -159,7 +156,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
private let scrollNode: ASScrollNode private let scrollNode: ASScrollNode
private let pageControlBackgroundNode: ASDisplayNode private let pageControlBackgroundNode: ASDisplayNode
private let pageControlNode: PageControlNode private let pageControlNode: PageControlNode
private var motionButtonNode: WallpaperOptionButtonNode
private var patternButtonNode: WallpaperOptionButtonNode private var patternButtonNode: WallpaperOptionButtonNode
private let chatListBackgroundNode: ASDisplayNode private let chatListBackgroundNode: ASDisplayNode
private var chatNodes: [ListViewItemNode]? private var chatNodes: [ListViewItemNode]?
@ -234,7 +230,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.pageControlNode = PageControlNode(dotSpacing: 7.0, dotColor: .white, inactiveDotColor: UIColor.white.withAlphaComponent(0.4)) self.pageControlNode = PageControlNode(dotSpacing: 7.0, dotColor: .white, inactiveDotColor: UIColor.white.withAlphaComponent(0.4))
self.motionButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_Motion, value: .check(false))
self.patternButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_Pattern, value: .check(false)) self.patternButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_Pattern, value: .check(false))
self.chatListBackgroundNode = ASDisplayNode() self.chatListBackgroundNode = ASDisplayNode()
@ -280,7 +275,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.chatListBackgroundNode.addSubnode(self.maskNode) self.chatListBackgroundNode.addSubnode(self.maskNode)
self.addSubnode(self.pageControlBackgroundNode) self.addSubnode(self.pageControlBackgroundNode)
self.addSubnode(self.pageControlNode) self.addSubnode(self.pageControlNode)
self.addSubnode(self.motionButtonNode)
self.addSubnode(self.patternButtonNode) self.addSubnode(self.patternButtonNode)
self.addSubnode(self.colorPanelNode) self.addSubnode(self.colorPanelNode)
self.addSubnode(self.patternPanelNode) self.addSubnode(self.patternPanelNode)
@ -293,21 +287,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.backgroundContainerNode.addSubnode(self.backgroundWrapperNode) self.backgroundContainerNode.addSubnode(self.backgroundWrapperNode)
self.backgroundWrapperNode.addSubnode(self.backgroundNode) self.backgroundWrapperNode.addSubnode(self.backgroundNode)
self.motionButtonNode.addTarget(self, action: #selector(self.toggleMotion), forControlEvents: .touchUpInside)
self.patternButtonNode.addTarget(self, action: #selector(self.togglePattern), forControlEvents: .touchUpInside) self.patternButtonNode.addTarget(self, action: #selector(self.togglePattern), forControlEvents: .touchUpInside)
/*self.colorPanelNode.colorAdded = { [weak self] in
if let strongSelf = self {
strongSelf.signalBackgroundNode.contentAnimations = [.subsequentUpdates]
}
}
self.colorPanelNode.colorRemoved = { [weak self] in
if let strongSelf = self {
strongSelf.signalBackgroundNode.contentAnimations = [.subsequentUpdates]
}
}*/
self.colorPanelNode.colorsChanged = { [weak self] colors, ended in self.colorPanelNode.colorsChanged = { [weak self] colors, ended in
if let strongSelf = self, let section = strongSelf.state.section { if let strongSelf = self, let section = strongSelf.state.section {
strongSelf.updateState({ current in strongSelf.updateState({ current in
@ -422,7 +403,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if !backgroundColors.isEmpty { if !backgroundColors.isEmpty {
if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper { if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper {
wallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(motion: state.motion, colors: backgroundColors, intensity: state.patternIntensity, rotation: state.rotation)) wallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: backgroundColors, intensity: state.patternIntensity, rotation: state.rotation))
let dimensions = file.file.dimensions ?? PixelDimensions(width: 100, height: 100) let dimensions = file.file.dimensions ?? PixelDimensions(width: 100, height: 100)
var convertedRepresentations: [ImageRepresentationWithReference] = [] var convertedRepresentations: [ImageRepresentationWithReference] = []
@ -543,7 +524,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
strongSelf.patternPanelNode.serviceBackgroundColor = color strongSelf.patternPanelNode.serviceBackgroundColor = color
strongSelf.pageControlBackgroundNode.backgroundColor = color strongSelf.pageControlBackgroundNode.backgroundColor = color
strongSelf.patternButtonNode.buttonColor = color strongSelf.patternButtonNode.buttonColor = color
strongSelf.motionButtonNode.buttonColor = color
} }
}) })
} }
@ -594,11 +574,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.patternButtonNode.setSelected(self.state.patternWallpaper != nil, animated: animated) self.patternButtonNode.setSelected(self.state.patternWallpaper != nil, animated: animated)
} }
if previousState.motion != self.state.motion {
self.motionButtonNode.setSelected(self.state.motion, animated: animated)
self.setMotionEnabled(self.state.motion, animated: animated)
}
let sectionChanged = previousState.section != self.state.section let sectionChanged = previousState.section != self.state.section
if sectionChanged, let section = self.state.section { if sectionChanged, let section = self.state.section {
self.view.endEditing(true) self.view.endEditing(true)
@ -1012,42 +987,19 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
transition.updateFrame(node: self.maskNode, frame: CGRect(x: 0.0, y: layout.size.height - bottomInset - 80.0, width: bounds.width, height: 80.0)) transition.updateFrame(node: self.maskNode, frame: CGRect(x: 0.0, y: layout.size.height - bottomInset - 80.0, width: bounds.width, height: 80.0))
let patternButtonSize = self.patternButtonNode.measure(layout.size) let patternButtonSize = self.patternButtonNode.measure(layout.size)
let motionButtonSize = self.motionButtonNode.measure(layout.size) let maxButtonWidth = patternButtonSize.width
let maxButtonWidth = max(patternButtonSize.width, motionButtonSize.width)
let buttonSize = CGSize(width: maxButtonWidth, height: 30.0) let buttonSize = CGSize(width: maxButtonWidth, height: 30.0)
let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - 10.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize) let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - 10.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize)
let centerButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonSize.width) / 2.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize) let centerButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonSize.width) / 2.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize)
let rightButtonFrame = CGRect(origin: CGPoint(x: ceil(layout.size.width / 2.0 + 10.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize) let rightButtonFrame = CGRect(origin: CGPoint(x: ceil(layout.size.width / 2.0 + 10.0), y: layout.size.height - bottomInset - 44.0), size: buttonSize)
var hasMotion: Bool = self.state.patternWallpaper != nil || self.state.displayPatternPanel
if self.state.backgroundColors.count >= 3 {
hasMotion = false
}
var patternAlpha: CGFloat = displayOptionButtons ? 1.0 : 0.0 var patternAlpha: CGFloat = displayOptionButtons ? 1.0 : 0.0
var motionAlpha: CGFloat = displayOptionButtons && hasMotion ? 1.0 : 0.0
var patternFrame = hasMotion ? leftButtonFrame : centerButtonFrame var patternFrame = centerButtonFrame
var motionFrame = hasMotion ? rightButtonFrame : centerButtonFrame
transition.updateFrame(node: self.patternButtonNode, frame: patternFrame) transition.updateFrame(node: self.patternButtonNode, frame: patternFrame)
transition.updateAlpha(node: self.patternButtonNode, alpha: patternAlpha) transition.updateAlpha(node: self.patternButtonNode, alpha: patternAlpha)
transition.updateFrame(node: self.motionButtonNode, frame: motionFrame)
transition.updateAlpha(node: self.motionButtonNode, alpha: motionAlpha)
if isFirstLayout {
self.setMotionEnabled(self.state.motion, animated: false)
}
}
@objc private func toggleMotion() {
self.updateState({ current in
var updated = current
updated.motion = !updated.motion
return updated
}, animated: true)
} }
@objc private func togglePattern() { @objc private func togglePattern() {
@ -1085,50 +1037,4 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.patternPanelNode.didAppear(initialWallpaper: wallpaper, intensity: self.state.patternIntensity) self.patternPanelNode.didAppear(initialWallpaper: wallpaper, intensity: self.state.patternIntensity)
} }
} }
private let motionAmount: CGFloat = 32.0
private func setMotionEnabled(_ enabled: Bool, animated: Bool) {
guard let (layout, _, _) = self.validLayout else {
return
}
if enabled {
let horizontal = UIInterpolatingMotionEffect(keyPath: "center.x", type: .tiltAlongHorizontalAxis)
horizontal.minimumRelativeValue = motionAmount
horizontal.maximumRelativeValue = -motionAmount
let vertical = UIInterpolatingMotionEffect(keyPath: "center.y", type: .tiltAlongVerticalAxis)
vertical.minimumRelativeValue = motionAmount
vertical.maximumRelativeValue = -motionAmount
let group = UIMotionEffectGroup()
group.motionEffects = [horizontal, vertical]
self.backgroundWrapperNode.view.addMotionEffect(group)
let scale = (layout.size.width + motionAmount * 2.0) / layout.size.width
if animated {
self.backgroundWrapperNode.transform = CATransform3DMakeScale(scale, scale, 1.0)
self.backgroundWrapperNode.layer.animateScale(from: 1.0, to: scale, duration: 0.2)
} else {
self.backgroundWrapperNode.transform = CATransform3DMakeScale(scale, scale, 1.0)
}
} else {
let position = self.backgroundWrapperNode.layer.presentation()?.position
for effect in self.backgroundWrapperNode.view.motionEffects {
self.backgroundWrapperNode.view.removeMotionEffect(effect)
}
let scale = (layout.size.width + motionAmount * 2.0) / layout.size.width
if animated {
self.backgroundWrapperNode.transform = CATransform3DIdentity
self.backgroundWrapperNode.layer.animateScale(from: scale, to: 1.0, duration: 0.2)
if let position = position {
self.backgroundWrapperNode.layer.animatePosition(from: position, to: self.backgroundWrapperNode.layer.position, duration: 0.2)
}
} else {
self.backgroundWrapperNode.transform = CATransform3DIdentity
}
}
}
} }

View File

@ -246,8 +246,8 @@ final class ThemeGridControllerNode: ASDisplayNode {
let wallpapersPromise = Promise<[Wallpaper]>() let wallpapersPromise = Promise<[Wallpaper]>()
self.wallpapersPromise = wallpapersPromise self.wallpapersPromise = wallpapersPromise
let deletedWallpaperSlugsValue = Atomic<Set<String>>(value: Set()) let deletedWallpaperIdsValue = Atomic<Set<ThemeGridControllerEntry.StableId>>(value: Set())
let deletedWallpaperSlugsPromise = ValuePromise<Set<String>>(Set()) let deletedWallpaperIdsPromise = ValuePromise<Set<ThemeGridControllerEntry.StableId>>(Set())
super.init() super.init()
@ -306,16 +306,16 @@ final class ThemeGridControllerNode: ASDisplayNode {
deleteWallpapers(wallpapers, { [weak self] in deleteWallpapers(wallpapers, { [weak self] in
if let strongSelf = self { if let strongSelf = self {
var updatedDeletedSlugs = deletedWallpaperSlugsValue.with { $0 } var updatedDeletedIds = deletedWallpaperIdsValue.with { $0 }
for entry in entries { for entry in entries {
if case let .file(file) = entry.wallpaper, strongSelf.currentState.selectedIds.contains(entry.stableId) { if strongSelf.currentState.selectedIds.contains(entry.stableId) {
updatedDeletedSlugs.insert(file.slug) updatedDeletedIds.insert(entry.stableId)
} }
} }
let _ = deletedWallpaperSlugsValue.swap(updatedDeletedSlugs) let _ = deletedWallpaperIdsValue.swap(updatedDeletedIds)
deletedWallpaperSlugsPromise.set(updatedDeletedSlugs) deletedWallpaperIdsPromise.set(updatedDeletedIds)
let _ = (strongSelf.context.sharedContext.accountManager.transaction { transaction in let _ = (strongSelf.context.sharedContext.accountManager.transaction { transaction in
WallpapersState.update(transaction: transaction, { state in WallpapersState.update(transaction: transaction, { state in
@ -341,8 +341,8 @@ final class ThemeGridControllerNode: ASDisplayNode {
}) })
self.controllerInteraction = interaction self.controllerInteraction = interaction
let transition = combineLatest(self.wallpapersPromise.get(), deletedWallpaperSlugsPromise.get(), context.sharedContext.presentationData) let transition = combineLatest(self.wallpapersPromise.get(), deletedWallpaperIdsPromise.get(), context.sharedContext.presentationData)
|> map { wallpapers, deletedWallpaperSlugs, presentationData -> (ThemeGridEntryTransition, Bool) in |> map { wallpapers, deletedWallpaperIds, presentationData -> (ThemeGridEntryTransition, Bool) in
var entries: [ThemeGridControllerEntry] = [] var entries: [ThemeGridControllerEntry] = []
var index = 1 var index = 1
@ -399,7 +399,7 @@ final class ThemeGridControllerNode: ASDisplayNode {
} }
for wallpaper in sortedWallpapers { for wallpaper in sortedWallpapers {
if case let .file(file) = wallpaper, deletedWallpaperSlugs.contains(file.slug) || (wallpaper.isPattern && file.settings.colors.isEmpty) { if case let .file(file) = wallpaper, (wallpaper.isPattern && file.settings.colors.isEmpty) {
continue continue
} }
let selected = presentationData.chatWallpaper.isBasicallyEqual(to: wallpaper) let selected = presentationData.chatWallpaper.isBasicallyEqual(to: wallpaper)
@ -416,6 +416,9 @@ final class ThemeGridControllerNode: ASDisplayNode {
} }
if !selected && !isDefault { if !selected && !isDefault {
let entry = ThemeGridControllerEntry(index: index, wallpaper: wallpaper, isEditable: isEditable, isSelected: false) let entry = ThemeGridControllerEntry(index: index, wallpaper: wallpaper, isEditable: isEditable, isSelected: false)
if deletedWallpaperIds.contains(entry.stableId) {
continue
}
if !entries.contains(where: { $0.stableId == entry.stableId }) { if !entries.contains(where: { $0.stableId == entry.stableId }) {
entries.append(entry) entries.append(entry)
index += 1 index += 1

View File

@ -623,12 +623,12 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
} }
let title = themeDisplayName(strings: item.strings, reference: theme) let title = themeDisplayName(strings: item.strings, reference: theme)
var accentColor = item.themeSpecificAccentColors[theme.generalThemeReference.index] var accentColor = item.themeSpecificAccentColors[theme.generalThemeReference.index]
if let customThemeIndex = accentColor?.themeIndex { /*if let customThemeIndex = accentColor?.themeIndex {
if let customTheme = themes[customThemeIndex] { if let customTheme = themes[customThemeIndex] {
theme = customTheme theme = customTheme
} }
accentColor = nil accentColor = nil
} }*/
var themeWallpaper: TelegramWallpaper? var themeWallpaper: TelegramWallpaper?
if case let .cloud(theme) = theme { if case let .cloud(theme) = theme {

View File

@ -308,6 +308,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
} else { } else {
self.playButtonNode.setImage(self.playButtonRotateImage, for: []) self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
} }
} else if case .color = wallpaper {
self.nativeNode.isHidden = false
self.nativeNode.update(wallpaper: wallpaper)
self.patternButtonNode.isSelected = false
} else { } else {
self.nativeNode.isHidden = true self.nativeNode.isHidden = true
self.patternButtonNode.isSelected = false self.patternButtonNode.isSelected = false

View File

@ -596,7 +596,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
let (_, initialImageWidth, refineLayout) = contentImageLayout(context, presentationData, presentationData.dateTimeFormat, message, attributes, wallpaper, imageDateAndStatus, .full, associatedData.automaticDownloadPeerType, .constrained(CGSize(width: constrainedSize.width - horizontalInsets.left - horizontalInsets.right, height: constrainedSize.height)), layoutConstants, contentMode) let (_, initialImageWidth, refineLayout) = contentImageLayout(context, presentationData, presentationData.dateTimeFormat, message, attributes, wallpaper, imageDateAndStatus, .full, associatedData.automaticDownloadPeerType, .constrained(CGSize(width: constrainedSize.width - horizontalInsets.left - horizontalInsets.right, height: constrainedSize.height)), layoutConstants, contentMode)
initialWidth = initialImageWidth + horizontalInsets.left + horizontalInsets.right initialWidth = initialImageWidth + horizontalInsets.left + horizontalInsets.right
refineContentImageLayout = refineLayout refineContentImageLayout = refineLayout
if case let .file(_, _, _, isTheme, _) = wallpaper.content, isTheme { if case let .file(_, _, _, _, isTheme, _) = wallpaper.content, isTheme {
skipStandardStatus = true skipStandardStatus = true
} }
} }

View File

@ -419,7 +419,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
unboundSize = CGSize(width: floor(dimensions.cgSize.width * 0.5), height: floor(dimensions.cgSize.height * 0.5)) unboundSize = CGSize(width: floor(dimensions.cgSize.width * 0.5), height: floor(dimensions.cgSize.height * 0.5))
} else if let wallpaper = media as? WallpaperPreviewMedia { } else if let wallpaper = media as? WallpaperPreviewMedia {
switch wallpaper.content { switch wallpaper.content {
case let .file(file, _, _, isTheme, isSupported): case let .file(file, _, _, _, isTheme, isSupported):
if let thumbnail = file.previewRepresentations.first, var dimensions = file.dimensions { if let thumbnail = file.previewRepresentations.first, var dimensions = file.dimensions {
let dimensionsVertical = dimensions.width < dimensions.height let dimensionsVertical = dimensions.width < dimensions.height
let thumbnailVertical = thumbnail.dimensions.width < thumbnail.dimensions.height let thumbnailVertical = thumbnail.dimensions.width < thumbnail.dimensions.height
@ -570,14 +570,24 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
emptyColor = message.effectivelyIncoming(context.account.peerId) ? presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor emptyColor = message.effectivelyIncoming(context.account.peerId) ? presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor
} }
if let wallpaper = media as? WallpaperPreviewMedia { if let wallpaper = media as? WallpaperPreviewMedia {
if case let .file(_, patternColors, rotation, _, _) = wallpaper.content { if case let .file(_, patternColors, rotation, intensity, _, _) = wallpaper.content {
var colors: [UIColor] = [] var colors: [UIColor] = []
var customPatternColor: UIColor? = nil
if let intensity = intensity, intensity < 0 {
if patternColors.isEmpty { if patternColors.isEmpty {
colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5)) colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5))
} else { } else {
colors.append(contentsOf: patternColors.map(UIColor.init(rgb:))) colors.append(contentsOf: patternColors.map(UIColor.init(rgb:)))
} }
patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation) customPatternColor = UIColor(white: 0.0, alpha: 1.0 - CGFloat(abs(intensity)))
} else {
if patternColors.isEmpty {
colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5))
} else {
colors.append(contentsOf: patternColors.map(UIColor.init(rgb:)))
}
}
patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation, customPatternColor: customPatternColor)
} }
} }
@ -715,7 +725,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
} else if let wallpaper = media as? WallpaperPreviewMedia { } else if let wallpaper = media as? WallpaperPreviewMedia {
updateImageSignal = { synchronousLoad, _ in updateImageSignal = { synchronousLoad, _ in
switch wallpaper.content { switch wallpaper.content {
case let .file(file, _, _, isTheme, _): case let .file(file, _, _, _, isTheme, _):
if isTheme { if isTheme {
return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file))) return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file)))
} else { } else {
@ -738,7 +748,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
} }
} }
if case let .file(file, _, _, _, _) = wallpaper.content { if case let .file(file, _, _, _, _, _) = wallpaper.content {
updatedFetchControls = FetchControls(fetch: { manual in updatedFetchControls = FetchControls(fetch: { manual in
if let strongSelf = self { if let strongSelf = self {
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).start()) strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).start())
@ -783,7 +793,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
} }
} else if let wallpaper = media as? WallpaperPreviewMedia { } else if let wallpaper = media as? WallpaperPreviewMedia {
switch wallpaper.content { switch wallpaper.content {
case let .file(file, _, _, _, _): case let .file(file, _, _, _, _, _):
updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file) updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file)
|> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in |> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in
return (resourceStatus, nil) return (resourceStatus, nil)

View File

@ -173,11 +173,13 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
} else if webpage.type == "telegram_background" { } else if webpage.type == "telegram_background" {
var colors: [UInt32] = [] var colors: [UInt32] = []
var rotation: Int32? var rotation: Int32?
if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, colorsValue, intensity, rotationValue) = wallpaper { var intensity: Int32?
if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, colorsValue, intensityValue, rotationValue) = wallpaper {
colors = colorsValue colors = colorsValue
rotation = rotationValue rotation = rotationValue
intensity = intensityValue
} }
let media = WallpaperPreviewMedia(content: .file(file, colors, rotation, false, false)) let media = WallpaperPreviewMedia(content: .file(file: file, colors: colors, rotation: rotation, intensity: intensity, false, false))
mediaAndFlags = (media, [.preferMediaAspectFilled]) mediaAndFlags = (media, [.preferMediaAspectFilled])
if let fileSize = file.size { if let fileSize = file.size {
badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData)) badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData))
@ -251,7 +253,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
file = contentFile file = contentFile
} }
if let file = file { if let file = file {
let media = WallpaperPreviewMedia(content: .file(file, [], nil, true, isSupported)) let media = WallpaperPreviewMedia(content: .file(file: file, colors: [], rotation: nil, intensity: nil, true, isSupported))
mediaAndFlags = (media, ChatMessageAttachedContentNodeMediaFlags()) mediaAndFlags = (media, ChatMessageAttachedContentNodeMediaFlags())
} else if let settings = settings { } else if let settings = settings {
let media = WallpaperPreviewMedia(content: .themeSettings(settings)) let media = WallpaperPreviewMedia(content: .themeSettings(settings))

View File

@ -5,7 +5,7 @@ import TelegramCore
import SyncCore import SyncCore
enum WallpaperPreviewMediaContent: Equatable { enum WallpaperPreviewMediaContent: Equatable {
case file(TelegramMediaFile, [UInt32], Int32?, Bool, Bool) case file(file: TelegramMediaFile, colors: [UInt32], rotation: Int32?, intensity: Int32?, Bool, Bool)
case color(UIColor) case color(UIColor)
case gradient([UInt32], Int32?) case gradient([UInt32], Int32?)
case themeSettings(TelegramThemeSettings) case themeSettings(TelegramThemeSettings)

View File

@ -428,7 +428,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
let patternColor: UIColor let patternColor: UIColor
if self.invertPattern { if self.invertPattern {
patternColor = .clear patternColor = .clear
patternBackgroundColor = .black patternBackgroundColor = .clear
} else { } else {
patternColor = .black patternColor = .black
patternBackgroundColor = .clear patternBackgroundColor = .clear

View File

@ -487,6 +487,8 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
c.restoreGState() c.restoreGState()
} }
let overlayImage = generateImage(arguments.drawingRect.size, rotatedContext: { size, c in
c.clear(CGRect(origin: CGPoint(), size: size))
let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage
if let image = image { if let image = image {
var fittedSize = CGSize(width: image.width, height: image.height) var fittedSize = CGSize(width: image.width, height: image.height)
@ -500,22 +502,23 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
c.interpolationQuality = customArguments.preview ? .low : .medium
c.clip(to: fittedRect, mask: image)
if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 { if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 {
c.setBlendMode(.copy) c.setBlendMode(.copy)
c.setFillColor(UIColor.black.cgColor)
c.fill(CGRect(origin: CGPoint(), size: size))
} else { } else {
c.setBlendMode(.normal) c.setBlendMode(.normal)
} }
c.interpolationQuality = customArguments.preview ? .low : .medium
c.clip(to: fittedRect, mask: image)
if colors.count >= 3 && customArguments.customPatternColor == nil { if colors.count >= 3 && customArguments.customPatternColor == nil {
c.setBlendMode(.softLight)
c.setFillColor(UIColor(white: 0.0, alpha: 0.5).cgColor) c.setFillColor(UIColor(white: 0.0, alpha: 0.5).cgColor)
c.fill(arguments.drawingRect) c.fill(CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
} else if colors.count == 1 { } else if colors.count == 1 {
c.setFillColor(customArguments.customPatternColor?.cgColor ?? patternColor(for: color, intensity: intensity, prominent: prominent).cgColor) c.setFillColor(customArguments.customPatternColor?.cgColor ?? patternColor(for: color, intensity: intensity, prominent: prominent).cgColor)
c.fill(arguments.drawingRect) c.fill(CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
} else { } else {
let gradientColors = colors.map { patternColor(for: $0, intensity: intensity, prominent: prominent).cgColor } as CFArray let gradientColors = colors.map { patternColor(for: $0, intensity: intensity, prominent: prominent).cgColor } as CFArray
let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0) let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0)
@ -534,6 +537,21 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: arguments.drawingSize.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: arguments.drawingSize.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
} }
} }
})
if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 {
c.setBlendMode(.normal)
} else {
c.setBlendMode(.softLight)
}
if let overlayImage = overlayImage {
c.translateBy(x: drawingRect.midX, y: drawingRect.midY)
c.scaleBy(x: 1.0, y: -1.0)
c.translateBy(x: -drawingRect.midX, y: -drawingRect.midY)
c.draw(overlayImage.cgImage!, in: drawingRect)
c.translateBy(x: drawingRect.midX, y: drawingRect.midY)
c.scaleBy(x: 1.0, y: -1.0)
c.translateBy(x: -drawingRect.midX, y: -drawingRect.midY)
}
} }
addCorners(context, arguments: arguments) addCorners(context, arguments: arguments)
return context return context
@ -818,11 +836,16 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: drawingRect.height), end: CGPoint(x: 0.0, y: 0.0), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
} }
case let .file(file): case let .file(file):
c.setFillColor(theme.chatList.backgroundColor.cgColor) if file.isPattern, let intensity = file.settings.intensity, intensity < 0 {
c.setFillColor(UIColor.black.cgColor)
c.fill(CGRect(origin: CGPoint(), size: size))
} else {
if let image = wallpaperImage, let cgImage = image.cgImage { if let image = wallpaperImage, let cgImage = image.cgImage {
let size = image.size.aspectFilled(drawingRect.size) let size = image.size.aspectFilled(drawingRect.size)
c.draw(cgImage, in: CGRect(origin: CGPoint(x: (drawingRect.size.width - size.width) / 2.0, y: (drawingRect.size.height - size.height) / 2.0), size: size)) c.draw(cgImage, in: CGRect(origin: CGPoint(x: (drawingRect.size.width - size.width) / 2.0, y: (drawingRect.size.height - size.height) / 2.0), size: size))
} }
}
c.setFillColor(theme.chatList.backgroundColor.cgColor)
default: default:
break break
} }
@ -1223,6 +1246,11 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
} }
rotation = settings.rotation rotation = settings.rotation
case let .file(file): case let .file(file):
if file.isPattern, let intensity = file.settings.intensity, intensity < 0 {
colors = [0x000000]
topBackgroundColor = .black
bottomBackgroundColor = .black
} else {
colors = file.settings.colors colors = file.settings.colors
if !file.settings.colors.isEmpty { if !file.settings.colors.isEmpty {
topBackgroundColor = UIColor(rgb: file.settings.colors[0]) topBackgroundColor = UIColor(rgb: file.settings.colors[0])
@ -1231,6 +1259,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
} }
} }
rotation = file.settings.rotation rotation = file.settings.rotation
}
default: default:
colors = [0xd6e2ee] colors = [0xd6e2ee]
topBackgroundColor = UIColor(rgb: 0xd6e2ee) topBackgroundColor = UIColor(rgb: 0xd6e2ee)
@ -1297,7 +1326,9 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
backgroundColor = (.black, nil, []) backgroundColor = (.black, nil, [])
case let .file(file): case let .file(file):
rotation = file.settings.rotation rotation = file.settings.rotation
if !file.settings.colors.isEmpty { if file.isPattern, let intensity = file.settings.intensity, intensity < 0 {
backgroundColor = (.black, nil, [])
} else if !file.settings.colors.isEmpty {
var bottomColor: UIColor? var bottomColor: UIColor?
if file.settings.colors.count >= 2 { if file.settings.colors.count >= 2 {
bottomColor = UIColor(rgb: file.settings.colors[1]) bottomColor = UIColor(rgb: file.settings.colors[1])
@ -1330,10 +1361,14 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
if wallpaper.wallpaper.isPattern { if wallpaper.wallpaper.isPattern {
if !file.settings.colors.isEmpty, let intensity = file.settings.intensity { if !file.settings.colors.isEmpty, let intensity = file.settings.intensity {
if intensity < 0 {
return .single(((.black, nil, []), incomingColor, outgoingColor, nil, rotation))
} else {
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(colors: file.settings.colors, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true) return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(colors: file.settings.colors, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true)
|> mapToSignal { _ in |> mapToSignal { _ in
return .single((effectiveBackgroundColor, incomingColor, outgoingColor, nil, rotation)) return .single((effectiveBackgroundColor, incomingColor, outgoingColor, nil, rotation))
} }
}
} else { } else {
return .complete() return .complete()
} }