diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index b0cdfedae7..7ae258e5f8 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -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)) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index 4e7b089bf9..454a270073 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -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 diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index b672dd99f1..8749863868 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -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 - } - } - } } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift index e5ff9d366b..63f7d215e3 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridControllerNode.swift @@ -246,8 +246,8 @@ final class ThemeGridControllerNode: ASDisplayNode { let wallpapersPromise = Promise<[Wallpaper]>() self.wallpapersPromise = wallpapersPromise - let deletedWallpaperSlugsValue = Atomic>(value: Set()) - let deletedWallpaperSlugsPromise = ValuePromise>(Set()) + let deletedWallpaperIdsValue = Atomic>(value: Set()) + let deletedWallpaperIdsPromise = ValuePromise>(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 diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index f4c991b813..db8b0f5436 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -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 { diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 47eddf6d74..bdd4bd03ff 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index b21acfdb19..e5ca7a3c71 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -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 } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 51b91c9b70..c99f5af2ef 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index 089ca0d5f4..e40eecd6e8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -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)) diff --git a/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift b/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift index 6e42d83cbe..7f32ba3261 100644 --- a/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift +++ b/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift @@ -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) diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index fccdbe94e0..bd2abfa388 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -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 diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 05e56f29e2..028ab8b72d 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -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()