223 lines
8.2 KiB
Swift

import Foundation
import UIKit
import Display
import ComponentFlow
import SwiftSignalKit
import TelegramCore
import AccountContext
import BundleIconComponent
import MultilineTextComponent
import ButtonComponent
import LottieComponent
final class PlaceholderComponent: Component {
typealias EnvironmentType = Empty
enum Mode {
case request
case denied
}
let context: AccountContext
let mode: Mode
let action: () -> Void
init(
context: AccountContext,
mode: Mode,
action: @escaping () -> Void
) {
self.context = context
self.mode = mode
self.action = action
}
static func ==(lhs: PlaceholderComponent, rhs: PlaceholderComponent) -> Bool {
if lhs.context !== rhs.context {
return false
}
if lhs.mode != rhs.mode {
return false
}
return true
}
public final class View: UIView {
private let animation = ComponentView<Empty>()
private let title = ComponentView<Empty>()
private let text = ComponentView<Empty>()
private let button = ComponentView<Empty>()
private var component: PlaceholderComponent?
private weak var state: EmptyComponentState?
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor(rgb: 0x1c1c1e)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(component: PlaceholderComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
self.component = component
self.state = state
let sideInset: CGFloat = 36.0
let animationHeight: CGFloat = 120.0
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
let title = presentationData.strings.Story_Camera_AccessPlaceholderTitle
let text = presentationData.strings.Story_Camera_AccessPlaceholderText
let buttonTitle = presentationData.strings.Story_Camera_AccessOpenSettings
let animationSize = self.animation.update(
transition: .immediate,
component: AnyComponent(LottieComponent(
content: LottieComponent.AppBundleContent(name: "Photos")
)),
environment: {},
containerSize: CGSize(width: animationHeight, height: animationHeight)
)
let titleSize = self.title.update(
transition: .immediate,
component: AnyComponent(
MultilineTextComponent(
text: .plain(NSAttributedString(string: title, font: Font.semibold(17.0), textColor: UIColor.white)),
horizontalAlignment: .center,
maximumNumberOfLines: 0
)
),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 3.0, height: availableSize.height)
)
let textSize = self.text.update(
transition: .immediate,
component: AnyComponent(
MultilineTextComponent(
text: .plain(NSAttributedString(string: text, font: Font.regular(15.0), textColor: UIColor(rgb: 0x98989f))),
horizontalAlignment: .center,
maximumNumberOfLines: 0
)
),
environment: {},
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: availableSize.height)
)
let buttonSize = self.button.update(
transition: .immediate,
component: AnyComponent(
ButtonComponent(
background: ButtonComponent.Background(
color: UIColor(rgb: 0x007aff),
foreground: .white,
pressedColor: UIColor(rgb: 0x007aff, alpha: 0.55)
),
content: AnyComponentWithIdentity(
id: buttonTitle,
component: AnyComponent(ButtonTextContentComponent(
text: buttonTitle,
badge: 0,
textColor: .white,
badgeBackground: .clear,
badgeForeground: .clear
))
),
isEnabled: true,
displaysProgress: false,
action: { [weak self] in
if let self {
self.component?.action()
}
}
)
),
environment: {},
containerSize: CGSize(width: 240.0, height: 50.0)
)
let titleSpacing: CGFloat = 12.0
let textSpacing: CGFloat = 14.0
let buttonSpacing: CGFloat = 18.0
let totalHeight = animationSize.height + titleSpacing + titleSize.height + textSpacing + textSize.height + buttonSpacing + buttonSize.height
var originY = floorToScreenPixels((availableSize.height - totalHeight) / 2.0)
let animationFrame = CGRect(
origin: CGPoint(
x: floorToScreenPixels((availableSize.width - animationSize.width) / 2.0),
y: originY
),
size: animationSize
)
if let view = self.animation.view as? LottieComponent.View {
if view.superview == nil {
self.addSubview(view)
Queue.mainQueue().justDispatch {
view.playOnce()
}
}
view.frame = animationFrame
}
originY += animationSize.height + titleSpacing
let titleFrame = CGRect(
origin: CGPoint(
x: floorToScreenPixels((availableSize.width - titleSize.width) / 2.0),
y: originY
),
size: titleSize
)
if let view = self.title.view {
if view.superview == nil {
self.addSubview(view)
}
view.frame = titleFrame
}
originY += titleSize.height + textSpacing
let textFrame = CGRect(
origin: CGPoint(
x: floorToScreenPixels((availableSize.width - textSize.width) / 2.0),
y: originY
),
size: textSize
)
if let view = self.text.view {
if view.superview == nil {
self.addSubview(view)
}
view.frame = textFrame
}
originY += textSize.height + buttonSpacing
let buttonFrame = CGRect(
origin: CGPoint(
x: floorToScreenPixels((availableSize.width - buttonSize.width) / 2.0),
y: originY
),
size: buttonSize
)
if let view = self.button.view {
if view.superview == nil {
self.addSubview(view)
}
view.frame = buttonFrame
}
return availableSize
}
}
func makeView() -> View {
return View()
}
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
}
}