HomeViewController.swift 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //
  2. // ViewController.swift
  3. // Bark
  4. //
  5. // Created by huangfeng on 2018/3/7.
  6. // Copyright © 2018年 Fin. All rights reserved.
  7. //
  8. import Material
  9. import RxCocoa
  10. import RxDataSources
  11. import RxSwift
  12. import UIKit
  13. import UserNotifications
  14. class HomeViewController: BaseViewController<HomeViewModel> {
  15. let newButton: BKButton = {
  16. let btn = BKButton()
  17. btn.setImage(Icon.add, for: .normal)
  18. btn.imageView?.tintColor = BKColor.grey.darken4
  19. btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
  20. return btn
  21. }()
  22. let serversButton: BKButton = {
  23. let btn = BKButton()
  24. btn.setImage(UIImage(named: "baseline_filter_drama_black_24pt"), for: .normal)
  25. btn.imageView?.tintColor = BKColor.grey.darken4
  26. btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
  27. return btn
  28. }()
  29. let startButton: FABButton = {
  30. let button = FABButton(title: NSLocalizedString("RegisterDevice"))
  31. button.backgroundColor = BKColor.grey.lighten5
  32. button.transition([.scale(0.75), .opacity(0)])
  33. return button
  34. }()
  35. let tableView: UITableView = {
  36. let tableView = UITableView()
  37. tableView.separatorStyle = .none
  38. tableView.backgroundColor = BKColor.background.primary
  39. tableView.register(PreviewCardCell.self, forCellReuseIdentifier: "\(PreviewCardCell.self)")
  40. tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
  41. return tableView
  42. }()
  43. override func makeUI() {
  44. self.view.backgroundColor = BKColor.background.primary
  45. navigationItem.setBarButtonItems(items: [
  46. UIBarButtonItem(customView: newButton),
  47. UIBarButtonItem(customView: serversButton),
  48. ], position: .right)
  49. self.view.addSubview(self.tableView)
  50. self.tableView.snp.makeConstraints { make in
  51. make.top.right.bottom.left.equalToSuperview()
  52. }
  53. self.view.addSubview(self.startButton)
  54. self.startButton.snp.makeConstraints { make in
  55. make.width.height.equalTo(150)
  56. make.centerX.equalToSuperview()
  57. make.centerY.equalToSuperview().offset(-50)
  58. }
  59. Client.shared.currentTabBarController?
  60. .tabBarItemDidClick
  61. .filter { $0 == .service }
  62. .subscribe(onNext: { [weak self] _ in
  63. self?.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
  64. }).disposed(by: self.rx.disposeBag)
  65. }
  66. override func bindViewModel() {
  67. // 第一次进入APP 查看通知权限设置
  68. let authorizationStatus = Single<UNAuthorizationStatus>.create { single -> Disposable in
  69. UNUserNotificationCenter.current().getNotificationSettings { settings in
  70. single(.success(settings.authorizationStatus))
  71. }
  72. return Disposables.create()
  73. }
  74. // 请求通知权限操作
  75. let startRequestAuthorization: () -> Observable<Bool> = {
  76. Single<Bool>.create { single -> Disposable in
  77. let center = UNUserNotificationCenter.current()
  78. center.requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { (_ granted: Bool, _: Error?) -> Void in
  79. single(.success(granted))
  80. })
  81. return Disposables.create()
  82. }
  83. .asObservable()
  84. }
  85. let output = viewModel.transform(
  86. input: HomeViewModel.Input(
  87. addCustomServerTap: newButton.rx.tap.asDriver(),
  88. serverListTap: serversButton.rx.tap.asDriver(),
  89. viewDidAppear: self.rx.methodInvoked(#selector(viewDidAppear(_:)))
  90. .map { _ in () }
  91. .asDriver(onErrorDriveWith: .empty()),
  92. start: self.startButton.rx.tap.asDriver(),
  93. clientState: Client.shared.state.asDriver(),
  94. authorizationStatus: authorizationStatus,
  95. startRequestAuthorizationCreator: startRequestAuthorization
  96. )
  97. )
  98. let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, PreviewCardCellViewModel>> { _, tableView, _, item -> UITableViewCell in
  99. if let cell = tableView.dequeueReusableCell(withIdentifier: "\(PreviewCardCell.self)") as? PreviewCardCell {
  100. cell.bindViewModel(model: item)
  101. return cell
  102. }
  103. return UITableViewCell()
  104. }
  105. // 标题
  106. output.title
  107. .drive(self.navigationItem.rx.title)
  108. .disposed(by: rx.disposeBag)
  109. // TableView数据源
  110. output.previews
  111. .drive(self.tableView.rx.items(dataSource: dataSource))
  112. .disposed(by: rx.disposeBag)
  113. // 跳转到对应页面
  114. output.push
  115. .drive(onNext: { [weak self] viewModel in
  116. self?.pushViewModel(viewModel: viewModel)
  117. })
  118. .disposed(by: rx.disposeBag)
  119. output.present
  120. .drive(onNext: { [weak self] viewModel in
  121. self?.presentViewModel(viewModel: viewModel)
  122. })
  123. .disposed(by: rx.disposeBag)
  124. // 通过ping服务器,判断 clienState
  125. output.clienStateChanged
  126. .drive(Client.shared.state)
  127. .disposed(by: rx.disposeBag)
  128. // 根据通知权限,设置是否隐藏注册按钮、显示示例预览列表
  129. output.tableViewHidden
  130. .map { !$0 }
  131. .drive(self.tableView.rx.isHidden)
  132. .disposed(by: rx.disposeBag)
  133. output.tableViewHidden
  134. .drive(self.startButton.rx.isHidden)
  135. .disposed(by: rx.disposeBag)
  136. // 注册推送
  137. output.registerForRemoteNotifications.drive(onNext: {
  138. UIApplication.shared.registerForRemoteNotifications()
  139. })
  140. .disposed(by: rx.disposeBag)
  141. // 弹出提示
  142. output.showSnackbar
  143. .drive(onNext: { [weak self] text in
  144. self?.showSnackbar(text: text)
  145. })
  146. .disposed(by: rx.disposeBag)
  147. // startButton是否可点击
  148. output.startButtonEnable
  149. .drive(self.startButton.rx.isEnabled)
  150. .disposed(by: rx.disposeBag)
  151. // 复制文本
  152. output.copy
  153. .drive(onNext: { [weak self] text in
  154. UIPasteboard.general.string = text
  155. self?.showSnackbar(text: NSLocalizedString("Copy"))
  156. })
  157. .disposed(by: rx.disposeBag)
  158. // 预览
  159. output.preview
  160. .drive(onNext: { url in
  161. UIApplication.shared.open(url, options: [:], completionHandler: nil)
  162. })
  163. .disposed(by: rx.disposeBag)
  164. // 原样刷新 TableView
  165. output.reloadData
  166. .drive(onNext: { [weak self] in
  167. self?.tableView.reloadData()
  168. })
  169. .disposed(by: rx.disposeBag)
  170. }
  171. func pushViewModel(viewModel: ViewModel) {
  172. var viewController: UIViewController?
  173. if let viewModel = viewModel as? NewServerViewModel {
  174. viewController = NewServerViewController(viewModel: viewModel)
  175. }
  176. else if let viewModel = viewModel as? SoundsViewModel {
  177. viewController = SoundsViewController(viewModel: viewModel)
  178. }
  179. else if let viewModel = viewModel as? CryptoSettingViewModel {
  180. self.navigationController?.present(BarkNavigationController(rootViewController: CryptoSettingController(viewModel: viewModel)), animated: true)
  181. return
  182. }
  183. if let viewController = viewController {
  184. self.navigationController?.pushViewController(viewController, animated: true)
  185. }
  186. }
  187. func presentViewModel(viewModel: ViewModel) {
  188. if let viewModel = viewModel as? ServerListViewModel {
  189. let controller = BarkSnackbarController(
  190. rootViewController: BarkNavigationController(
  191. rootViewController: ServerListViewController(viewModel: viewModel)))
  192. self.navigationController?.present(controller, animated: true, completion: nil)
  193. }
  194. }
  195. }