Newer
Older
import UIKit
import Theme
import Shared
import Combine
import DependencyInjection
import ScrollViewController
public final class SettingsController: UIViewController {
@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
title: Localized.Settings.InfoDrawer.Biometrics.title,
subtitle: Localized.Settings.InfoDrawer.Biometrics.subtitle
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) }
customView: UIStackView(arrangedSubviews: [menuButton, titleLabel])
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
)
}
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)
.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),
guard let url = URL(string: "https://elixxir.io/privategrity-corporation-privacy-policy/") else { return }
UIApplication.shared.open(url, options: [:])
}
}.store(in: &cancellables)
.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),
guard let url = URL(string: "https://elixxir.io/privategrity-corporation-terms-of-use/") else { return }
UIApplication.shared.open(url, options: [:])
}
}.store(in: &cancellables)
.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)
.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)
}
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
),
font: Fonts.Mulish.semiBold.font(size: 14.0),
text: subtitle,
color: Asset.neutralWeak.color,
lineHeightMultiple: 1.35,
spacingAfter: 25
),
)
])
actionButton.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink {
drawer.dismiss(animated: true) { [weak self] in
cancelButton.publisher(for: .touchUpInside)
.receive(on: DispatchQueue.main)
.sink {
drawer.dismiss(animated: true) { [weak self] in
self?.drawerCancellables.removeAll()
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
),
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
coordinator.toDrawer(drawer, from: self)