Bark/Controller/HomeViewModel.swift
2021-06-16 17:13:12 +08:00

197 lines
7.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HomeViewModel.swift
// Bark
//
// Created by huangfeng on 2020/11/18.
// Copyright © 2020 Fin. All rights reserved.
//
import Foundation
import RxSwift
import RxCocoa
import RxDataSources
import SwiftyJSON
import UserNotifications
class HomeViewModel: ViewModel, ViewModelType {
struct Input {
let addCustomServerTap: Driver<Void>
let viewDidAppear: Driver<Void>
let start: Driver<Void>
let clientState: Driver<Client.ClienState>
}
struct Output {
let previews: Driver<[SectionModel<String,PreviewCardCellViewModel>]>
let push: Driver<ViewModel>
let title: Driver<String>
let clienStateChanged: Driver<Client.ClienState>
let tableViewHidden: Driver<Bool>
let showSnackbar: Driver<String>
let startButtonEnable: Driver<Bool>
let copy: Driver<String>
let preview: Driver<URL>
let reloadData: Driver<Void>
let registerForRemoteNotifications: Driver<Void>
}
let previews:[PreviewModel] = {
return [
PreviewModel(
body: NSLocalizedString("CustomedNotificationContent"),
notice: NSLocalizedString("Notice1")),
PreviewModel(
title: NSLocalizedString("CustomedNotificationTitle"),
body: NSLocalizedString("CustomedNotificationContent"),
notice: NSLocalizedString("Notice2")),
PreviewModel(
body: NSLocalizedString("notificationSound"),
notice: NSLocalizedString("setSounds"),
queryParameter: "sound=minuet",
moreInfo:NSLocalizedString("viewAllSounds"),
moreViewModel: SoundsViewModel()
),
PreviewModel(
body: NSLocalizedString("archiveNotificationMessageTitle"),
notice: NSLocalizedString("archiveNotificationMessage"),
queryParameter: "isArchive=1"
),
PreviewModel(
body: NSLocalizedString("messageGroup"),
notice: NSLocalizedString("groupMessagesNotice"),
queryParameter: "group=groupName"
),
PreviewModel(
body: "URL Test",
notice: NSLocalizedString("urlParameter"),
queryParameter: "url=https://www.baidu.com"
),
PreviewModel(
body: "Copy Test",
notice: NSLocalizedString("copyParameter"),
queryParameter: "copy=test",
image: UIImage(named: "copyTest")
),
PreviewModel(
body: NSLocalizedString("automaticallyCopyTitle"),
notice: NSLocalizedString("automaticallyCopy"),
queryParameter: "autoCopy=1&copy=optional"
)
]
}()
func transform(input: Input) -> Output {
let title = BehaviorRelay(value: URL(string: ServerManager.shared.currentAddress)?.host ?? "")
let sectionModel = SectionModel(
model: "previews",
items: previews.map { PreviewCardCellViewModel(previewModel: $0, clientState: input.clientState) })
//
let customServer = input.addCustomServerTap.map{ NewServerViewModel() as ViewModel }
// title
customServer
.flatMapLatest({ (model) -> Driver<String> in
return (model as! NewServerViewModel).pop.asDriver(onErrorJustReturn: "")
})
.drive(title)
.disposed(by: rx.disposeBag)
//previewnotice
let noticeTap = Driver.merge(sectionModel.items.map{ $0.noticeTap.asDriver(onErrorDriveWith: .empty()) })
//
let clienState = input.viewDidAppear
.asObservable().flatMapLatest { _ -> Observable<Result<JSON,ApiError>> in
BarkApi.provider
.request(.ping(baseURL: ServerManager.shared.currentAddress))
.filterResponseError()
}
.map { (response) -> Client.ClienState in
switch response {
case .failure:
return .serverError
default:
return .ok
}
}
//APP
let authorizationStatus = Single<UNAuthorizationStatus>.create { (single) -> Disposable in
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
single(.success(settings.authorizationStatus))
}
return Disposables.create()
}
.map { $0 == .authorized}
//
let startRequestAuthorization = Single<Bool>.create { (single) -> Disposable in
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert , .sound , .badge], completionHandler: {(_ granted: Bool, _ error: Error?) -> Void in
single(.success(granted))
})
return Disposables.create()
}
.asObservable()
//
let tableViewHidden = authorizationStatus
.asObservable()
.concat(input.start
.asObservable()
.flatMapLatest{ startRequestAuthorization })
.asDriver(onErrorJustReturn: false)
let showSnackbar = PublishRelay<String>()
//
tableViewHidden
.skip(1)
.compactMap { (granted) -> String? in
if !granted {
return NSLocalizedString("AllowNotifications")
}
return nil
}
.asObservable()
.bind(to: showSnackbar)
.disposed(by: rx.disposeBag)
// viewController
let registerForRemoteNotifications = tableViewHidden
.skip(1)
.filter{ $0 }
.map{ _ in () }
//client state
input.clientState.drive(onNext: { state in
switch state {
case .ok: break;
case .serverError:
showSnackbar.accept(NSLocalizedString("ServerError"))
default: break;
}
})
.disposed(by: rx.disposeBag)
return Output(
previews:Driver.just([sectionModel]),
push: Driver<ViewModel>.merge(customServer,noticeTap),
title: title.asDriver(),
clienStateChanged: clienState.asDriver(onErrorDriveWith: .empty()),
tableViewHidden: tableViewHidden,
showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()),
startButtonEnable: Driver.just(true),
copy: Driver.merge(sectionModel.items.map{ $0.copy.asDriver(onErrorDriveWith: .empty()) }),
preview: Driver.merge(sectionModel.items.map{ $0.preview.asDriver(onErrorDriveWith: .empty()) }),
reloadData: input.clientState.map{ _ in ()},
registerForRemoteNotifications: registerForRemoteNotifications
)
}
}