Bark/Controller/ServerListViewModel.swift

177 lines
6.2 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.

//
// ServerListViewModel.swift
// Bark
//
// Created by huangfeng on 2022/3/25.
// Copyright © 2022 Fin. All rights reserved.
//
import Differentiator
import Foundation
import Moya
import RxCocoa
import RxSwift
import SwiftyJSON
class ServerListViewModel: ViewModel, ViewModelType {
struct Input {
let selectServer: Driver<Server>
let copyServer: Driver<Server>
let deleteServer: Driver<Server>
let resetServer: Driver<(Server, String?)>
}
struct Output {
let servers: Driver<[SectionModel<String, ServerListTableViewCellViewModel>]>
let showSnackbar: Driver<String>
let copy: Driver<String>
}
let currentServerChanged = PublishRelay<Server>()
func transform(input: Input) -> Output {
//
let showSnackbar = PublishRelay<String>()
// Server
let copy = input.copyServer.map { server -> String in
"\(server.address)/\(server.key)/"
}
//
let deleteCheck = input.deleteServer.map { server -> Server? in
if ServerManager.shared.servers.count > 1 {
return server
}
return nil
}.asObservable().share()
//
deleteCheck.filter { $0 == nil }
.map { _ in NSLocalizedString("deleteFailed") }
.bind(to: showSnackbar)
.disposed(by: rx.disposeBag)
// deviceToken
let delete = deleteCheck.compactMap { $0 }
.flatMapLatest { server -> Observable<Result<JSON, ApiError>>in
if server.key.count > 0 {
return BarkApi.provider
.request(.register(address: server.address, key: server.key, devicetoken: "deleted"))
.filterResponseError()
}
return Observable.just(Result<JSON, ApiError>.success(JSON()))
.delay(.milliseconds(300), scheduler: MainScheduler.instance)
}
//
// withLatestFrom delete ,
// input.deleteServer server
let serverDeleted = delete.withLatestFrom(input.deleteServer)
.map { server in
ServerManager.shared.removeServer(server: server)
}.share()
//
serverDeleted.map { NSLocalizedString("deletedSuccessfully") }
.bind(to: showSnackbar)
.disposed(by: rx.disposeBag)
// DeviceToken
let resetServer = input.resetServer
.map { ($0.0, $0.1, Client.shared.deviceToken.value) }
.asObservable().share()
//
resetServer.filter { ($0.2?.count ?? 0) <= 0 }
.map { _ in NSLocalizedString("resetFailed2") }
.bind(to: showSnackbar)
.disposed(by: rx.disposeBag)
// key deviceToken, 使
resetServer.filter { ($0.2?.count ?? 0) > 0 && $0.0.key.count > 0 }.flatMapLatest {
BarkApi.provider
.request(.register(address: $0.0.address, key: $0.0.key, devicetoken: "deleted"))
.filterResponseError()
}
.subscribe()
.disposed(by: rx.disposeBag)
//
let serverReseted = resetServer.filter { ($0.2?.count ?? 0) > 0 }
.flatMapLatest { r -> Observable<Result<JSON, ApiError>> in
let server = r.0
let newKey = r.1
let deviceToken = r.2!
return BarkApi.provider
.request(.register(address: server.address, key: newKey, devicetoken: deviceToken))
.filterResponseError()
}
.map { result -> String? in
switch result {
case .success(let json):
return json["data", "key"].rawString()
case .failure:
return nil
}
}.share()
//
let serverResetSuccess = serverReseted.compactMap { $0 }.withLatestFrom(input.resetServer) { newKey, r in
let server = r.0
server.key = newKey
ServerManager.shared.updateServerKey(server: server)
}.share()
//
serverReseted.filter { $0 == nil }
.map { _ in NSLocalizedString("resetFailed") }
.bind(to: showSnackbar)
.disposed(by: rx.disposeBag)
//
let servers = Observable
.merge(
Observable.just(()),
serverDeleted,
serverResetSuccess
)
.map {
[SectionModel(
model: "servers",
items: ServerManager.shared.servers.map { ServerListTableViewCellViewModel(server: $0) }
)]
}.asDriver(onErrorDriveWith: .empty())
//
let serverSelected = input.selectServer.asObservable().map { server in
ServerManager.shared.setCurrentServer(serverId: server.id)
showSnackbar.accept(NSLocalizedString("setSuccessfully"))
return ()
}
//
let serverChanged = Observable.merge(serverSelected, serverDeleted, serverResetSuccess)
.share()
serverChanged.map {
ServerManager.shared.currentServer
}
.bind(to: self.currentServerChanged)
.disposed(by: rx.disposeBag)
// Client.shared.state
serverChanged.map {
ServerManager.shared.currentServer.state
}
.bind(to: Client.shared.state)
.disposed(by: rx.disposeBag)
return Output(
servers: servers,
showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()),
copy: copy
)
}
}