/* Copyright 2021-2024 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ import UIKit final class TemplateScreenViewController: UIViewController { // MARK: - Constants private enum Constants { static let aConstant: Int = 666 } // MARK: - Properties // MARK: Outlets @IBOutlet private weak var scrollView: UIScrollView! @IBOutlet private weak var informationLabel: UILabel! @IBOutlet private weak var doneButton: UIButton! // MARK: Private private var viewModel: TemplateScreenViewModelProtocol! private var theme: Theme! private var keyboardAvoider: KeyboardAvoider? private var errorPresenter: MXKErrorPresentation! private var activityPresenter: ActivityIndicatorPresenter! // MARK: - Setup class func instantiate(with viewModel: TemplateScreenViewModelProtocol) -> TemplateScreenViewController { let viewController = StoryboardScene.TemplateScreenViewController.initialScene.instantiate() viewController.viewModel = viewModel viewController.theme = ThemeService.shared().theme return viewController } // MARK: - Life cycle override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.setupViews() self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView) self.activityPresenter = ActivityIndicatorPresenter() self.errorPresenter = MXKErrorAlertPresentation() self.registerThemeServiceDidChangeThemeNotification() self.update(theme: self.theme) self.viewModel.viewDelegate = self self.viewModel.process(viewAction: .loadData) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.keyboardAvoider?.startAvoiding() } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.keyboardAvoider?.stopAvoiding() } override var preferredStatusBarStyle: UIStatusBarStyle { return self.theme.statusBarStyle } // MARK: - Private private func update(theme: Theme) { self.theme = theme self.view.backgroundColor = theme.headerBackgroundColor if let navigationBar = self.navigationController?.navigationBar { theme.applyStyle(onNavigationBar: navigationBar) } // TODO: Set view colors here self.informationLabel.textColor = theme.textPrimaryColor self.doneButton.backgroundColor = theme.backgroundColor theme.applyStyle(onButton: self.doneButton) } private func registerThemeServiceDidChangeThemeNotification() { NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil) } @objc private func themeDidChange() { self.update(theme: ThemeService.shared().theme) } private func setupViews() { let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in self?.cancelButtonAction() } self.navigationItem.rightBarButtonItem = cancelBarButtonItem self.title = "Template" self.scrollView.keyboardDismissMode = .interactive self.informationLabel.text = "VectorL10n.templateScreenTitle" } private func render(viewState: TemplateScreenViewState) { switch viewState { case .idle: break case .loading: self.renderLoading() case .loaded(let displayName): self.renderLoaded(displayName: displayName) case .error(let error): self.render(error: error) } } private func renderLoading() { self.activityPresenter.presentActivityIndicator(on: self.view, animated: true) self.informationLabel.text = "Fetch display name" } private func renderLoaded(displayName: String) { self.activityPresenter.removeCurrentActivityIndicator(animated: true) self.informationLabel.text = "You display name: \(displayName)" } private func render(error: Error) { self.activityPresenter.removeCurrentActivityIndicator(animated: true) self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil) } // MARK: - Actions @IBAction private func doneButtonAction(_ sender: Any) { self.viewModel.process(viewAction: .complete) } private func cancelButtonAction() { self.viewModel.process(viewAction: .cancel) } } // MARK: - TemplateScreenViewModelViewDelegate extension TemplateScreenViewController: TemplateScreenViewModelViewDelegate { func templateScreenViewModel(_ viewModel: TemplateScreenViewModelProtocol, didUpdateViewState viewSate: TemplateScreenViewState) { self.render(viewState: viewSate) } }