Something went wrong on our end
-
Bruno Muniz authoredBruno Muniz authored
SettingsController.swift 11.04 KiB
import HUD
import DrawerFeature
import UIKit
import Theme
import Shared
import Combine
import DependencyInjection
import ScrollViewController
public final class SettingsController: UIViewController {
@Dependency private var hud: HUD
@Dependency private var coordinator: SettingsCoordinating
@Dependency private var statusBarController: StatusBarStyleControlling
lazy private var scrollViewController = ScrollViewController()
lazy private var screenView = SettingsView {
switch $0 {
case .icognitoKeyboard:
self.presentInfo(
title: Localized.Settings.InfoDrawer.Icognito.title,
subtitle: Localized.Settings.InfoDrawer.Icognito.subtitle
)
case .biometrics:
self.presentInfo(
title: Localized.Settings.InfoDrawer.Biometrics.title,
subtitle: Localized.Settings.InfoDrawer.Biometrics.subtitle
)
case .notifications:
self.presentInfo(
title: Localized.Settings.InfoDrawer.Notifications.title,
subtitle: Localized.Settings.InfoDrawer.Notifications.subtitle,
urlString: "https://links.xx.network/denseids"
)
case .dummyTraffic:
self.presentInfo(
title: Localized.Settings.InfoDrawer.Traffic.title,
subtitle: Localized.Settings.InfoDrawer.Traffic.subtitle,
urlString: "https://links.xx.network/covertraffic"
)
}
}
private let viewModel = SettingsViewModel()
private var cancellables = Set<AnyCancellable>()
private var drawerCancellables = Set<AnyCancellable>()
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
statusBarController.style.send(.darkContent)
navigationController?.navigationBar
.customize(backgroundColor: Asset.neutralWhite.color)
}
public override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
setupScrollView()
setupBindings()
viewModel.loadCachedSettings()
}
private func setupNavigationBar() {
navigationItem.backButtonTitle = ""
let titleLabel = UILabel()
titleLabel.text = Localized.Settings.title
titleLabel.textColor = Asset.neutralActive.color
titleLabel.font = Fonts.Mulish.semiBold.font(size: 18.0)
let menuButton = UIButton()
menuButton.tintColor = Asset.neutralDark.color
menuButton.setImage(Asset.chatListMenu.image, for: .normal)
menuButton.addTarget(self, action: #selector(didTapMenu), for: .touchUpInside)
menuButton.snp.makeConstraints { $0.width.equalTo(50) }
navigationItem.leftBarButtonItem = UIBarButtonItem(
customView: UIStackView(arrangedSubviews: [menuButton, titleLabel])
)
}
private func setupScrollView() {
scrollViewController.view.backgroundColor = Asset.neutralWhite.color
addChild(scrollViewController)
view.addSubview(scrollViewController.view)
scrollViewController.view.snp.makeConstraints { $0.edges.equalToSuperview() }
scrollViewController.didMove(toParent: self)
scrollViewController.contentView = screenView
}
private func setupBindings() {
viewModel.hud
.receive(on: DispatchQueue.main)
.sink { [hud] in hud.update(with: $0) }
.store(in: &cancellables)
screenView.inAppNotifications.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didToggleInAppNotifications() }
.store(in: &cancellables)
screenView.dummyTraffic.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didToggleDummyTraffic() }
.store(in: &cancellables)
screenView.remoteNotifications.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didTogglePushNotifications() }
.store(in: &cancellables)
screenView.hideActiveApp.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didToggleHideActiveApps() }
.store(in: &cancellables)
screenView.icognitoKeyboard.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didToggleIcognitoKeyboard() }
.store(in: &cancellables)
screenView.biometrics.switcherView
.publisher(for: .valueChanged)
.sink { [weak viewModel] in viewModel?.didToggleBiometrics() }
.store(in: &cancellables)
screenView.privacyPolicyButton
.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink { [unowned self] in
presentDrawer(
title: Localized.Settings.Drawer.title(Localized.Settings.privacyPolicy),
subtitle: Localized.Settings.Drawer.subtitle(Localized.Settings.privacyPolicy),
actionTitle: Localized.ChatList.Dashboard.open) {
guard let url = URL(string: "https://xx.network/privategrity-corporation-privacy-policy") else { return }
UIApplication.shared.open(url, options: [:])
}
}.store(in: &cancellables)
screenView.disclosuresButton
.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink { [unowned self] in
presentDrawer(
title: Localized.Settings.Drawer.title(Localized.Settings.disclosures),
subtitle: Localized.Settings.Drawer.subtitle(Localized.Settings.disclosures),
actionTitle: Localized.ChatList.Dashboard.open) {
guard let url = URL(string: "https://xx.network/privategrity-corporation-terms-of-use") else { return }
UIApplication.shared.open(url, options: [:])
}
}.store(in: &cancellables)
screenView.deleteButton
.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink { [unowned self] in coordinator.toDelete(from: self) }
.store(in: &cancellables)
screenView.accountBackupButton
.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink { [unowned self] in coordinator.toBackup(from: self) }
.store(in: &cancellables)
screenView.advancedButton
.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink { [unowned self] in coordinator.toAdvanced(from: self) }
.store(in: &cancellables)
viewModel.state
.map(\.isBiometricsPossible)
.removeDuplicates()
.receive(on: DispatchQueue.main)
.sink { [weak screenView] in screenView?.biometrics.switcherView.isEnabled = $0 }
.store(in: &cancellables)
viewModel.state
.removeDuplicates()
.receive(on: DispatchQueue.main)
.sink { [unowned self] state in
screenView.biometrics.switcherView.setOn(state.isBiometricsEnabled, animated: true)
screenView.hideActiveApp.switcherView.setOn(state.isHideActiveApps, animated: true)
screenView.icognitoKeyboard.switcherView.setOn(state.isIcognitoKeyboard, animated: true)
screenView.inAppNotifications.switcherView.setOn(state.isInAppNotification, animated: true)
screenView.remoteNotifications.switcherView.setOn(state.isPushNotification, animated: true)
screenView.dummyTraffic.switcherView.setOn(state.isDummyTrafficOn, animated: true)
}.store(in: &cancellables)
}
private func presentDrawer(
title: String,
subtitle: String,
actionTitle: String,
action: @escaping () -> Void
) {
let actionButton = CapsuleButton()
actionButton.setStyle(.red)
actionButton.setTitle(actionTitle, for: .normal)
let cancelButton = CapsuleButton()
cancelButton.setStyle(.seeThrough)
cancelButton.setTitle(Localized.ChatList.Dashboard.cancel, for: .normal)
let drawer = DrawerController(with: [
DrawerImage(
image: Asset.drawerNegative.image
),
DrawerText(
font: Fonts.Mulish.semiBold.font(size: 18.0),
text: title,
color: Asset.neutralActive.color
),
DrawerText(
font: Fonts.Mulish.semiBold.font(size: 14.0),
text: subtitle,
color: Asset.neutralWeak.color,
lineHeightMultiple: 1.35,
spacingAfter: 25
),
DrawerStack(
spacing: 20.0,
views: [actionButton, cancelButton]
)
])
actionButton.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink {
drawer.dismiss(animated: true) { [weak self] in
guard let self = self else { return }
self.drawerCancellables.removeAll()
action()
}
}.store(in: &drawerCancellables)
cancelButton.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink {
drawer.dismiss(animated: true) { [weak self] in
self?.drawerCancellables.removeAll()
}
}.store(in: &drawerCancellables)
coordinator.toDrawer(drawer, from: self)
}
@objc private func didTapMenu() {
coordinator.toSideMenu(from: self)
}
}
extension SettingsController {
private func presentInfo(
title: String,
subtitle: String,
urlString: String = ""
) {
let actionButton = CapsuleButton()
actionButton.set(
style: .seeThrough,
title: Localized.Settings.InfoDrawer.action
)
let drawer = DrawerController(with: [
DrawerText(
font: Fonts.Mulish.bold.font(size: 26.0),
text: title,
color: Asset.neutralActive.color,
alignment: .left,
spacingAfter: 19
),
DrawerLinkText(
text: subtitle,
urlString: urlString,
spacingAfter: 37
),
DrawerStack(views: [
actionButton,
FlexibleSpace()
])
])
actionButton.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink {
drawer.dismiss(animated: true) { [weak self] in
guard let self = self else { return }
self.drawerCancellables.removeAll()
}
}.store(in: &drawerCancellables)
coordinator.toDrawer(drawer, from: self)
}
}