mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Various improvements
This commit is contained in:
@@ -35,6 +35,7 @@ import SaveToCameraRoll
|
||||
import SegmentedControlNode
|
||||
import AnimatedCountLabelNode
|
||||
import HexColor
|
||||
import QrCodeUI
|
||||
|
||||
private func closeButtonImage(theme: PresentationTheme) -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
||||
@@ -536,7 +537,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
snapshotView.frame = self.containerNode.view.frame
|
||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreen.themeCrossfadeDuration, delay: ChatQrCodeScreen.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreenImpl.themeCrossfadeDuration, delay: ChatQrCodeScreenImpl.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
@@ -561,7 +562,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
public final class ChatQrCodeScreen: ViewController {
|
||||
public final class ChatQrCodeScreenImpl: ViewController, ChatQrCodeScreen {
|
||||
public static let themeCrossfadeDuration: Double = 0.3
|
||||
public static let themeCrossfadeDelay: Double = 0.05
|
||||
|
||||
@@ -603,7 +604,7 @@ public final class ChatQrCodeScreen: ViewController {
|
||||
private var animatedIn = false
|
||||
|
||||
private let context: AccountContext
|
||||
fileprivate let subject: ChatQrCodeScreen.Subject
|
||||
fileprivate let subject: ChatQrCodeScreenImpl.Subject
|
||||
|
||||
private var presentationData: PresentationData
|
||||
private var presentationThemePromise = Promise<PresentationTheme?>()
|
||||
@@ -611,13 +612,15 @@ public final class ChatQrCodeScreen: ViewController {
|
||||
|
||||
public var dismissed: (() -> Void)?
|
||||
|
||||
public init(context: AccountContext, subject: ChatQrCodeScreen.Subject) {
|
||||
public init(context: AccountContext, subject: ChatQrCodeScreenImpl.Subject) {
|
||||
self.context = context
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.subject = subject
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
self.navigationPresentation = .flatModal
|
||||
|
||||
self.statusBar.statusBarStyle = .Ignore
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
|
||||
@@ -664,14 +667,11 @@ public final class ChatQrCodeScreen: ViewController {
|
||||
}
|
||||
strongSelf.dismiss()
|
||||
}
|
||||
self.controllerNode.dismiss = { [weak self] in
|
||||
self?.presentingViewController?.dismiss(animated: false, completion: nil)
|
||||
}
|
||||
self.controllerNode.cancel = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.dismiss()
|
||||
strongSelf.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,19 +690,25 @@ public final class ChatQrCodeScreen: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
override public func dismiss(completion: (() -> Void)? = nil) {
|
||||
public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||
self.forEachController({ controller in
|
||||
if let controller = controller as? TooltipScreen {
|
||||
controller.dismiss()
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
self.controllerNode.animateOut(completion: completion)
|
||||
|
||||
if flag {
|
||||
self.controllerNode.animateOut(completion: {
|
||||
super.dismiss(animated: false, completion: completion)
|
||||
})
|
||||
} else {
|
||||
super.dismiss(animated: flag, completion: completion)
|
||||
}
|
||||
|
||||
self.dismissed?()
|
||||
}
|
||||
|
||||
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
@@ -754,7 +760,7 @@ private func generateShadowImage() -> UIImage? {
|
||||
private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDelegate {
|
||||
private let context: AccountContext
|
||||
private var presentationData: PresentationData
|
||||
private weak var controller: ChatQrCodeScreen?
|
||||
private weak var controller: ChatQrCodeScreenImpl?
|
||||
|
||||
private let contentNode: ContentNode
|
||||
|
||||
@@ -772,6 +778,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
private let animationContainerNode: ASDisplayNode
|
||||
private var animationNode: AnimationNode
|
||||
private let doneButton: SolidRoundedButtonNode
|
||||
private let scanButton: SolidRoundedButtonNode
|
||||
|
||||
private let listNode: ListView
|
||||
private var entries: [ThemeSettingsThemeEntry]?
|
||||
@@ -805,10 +812,9 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
var present: ((ViewController) -> Void)?
|
||||
var previewTheme: ((String?, Bool?, PresentationTheme) -> Void)?
|
||||
var completion: ((String?) -> Void)?
|
||||
var dismiss: (() -> Void)?
|
||||
var cancel: (() -> Void)?
|
||||
|
||||
init(context: AccountContext, presentationData: PresentationData, controller: ChatQrCodeScreen) {
|
||||
init(context: AccountContext, presentationData: PresentationData, controller: ChatQrCodeScreenImpl) {
|
||||
self.context = context
|
||||
self.controller = controller
|
||||
self.presentationData = presentationData
|
||||
@@ -817,7 +823,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
self.wrappingScrollNode.view.alwaysBounceVertical = true
|
||||
self.wrappingScrollNode.view.delaysContentTouches = false
|
||||
self.wrappingScrollNode.view.canCancelContentTouches = true
|
||||
|
||||
|
||||
switch controller.subject {
|
||||
case let .peer(peer, threadId, temporary):
|
||||
self.contentNode = QrContentNode(context: context, peer: peer, threadId: threadId, isStatic: false, temporary: temporary)
|
||||
@@ -888,6 +894,11 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
self.doneButton.title = self.presentationData.strings.Share_ShareMessage
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
self.scanButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: .clear, foregroundColor: self.presentationData.theme.actionSheet.controlAccentColor), font: .regular, height: 42.0, cornerRadius: 0.0, gloss: false)
|
||||
self.scanButton.title = "Scan QR Code"
|
||||
self.scanButton.icon = UIImage(bundleImageName: "Settings/ScanQr")
|
||||
|
||||
self.listNode = ListView()
|
||||
self.listNode.transform = CATransform3DMakeRotation(-CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
|
||||
@@ -910,6 +921,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
self.contentContainerNode.addSubnode(self.titleNode)
|
||||
self.contentContainerNode.addSubnode(self.segmentedNode)
|
||||
self.contentContainerNode.addSubnode(self.doneButton)
|
||||
self.contentContainerNode.addSubnode(self.scanButton)
|
||||
|
||||
self.topContentContainerNode.addSubnode(self.animationContainerNode)
|
||||
self.animationContainerNode.addSubnode(self.animationNode)
|
||||
@@ -992,6 +1004,14 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
}
|
||||
}
|
||||
|
||||
self.scanButton.pressed = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let controller = QrCodeScanScreen(context: self.context, subject: .peer)
|
||||
self.controller?.push(controller)
|
||||
}
|
||||
|
||||
let animatedEmojiStickers = context.engine.stickers.loadedStickerPack(reference: .animatedEmoji, forceActualized: false)
|
||||
|> map { animatedEmoji -> [String: [StickerPackItem]] in
|
||||
var animatedEmojiStickers: [String: [StickerPackItem]] = [:]
|
||||
@@ -1246,9 +1266,6 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
|
||||
private var switchThemeIconAnimator: DisplayLinkAnimator?
|
||||
func updatePresentationData(_ presentationData: PresentationData) {
|
||||
guard !self.animatedOut else {
|
||||
return
|
||||
}
|
||||
let previousTheme = self.presentationData.theme
|
||||
self.presentationData = presentationData
|
||||
|
||||
@@ -1261,6 +1278,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
|
||||
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
|
||||
self.doneButton.updateTheme(SolidRoundedButtonTheme(theme: self.presentationData.theme))
|
||||
self.scanButton.updateTheme(SolidRoundedButtonTheme(backgroundColor: .clear, foregroundColor: self.presentationData.theme.actionSheet.controlAccentColor))
|
||||
|
||||
let previousIconColors = iconColors(theme: previousTheme)
|
||||
let newIconColors = iconColors(theme: self.presentationData.theme)
|
||||
@@ -1336,7 +1354,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
if let snapshotView = self.contentNode.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.contentNode.view.insertSubview(snapshotView, aboveSubview: self.contentNode.containerNode.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreen.themeCrossfadeDuration, delay: ChatQrCodeScreen.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreenImpl.themeCrossfadeDuration, delay: ChatQrCodeScreenImpl.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
@@ -1345,14 +1363,14 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
snapshotView.frame = self.animationNode.frame
|
||||
self.animationNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.animationNode.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreen.themeCrossfadeDuration, delay: ChatQrCodeScreen.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreenImpl.themeCrossfadeDuration, delay: ChatQrCodeScreenImpl.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
Queue.mainQueue().after(ChatQrCodeScreen.themeCrossfadeDelay) {
|
||||
Queue.mainQueue().after(ChatQrCodeScreenImpl.themeCrossfadeDelay) {
|
||||
if let effectView = self.effectNode.view as? UIVisualEffectView {
|
||||
UIView.animate(withDuration: ChatQrCodeScreen.themeCrossfadeDuration, delay: 0.0, options: .curveLinear) {
|
||||
UIView.animate(withDuration: ChatQrCodeScreenImpl.themeCrossfadeDuration, delay: 0.0, options: .curveLinear) {
|
||||
effectView.effect = UIBlurEffect(style: self.presentationData.theme.actionSheet.backgroundType == .light ? .light : .dark)
|
||||
} completion: { _ in
|
||||
}
|
||||
@@ -1360,14 +1378,14 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
|
||||
let previousColor = self.contentBackgroundNode.backgroundColor ?? .clear
|
||||
self.contentBackgroundNode.backgroundColor = self.presentationData.theme.actionSheet.itemBackgroundColor
|
||||
self.contentBackgroundNode.layer.animate(from: previousColor.cgColor, to: (self.contentBackgroundNode.backgroundColor ?? .clear).cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: ChatQrCodeScreen.themeCrossfadeDuration)
|
||||
self.contentBackgroundNode.layer.animate(from: previousColor.cgColor, to: (self.contentBackgroundNode.backgroundColor ?? .clear).cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: ChatQrCodeScreenImpl.themeCrossfadeDuration)
|
||||
}
|
||||
|
||||
if let snapshotView = self.contentContainerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.frame = self.contentContainerNode.frame
|
||||
self.contentContainerNode.view.superview?.insertSubview(snapshotView, aboveSubview: self.contentContainerNode.view)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreen.themeCrossfadeDuration, delay: ChatQrCodeScreen.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: ChatQrCodeScreenImpl.themeCrossfadeDuration, delay: ChatQrCodeScreenImpl.themeCrossfadeDelay, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
@@ -1395,11 +1413,8 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
self.animatedOut = true
|
||||
|
||||
let offset = self.bounds.size.height - self.contentBackgroundNode.frame.minY
|
||||
self.wrappingScrollNode.layer.animateBoundsOriginYAdditive(from: 0.0, to: -offset, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.dismiss?()
|
||||
completion?()
|
||||
}
|
||||
self.wrappingScrollNode.layer.animateBoundsOriginYAdditive(from: 0.0, to: -offset, duration: 0.3, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, completion: { _ in
|
||||
completion?()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1421,7 +1436,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
|
||||
let bottomInset: CGFloat = 10.0 + cleanInsets.bottom
|
||||
let titleHeight: CGFloat = 54.0
|
||||
let contentHeight = titleHeight + bottomInset + 188.0
|
||||
let contentHeight = titleHeight + bottomInset + 188.0 + 52.0
|
||||
|
||||
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
|
||||
|
||||
@@ -1459,9 +1474,12 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, ASScrollViewDeleg
|
||||
transition.updateFrame(node: self.cancelButton, frame: cancelFrame)
|
||||
|
||||
let buttonInset: CGFloat = 16.0
|
||||
let doneButtonHeight = self.doneButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
||||
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - insets.bottom - 6.0, width: contentFrame.width, height: doneButtonHeight))
|
||||
let scanButtonHeight = self.scanButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
||||
transition.updateFrame(node: self.scanButton, frame: CGRect(x: buttonInset, y: contentHeight - scanButtonHeight - insets.bottom - 6.0, width: contentFrame.width, height: scanButtonHeight))
|
||||
|
||||
let doneButtonHeight = self.doneButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
|
||||
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - scanButtonHeight - 10.0 - insets.bottom - 6.0, width: contentFrame.width, height: doneButtonHeight))
|
||||
|
||||
transition.updateFrame(node: self.contentContainerNode, frame: contentContainerFrame)
|
||||
transition.updateFrame(node: self.topContentContainerNode, frame: contentContainerFrame)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user