1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-03 00:54:42 +03:00
vimr/VimR/UiRoot.swift

79 lines
2.4 KiB
Swift
Raw Normal View History

2017-01-22 16:22:05 +03:00
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Cocoa
import RxSwift
class UiRoot: UiComponent {
2017-01-22 16:22:05 +03:00
typealias StateType = AppState
2017-04-15 11:38:07 +03:00
var hasMainWindows: Bool {
return !self.mainWindows.isEmpty
}
2017-01-25 00:39:19 +03:00
required init(source: Observable<StateType>, emitter: ActionEmitter, state: StateType) {
self.source = source
self.emitter = emitter
2017-02-19 20:00:41 +03:00
self.fileMonitor = FileMonitor(source: source, emitter: emitter, state: state)
2017-02-28 00:45:26 +03:00
self.prefWindow = PrefWindow(source: source, emitter: emitter, state: state)
self.openQuicklyWindow = OpenQuicklyWindow(source: source, emitter: emitter, state: state)
2017-02-19 20:00:41 +03:00
source
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [unowned self] state in
2017-04-15 11:38:07 +03:00
let uuidsInState = Set(state.mainWindows.keys)
2017-01-25 00:39:19 +03:00
uuidsInState
.subtracting(self.mainWindows.keys)
2017-01-22 16:22:05 +03:00
.flatMap { state.mainWindows[$0] }
.forEach(self.createNewMainWindow)
2017-04-15 11:38:07 +03:00
self.mainWindows.keys
.filter { !uuidsInState.contains($0) }
2017-04-01 22:02:31 +03:00
.forEach(self.removeMainWindow)
2017-04-15 11:38:07 +03:00
if state.quitWhenNoMainWindow && self.mainWindows.isEmpty {
NSApp.terminate(self)
}
})
.addDisposableTo(self.disposeBag)
}
2017-02-28 00:45:26 +03:00
fileprivate let source: Observable<AppState>
fileprivate let emitter: ActionEmitter
fileprivate let disposeBag = DisposeBag()
fileprivate let fileMonitor: FileMonitor
fileprivate let prefWindow: PrefWindow
fileprivate let openQuicklyWindow: OpenQuicklyWindow
fileprivate var mainWindows = [String: MainWindow]()
fileprivate var subjectForMainWindows = [String: PublishSubject<MainWindow.State>]()
fileprivate var disposables = [String: Disposable]()
fileprivate func createNewMainWindow(with state: MainWindow.State) {
let subject = PublishSubject<MainWindow.State>()
let source = self.source.mapOmittingNil { $0.mainWindows[state.uuid] }
self.subjectForMainWindows[state.uuid] = subject
self.disposables[state.uuid] = source.subscribe(subject)
let mainWindow = MainWindow(source: subject.asObservable(), emitter: self.emitter, state: state)
self.mainWindows[state.uuid] = mainWindow
mainWindow.show()
}
fileprivate func removeMainWindow(with uuid: String) {
self.subjectForMainWindows[uuid]?.onCompleted()
self.disposables[uuid]?.dispose()
self.subjectForMainWindows.removeValue(forKey: uuid)
self.disposables.removeValue(forKey: uuid)
self.mainWindows.removeValue(forKey: uuid)
}
}