mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Wallpaper improvements
This commit is contained in:
parent
f158b8fa79
commit
3bf5ad9f8a
@ -9123,6 +9123,9 @@ Sorry for the inconvenience.";
|
||||
"Notification.YouChangedWallpaper" = "You set a new background for this chat";
|
||||
"Notification.Wallpaper.View" = "View Background";
|
||||
|
||||
"Notification.ChangedToSameWallpaper" = "%1$@ set the same background for this chat";
|
||||
"Notification.YouChangedToSameWallpaper" = "You set the same background for this chat";
|
||||
|
||||
"Channel.AdminLog.JoinedViaFolderInviteLink" = "%1$@ joined via invite link %2$@ (community)";
|
||||
|
||||
"Conversation.OpenChatFolder" = "VIEW CHAT LIST";
|
||||
|
@ -308,7 +308,7 @@ func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGall
|
||||
completion()
|
||||
}
|
||||
|
||||
let _ = uploadWallpaper(account: context.account, resource: resource, settings: WallpaperSettings(blur: false, motion: mode.contains(.motion), colors: [], intensity: nil)).start(next: { status in
|
||||
let _ = uploadWallpaper(account: context.account, resource: resource, settings: WallpaperSettings(blur: false, motion: mode.contains(.motion), colors: [], intensity: nil), forChat: true).start(next: { status in
|
||||
if case let .complete(wallpaper) = status {
|
||||
if case let .file(file) = wallpaper {
|
||||
context.account.postbox.mediaBox.copyResourceData(from: resource.id, to: file.file.resource.id, synchronous: true)
|
||||
|
@ -95,18 +95,14 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
private let blurredNode: BlurredImageNode
|
||||
let cropNode: WallpaperCropNode
|
||||
|
||||
private let cancelButtonBackgroundNode: NavigationBackgroundNode
|
||||
private var cancelButtonNode: HighlightableButtonNode
|
||||
|
||||
private let shareButtonBackgroundNode: NavigationBackgroundNode
|
||||
private var shareButtonNode: HighlightableButtonNode
|
||||
private var cancelButtonNode: WallpaperNavigationButtonNode
|
||||
private var shareButtonNode: WallpaperNavigationButtonNode
|
||||
|
||||
private var blurButtonNode: WallpaperOptionButtonNode
|
||||
private var motionButtonNode: WallpaperOptionButtonNode
|
||||
private var patternButtonNode: WallpaperOptionButtonNode
|
||||
private var colorsButtonNode: WallpaperOptionButtonNode
|
||||
private var playButtonNode: HighlightableButtonNode
|
||||
private let playButtonBackgroundNode: NavigationBackgroundNode
|
||||
private var playButtonNode: WallpaperNavigationButtonNode
|
||||
|
||||
private let messagesContainerNode: ASDisplayNode
|
||||
private var messageNodes: [ListViewItemNode]?
|
||||
@ -163,21 +159,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
|
||||
self.colorsButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_WallpaperColors, value: .colors(false, [.clear]))
|
||||
|
||||
self.cancelButtonBackgroundNode = NavigationBackgroundNode(color: UIColor(white: 0.0, alpha: 0.3))
|
||||
self.cancelButtonNode = HighlightableButtonNode()
|
||||
self.cancelButtonNode.insertSubnode(self.cancelButtonBackgroundNode, at: 0)
|
||||
self.cancelButtonNode.setAttributedTitle(NSAttributedString(string: self.presentationData.strings.Common_Cancel, font: Font.semibold(15.0), textColor: .white), for: .normal)
|
||||
self.cancelButtonNode.titleNode.textShadowColor = UIColor(rgb: 0x000000, alpha: 0.1)
|
||||
|
||||
self.shareButtonBackgroundNode = NavigationBackgroundNode(color: UIColor(white: 0.0, alpha: 0.3))
|
||||
self.shareButtonNode = HighlightableButtonNode()
|
||||
self.shareButtonNode.insertSubnode(self.shareButtonBackgroundNode, at: 0)
|
||||
self.shareButtonNode.setImage(generateTintedImage(image: UIImage(bundleImageName: "Chat/Links/Share"), color: .white), for: .normal)
|
||||
|
||||
self.playButtonBackgroundNode = NavigationBackgroundNode(color: UIColor(white: 0.0, alpha: 0.3))
|
||||
self.playButtonNode = HighlightableButtonNode()
|
||||
self.playButtonNode.insertSubnode(self.playButtonBackgroundNode, at: 0)
|
||||
|
||||
self.cancelButtonNode = WallpaperNavigationButtonNode(content: .text(self.presentationData.strings.Common_Cancel))
|
||||
self.shareButtonNode = WallpaperNavigationButtonNode(content: .icon(image: UIImage(bundleImageName: "Chat/Links/Share"), size: CGSize(width: 28.0, height: 28.0)))
|
||||
|
||||
self.playButtonPlayImage = generateImage(CGSize(width: 48.0, height: 48.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(UIColor.white.cgColor)
|
||||
@ -205,7 +189,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
|
||||
self.playButtonRotateImage = generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorRotateIcon"), color: .white)
|
||||
|
||||
self.playButtonNode.setImage(self.playButtonPlayImage, for: [])
|
||||
self.playButtonNode = WallpaperNavigationButtonNode(content: .icon(image: self.playButtonPlayImage, size: CGSize(width: 48.0, height: 48.0)))
|
||||
|
||||
super.init()
|
||||
|
||||
@ -245,7 +229,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
self.colorsButtonNode.addTarget(self, action: #selector(self.toggleColors), forControlEvents: .touchUpInside)
|
||||
self.playButtonNode.addTarget(self, action: #selector(self.togglePlay), forControlEvents: .touchUpInside)
|
||||
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
|
||||
self.shareButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
|
||||
self.shareButtonNode.addTarget(self, action: #selector(self.actionPressed), forControlEvents: .touchUpInside)
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -331,9 +315,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
self.patternButtonNode.isSelected = file.isPattern
|
||||
|
||||
if file.isPattern && file.settings.colors.count >= 3 {
|
||||
self.playButtonNode.setImage(self.playButtonPlayImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonPlayImage)
|
||||
} else {
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
}
|
||||
} else if case let .gradient(gradient) = wallpaper {
|
||||
self.nativeNode.isHidden = false
|
||||
@ -341,9 +325,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
self.patternButtonNode.isSelected = false
|
||||
|
||||
if gradient.colors.count >= 3 {
|
||||
self.playButtonNode.setImage(self.playButtonPlayImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonPlayImage)
|
||||
} else {
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
}
|
||||
} else if case .color = wallpaper {
|
||||
self.nativeNode.isHidden = false
|
||||
@ -352,19 +336,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
} else {
|
||||
self.nativeNode.isHidden = true
|
||||
self.patternButtonNode.isSelected = false
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
}
|
||||
case .asset:
|
||||
self.nativeNode._internalUpdateIsSettingUpWallpaper()
|
||||
self.nativeNode.isHidden = true
|
||||
self.patternButtonNode.isSelected = false
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
default:
|
||||
self.nativeNode.isHidden = true
|
||||
self.patternButtonNode.isSelected = false
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
}
|
||||
|
||||
var canShare = false
|
||||
switch entry {
|
||||
case let .wallpaper(wallpaper, message):
|
||||
self.initialWallpaper = wallpaper
|
||||
@ -389,6 +374,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
actionSignal = .single(defaultAction)
|
||||
colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox)
|
||||
isBlurrable = false
|
||||
canShare = true
|
||||
case .gradient:
|
||||
displaySize = CGSize(width: 1.0, height: 1.0)
|
||||
contentSize = displaySize
|
||||
@ -399,6 +385,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
actionSignal = .single(defaultAction)
|
||||
colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox)
|
||||
isBlurrable = false
|
||||
canShare = true
|
||||
case let .file(file):
|
||||
let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000)
|
||||
contentSize = dimensions.cgSize
|
||||
@ -467,6 +454,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
actionSignal = .single(nil)
|
||||
} else {
|
||||
actionSignal = .single(defaultAction)
|
||||
canShare = true
|
||||
}
|
||||
colorSignal = .single(UIColor(rgb: 0x000000, alpha: 0.3))
|
||||
case let .image(representations, _):
|
||||
@ -590,6 +578,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
}
|
||||
self.contentSize = contentSize
|
||||
|
||||
self.shareButtonNode.isHidden = !canShare
|
||||
|
||||
if self.cropNode.supernode == nil {
|
||||
self.imageNode.contentMode = .scaleAspectFill
|
||||
self.wrapperNode.addSubnode(self.imageNode)
|
||||
@ -656,16 +646,6 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
strongSelf.blurButtonNode.buttonColor = color
|
||||
strongSelf.motionButtonNode.buttonColor = color
|
||||
strongSelf.colorsButtonNode.buttonColor = color
|
||||
|
||||
if color == UIColor(rgb: 0x000000, alpha: 0.3) {
|
||||
strongSelf.playButtonBackgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.55), transition: .immediate)
|
||||
strongSelf.cancelButtonBackgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.55), transition: .immediate)
|
||||
strongSelf.shareButtonBackgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.55), transition: .immediate)
|
||||
} else {
|
||||
strongSelf.playButtonBackgroundNode.updateColor(color: color, transition: .immediate)
|
||||
strongSelf.cancelButtonBackgroundNode.updateColor(color: color, transition: .immediate)
|
||||
strongSelf.shareButtonBackgroundNode.updateColor(color: color, transition: .immediate)
|
||||
}
|
||||
}))
|
||||
} else if self.arguments.patternEnabled != previousArguments.patternEnabled {
|
||||
self.patternButtonNode.isSelected = self.arguments.patternEnabled
|
||||
@ -959,9 +939,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
let playFrame = CGRect(origin: CGPoint(x: centerButtonFrame.midX - playButtonSize.width / 2.0, y: centerButtonFrame.midY - playButtonSize.height / 2.0), size: playButtonSize)
|
||||
var playAlpha: CGFloat = 0.0
|
||||
|
||||
var cancelSize = self.cancelButtonNode.measure(layout.size)
|
||||
cancelSize.width += 16.0
|
||||
cancelSize.height = 28.0
|
||||
let cancelSize = self.cancelButtonNode.measure(layout.size)
|
||||
let cancelFrame = CGRect(origin: CGPoint(x: 16.0 + offset.x, y: 16.0), size: cancelSize)
|
||||
|
||||
let shareFrame = CGRect(origin: CGPoint(x: layout.size.width - 16.0 - 28.0 + offset.x, y: 16.0), size: CGSize(width: 28.0, height: 28.0))
|
||||
@ -1061,18 +1039,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
transition.updateAlpha(node: self.colorsButtonNode, alpha: colorsAlpha * alpha)
|
||||
|
||||
transition.updateFrame(node: self.playButtonNode, frame: playFrame)
|
||||
transition.updateFrame(node: self.playButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: playFrame.size))
|
||||
self.playButtonBackgroundNode.update(size: playFrame.size, cornerRadius: playFrame.size.height / 2.0, transition: transition)
|
||||
transition.updateAlpha(node: self.playButtonNode, alpha: playAlpha * alpha)
|
||||
transition.updateSublayerTransformScale(node: self.playButtonNode, scale: max(0.1, playAlpha))
|
||||
|
||||
transition.updateFrame(node: self.cancelButtonNode, frame: cancelFrame)
|
||||
transition.updateFrame(node: self.cancelButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: cancelFrame.size))
|
||||
self.cancelButtonBackgroundNode.update(size: cancelFrame.size, cornerRadius: cancelFrame.size.height / 2.0, transition: transition)
|
||||
|
||||
transition.updateFrame(node: self.shareButtonNode, frame: shareFrame)
|
||||
transition.updateFrame(node: self.shareButtonBackgroundNode, frame: CGRect(origin: CGPoint(), size: shareFrame.size))
|
||||
self.shareButtonBackgroundNode.update(size: shareFrame.size, cornerRadius: shareFrame.size.height / 2.0, transition: transition)
|
||||
}
|
||||
|
||||
private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) {
|
||||
|
@ -34,8 +34,10 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
|
||||
private let doneButton = HighlightTrackingButtonNode()
|
||||
private let doneButtonBackgroundNode: NavigationBackgroundNode
|
||||
private let doneButtonBackgroundView: UIVisualEffectView
|
||||
|
||||
private let doneButtonTitleNode: ImmediateTextNode
|
||||
private let doneButtonVibrancyView: UIVisualEffectView
|
||||
private let doneButtonVibrancyTitleNode: ImmediateTextNode
|
||||
|
||||
private let doneButtonSolidBackgroundNode: ASDisplayNode
|
||||
private let doneButtonSolidTitleNode: ImmediateTextNode
|
||||
@ -49,26 +51,25 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
self.cancelButtonType = cancelButtonType
|
||||
self.doneButtonType = doneButtonType
|
||||
|
||||
self.doneButtonBackgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0xf2f2f2, alpha: 0.55))
|
||||
self.doneButtonBackgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0xf2f2f2, alpha: 0.75))
|
||||
self.doneButtonBackgroundNode.cornerRadius = 14.0
|
||||
|
||||
let blurEffect: UIBlurEffect
|
||||
if #available(iOS 13.0, *) {
|
||||
blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight)
|
||||
blurEffect = UIBlurEffect(style: .extraLight)
|
||||
} else {
|
||||
blurEffect = UIBlurEffect(style: .light)
|
||||
}
|
||||
|
||||
self.doneButtonBackgroundView = UIVisualEffectView(effect: blurEffect)
|
||||
self.doneButtonBackgroundView.clipsToBounds = true
|
||||
self.doneButtonBackgroundView.layer.cornerRadius = 14.0
|
||||
self.doneButtonBackgroundView.isUserInteractionEnabled = false
|
||||
self.doneButtonVibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
|
||||
|
||||
self.doneButtonTitleNode = ImmediateTextNode()
|
||||
self.doneButtonTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonTitleNode.textShadowColor = UIColor(rgb: 0x000000, alpha: 0.1)
|
||||
self.doneButtonTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonVibrancyTitleNode = ImmediateTextNode()
|
||||
self.doneButtonVibrancyTitleNode.displaysAsynchronously = false
|
||||
self.doneButtonVibrancyTitleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.doneButtonSolidBackgroundNode = ASDisplayNode()
|
||||
self.doneButtonSolidBackgroundNode.alpha = 0.0
|
||||
self.doneButtonSolidBackgroundNode.clipsToBounds = true
|
||||
@ -86,7 +87,9 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.doneButtonBackgroundNode)
|
||||
self.addSubnode(self.doneButtonTitleNode)
|
||||
self.doneButtonVibrancyView.contentView.addSubnode(self.doneButtonVibrancyTitleNode)
|
||||
self.doneButtonBackgroundNode.view.addSubview(self.doneButtonVibrancyView)
|
||||
self.doneButtonBackgroundNode.addSubnode(self.doneButtonTitleNode)
|
||||
|
||||
self.addSubnode(self.doneButtonSolidBackgroundNode)
|
||||
self.addSubnode(self.doneButtonSolidTitleNode)
|
||||
@ -106,8 +109,8 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 0.55
|
||||
strongSelf.doneButtonTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonTitleNode.alpha = 0.55
|
||||
strongSelf.doneButtonVibrancyTitleNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.doneButtonVibrancyTitleNode.alpha = 0.55
|
||||
}
|
||||
} else {
|
||||
if strongSelf.isSolid {
|
||||
@ -118,8 +121,8 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
} else {
|
||||
strongSelf.doneButtonBackgroundNode.alpha = 1.0
|
||||
strongSelf.doneButtonBackgroundNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.doneButtonVibrancyTitleNode.alpha = 1.0
|
||||
strongSelf.doneButtonVibrancyTitleNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,6 +146,7 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
transition.updateAlpha(node: self.doneButtonBackgroundNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidBackgroundNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
transition.updateAlpha(node: self.doneButtonTitleNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonVibrancyTitleNode, alpha: isSolid ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneButtonSolidTitleNode, alpha: isSolid ? 1.0 : 0.0)
|
||||
}
|
||||
|
||||
@ -163,7 +167,8 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
doneTitle = ""
|
||||
self.doneButton.isUserInteractionEnabled = false
|
||||
}
|
||||
self.doneButtonTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: .white)
|
||||
self.doneButtonTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
self.doneButtonVibrancyTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: .white)
|
||||
|
||||
self.doneButtonSolidBackgroundNode.backgroundColor = theme.list.itemCheckColors.fillColor
|
||||
self.doneButtonSolidTitleNode.attributedText = NSAttributedString(string: doneTitle, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor)
|
||||
@ -177,16 +182,17 @@ final class WallpaperGalleryToolbarNode: ASDisplayNode {
|
||||
self.doneButton.frame = doneFrame
|
||||
self.doneButtonBackgroundNode.frame = doneFrame
|
||||
self.doneButtonBackgroundNode.update(size: doneFrame.size, cornerRadius: 14.0, transition: transition)
|
||||
self.doneButtonBackgroundView.frame = doneFrame
|
||||
|
||||
self.doneButtonVibrancyView.frame = self.doneButtonBackgroundNode.bounds
|
||||
self.doneButtonSolidBackgroundNode.frame = doneFrame
|
||||
|
||||
let doneTitleSize = self.doneButtonTitleNode.updateLayout(doneFrame.size)
|
||||
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: doneFrame.minX + floorToScreenPixels((doneFrame.width - doneTitleSize.width) / 2.0), y: doneFrame.minY + floorToScreenPixels((doneFrame.height - doneTitleSize.height) / 2.0)), size: doneTitleSize)
|
||||
self.doneButtonTitleNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((doneFrame.width - doneTitleSize.width) / 2.0), y: floorToScreenPixels((doneFrame.height - doneTitleSize.height) / 2.0)), size: doneTitleSize)
|
||||
|
||||
let _ = self.doneButtonVibrancyTitleNode.updateLayout(doneFrame.size)
|
||||
self.doneButtonVibrancyTitleNode.frame = self.doneButtonTitleNode.frame
|
||||
|
||||
let _ = self.doneButtonSolidTitleNode.updateLayout(doneFrame.size)
|
||||
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame
|
||||
|
||||
self.doneButtonSolidTitleNode.frame = self.doneButtonTitleNode.frame.offsetBy(dx: doneFrame.minX, dy: doneFrame.minY)
|
||||
}
|
||||
|
||||
@objc func cancelPressed() {
|
||||
|
@ -34,11 +34,156 @@ private func generateColorsImage(diameter: CGFloat, colors: [UIColor]) -> UIImag
|
||||
})
|
||||
}
|
||||
|
||||
final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
|
||||
enum Content {
|
||||
case icon(image: UIImage?, size: CGSize)
|
||||
case text(String)
|
||||
}
|
||||
|
||||
private let content: Content
|
||||
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
private let vibrancyView: UIVisualEffectView
|
||||
|
||||
private let iconNode: ASImageNode
|
||||
private let darkIconNode: ASImageNode
|
||||
|
||||
private let textNode: ImmediateTextNode
|
||||
private let darkTextNode: ImmediateTextNode
|
||||
|
||||
func setIcon(_ image: UIImage?) {
|
||||
self.iconNode.image = generateTintedImage(image: image, color: .white)
|
||||
self.darkIconNode.image = generateTintedImage(image: image, color: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
}
|
||||
|
||||
init(content: Content) {
|
||||
self.content = content
|
||||
|
||||
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0xf2f2f2, alpha: 0.75))
|
||||
self.backgroundNode.cornerRadius = 14.0
|
||||
|
||||
let blurEffect: UIBlurEffect
|
||||
if #available(iOS 13.0, *) {
|
||||
blurEffect = UIBlurEffect(style: .extraLight)
|
||||
} else {
|
||||
blurEffect = UIBlurEffect(style: .light)
|
||||
}
|
||||
self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
|
||||
|
||||
self.iconNode = ASImageNode()
|
||||
self.iconNode.displaysAsynchronously = false
|
||||
self.iconNode.contentMode = .center
|
||||
|
||||
self.darkIconNode = ASImageNode()
|
||||
self.darkIconNode.displaysAsynchronously = false
|
||||
self.darkIconNode.contentMode = .center
|
||||
|
||||
var title: String
|
||||
switch content {
|
||||
case let .text(text):
|
||||
title = text
|
||||
self.backgroundNode.cornerRadius = 14.0
|
||||
case let .icon(icon, size):
|
||||
title = ""
|
||||
self.backgroundNode.cornerRadius = size.height / 2.0
|
||||
|
||||
self.iconNode.image = generateTintedImage(image: icon, color: .white)
|
||||
self.darkIconNode.image = generateTintedImage(image: icon, color: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
}
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.attributedText = NSAttributedString(string: title, font: Font.semibold(15.0), textColor: .white)
|
||||
|
||||
self.darkTextNode = ImmediateTextNode()
|
||||
self.darkTextNode.attributedText = NSAttributedString(string: title, font: Font.semibold(15.0), textColor: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.vibrancyView.contentView.addSubnode(self.iconNode)
|
||||
self.vibrancyView.contentView.addSubnode(self.textNode)
|
||||
self.backgroundNode.view.addSubview(self.vibrancyView)
|
||||
self.backgroundNode.addSubnode(self.darkIconNode)
|
||||
self.backgroundNode.addSubnode(self.darkTextNode)
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
if highlighted {
|
||||
strongSelf.backgroundNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.backgroundNode.alpha = 0.4
|
||||
|
||||
strongSelf.iconNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.iconNode.alpha = 0.4
|
||||
|
||||
strongSelf.textNode.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.textNode.alpha = 0.4
|
||||
} else {
|
||||
strongSelf.backgroundNode.alpha = 1.0
|
||||
strongSelf.backgroundNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
|
||||
strongSelf.iconNode.alpha = 1.0
|
||||
strongSelf.iconNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
|
||||
strongSelf.textNode.alpha = 1.0
|
||||
strongSelf.textNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buttonColor: UIColor = UIColor(rgb: 0x000000, alpha: 0.3) {
|
||||
didSet {
|
||||
if self.buttonColor == UIColor(rgb: 0x000000, alpha: 0.3) {
|
||||
self.backgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.75), transition: .immediate)
|
||||
} else {
|
||||
self.backgroundNode.updateColor(color: self.buttonColor, transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var textSize: CGSize?
|
||||
override func measure(_ constrainedSize: CGSize) -> CGSize {
|
||||
switch self.content {
|
||||
case .text:
|
||||
let size = self.textNode.updateLayout(constrainedSize)
|
||||
let _ = self.darkTextNode.updateLayout(constrainedSize)
|
||||
self.textSize = size
|
||||
return CGSize(width: ceil(size.width) + 16.0, height: 28.0)
|
||||
case let .icon(_, size):
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
self.backgroundNode.frame = self.bounds
|
||||
self.backgroundNode.update(size: self.backgroundNode.bounds.size, cornerRadius: 14.0, transition: .immediate)
|
||||
self.vibrancyView.frame = self.bounds
|
||||
|
||||
self.iconNode.frame = self.bounds
|
||||
self.darkIconNode.frame = self.bounds
|
||||
|
||||
if let textSize = self.textSize {
|
||||
self.textNode.frame = CGRect(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: floorToScreenPixels((size.height - textSize.height) / 2.0), width: textSize.width, height: textSize.height)
|
||||
self.darkTextNode.frame = self.textNode.frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
private let vibrancyView: UIVisualEffectView
|
||||
|
||||
private let checkNode: CheckNode
|
||||
private let darkCheckNode: CheckNode
|
||||
|
||||
private let colorNode: ASImageNode
|
||||
|
||||
private let textNode: ImmediateTextNode
|
||||
private let darkTextNode: ImmediateTextNode
|
||||
|
||||
private var textSize: CGSize?
|
||||
|
||||
@ -60,12 +205,14 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
self._value = .colors(newValue, colors)
|
||||
}
|
||||
self.checkNode.setSelected(newValue, animated: false)
|
||||
self.darkCheckNode.setSelected(newValue, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
var title: String {
|
||||
didSet {
|
||||
self.textNode.attributedText = NSAttributedString(string: title, font: Font.medium(13), textColor: .white)
|
||||
self.darkTextNode.attributedText = NSAttributedString(string: title, font: Font.medium(13), textColor: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,36 +223,60 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0xffffff, alpha: 0.4))
|
||||
self.backgroundNode.cornerRadius = 14.0
|
||||
|
||||
self.checkNode = CheckNode(theme: CheckNodeTheme(backgroundColor: .white, strokeColor: .clear, borderColor: .white, overlayBorder: false, hasInset: false, hasShadow: true, borderWidth: 1.5))
|
||||
let blurEffect: UIBlurEffect
|
||||
if #available(iOS 13.0, *) {
|
||||
blurEffect = UIBlurEffect(style: .extraLight)
|
||||
} else {
|
||||
blurEffect = UIBlurEffect(style: .light)
|
||||
}
|
||||
self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
|
||||
|
||||
let darkColor = UIColor(rgb: 0x000000, alpha: 0.25)
|
||||
|
||||
self.checkNode = CheckNode(theme: CheckNodeTheme(backgroundColor: .white, strokeColor: .clear, borderColor: .white, overlayBorder: false, hasInset: false, hasShadow: false, borderWidth: 1.5))
|
||||
self.checkNode.isUserInteractionEnabled = false
|
||||
|
||||
self.darkCheckNode = CheckNode(theme: CheckNodeTheme(backgroundColor: darkColor, strokeColor: .clear, borderColor: darkColor, overlayBorder: false, hasInset: false, hasShadow: false, borderWidth: 1.5))
|
||||
self.darkCheckNode.isUserInteractionEnabled = false
|
||||
|
||||
self.colorNode = ASImageNode()
|
||||
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode.attributedText = NSAttributedString(string: title, font: Font.medium(13), textColor: .white)
|
||||
self.textNode.textShadowColor = UIColor(rgb: 0x000000, alpha: 0.1)
|
||||
|
||||
self.darkTextNode = ImmediateTextNode()
|
||||
self.darkTextNode.displaysAsynchronously = false
|
||||
self.darkTextNode.attributedText = NSAttributedString(string: title, font: Font.medium(13), textColor: UIColor(rgb: 0x000000, alpha: 0.25))
|
||||
|
||||
super.init()
|
||||
|
||||
switch value {
|
||||
case let .check(selected):
|
||||
self.checkNode.isHidden = false
|
||||
self.darkCheckNode.isHidden = false
|
||||
self.colorNode.isHidden = true
|
||||
self.checkNode.selected = selected
|
||||
self.darkCheckNode.selected = selected
|
||||
case let .color(_, color):
|
||||
self.checkNode.isHidden = true
|
||||
self.darkCheckNode.isHidden = true
|
||||
self.colorNode.isHidden = false
|
||||
self.colorNode.image = generateFilledCircleImage(diameter: 18.0, color: color)
|
||||
case let .colors(_, colors):
|
||||
self.checkNode.isHidden = true
|
||||
self.darkCheckNode.isHidden = true
|
||||
self.colorNode.isHidden = false
|
||||
self.colorNode.image = generateColorsImage(diameter: 18.0, colors: colors)
|
||||
}
|
||||
|
||||
self.addSubnode(self.backgroundNode)
|
||||
self.addSubnode(self.checkNode)
|
||||
self.vibrancyView.contentView.addSubnode(self.checkNode)
|
||||
self.vibrancyView.contentView.addSubnode(self.textNode)
|
||||
self.backgroundNode.view.addSubview(self.vibrancyView)
|
||||
self.addSubnode(self.darkCheckNode)
|
||||
self.addSubnode(self.darkTextNode)
|
||||
self.addSubnode(self.colorNode)
|
||||
self.addSubnode(self.textNode)
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let strongSelf = self {
|
||||
@ -141,7 +312,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
var buttonColor: UIColor = UIColor(rgb: 0x000000, alpha: 0.3) {
|
||||
didSet {
|
||||
if self.buttonColor == UIColor(rgb: 0x000000, alpha: 0.3) {
|
||||
self.backgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.55), transition: .immediate)
|
||||
self.backgroundNode.updateColor(color: UIColor(rgb: 0xf2f2f2, alpha: 0.75), transition: .immediate)
|
||||
} else {
|
||||
self.backgroundNode.updateColor(color: self.buttonColor, transition: .immediate)
|
||||
}
|
||||
@ -214,6 +385,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
self._value = .colors(selected, colors)
|
||||
}
|
||||
self.checkNode.setSelected(selected, animated: animated)
|
||||
self.darkCheckNode.setSelected(selected, animated: animated)
|
||||
}
|
||||
|
||||
func setEnabled(_ enabled: Bool) {
|
||||
@ -227,6 +399,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
override func measure(_ constrainedSize: CGSize) -> CGSize {
|
||||
let size = self.textNode.updateLayout(constrainedSize)
|
||||
let _ = self.darkTextNode.updateLayout(constrainedSize)
|
||||
self.textSize = size
|
||||
return CGSize(width: ceil(size.width) + 48.0, height: 30.0)
|
||||
}
|
||||
@ -236,6 +409,7 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
self.backgroundNode.frame = self.bounds
|
||||
self.backgroundNode.update(size: self.backgroundNode.bounds.size, cornerRadius: 15.0, transition: .immediate)
|
||||
self.vibrancyView.frame = self.bounds
|
||||
|
||||
guard let _ = self.textSize else {
|
||||
return
|
||||
@ -244,12 +418,14 @@ final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
|
||||
let padding: CGFloat = 6.0
|
||||
let spacing: CGFloat = 9.0
|
||||
let checkSize = CGSize(width: 18.0, height: 18.0)
|
||||
|
||||
self.checkNode.frame = CGRect(origin: CGPoint(x: padding, y: padding), size: checkSize)
|
||||
self.colorNode.frame = CGRect(origin: CGPoint(x: padding, y: padding), size: checkSize)
|
||||
let checkFrame = CGRect(origin: CGPoint(x: padding, y: padding), size: checkSize)
|
||||
self.checkNode.frame = checkFrame
|
||||
self.darkCheckNode.frame = checkFrame
|
||||
self.colorNode.frame = checkFrame
|
||||
|
||||
if let textSize = self.textSize {
|
||||
self.textNode.frame = CGRect(x: max(padding + checkSize.width + spacing, padding + checkSize.width + floor((self.bounds.width - padding - checkSize.width - textSize.width) / 2.0) - 2.0), y: 6.0 + UIScreenPixel, width: textSize.width, height: textSize.height)
|
||||
self.textNode.frame = CGRect(x: max(padding + checkSize.width + spacing, padding + checkSize.width + floor((self.bounds.width - padding - checkSize.width - textSize.width) / 2.0) - 2.0), y: floorToScreenPixels((self.bounds.height - textSize.height) / 2.0), width: textSize.width, height: textSize.height)
|
||||
self.darkTextNode.frame = self.textNode.frame
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,12 +419,16 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
|
||||
func didAppear(initialWallpaper: TelegramWallpaper? = nil, intensity: Int32? = nil) {
|
||||
let wallpaper: TelegramWallpaper?
|
||||
|
||||
switch initialWallpaper {
|
||||
case var .file(file):
|
||||
file.settings = self.wallpapers[0].settings ?? WallpaperSettings()
|
||||
wallpaper = .file(file)
|
||||
default:
|
||||
wallpaper = self.wallpapers.first
|
||||
if self.wallpapers.isEmpty {
|
||||
wallpaper = nil
|
||||
} else {
|
||||
switch initialWallpaper {
|
||||
case var .file(file):
|
||||
file.settings = self.wallpapers[0].settings ?? WallpaperSettings()
|
||||
wallpaper = .file(file)
|
||||
default:
|
||||
wallpaper = self.wallpapers.first
|
||||
}
|
||||
}
|
||||
|
||||
if let wallpaper = wallpaper {
|
||||
|
@ -102,6 +102,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
case attachMenuBotAllowed
|
||||
case requestedPeer(buttonId: Int32, peerId: PeerId)
|
||||
case setChatWallpaper(wallpaper: TelegramWallpaper)
|
||||
case setSameChatWallpaper
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
@ -188,6 +189,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
} else {
|
||||
self = .unknown
|
||||
}
|
||||
case 34:
|
||||
self = .setSameChatWallpaper
|
||||
default:
|
||||
self = .unknown
|
||||
}
|
||||
@ -352,6 +355,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
case let .setChatWallpaper(wallpaper):
|
||||
encoder.encodeInt32(33, forKey: "_rawValue")
|
||||
encoder.encode(TelegramWallpaperNativeCodable(wallpaper), forKey: "wallpaper")
|
||||
case .setSameChatWallpaper:
|
||||
encoder.encodeInt32(34, forKey: "_rawValue")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,3 +152,28 @@ func _internal_setChatWallpaper(account: Account, peerId: PeerId, wallpaper: Tel
|
||||
} |> switchToLatest
|
||||
}
|
||||
}
|
||||
|
||||
public enum SetExistingChatWallpaperError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_setExistingChatWallpaper(account: Account, messageId: MessageId) -> Signal<Void, SetExistingChatWallpaperError> {
|
||||
return account.postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(messageId.peerId)
|
||||
}
|
||||
|> castError(SetExistingChatWallpaperError.self)
|
||||
|> mapToSignal { peer -> Signal<Void, SetExistingChatWallpaperError> in
|
||||
guard let peer = peer, let inputPeer = apiInputPeer(peer) else {
|
||||
return .complete()
|
||||
}
|
||||
let flags: Int32 = 1 << 1
|
||||
return account.network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: nil, settings: nil, id: messageId.id))
|
||||
|> `catch` { _ -> Signal<Api.Updates, SetExistingChatWallpaperError> in
|
||||
return .fail(.generic)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Void, SetExistingChatWallpaperError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,5 +20,9 @@ public extension TelegramEngine {
|
||||
public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal<Void, NoError> {
|
||||
return _internal_setChatWallpaper(account: self.account, peerId: peerId, wallpaper: wallpaper)
|
||||
}
|
||||
|
||||
public func setExistingChatWallpaper(messageId: MessageId) -> Signal<Void, SetExistingChatWallpaperError> {
|
||||
return _internal_setExistingChatWallpaper(account: self.account, messageId: messageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ private func uploadedWallpaper(postbox: Postbox, network: Network, resource: Med
|
||||
}
|
||||
}
|
||||
|
||||
public func uploadWallpaper(account: Account, resource: MediaResource, mimeType: String = "image/jpeg", settings: WallpaperSettings) -> Signal<UploadWallpaperStatus, UploadWallpaperError> {
|
||||
public func uploadWallpaper(account: Account, resource: MediaResource, mimeType: String = "image/jpeg", settings: WallpaperSettings, forChat: Bool) -> Signal<UploadWallpaperStatus, UploadWallpaperError> {
|
||||
return uploadedWallpaper(postbox: account.postbox, network: account.network, resource: resource)
|
||||
|> mapError { _ -> UploadWallpaperError in }
|
||||
|> mapToSignal { result -> Signal<(UploadWallpaperStatus, MediaResource?), UploadWallpaperError> in
|
||||
@ -130,7 +130,11 @@ public func uploadWallpaper(account: Account, resource: MediaResource, mimeType:
|
||||
case let .progress(progress):
|
||||
return .single((.progress(progress), result.resource))
|
||||
case let .inputFile(file):
|
||||
return account.network.request(Api.functions.account.uploadWallPaper(flags: 0, file: file, mimeType: mimeType, settings: apiWallpaperSettings(settings)))
|
||||
var flags: Int32 = 0
|
||||
if forChat {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
return account.network.request(Api.functions.account.uploadWallPaper(flags: flags, file: file, mimeType: mimeType, settings: apiWallpaperSettings(settings)))
|
||||
|> mapError { _ in return UploadWallpaperError.generic }
|
||||
|> map { wallpaper -> (UploadWallpaperStatus, MediaResource?) in
|
||||
return (.complete(TelegramWallpaper(apiWallpaper: wallpaper)), result.resource)
|
||||
|
@ -880,6 +880,13 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
let resultTitleString = strings.Notification_ChangedWallpaper(authorName)
|
||||
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
}
|
||||
case .setSameChatWallpaper:
|
||||
if message.author?.id == accountPeerId {
|
||||
attributedString = NSAttributedString(string: strings.Notification_YouChangedToSameWallpaper, font: titleFont, textColor: primaryTextColor)
|
||||
} else {
|
||||
let resultTitleString = strings.Notification_ChangedToSameWallpaper(authorName)
|
||||
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
}
|
||||
case .unknown:
|
||||
attributedString = nil
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
|
||||
let sharedContext = self.sharedContext
|
||||
let account = self.account
|
||||
|
||||
let uploadSignal = uploadWallpaper(account: account, resource: currentResource, settings: currentWallpaper.settings ?? WallpaperSettings())
|
||||
let uploadSignal = uploadWallpaper(account: account, resource: currentResource, settings: currentWallpaper.settings ?? WallpaperSettings(), forChat: false)
|
||||
|> map { result -> UploadWallpaperStatus in
|
||||
switch result {
|
||||
case let .complete(wallpaper):
|
||||
|
Loading…
x
Reference in New Issue
Block a user