mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 03:09:56 +00:00
Theme fixes
This commit is contained in:
parent
735ee8a54b
commit
7e52c6c345
@ -166,7 +166,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
|
||||
|
||||
if patternIntensity < 0.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 {
|
||||
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))
|
||||
|
||||
@ -156,9 +156,9 @@ final class ThemeAccentColorController: ViewController {
|
||||
var coloredWallpaper: TelegramWallpaper?
|
||||
if !state.backgroundColors.isEmpty {
|
||||
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 {
|
||||
coloredWallpaper = .gradient(state.backgroundColors, WallpaperSettings(motion: state.motion, rotation: state.rotation))
|
||||
coloredWallpaper = .gradient(state.backgroundColors, WallpaperSettings(rotation: state.rotation))
|
||||
} else {
|
||||
coloredWallpaper = .color(state.backgroundColors[0])
|
||||
}
|
||||
@ -602,7 +602,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
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
|
||||
return initialState
|
||||
|
||||
@ -48,7 +48,6 @@ struct ThemeColorState {
|
||||
fileprivate var previousPatternWallpaper: TelegramWallpaper?
|
||||
var patternWallpaper: TelegramWallpaper?
|
||||
var patternIntensity: Int32
|
||||
var motion: Bool
|
||||
|
||||
var defaultMessagesColor: UIColor?
|
||||
var messagesColors: (UIColor, UIColor?)?
|
||||
@ -66,13 +65,12 @@ struct ThemeColorState {
|
||||
self.previousPatternWallpaper = nil
|
||||
self.patternWallpaper = nil
|
||||
self.patternIntensity = 50
|
||||
self.motion = false
|
||||
self.defaultMessagesColor = nil
|
||||
self.messagesColors = nil
|
||||
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.colorPanelCollapsed = false
|
||||
self.displayPatternPanel = false
|
||||
@ -83,7 +81,6 @@ struct ThemeColorState {
|
||||
self.previousPatternWallpaper = nil
|
||||
self.patternWallpaper = patternWallpaper
|
||||
self.patternIntensity = patternIntensity
|
||||
self.motion = motion
|
||||
self.defaultMessagesColor = defaultMessagesColor
|
||||
self.messagesColors = messagesColors
|
||||
self.rotation = rotation
|
||||
@ -159,7 +156,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
private let scrollNode: ASScrollNode
|
||||
private let pageControlBackgroundNode: ASDisplayNode
|
||||
private let pageControlNode: PageControlNode
|
||||
private var motionButtonNode: WallpaperOptionButtonNode
|
||||
private var patternButtonNode: WallpaperOptionButtonNode
|
||||
private let chatListBackgroundNode: ASDisplayNode
|
||||
private var chatNodes: [ListViewItemNode]?
|
||||
@ -233,8 +229,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
self.pageControlBackgroundNode.cornerRadius = 10.5
|
||||
|
||||
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.chatListBackgroundNode = ASDisplayNode()
|
||||
@ -280,7 +275,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
self.chatListBackgroundNode.addSubnode(self.maskNode)
|
||||
self.addSubnode(self.pageControlBackgroundNode)
|
||||
self.addSubnode(self.pageControlNode)
|
||||
self.addSubnode(self.motionButtonNode)
|
||||
self.addSubnode(self.patternButtonNode)
|
||||
self.addSubnode(self.colorPanelNode)
|
||||
self.addSubnode(self.patternPanelNode)
|
||||
@ -292,21 +286,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
|
||||
self.backgroundContainerNode.addSubnode(self.backgroundWrapperNode)
|
||||
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.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
|
||||
if let strongSelf = self, let section = strongSelf.state.section {
|
||||
@ -422,7 +403,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
|
||||
if !backgroundColors.isEmpty {
|
||||
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)
|
||||
var convertedRepresentations: [ImageRepresentationWithReference] = []
|
||||
@ -543,7 +524,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
strongSelf.patternPanelNode.serviceBackgroundColor = color
|
||||
strongSelf.pageControlBackgroundNode.backgroundColor = 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)
|
||||
}
|
||||
|
||||
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
|
||||
if sectionChanged, let section = self.state.section {
|
||||
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))
|
||||
|
||||
let patternButtonSize = self.patternButtonNode.measure(layout.size)
|
||||
let motionButtonSize = self.motionButtonNode.measure(layout.size)
|
||||
let maxButtonWidth = max(patternButtonSize.width, motionButtonSize.width)
|
||||
let maxButtonWidth = patternButtonSize.width
|
||||
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 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)
|
||||
|
||||
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 motionAlpha: CGFloat = displayOptionButtons && hasMotion ? 1.0 : 0.0
|
||||
|
||||
var patternFrame = hasMotion ? leftButtonFrame : centerButtonFrame
|
||||
var motionFrame = hasMotion ? rightButtonFrame : centerButtonFrame
|
||||
var patternFrame = centerButtonFrame
|
||||
|
||||
transition.updateFrame(node: self.patternButtonNode, frame: patternFrame)
|
||||
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() {
|
||||
@ -1085,50 +1037,4 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,8 +246,8 @@ final class ThemeGridControllerNode: ASDisplayNode {
|
||||
let wallpapersPromise = Promise<[Wallpaper]>()
|
||||
self.wallpapersPromise = wallpapersPromise
|
||||
|
||||
let deletedWallpaperSlugsValue = Atomic<Set<String>>(value: Set())
|
||||
let deletedWallpaperSlugsPromise = ValuePromise<Set<String>>(Set())
|
||||
let deletedWallpaperIdsValue = Atomic<Set<ThemeGridControllerEntry.StableId>>(value: Set())
|
||||
let deletedWallpaperIdsPromise = ValuePromise<Set<ThemeGridControllerEntry.StableId>>(Set())
|
||||
|
||||
super.init()
|
||||
|
||||
@ -306,16 +306,16 @@ final class ThemeGridControllerNode: ASDisplayNode {
|
||||
|
||||
deleteWallpapers(wallpapers, { [weak self] in
|
||||
if let strongSelf = self {
|
||||
var updatedDeletedSlugs = deletedWallpaperSlugsValue.with { $0 }
|
||||
var updatedDeletedIds = deletedWallpaperIdsValue.with { $0 }
|
||||
|
||||
for entry in entries {
|
||||
if case let .file(file) = entry.wallpaper, strongSelf.currentState.selectedIds.contains(entry.stableId) {
|
||||
updatedDeletedSlugs.insert(file.slug)
|
||||
if strongSelf.currentState.selectedIds.contains(entry.stableId) {
|
||||
updatedDeletedIds.insert(entry.stableId)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = deletedWallpaperSlugsValue.swap(updatedDeletedSlugs)
|
||||
deletedWallpaperSlugsPromise.set(updatedDeletedSlugs)
|
||||
let _ = deletedWallpaperIdsValue.swap(updatedDeletedIds)
|
||||
deletedWallpaperIdsPromise.set(updatedDeletedIds)
|
||||
|
||||
let _ = (strongSelf.context.sharedContext.accountManager.transaction { transaction in
|
||||
WallpapersState.update(transaction: transaction, { state in
|
||||
@ -341,8 +341,8 @@ final class ThemeGridControllerNode: ASDisplayNode {
|
||||
})
|
||||
self.controllerInteraction = interaction
|
||||
|
||||
let transition = combineLatest(self.wallpapersPromise.get(), deletedWallpaperSlugsPromise.get(), context.sharedContext.presentationData)
|
||||
|> map { wallpapers, deletedWallpaperSlugs, presentationData -> (ThemeGridEntryTransition, Bool) in
|
||||
let transition = combineLatest(self.wallpapersPromise.get(), deletedWallpaperIdsPromise.get(), context.sharedContext.presentationData)
|
||||
|> map { wallpapers, deletedWallpaperIds, presentationData -> (ThemeGridEntryTransition, Bool) in
|
||||
var entries: [ThemeGridControllerEntry] = []
|
||||
var index = 1
|
||||
|
||||
@ -399,7 +399,7 @@ final class ThemeGridControllerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
let selected = presentationData.chatWallpaper.isBasicallyEqual(to: wallpaper)
|
||||
@ -416,6 +416,9 @@ final class ThemeGridControllerNode: ASDisplayNode {
|
||||
}
|
||||
if !selected && !isDefault {
|
||||
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 }) {
|
||||
entries.append(entry)
|
||||
index += 1
|
||||
|
||||
@ -623,12 +623,12 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
let title = themeDisplayName(strings: item.strings, reference: theme)
|
||||
var accentColor = item.themeSpecificAccentColors[theme.generalThemeReference.index]
|
||||
if let customThemeIndex = accentColor?.themeIndex {
|
||||
/*if let customThemeIndex = accentColor?.themeIndex {
|
||||
if let customTheme = themes[customThemeIndex] {
|
||||
theme = customTheme
|
||||
}
|
||||
accentColor = nil
|
||||
}
|
||||
}*/
|
||||
|
||||
var themeWallpaper: TelegramWallpaper?
|
||||
if case let .cloud(theme) = theme {
|
||||
|
||||
@ -308,6 +308,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
} else {
|
||||
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 {
|
||||
self.nativeNode.isHidden = true
|
||||
self.patternButtonNode.isSelected = false
|
||||
|
||||
@ -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)
|
||||
initialWidth = initialImageWidth + horizontalInsets.left + horizontalInsets.right
|
||||
refineContentImageLayout = refineLayout
|
||||
if case let .file(_, _, _, isTheme, _) = wallpaper.content, isTheme {
|
||||
if case let .file(_, _, _, _, isTheme, _) = wallpaper.content, isTheme {
|
||||
skipStandardStatus = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))
|
||||
} else if let wallpaper = media as? WallpaperPreviewMedia {
|
||||
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 {
|
||||
let dimensionsVertical = dimensions.width < 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
|
||||
}
|
||||
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] = []
|
||||
if patternColors.isEmpty {
|
||||
colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5))
|
||||
var customPatternColor: UIColor? = nil
|
||||
if let intensity = intensity, intensity < 0 {
|
||||
if patternColors.isEmpty {
|
||||
colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5))
|
||||
} else {
|
||||
colors.append(contentsOf: patternColors.map(UIColor.init(rgb:)))
|
||||
}
|
||||
customPatternColor = UIColor(white: 0.0, alpha: 1.0 - CGFloat(abs(intensity)))
|
||||
} else {
|
||||
colors.append(contentsOf: patternColors.map(UIColor.init(rgb:)))
|
||||
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)
|
||||
patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation, customPatternColor: customPatternColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,7 +725,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
} else if let wallpaper = media as? WallpaperPreviewMedia {
|
||||
updateImageSignal = { synchronousLoad, _ in
|
||||
switch wallpaper.content {
|
||||
case let .file(file, _, _, isTheme, _):
|
||||
case let .file(file, _, _, _, isTheme, _):
|
||||
if isTheme {
|
||||
return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file)))
|
||||
} 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
|
||||
if let strongSelf = self {
|
||||
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 {
|
||||
switch wallpaper.content {
|
||||
case let .file(file, _, _, _, _):
|
||||
case let .file(file, _, _, _, _, _):
|
||||
updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file)
|
||||
|> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in
|
||||
return (resourceStatus, nil)
|
||||
|
||||
@ -173,11 +173,13 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
} else if webpage.type == "telegram_background" {
|
||||
var colors: [UInt32] = []
|
||||
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
|
||||
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])
|
||||
if let fileSize = file.size {
|
||||
badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData))
|
||||
@ -251,7 +253,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
file = contentFile
|
||||
}
|
||||
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())
|
||||
} else if let settings = settings {
|
||||
let media = WallpaperPreviewMedia(content: .themeSettings(settings))
|
||||
|
||||
@ -5,7 +5,7 @@ import TelegramCore
|
||||
import SyncCore
|
||||
|
||||
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 gradient([UInt32], Int32?)
|
||||
case themeSettings(TelegramThemeSettings)
|
||||
|
||||
@ -428,7 +428,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
let patternColor: UIColor
|
||||
if self.invertPattern {
|
||||
patternColor = .clear
|
||||
patternBackgroundColor = .black
|
||||
patternBackgroundColor = .clear
|
||||
} else {
|
||||
patternColor = .black
|
||||
patternBackgroundColor = .clear
|
||||
|
||||
@ -450,7 +450,7 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
|
||||
let context = DrawingContext(size: arguments.drawingSize, scale: fullSizeImage == nil ? 1.0 : scale, clear: !arguments.corners.isEmpty)
|
||||
context.withFlippedContext { c in
|
||||
c.setBlendMode(.copy)
|
||||
|
||||
|
||||
if colors.count == 1 {
|
||||
if customArguments.colors[0].alpha.isZero {
|
||||
c.clear(arguments.drawingRect)
|
||||
@ -486,53 +486,71 @@ 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.restoreGState()
|
||||
}
|
||||
|
||||
let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage
|
||||
if let image = image {
|
||||
var fittedSize = CGSize(width: image.width, height: image.height)
|
||||
if abs(fittedSize.width - arguments.boundingSize.width).isLessThanOrEqualTo(CGFloat(1.0)) {
|
||||
fittedSize.width = arguments.boundingSize.width
|
||||
}
|
||||
if abs(fittedSize.height - arguments.boundingSize.height).isLessThanOrEqualTo(CGFloat(1.0)) {
|
||||
fittedSize.height = arguments.boundingSize.height
|
||||
}
|
||||
fittedSize = fittedSize.aspectFilled(arguments.drawingRect.size)
|
||||
|
||||
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 {
|
||||
c.setBlendMode(.copy)
|
||||
} else {
|
||||
c.setBlendMode(.normal)
|
||||
}
|
||||
|
||||
if colors.count >= 3 && customArguments.customPatternColor == nil {
|
||||
c.setBlendMode(.softLight)
|
||||
c.setFillColor(UIColor(white: 0.0, alpha: 0.5).cgColor)
|
||||
c.fill(arguments.drawingRect)
|
||||
} else if colors.count == 1 {
|
||||
c.setFillColor(customArguments.customPatternColor?.cgColor ?? patternColor(for: color, intensity: intensity, prominent: prominent).cgColor)
|
||||
c.fill(arguments.drawingRect)
|
||||
} else {
|
||||
let gradientColors = colors.map { patternColor(for: $0, intensity: intensity, prominent: prominent).cgColor } as CFArray
|
||||
let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0)
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< colors.count {
|
||||
locations.append(delta * CGFloat(i))
|
||||
let overlayImage = generateImage(arguments.drawingRect.size, rotatedContext: { size, c in
|
||||
c.clear(CGRect(origin: CGPoint(), size: size))
|
||||
let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage
|
||||
if let image = image {
|
||||
var fittedSize = CGSize(width: image.width, height: image.height)
|
||||
if abs(fittedSize.width - arguments.boundingSize.width).isLessThanOrEqualTo(CGFloat(1.0)) {
|
||||
fittedSize.width = arguments.boundingSize.width
|
||||
}
|
||||
if abs(fittedSize.height - arguments.boundingSize.height).isLessThanOrEqualTo(CGFloat(1.0)) {
|
||||
fittedSize.height = arguments.boundingSize.height
|
||||
}
|
||||
fittedSize = fittedSize.aspectFilled(arguments.drawingRect.size)
|
||||
|
||||
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)
|
||||
|
||||
if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 {
|
||||
c.setBlendMode(.copy)
|
||||
c.setFillColor(UIColor.black.cgColor)
|
||||
c.fill(CGRect(origin: CGPoint(), size: size))
|
||||
} else {
|
||||
c.setBlendMode(.normal)
|
||||
}
|
||||
|
||||
c.interpolationQuality = customArguments.preview ? .low : .medium
|
||||
c.clip(to: fittedRect, mask: image)
|
||||
|
||||
if colors.count >= 3 && customArguments.customPatternColor == nil {
|
||||
c.setFillColor(UIColor(white: 0.0, alpha: 0.5).cgColor)
|
||||
c.fill(CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
|
||||
} else if colors.count == 1 {
|
||||
c.setFillColor(customArguments.customPatternColor?.cgColor ?? patternColor(for: color, intensity: intensity, prominent: prominent).cgColor)
|
||||
c.fill(CGRect(origin: CGPoint(), size: arguments.drawingRect.size))
|
||||
} else {
|
||||
let gradientColors = colors.map { patternColor(for: $0, intensity: intensity, prominent: prominent).cgColor } as CFArray
|
||||
let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0)
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
for i in 0 ..< colors.count {
|
||||
locations.append(delta * CGFloat(i))
|
||||
}
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
|
||||
c.translateBy(x: arguments.drawingSize.width / 2.0, y: arguments.drawingSize.height / 2.0)
|
||||
c.rotate(by: CGFloat(customArguments.rotation ?? 0) * CGFloat.pi / -180.0)
|
||||
c.translateBy(x: -arguments.drawingSize.width / 2.0, y: -arguments.drawingSize.height / 2.0)
|
||||
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: arguments.drawingSize.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
|
||||
}
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
|
||||
c.translateBy(x: arguments.drawingSize.width / 2.0, y: arguments.drawingSize.height / 2.0)
|
||||
c.rotate(by: CGFloat(customArguments.rotation ?? 0) * CGFloat.pi / -180.0)
|
||||
c.translateBy(x: -arguments.drawingSize.width / 2.0, y: -arguments.drawingSize.height / 2.0)
|
||||
|
||||
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)
|
||||
@ -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])
|
||||
}
|
||||
case let .file(file):
|
||||
c.setFillColor(theme.chatList.backgroundColor.cgColor)
|
||||
if let image = wallpaperImage, let cgImage = image.cgImage {
|
||||
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))
|
||||
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 {
|
||||
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.setFillColor(theme.chatList.backgroundColor.cgColor)
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1223,14 +1246,20 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
}
|
||||
rotation = settings.rotation
|
||||
case let .file(file):
|
||||
colors = file.settings.colors
|
||||
if !file.settings.colors.isEmpty {
|
||||
topBackgroundColor = UIColor(rgb: file.settings.colors[0])
|
||||
if file.settings.colors.count >= 2 {
|
||||
bottomBackgroundColor = UIColor(rgb: file.settings.colors[1])
|
||||
if file.isPattern, let intensity = file.settings.intensity, intensity < 0 {
|
||||
colors = [0x000000]
|
||||
topBackgroundColor = .black
|
||||
bottomBackgroundColor = .black
|
||||
} else {
|
||||
colors = file.settings.colors
|
||||
if !file.settings.colors.isEmpty {
|
||||
topBackgroundColor = UIColor(rgb: file.settings.colors[0])
|
||||
if file.settings.colors.count >= 2 {
|
||||
bottomBackgroundColor = UIColor(rgb: file.settings.colors[1])
|
||||
}
|
||||
}
|
||||
rotation = file.settings.rotation
|
||||
}
|
||||
rotation = file.settings.rotation
|
||||
default:
|
||||
colors = [0xd6e2ee]
|
||||
topBackgroundColor = UIColor(rgb: 0xd6e2ee)
|
||||
@ -1297,7 +1326,9 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
backgroundColor = (.black, nil, [])
|
||||
case let .file(file):
|
||||
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?
|
||||
if file.settings.colors.count >= 2 {
|
||||
bottomColor = UIColor(rgb: file.settings.colors[1])
|
||||
@ -1330,9 +1361,13 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
|
||||
if wallpaper.wallpaper.isPattern {
|
||||
if !file.settings.colors.isEmpty, let intensity = file.settings.intensity {
|
||||
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
|
||||
return .single((effectiveBackgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
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)
|
||||
|> mapToSignal { _ in
|
||||
return .single((effectiveBackgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user