Swiftgram/submodules/WalletUI/Sources/WalletPresentationData.swift

323 lines
12 KiB
Swift

import Foundation
import UIKit
import SwiftSignalKit
import Display
import OverlayStatusController
public enum WalletTimeFormat {
case regular
case military
}
public enum WalletDateFormat {
case monthFirst
case dayFirst
}
public struct WalletPresentationDateTimeFormat: Equatable {
public let timeFormat: WalletTimeFormat
public let dateFormat: WalletDateFormat
public let dateSeparator: String
public let decimalSeparator: String
public let groupingSeparator: String
public init(timeFormat: WalletTimeFormat, dateFormat: WalletDateFormat, dateSeparator: String, decimalSeparator: String, groupingSeparator: String) {
self.timeFormat = timeFormat
self.dateFormat = dateFormat
self.dateSeparator = dateSeparator
self.decimalSeparator = decimalSeparator
self.groupingSeparator = groupingSeparator
}
}
public final class WalletInfoTheme {
public let buttonBackgroundColor: UIColor
public let buttonTextColor: UIColor
public let incomingFundsTitleColor: UIColor
public let outgoingFundsTitleColor: UIColor
public init(
buttonBackgroundColor: UIColor,
buttonTextColor: UIColor,
incomingFundsTitleColor: UIColor,
outgoingFundsTitleColor: UIColor
) {
self.buttonBackgroundColor = buttonBackgroundColor
self.buttonTextColor = buttonTextColor
self.incomingFundsTitleColor = incomingFundsTitleColor
self.outgoingFundsTitleColor = outgoingFundsTitleColor
}
}
public final class WalletTransactionTheme {
public let descriptionBackgroundColor: UIColor
public let descriptionTextColor: UIColor
public init(
descriptionBackgroundColor: UIColor,
descriptionTextColor: UIColor
) {
self.descriptionBackgroundColor = descriptionBackgroundColor
self.descriptionTextColor = descriptionTextColor
}
}
public final class WalletSetupTheme {
public let buttonFillColor: UIColor
public let buttonForegroundColor: UIColor
public let inputBackgroundColor: UIColor
public let inputPlaceholderColor: UIColor
public let inputTextColor: UIColor
public let inputClearButtonColor: UIColor
public init(
buttonFillColor: UIColor,
buttonForegroundColor: UIColor,
inputBackgroundColor: UIColor,
inputPlaceholderColor: UIColor,
inputTextColor: UIColor,
inputClearButtonColor: UIColor
) {
self.buttonFillColor = buttonFillColor
self.buttonForegroundColor = buttonForegroundColor
self.inputBackgroundColor = inputBackgroundColor
self.inputPlaceholderColor = inputPlaceholderColor
self.inputTextColor = inputTextColor
self.inputClearButtonColor = inputClearButtonColor
}
}
public final class WalletListTheme {
public let itemPrimaryTextColor: UIColor
public let itemSecondaryTextColor: UIColor
public let itemPlaceholderTextColor: UIColor
public let itemDestructiveColor: UIColor
public let itemAccentColor: UIColor
public let itemDisabledTextColor: UIColor
public let plainBackgroundColor: UIColor
public let blocksBackgroundColor: UIColor
public let itemPlainSeparatorColor: UIColor
public let itemBlocksBackgroundColor: UIColor
public let itemBlocksSeparatorColor: UIColor
public let itemHighlightedBackgroundColor: UIColor
public let sectionHeaderTextColor: UIColor
public let freeTextColor: UIColor
public let freeTextErrorColor: UIColor
public let inputClearButtonColor: UIColor
public init(
itemPrimaryTextColor: UIColor,
itemSecondaryTextColor: UIColor,
itemPlaceholderTextColor: UIColor,
itemDestructiveColor: UIColor,
itemAccentColor: UIColor,
itemDisabledTextColor: UIColor,
plainBackgroundColor: UIColor,
blocksBackgroundColor: UIColor,
itemPlainSeparatorColor: UIColor,
itemBlocksBackgroundColor: UIColor,
itemBlocksSeparatorColor: UIColor,
itemHighlightedBackgroundColor: UIColor,
sectionHeaderTextColor: UIColor,
freeTextColor: UIColor,
freeTextErrorColor: UIColor,
inputClearButtonColor: UIColor
) {
self.itemPrimaryTextColor = itemPrimaryTextColor
self.itemSecondaryTextColor = itemSecondaryTextColor
self.itemPlaceholderTextColor = itemPlaceholderTextColor
self.itemDestructiveColor = itemDestructiveColor
self.itemAccentColor = itemAccentColor
self.itemDisabledTextColor = itemDisabledTextColor
self.plainBackgroundColor = plainBackgroundColor
self.blocksBackgroundColor = blocksBackgroundColor
self.itemPlainSeparatorColor = itemPlainSeparatorColor
self.itemBlocksBackgroundColor = itemBlocksBackgroundColor
self.itemBlocksSeparatorColor = itemBlocksSeparatorColor
self.itemHighlightedBackgroundColor = itemHighlightedBackgroundColor
self.sectionHeaderTextColor = sectionHeaderTextColor
self.freeTextColor = freeTextColor
self.freeTextErrorColor = freeTextErrorColor
self.inputClearButtonColor = inputClearButtonColor
}
}
public final class WalletTheme: Equatable {
public let info: WalletInfoTheme
public let transaction: WalletTransactionTheme
public let setup: WalletSetupTheme
public let list: WalletListTheme
public let statusBarStyle: StatusBarStyle
public let navigationBar: NavigationBarTheme
public let keyboardAppearance: UIKeyboardAppearance
public let alert: AlertControllerTheme
public let actionSheet: ActionSheetControllerTheme
private let resourceCache = WalletThemeResourceCache()
public init(info: WalletInfoTheme, transaction: WalletTransactionTheme, setup: WalletSetupTheme, list: WalletListTheme, statusBarStyle: StatusBarStyle, navigationBar: NavigationBarTheme, keyboardAppearance: UIKeyboardAppearance, alert: AlertControllerTheme, actionSheet: ActionSheetControllerTheme) {
self.info = info
self.transaction = transaction
self.setup = setup
self.list = list
self.statusBarStyle = statusBarStyle
self.navigationBar = navigationBar
self.keyboardAppearance = keyboardAppearance
self.alert = alert
self.actionSheet = actionSheet
}
func image(_ key: Int32, _ generate: (WalletTheme) -> UIImage?) -> UIImage? {
return self.resourceCache.image(key, self, generate)
}
public static func ==(lhs: WalletTheme, rhs: WalletTheme) -> Bool {
return lhs === rhs
}
}
public final class WalletPresentationData {
public let theme: WalletTheme
public let strings: WalletStrings
public let dateTimeFormat: WalletPresentationDateTimeFormat
public init(theme: WalletTheme, strings: WalletStrings, dateTimeFormat: WalletPresentationDateTimeFormat) {
self.theme = theme
self.strings = strings
self.dateTimeFormat = dateTimeFormat
}
}
private final class WalletThemeResourceCacheHolder {
var images: [Int32: UIImage] = [:]
}
private final class WalletThemeResourceCache {
private let imageCache = Atomic<WalletThemeResourceCacheHolder>(value: WalletThemeResourceCacheHolder())
public func image(_ key: Int32, _ theme: WalletTheme, _ generate: (WalletTheme) -> UIImage?) -> UIImage? {
let result = self.imageCache.with { holder -> UIImage? in
return holder.images[key]
}
if let result = result {
return result
} else {
if let image = generate(theme) {
self.imageCache.with { holder -> Void in
holder.images[key] = image
}
return image
} else {
return nil
}
}
}
}
enum WalletThemeResourceKey: Int32 {
case itemListCornersBoth
case itemListCornersTop
case itemListCornersBottom
case itemListClearInputIcon
case navigationShareIcon
case clockMin
case clockFrame
}
func cornersImage(_ theme: WalletTheme, top: Bool, bottom: Bool) -> UIImage? {
if !top && !bottom {
return nil
}
let key: WalletThemeResourceKey
if top && bottom {
key = .itemListCornersBoth
} else if top {
key = .itemListCornersTop
} else {
key = .itemListCornersBottom
}
return theme.image(key.rawValue, { theme in
return generateImage(CGSize(width: 50.0, height: 50.0), rotatedContext: { (size, context) in
let bounds = CGRect(origin: CGPoint(), size: size)
context.setFillColor(theme.list.blocksBackgroundColor.cgColor)
context.fill(bounds)
context.setBlendMode(.clear)
var corners: UIRectCorner = []
if top {
corners.insert(.topLeft)
corners.insert(.topRight)
}
if bottom {
corners.insert(.bottomLeft)
corners.insert(.bottomRight)
}
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: 11.0, height: 11.0))
context.addPath(path.cgPath)
context.fillPath()
})?.stretchableImage(withLeftCapWidth: 25, topCapHeight: 25)
})
}
func itemListClearInputIcon(_ theme: WalletTheme) -> UIImage? {
return theme.image(WalletThemeResourceKey.itemListClearInputIcon.rawValue, { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Wallet/ClearInput"), color: theme.list.inputClearButtonColor)
})
}
func navigationShareIcon(_ theme: WalletTheme) -> UIImage? {
return theme.image(WalletThemeResourceKey.navigationShareIcon.rawValue, { theme in
generateTintedImage(image: UIImage(bundleImageName: "Chat List/NavigationShare"), color: theme.navigationBar.buttonColor)
})
}
func clockFrameImage(_ theme: WalletTheme) -> UIImage? {
return theme.image(WalletThemeResourceKey.clockFrame.rawValue, { theme in
let color = theme.list.itemSecondaryTextColor
return generateImage(CGSize(width: 11.0, height: 11.0), contextGenerator: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setStrokeColor(color.cgColor)
context.setFillColor(color.cgColor)
let strokeWidth: CGFloat = 1.0
context.setLineWidth(strokeWidth)
context.strokeEllipse(in: CGRect(x: strokeWidth / 2.0, y: strokeWidth / 2.0, width: size.width - strokeWidth, height: size.height - strokeWidth))
context.fill(CGRect(x: (11.0 - strokeWidth) / 2.0, y: strokeWidth * 3.0, width: strokeWidth, height: 11.0 / 2.0 - strokeWidth * 3.0))
})
})
}
func clockMinImage(_ theme: WalletTheme) -> UIImage? {
return theme.image(WalletThemeResourceKey.clockMin.rawValue, { theme in
let color = theme.list.itemSecondaryTextColor
return generateImage(CGSize(width: 11.0, height: 11.0), contextGenerator: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(color.cgColor)
let strokeWidth: CGFloat = 1.0
context.fill(CGRect(x: (11.0 - strokeWidth) / 2.0, y: (11.0 - strokeWidth) / 2.0, width: 11.0 / 2.0 - strokeWidth, height: strokeWidth))
})
})
}
func walletStringsFormattedNumber(_ count: Int32, _ groupingSeparator: String = "") -> String {
let string = "\(count)"
if groupingSeparator.isEmpty || abs(count) < 1000 {
return string
} else {
var groupedString: String = ""
for i in 0 ..< Int(ceil(Double(string.count) / 3.0)) {
let index = string.count - Int(i + 1) * 3
if !groupedString.isEmpty {
groupedString = groupingSeparator + groupedString
}
groupedString = String(string[string.index(string.startIndex, offsetBy: max(0, index)) ..< string.index(string.startIndex, offsetBy: index + 3)]) + groupedString
}
return groupedString
}
}
func OverlayStatusController(theme: WalletTheme, type: OverlayStatusControllerType) -> ViewController {
return OverlayStatusController(style: theme.keyboardAppearance == .dark ? .dark : .light, type: type)
}