From 724a303c9c19265d1fe8d95b8506aae476aa5ce1 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 13 Apr 2023 22:29:58 +0400 Subject: [PATCH 1/3] Chat wallpaper fixes --- .../Themes/CustomWallpaperPicker.swift | 6 +--- .../Sources/Themes/ThemeGridController.swift | 22 ++++++++++---- .../Sources/Themes/WallpaperGalleryItem.swift | 14 +++++++++ .../PendingMessageUploadedContent.swift | 4 +-- .../PendingPeerMediaUploadManager.swift | 29 +++++++++++++++++-- .../TelegramEngine/Themes/ChatThemes.swift | 24 +++++++++++---- .../Themes/TelegramEngineThemes.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 15 +++++++++- ...hatMessageWallpaperBubbleContentNode.swift | 2 +- 9 files changed, 93 insertions(+), 25 deletions(-) diff --git a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift index d938dd0358..47ef6d0b8f 100644 --- a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift +++ b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift @@ -284,11 +284,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa finalCropRect = CGRect(x: (image.size.width - fittedSize.width) / 2.0, y: (image.size.height - fittedSize.height) / 2.0, width: fittedSize.width, height: fittedSize.height) } croppedImage = TGPhotoEditorCrop(image, nil, .up, 0.0, finalCropRect, false, CGSize(width: 1440.0, height: 2960.0), image.size, true) - - if mode.contains(.blur) { - croppedImage = blurredImage(croppedImage, radius: 30.0)! - } - + let thumbnailDimensions = finalCropRect.size.fitted(CGSize(width: 320.0, height: 320.0)) let thumbnailImage = generateScaledImage(image: croppedImage, size: thumbnailDimensions, scale: 1.0) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift index 048a0af79e..8bf500a949 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeGridController.swift @@ -142,18 +142,28 @@ public final class ThemeGridController: ViewController { } }, presentGallery: { [weak self] in if let strongSelf = self { + let dismissControllers = { [weak self] in + if let self, let navigationController = self.navigationController as? NavigationController { + let controllers = navigationController.viewControllers.filter({ controller in + if controller is WallpaperGalleryController || controller is MediaPickerScreen { + return false + } + return true + }) + navigationController.setViewControllers(controllers, animated: true) + } + } + let controller = MediaPickerScreen(context: strongSelf.context, peer: nil, threadTitle: nil, chatLocation: nil, bannedSendPhotos: nil, bannedSendVideos: nil, subject: .assets(nil, .wallpaper)) controller.customSelection = { [weak self] asset in guard let strongSelf = self else { return } let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset)) - controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness in - if let strongSelf = self, let controller = controller { - uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak controller] in - if let controller = controller { - controller.dismiss(forceAway: true) - } + controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in + if let strongSelf = self { + uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { + dismissControllers() }) } } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index edd7fec83b..51ccf0e2d1 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -668,6 +668,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode { self.patternButtonNode.isSelected = false self.playButtonNode.setIcon(self.playButtonRotateImage) } + + if let settings = wallpaper.settings { + if settings.blur { + self.blurButtonNode.setSelected(true, animated: false) + self.setBlurEnabled(true, animated: false) + } + if settings.motion { + self.motionButtonNode.setSelected(true, animated: false) + self.setMotionEnabled(true, animated: false) + } + if case let .file(file) = wallpaper, !file.isPattern, let intensity = file.settings.intensity { + self.sliderNode.value = (1.0 - CGFloat(intensity) / 100.0) + } + } case .asset: self.nativeNode._internalUpdateIsSettingUpWallpaper() self.nativeNode.isHidden = true diff --git a/submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift b/submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift index 29d6a27614..595b020200 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/PendingMessageUploadedContent.swift @@ -212,8 +212,8 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods: let inputPoll = Api.InputMedia.inputMediaPoll(flags: pollMediaFlags, poll: Api.Poll.poll(id: 0, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities) return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputPoll, text), reuploadInfo: nil, cacheReferenceKey: nil))) } else if let media = media as? TelegramMediaDice { - let input = Api.InputMedia.inputMediaDice(emoticon: media.emoji) - return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(input, text), reuploadInfo: nil, cacheReferenceKey: nil))) + let inputDice = Api.InputMedia.inputMediaDice(emoticon: media.emoji) + return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputDice, text), reuploadInfo: nil, cacheReferenceKey: nil))) } else { return nil } diff --git a/submodules/TelegramCore/Sources/PendingMessages/PendingPeerMediaUploadManager.swift b/submodules/TelegramCore/Sources/PendingMessages/PendingPeerMediaUploadManager.swift index 2e6468064e..a1938e5310 100644 --- a/submodules/TelegramCore/Sources/PendingMessages/PendingPeerMediaUploadManager.swift +++ b/submodules/TelegramCore/Sources/PendingMessages/PendingPeerMediaUploadManager.swift @@ -11,6 +11,7 @@ public final class PeerMediaUploadingItem: Equatable { public enum Error { case generic + case flood } public enum Content: Equatable { @@ -69,7 +70,14 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A } } return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: result, applyUpdates: false) - |> castError(PeerMediaUploadingItem.Error.self) + |> mapError { error -> PeerMediaUploadingItem.Error in + switch error { + case .generic: + return .generic + case .flood: + return .flood + } + } |> map { updates -> PeerMediaUploadingItem.ProgressValue in return .done(updates) } @@ -78,7 +86,14 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A } } else { return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: wallpaper, applyUpdates: false) - |> castError(PeerMediaUploadingItem.Error.self) + |> mapError { error -> PeerMediaUploadingItem.Error in + switch error { + case .generic: + return .generic + case .flood: + return .flood + } + } |> map { updates -> PeerMediaUploadingItem.ProgressValue in return .done(updates) } @@ -265,7 +280,15 @@ private final class PendingPeerMediaUploadManagerImpl { } if let context = strongSelf.contexts[peerId], context === initialContext { strongSelf.contexts.removeValue(forKey: peerId) - context.disposable.dispose() + + if let messageId = context.value.messageId { + context.disposable.set(strongSelf.postbox.transaction({ transaction in + transaction.deleteMessages([messageId], forEachMedia: nil) + }).start()) + } else { + context.disposable.dispose() + } + strongSelf.updateValues() } })) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Themes/ChatThemes.swift b/submodules/TelegramCore/Sources/TelegramEngine/Themes/ChatThemes.swift index 8e97221e71..437097df2d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Themes/ChatThemes.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Themes/ChatThemes.swift @@ -118,13 +118,19 @@ func managedChatThemesUpdates(accountManager: AccountManager then(.complete() |> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart } -func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, applyUpdates: Bool = true) -> Signal { +public enum SetChatWallpaperError { + case generic + case flood +} + +func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, applyUpdates: Bool = true) -> Signal { return postbox.loadedPeerWithId(peerId) + |> castError(SetChatWallpaperError.self) |> mapToSignal { peer in guard let inputPeer = apiInputPeer(peer) else { return .complete() } - return postbox.transaction { transaction -> Signal in + return postbox.transaction { transaction -> Signal in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in if let current = current as? CachedUserData { return current.withUpdatedWallpaper(wallpaper) @@ -143,16 +149,22 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager inputSettings = inputWallpaperAndInputSettings.1 } return network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: inputWallpaper, settings: inputSettings, id: nil), automaticFloodWait: false) - |> `catch` { error in - return .complete() + |> mapError { error -> SetChatWallpaperError in + if error.errorDescription.hasPrefix("FLOOD_WAIT") { + return .flood + } else { + return .generic + } } - |> mapToSignal { updates -> Signal in + |> mapToSignal { updates -> Signal in if applyUpdates { stateManager.addUpdates(updates) } return .single(updates) } - } |> switchToLatest + } + |> castError(SetChatWallpaperError.self) + |> switchToLatest } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift b/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift index 623efabd58..e189e3cbaa 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Themes/TelegramEngineThemes.swift @@ -17,7 +17,7 @@ public extension TelegramEngine { return _internal_setChatTheme(account: self.account, peerId: peerId, emoticon: emoticon) } - public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal { + public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal { return _internal_setChatWallpaper(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, wallpaper: wallpaper) |> ignoreValues } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index c399cfad06..3733d0799d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -857,7 +857,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return true } strongSelf.chatDisplayNode.dismissInput() - let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, nil, [], nil, nil, nil), mode: .peer(EnginePeer(peer), true)) + var options = WallpaperPresentationOptions() + var intensity: Int32? + if let settings = wallpaper.settings { + if settings.blur { + options.insert(.blur) + } + if settings.motion { + options.insert(.motion) + } + if case let .file(file) = wallpaper, !file.isPattern { + intensity = settings.intensity + } + } + let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, options, [], intensity, nil, nil), mode: .peer(EnginePeer(peer), true)) wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _, brightness in var settings: WallpaperSettings? if case let .wallpaper(wallpaper, _) = entry { diff --git a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift index 853caa832f..6624a49de8 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -328,7 +328,7 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode { if let dimensions = file.dimensions?.cgSize { imageSize = dimensions.aspectFilled(boundingSize) } - updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: FileMediaReference.message(message: MessageReference(item.message), media: file), representations: representations, alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true) + updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: FileMediaReference.message(message: MessageReference(item.message), media: file), representations: representations, alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true, blurred: wallpaper?.settings?.blur == true) } case let .image(representations): if let dimensions = representations.last?.dimensions.cgSize { From 8d9068d87d8adf90ee732904376facdc08b6fab9 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 13 Apr 2023 23:02:05 +0400 Subject: [PATCH 2/3] Various fixes --- .../Sources/PeerInfo/PeerInfoHeaderNode.swift | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 1edb30a8f1..6205c1f7fd 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -2311,7 +2311,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { var emojiStatusPackDisposable = MetaDisposable() var emojiStatusFileAndPackTitle = Promise<(TelegramMediaFile, LoadedStickerPack)?>() - private var validWidth: CGFloat? + private var validLayout: (width: CGFloat, deviceMetrics: DeviceMetrics)? init(context: AccountContext, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) { self.context = context @@ -2577,7 +2577,9 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.peer = peer self.threadData = threadData self.avatarListNode.listContainerNode.peer = peer - self.validWidth = width + + let isFirstTime = self.validLayout == nil + self.validLayout = (width, deviceMetrics) let previousPanelStatusData = self.currentPanelStatusData self.currentPanelStatusData = panelStatusData.0 @@ -3628,6 +3630,10 @@ final class PeerInfoHeaderNode: ASDisplayNode { transition.updateFrame(node: self.separatorNode, frame: separatorFrame) } + if isFirstTime { + self.updateAvatarMask(transition: .immediate) + } + return resolvedHeight } @@ -3690,17 +3696,22 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.avatarListNode.animateAvatarCollapse(transition: transition) } - if let width = self.validWidth { - let maskScale: CGFloat = isAvatarExpanded ? width / 100.0 : 1.0 - transition.updateTransformScale(layer: self.avatarListNode.maskNode.layer, scale: maskScale) - transition.updateTransformScale(layer: self.avatarListNode.bottomCoverNode.layer, scale: maskScale) - transition.updateTransformScale(layer: self.avatarListNode.topCoverNode.layer, scale: maskScale) - - let maskAnchorPoint = CGPoint(x: 0.5, y: isAvatarExpanded ? 0.37 : 0.5) - transition.updateAnchorPoint(layer: self.avatarListNode.maskNode.layer, anchorPoint: maskAnchorPoint) - } + self.updateAvatarMask(transition: transition) } } + + private func updateAvatarMask(transition: ContainedViewLayoutTransition) { + guard let (width, deviceMetrics) = self.validLayout, deviceMetrics.hasDynamicIsland else { + return + } + let maskScale: CGFloat = isAvatarExpanded ? width / 100.0 : 1.0 + transition.updateTransformScale(layer: self.avatarListNode.maskNode.layer, scale: maskScale) + transition.updateTransformScale(layer: self.avatarListNode.bottomCoverNode.layer, scale: maskScale) + transition.updateTransformScale(layer: self.avatarListNode.topCoverNode.layer, scale: maskScale) + + let maskAnchorPoint = CGPoint(x: 0.5, y: isAvatarExpanded ? 0.37 : 0.5) + transition.updateAnchorPoint(layer: self.avatarListNode.maskNode.layer, anchorPoint: maskAnchorPoint) + } } private class DynamicIslandMaskNode: ASDisplayNode { From c339bc8701bdc21a24598886445bf5bbf54165fe Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 14 Apr 2023 00:36:03 +0400 Subject: [PATCH 3/3] Chat wallpaper fixes --- .../TGPhotoEditorController.h | 2 +- .../TGPhotoEditorTabController.h | 2 +- .../LegacyComponents/TGPhotoVideoEditor.h | 2 +- .../Sources/TGCameraController.m | 2 +- .../Sources/TGMediaPickerGalleryModel.m | 2 +- .../Sources/TGPhotoCropController.m | 2 +- .../Sources/TGPhotoEditorTabController.m | 2 +- .../Sources/TGPhotoVideoEditor.m | 130 +----------------- .../Sources/LegacyAttachmentMenu.swift | 6 +- .../Themes/CustomWallpaperPicker.swift | 18 ++- .../Themes/WallpaperGalleryController.swift | 12 +- .../Sources/Themes/WallpaperGalleryItem.swift | 64 +++++---- ...hatMessageWallpaperBubbleContentNode.swift | 2 +- 13 files changed, 66 insertions(+), 180 deletions(-) diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorController.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorController.h index 7e480079f4..b2406758b0 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorController.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorController.h @@ -34,7 +34,7 @@ typedef enum { @property (nonatomic, copy) UIView *(^beginTransitionIn)(CGRect *referenceFrame, UIView **parentView); @property (nonatomic, copy) void (^finishedTransitionIn)(void); -@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView); +@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView, bool saving); @property (nonatomic, copy) void (^finishedTransitionOut)(bool saved); @property (nonatomic, copy) void (^onDismiss)(); diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorTabController.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorTabController.h index bd87dbf0e8..c738996f98 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorTabController.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoEditorTabController.h @@ -30,7 +30,7 @@ @property (nonatomic, copy) UIView *(^beginTransitionIn)(CGRect *referenceFrame, UIView **parentView, bool *noTransitionView); @property (nonatomic, copy) void(^finishedTransitionIn)(void); -@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView); +@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView, bool saving); @property (nonatomic, copy) void(^finishedTransitionOut)(void); @property (nonatomic, copy) void (^valuesChanged)(void); diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoVideoEditor.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoVideoEditor.h index 6e5c165ac0..8c113270c6 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoVideoEditor.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoVideoEditor.h @@ -6,6 +6,6 @@ + (void)presentWithContext:(id)context controller:(TGViewController *)controller caption:(NSAttributedString *)caption withItem:(id)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString *)recipientName stickersContext:(id)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView *)mainSnapshot snapshots:(NSArray *)snapshots immediate:(bool)immediate appeared:(void (^)(void))appeared completion:(void (^)(id, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed; -+ (void)presentEditorWithContext:(id)context controller:(TGViewController *)controller withItem:(id)item cropRect:(CGRect)cropRect adjustments:(id)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)())beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut; ++ (void)presentEditorWithContext:(id)context controller:(TGViewController *)controller withItem:(id)item cropRect:(CGRect)cropRect adjustments:(id)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut; @end diff --git a/submodules/LegacyComponents/Sources/TGCameraController.m b/submodules/LegacyComponents/Sources/TGCameraController.m index 4dc4705dac..182b89cfd7 100644 --- a/submodules/LegacyComponents/Sources/TGCameraController.m +++ b/submodules/LegacyComponents/Sources/TGCameraController.m @@ -2030,7 +2030,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus return imageView; }; - controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView) + controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView, __unused bool saving) { __strong TGCameraController *strongSelf = weakSelf; if (strongSelf == nil) diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m index c786c20090..6dd0f99aa7 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m @@ -516,7 +516,7 @@ [zoomableItemView reset]; }; - controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView) + controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView, __unused bool saving) { __strong TGMediaPickerGalleryModel *strongSelf = weakSelf; if (strongSelf == nil) diff --git a/submodules/LegacyComponents/Sources/TGPhotoCropController.m b/submodules/LegacyComponents/Sources/TGPhotoCropController.m index 90760c8b22..d8786151bb 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoCropController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoCropController.m @@ -389,7 +389,7 @@ NSString * const TGPhotoCropOriginalAspectRatio = @"original"; UIView *parentView = nil; if (self.beginTransitionOut != nil) - referenceView = self.beginTransitionOut(&referenceFrame, &parentView); + referenceView = self.beginTransitionOut(&referenceFrame, &parentView, saving); UIView *toTransitionView = nil; CGRect targetFrame = CGRectZero; diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m index 497c2548dc..a54c7c0792 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m @@ -274,7 +274,7 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f; } if (self.beginTransitionOut != nil) - referenceView = self.beginTransitionOut(&referenceFrame, &parentView); + referenceView = self.beginTransitionOut(&referenceFrame, &parentView, saving); if (parentView == nil) parentView = referenceView.superview.superview; diff --git a/submodules/LegacyComponents/Sources/TGPhotoVideoEditor.m b/submodules/LegacyComponents/Sources/TGPhotoVideoEditor.m index 537beec6c3..ae56a52631 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoVideoEditor.m +++ b/submodules/LegacyComponents/Sources/TGPhotoVideoEditor.m @@ -283,7 +283,7 @@ } } -+ (void)presentEditorWithContext:(id)context controller:(TGViewController *)controller withItem:(id)item cropRect:(CGRect)cropRect adjustments:(id)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)())beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut; ++ (void)presentEditorWithContext:(id)context controller:(TGViewController *)controller withItem:(id)item cropRect:(CGRect)cropRect adjustments:(id)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut; { id windowManager = [context makeOverlayWindowManager]; @@ -304,18 +304,16 @@ editorController.dontHideStatusBar = true; editorController.ignoreCropForResult = true; - CGRect fromRect = referenceView.frame;// [referenceView convertRect:referenceView.bounds toView:nil]; + CGRect fromRect = referenceView.frame; editorController.beginTransitionIn = ^UIView *(CGRect *referenceFrame, UIView **parentView) { *referenceFrame = fromRect; *parentView = referenceView.superview; - //UIImageView *imageView = [[UIImageView alloc] initWithFrame:fromRect]; - //imageView.image = image; return referenceView; }; - editorController.beginTransitionOut = ^UIView *(CGRect *referenceFrame, UIView **parentView) + editorController.beginTransitionOut = ^UIView *(CGRect *referenceFrame, UIView **parentView, bool saving) { CGRect startFrame = CGRectZero; if (referenceFrame != NULL) @@ -326,7 +324,7 @@ } if (beginTransitionOut) { - beginTransitionOut(); + beginTransitionOut(saving); } return referenceView; @@ -382,126 +380,6 @@ TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:editorController]; controllerWindow.hidden = false; controller.view.clipsToBounds = true; - -// TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:windowContext]; -// galleryController.adjustsStatusBarVisibility = true; -// galleryController.animateTransition = false; -// galleryController.finishedTransitionIn = ^(id item, TGModernGalleryItemView *itemView) { -// appeared(); -// }; -// //galleryController.hasFadeOutTransition = true; -// -// id galleryItem = nil; -// if (item.isVideo) -// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:item]; -// else -// galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:item]; -// galleryItem.editingContext = editingContext; -// galleryItem.stickersContext = stickersContext; -// -// TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName]; -// model.controller = galleryController; -// model.stickersContext = stickersContext; -// -// model.willFinishEditingItem = ^(id editableItem, id adjustments, id representation, bool hasChanges) -// { -// if (hasChanges) -// { -// [editingContext setAdjustments:adjustments forItem:editableItem]; -// [editingContext setTemporaryRep:representation forItem:editableItem]; -// } -// }; -// -// model.didFinishEditingItem = ^(id editableItem, __unused id adjustments, UIImage *resultImage, UIImage *thumbnailImage) -// { -// [editingContext setImage:resultImage thumbnailImage:thumbnailImage forItem:editableItem synchronous:false]; -// }; -// -// model.saveItemCaption = ^(id editableItem, NSAttributedString *caption) -// { -// [editingContext setCaption:caption forItem:editableItem]; -// }; -// -// model.didFinishRenderingFullSizeImage = ^(id editableItem, UIImage *resultImage) -// { -// [editingContext setFullSizeImage:resultImage forItem:editableItem]; -// }; -// -// model.interfaceView.hasSwipeGesture = false; -// galleryController.model = model; -// -// __weak TGModernGalleryController *weakGalleryController = galleryController; -// -// [model.interfaceView updateSelectionInterface:1 counterVisible:false animated:false]; -// model.interfaceView.thumbnailSignalForItem = ^SSignal *(id item) -// { -// return nil; -// }; -// model.interfaceView.donePressed = ^(TGMediaPickerGalleryItem *item) -// { -// __strong TGModernGalleryController *strongController = weakGalleryController; -// if (strongController == nil) -// return; -// -// if ([item isKindOfClass:[TGMediaPickerGalleryVideoItem class]]) -// { -// TGMediaPickerGalleryVideoItemView *itemView = (TGMediaPickerGalleryVideoItemView *)[strongController itemViewForItem:item]; -// [itemView stop]; -// [itemView setPlayButtonHidden:true animated:true]; -// } -// -// if (completion != nil) -// completion(item.asset, editingContext); -// -// [strongController dismissWhenReadyAnimated:true]; -// }; -// -// galleryController.beginTransitionIn = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView) -// { -// return nil; -// }; -// -// galleryController.beginTransitionOut = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView) -// { -// return nil; -// }; -// -// galleryController.completedTransitionOut = ^ -// { -// TGModernGalleryController *strongGalleryController = weakGalleryController; -// if (strongGalleryController != nil && strongGalleryController.overlayWindow == nil) -// { -// TGNavigationController *navigationController = (TGNavigationController *)strongGalleryController.navigationController; -// TGOverlayControllerWindow *window = (TGOverlayControllerWindow *)navigationController.view.window; -// if ([window isKindOfClass:[TGOverlayControllerWindow class]]) -// [window dismiss]; -// } -// if (dismissed) { -// dismissed(); -// } -// }; -// -// if (paint || adjustments) { -// [model.interfaceView immediateEditorTransitionIn]; -// } -// -// for (UIView *view in snapshots) { -// [galleryController.view addSubview:view]; -// } -// -// TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:galleryController]; -// controllerWindow.hidden = false; -// galleryController.view.clipsToBounds = true; -// -// if (paint) { -// TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{ -// [model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorPaintTab snapshots:snapshots fromRect:fromRect]; -// }); -// } else if (adjustments) { -// TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{ -// [model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorToolsTab snapshots:snapshots fromRect:fromRect]; -// }); -// } } diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift index 9c5a507cd7..c13b957f82 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift @@ -64,7 +64,7 @@ public enum LegacyMediaEditorMode { } -public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditableItem, cropRect: CGRect, adjustments: TGMediaEditAdjustments?, referenceView: UIView, beginTransitionOut: (() -> Void)?, finishTransitionOut: (() -> Void)?, completion: @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, fullSizeCompletion: @escaping (UIImage?) -> Void, present: @escaping (ViewController, Any?) -> Void) { +public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditableItem, cropRect: CGRect, adjustments: TGMediaEditAdjustments?, referenceView: UIView, beginTransitionOut: ((Bool) -> Void)?, finishTransitionOut: (() -> Void)?, completion: @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, fullSizeCompletion: @escaping (UIImage?) -> Void, present: @escaping (ViewController, Any?) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: nil) legacyController.blocksBackgroundWhenInOverlay = true @@ -90,8 +90,8 @@ public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditable Queue.mainQueue().async { fullSizeCompletion(image) } - }, beginTransitionOut: { - beginTransitionOut?() + }, beginTransitionOut: { saving in + beginTransitionOut?(saving) }, finishTransitionOut: { [weak legacyController] in legacyController?.dismiss() finishTransitionOut?() diff --git a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift index 47ef6d0b8f..80d446da8d 100644 --- a/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift +++ b/submodules/SettingsUI/Sources/Themes/CustomWallpaperPicker.swift @@ -297,19 +297,23 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) + let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start() + var intensity: Int32? if let brightness { intensity = max(0, min(100, Int32(brightness * 100.0))) } - let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity) - let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings) - - Queue.mainQueue().async { - completion() + Queue.mainQueue().after(0.05) { + let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity) + let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings) + + context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper)) + + Queue.mainQueue().async { + completion() + } } - - context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper)) } return croppedImage }).start() diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift index ed244c8c5e..2a179523d5 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift @@ -169,10 +169,10 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl class WallpaperGalleryInteraction { let editMedia: (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void let beginTransitionToEditor: () -> Void - let beginTransitionFromEditor: () -> Void + let beginTransitionFromEditor: (Bool) -> Void let finishTransitionFromEditor: () -> Void - init(editMedia: @escaping (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void, beginTransitionToEditor: @escaping () -> Void, beginTransitionFromEditor: @escaping () -> Void, finishTransitionFromEditor: @escaping () -> Void) { + init(editMedia: @escaping (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void, beginTransitionToEditor: @escaping () -> Void, beginTransitionFromEditor: @escaping (Bool) -> Void, finishTransitionFromEditor: @escaping () -> Void) { self.editMedia = editMedia self.beginTransitionToEditor = beginTransitionToEditor self.beginTransitionFromEditor = beginTransitionFromEditor @@ -253,8 +253,8 @@ public class WallpaperGalleryController: ViewController { return } let item = LegacyWallpaperItem(asset: asset, screenImage: image, dimensions: CGSize(width: asset.pixelWidth, height: asset.pixelHeight)) - legacyWallpaperEditor(context: context, item: item, cropRect: cropRect, adjustments: adjustments, referenceView: referenceView, beginTransitionOut: { [weak self] in - self?.interaction?.beginTransitionFromEditor() + legacyWallpaperEditor(context: context, item: item, cropRect: cropRect, adjustments: adjustments, referenceView: referenceView, beginTransitionOut: { [weak self] saving in + self?.interaction?.beginTransitionFromEditor(saving) }, finishTransitionOut: { [weak self] in self?.interaction?.finishTransitionFromEditor() }, completion: { image, adjustments in @@ -274,7 +274,7 @@ public class WallpaperGalleryController: ViewController { if let toolbarNode = self.toolbarNode { transition.updateAlpha(node: toolbarNode, alpha: 0.0) } - }, beginTransitionFromEditor: { [weak self] in + }, beginTransitionFromEditor: { [weak self] saving in guard let self else { return } @@ -283,7 +283,7 @@ public class WallpaperGalleryController: ViewController { transition.updateAlpha(node: toolbarNode, alpha: 1.0) } if let centralItemNode = self.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode { - centralItemNode.beginTransitionFromEditor() + centralItemNode.beginTransitionFromEditor(saving: saving) } }, finishTransitionFromEditor: { [weak self] in guard let self else { diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 51ccf0e2d1..f30c149eeb 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -506,10 +506,13 @@ final class WallpaperGalleryItemNode: GalleryItemNode { return context })) - self.temporaryImageNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.2, removeOnCompletion: false, completion: { [weak self] _ in - self?.temporaryImageNode.image = nil - self?.temporaryImageNode.layer.removeAllAnimations() - }) + Queue.mainQueue().after(0.1) { + self.brightnessNode.isHidden = false + self.temporaryImageNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.2, removeOnCompletion: false, completion: { [weak self] _ in + self?.temporaryImageNode.image = nil + self?.temporaryImageNode.layer.removeAllAnimations() + }) + } }, { [weak self] image in guard let self else { return @@ -532,13 +535,38 @@ final class WallpaperGalleryItemNode: GalleryItemNode { public private(set) var editedFullSizeImage: UIImage? private var currentAdjustments: TGMediaEditAdjustments? + func beginTransitionToEditor() { + self.cropNode.isHidden = true + + let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut) + transition.updateAlpha(node: self.messagesContainerNode, alpha: 0.0) + transition.updateAlpha(node: self.buttonsContainerNode, alpha: 0.0) + transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 0.0) + + self.interaction?.beginTransitionToEditor() + } + + func beginTransitionFromEditor(saving: Bool) { + if saving { + self.brightnessNode.isHidden = true + } + let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut) + transition.updateAlpha(node: self.messagesContainerNode, alpha: 1.0) + transition.updateAlpha(node: self.buttonsContainerNode, alpha: 1.0) + transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 1.0) + } + + func finishTransitionFromEditor() { + self.cropNode.isHidden = false + self.temporaryImageNode.alpha = 1.0 + } + private func animateIntensityChange(delay: Double) { let targetValue: CGFloat = self.sliderNode.value self.sliderNode.internalUpdateLayout(size: self.sliderNode.frame.size, value: 1.0) self.sliderNode.ignoreUpdates = true Queue.mainQueue().after(delay, { self.brightnessNode.backgroundColor = UIColor(rgb: 0x000000) - self.brightnessNode.layer.compositingFilter = nil self.sliderNode.ignoreUpdates = false let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .easeInOut) @@ -551,37 +579,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let value = self.isDarkAppearance ? self.sliderNode.value : 1.0 if value < 1.0 { self.brightnessNode.backgroundColor = UIColor(rgb: 0x000000) - self.brightnessNode.layer.compositingFilter = nil transition.updateAlpha(node: self.brightnessNode, alpha: 1.0 - value) } else { - self.brightnessNode.layer.compositingFilter = nil transition.updateAlpha(node: self.brightnessNode, alpha: 0.0) } } - func beginTransitionToEditor() { - self.cropNode.isHidden = true - - let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut) - transition.updateAlpha(node: self.messagesContainerNode, alpha: 0.0) - transition.updateAlpha(node: self.buttonsContainerNode, alpha: 0.0) - transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 0.0) - - self.interaction?.beginTransitionToEditor() - } - - func beginTransitionFromEditor() { - let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut) - transition.updateAlpha(node: self.messagesContainerNode, alpha: 1.0) - transition.updateAlpha(node: self.buttonsContainerNode, alpha: 1.0) - transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 1.0) - } - - func finishTransitionFromEditor() { - self.cropNode.isHidden = false - self.temporaryImageNode.alpha = 1.0 - } - @objc private func cancelPressed() { self.dismiss() } @@ -680,6 +683,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } if case let .file(file) = wallpaper, !file.isPattern, let intensity = file.settings.intensity { self.sliderNode.value = (1.0 - CGFloat(intensity) / 100.0) + self.updateIntensity(transition: .immediate) } } case .asset: diff --git a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift index 6624a49de8..b058041762 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -334,7 +334,7 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode { if let dimensions = representations.last?.dimensions.cgSize { imageSize = dimensions.aspectFilled(boundingSize) } - updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: nil, representations: representations.map({ ImageRepresentationWithReference(representation: $0, reference: .standalone(resource: $0.resource)) }), alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true) + updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: nil, representations: representations.map({ ImageRepresentationWithReference(representation: $0, reference: .standalone(resource: $0.resource)) }), alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true, blurred: wallpaper?.settings?.blur == true) case let .color(color): updateImageSignal = solidColorImage(color) case let .gradient(colors, rotation):