mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Refactor SettingsUI and related modules
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import Postbox
|
||||
import AsyncDisplayKit
|
||||
import UIKit
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import QrCode
|
||||
|
||||
public final class ShareProxyServerActionSheetController: ActionSheetController {
|
||||
private var presentationDisposable: Disposable?
|
||||
|
||||
private let _ready = Promise<Bool>()
|
||||
override public var ready: Promise<Bool> {
|
||||
return self._ready
|
||||
}
|
||||
|
||||
private var isDismissed: Bool = false
|
||||
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings, updatedPresentationData: Signal<(theme: PresentationTheme, strings: PresentationStrings), NoError>, link: String) {
|
||||
let sheetTheme = ActionSheetControllerTheme(presentationTheme: theme)
|
||||
super.init(theme: sheetTheme)
|
||||
|
||||
let presentActivityController: (Any) -> Void = { [weak self] item in
|
||||
let activityController = UIActivityViewController(activityItems: [item], applicationActivities: nil)
|
||||
if let window = self?.view.window, let rootViewController = window.rootViewController {
|
||||
activityController.popoverPresentationController?.sourceView = window
|
||||
activityController.popoverPresentationController?.sourceRect = CGRect(origin: CGPoint(x: window.bounds.width / 2.0, y: window.bounds.size.height - 1.0), size: CGSize(width: 1.0, height: 1.0))
|
||||
rootViewController.present(activityController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ProxyServerQRCodeItem(strings: strings, link: link, ready: { [weak self] in
|
||||
self?._ready.set(.single(true))
|
||||
}))
|
||||
items.append(ActionSheetButtonItem(title: strings.SocksProxySetup_ShareQRCode, action: { [weak self] in
|
||||
self?.dismissAnimated()
|
||||
let _ = (qrCode(string: link, color: .black, backgroundColor: .white, scale: 1.0)
|
||||
|> map { generator -> UIImage? in
|
||||
let imageSize = CGSize(width: 512.0, height: 512.0)
|
||||
let context = generator(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))
|
||||
return context?.generateImage()
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { image in
|
||||
if let image = image {
|
||||
presentActivityController(image)
|
||||
}
|
||||
})
|
||||
}))
|
||||
items.append(ActionSheetButtonItem(title: strings.SocksProxySetup_ShareLink, action: { [weak self] in
|
||||
self?.dismissAnimated()
|
||||
presentActivityController(link)
|
||||
}))
|
||||
self.setItemGroups([
|
||||
ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: strings.Common_Cancel, action: { [weak self] in
|
||||
self?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
|
||||
self.presentationDisposable = updatedPresentationData.start(next: { [weak self] theme, strings in
|
||||
if let strongSelf = self {
|
||||
strongSelf.theme = ActionSheetControllerTheme(presentationTheme: theme)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.presentationDisposable?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProxyServerQRCodeItem: ActionSheetItem {
|
||||
private let strings: PresentationStrings
|
||||
private let link: String
|
||||
private let ready: () -> Void
|
||||
|
||||
init(strings: PresentationStrings, link: String, ready: @escaping () -> Void = {}) {
|
||||
self.strings = strings
|
||||
self.link = link
|
||||
self.ready = ready
|
||||
}
|
||||
|
||||
func node(theme: ActionSheetControllerTheme) -> ActionSheetItemNode {
|
||||
return ProxyServerQRCodeItemNode(theme: theme, strings: self.strings, link: self.link, ready: self.ready)
|
||||
}
|
||||
|
||||
func updateNode(_ node: ActionSheetItemNode) {
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProxyServerQRCodeItemNode: ActionSheetItemNode {
|
||||
private let theme: ActionSheetControllerTheme
|
||||
private let strings: PresentationStrings
|
||||
private let link: String
|
||||
|
||||
private let label: ASTextNode
|
||||
private let imageNode: TransformImageNode
|
||||
|
||||
private let ready: () -> Void
|
||||
|
||||
private var cachedHasLabel = true
|
||||
private var cachedHasImage = true
|
||||
|
||||
init(theme: ActionSheetControllerTheme, strings: PresentationStrings, link: String, ready: @escaping () -> Void = {}) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.link = link
|
||||
self.ready = ready
|
||||
|
||||
self.label = ASTextNode()
|
||||
self.label.isUserInteractionEnabled = false
|
||||
self.label.maximumNumberOfLines = 0
|
||||
self.label.displaysAsynchronously = false
|
||||
self.label.truncationMode = .byTruncatingTail
|
||||
self.label.isUserInteractionEnabled = false
|
||||
self.label.attributedText = NSAttributedString(string: strings.SocksProxySetup_ShareQRCodeInfo, font: ActionSheetTextNode.defaultFont, textColor: self.theme.secondaryTextColor, paragraphAlignment: .center)
|
||||
|
||||
self.imageNode = TransformImageNode()
|
||||
self.imageNode.setSignal(qrCode(string: link, color: .black, backgroundColor: .white), attemptSynchronously: true)
|
||||
|
||||
super.init(theme: theme)
|
||||
|
||||
self.addSubnode(self.label)
|
||||
self.addSubnode(self.imageNode)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
let imageInset: CGFloat = 44.0
|
||||
let side = constrainedSize.width - imageInset * 2.0
|
||||
var imageSize = CGSize(width: side, height: side)
|
||||
|
||||
let makeLayout = self.imageNode.asyncLayout()
|
||||
let apply = makeLayout(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: nil))
|
||||
apply()
|
||||
|
||||
var labelSize = self.label.measure(CGSize(width: max(1.0, constrainedSize.width - 64.0), height: constrainedSize.height))
|
||||
|
||||
self.cachedHasImage = constrainedSize.width < constrainedSize.height
|
||||
if !self.cachedHasImage {
|
||||
imageSize = CGSize()
|
||||
}
|
||||
|
||||
self.ready()
|
||||
|
||||
self.cachedHasLabel = constrainedSize.height > 480 || !self.cachedHasImage
|
||||
if !self.cachedHasLabel {
|
||||
labelSize = CGSize()
|
||||
}
|
||||
return CGSize(width: constrainedSize.width, height: 14.0 + (labelSize.height > 0.0 ? labelSize.height + 14.0 : 0.0) + (imageSize.height > 0.0 ? imageSize.height + 14.0 : 8.0))
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
let inset: CGFloat = 32.0
|
||||
let imageInset: CGFloat = 44.0
|
||||
let spacing: CGFloat = 18.0
|
||||
|
||||
let labelSize: CGSize
|
||||
if self.cachedHasLabel {
|
||||
labelSize = self.label.measure(CGSize(width: max(1.0, size.width - inset * 2.0), height: size.height))
|
||||
self.label.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - labelSize.width) / 2.0), y: spacing), size: labelSize)
|
||||
} else {
|
||||
labelSize = CGSize()
|
||||
}
|
||||
|
||||
let imageOrigin = CGPoint(x: imageInset, y: self.label.frame.maxY + spacing - 4.0)
|
||||
var imageSize: CGSize
|
||||
if !self.cachedHasImage {
|
||||
imageSize = CGSize()
|
||||
} else {
|
||||
imageSize = CGSize(width: size.width - imageInset * 2.0, height: size.width - imageInset * 2.0)
|
||||
}
|
||||
self.imageNode.frame = CGRect(origin: imageOrigin, size: imageSize)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user