MongoView/MongoView/Windows/DatabaseWindowController.swift

156 lines
5.0 KiB
Swift

//
// DatabaseWindowController.swift
// MongoView
//
// Created by Shadowfacts on 1/9/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import Cocoa
import Combine
class DatabaseWindowController: NSWindowController {
@IBOutlet weak var toolbar: NSToolbar!
weak var statusView: WindowStatusView?
private var titleObservation: NSKeyValueObservation?
var mongoController: MongoController!
var initialCollection: DatabaseCollection?
private var databaseViewController: DatabaseViewController!
private var statusChangeHandler: Cancellable?
private var connectionStatusChangeHandler: Cancellable?
convenience init() {
self.init(windowNibName: "DatabaseWindowController")
}
override func windowDidLoad() {
super.windowDidLoad()
let setupMongo = mongoController == nil
if setupMongo {
mongoController = MongoController(connectionString: "mongodb://localhost:27017")
}
statusChangeHandler = mongoController.$statusManager
.receive(on: DispatchQueue.main)
.sink { self.updateStatusText(manager: $0) }
connectionStatusChangeHandler = mongoController.$status
.receive(on: DispatchQueue.main)
.filter { $0 == .connected }
.sink { (_) in self.initializeUI() }
if setupMongo {
mongoController.setup()
}
titleObservation = observe(\.contentViewController?.title) { [unowned self] (_, _) in
self.updateWindowTitle()
}
updateWindowTitle()
window!.tabbingMode = .preferred
window!.tabbingIdentifier = mongoController.connectionString
window!.titleVisibility = .hidden
}
override func newWindowForTab(_ sender: Any?) {
(NSApplication.shared.delegate as! AppDelegate).newWindow(mongoController: mongoController)
}
private func updateWindowTitle() {
window?.title = databaseViewController?.title ?? "MongoView"
}
private func updateStatusText(manager: StatusManager) {
guard let statusView = self.statusView,
let mostRelevant = manager.mostRelevant else { return }
let dayComparisonResult = Calendar.current.compare(mostRelevant.timestamp, to: Date(), toGranularity: .day)
let formatter = DateFormatter()
if dayComparisonResult == .orderedSame {
formatter.dateStyle = .none
} else {
formatter.dateStyle = .short
}
formatter.timeStyle = .medium
let timestamp = formatter.string(from: mostRelevant.timestamp)
let string = "\(mostRelevant.message) | \(timestamp)"
statusView.setText(string)
}
private func initializeUI() {
databaseViewController = DatabaseViewController(mongoController: mongoController)
contentViewController = databaseViewController
if let initialCollection = initialCollection {
databaseViewController.showCollection(initialCollection)
}
}
}
extension NSToolbarItem.Identifier {
static let mongoStatus = NSToolbarItem.Identifier("MongoView.mongoStatus")
static let refresh = NSToolbarItem.Identifier("MongoView.refresh")
}
extension DatabaseWindowController: NSToolbarDelegate {
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
.space,
.flexibleSpace,
.mongoStatus,
.refresh,
]
}
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
.refresh,
.flexibleSpace,
.mongoStatus,
.flexibleSpace,
]
}
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
if itemIdentifier == .mongoStatus {
return createMongoStatusToolbarItem()
} else if itemIdentifier == .refresh {
return createRefreshToolbarItem()
}
return NSToolbarItem(itemIdentifier: itemIdentifier)
}
func createMongoStatusToolbarItem() -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: .mongoStatus)
item.label = "Status"
item.paletteLabel = "Status"
let statusView = WindowStatusView.create()
self.statusView = statusView
item.view = statusView
return item
}
func createRefreshToolbarItem() -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: .refresh)
item.label = "Refresh"
item.paletteLabel = "Refresh"
item.target = self
let button = NSButton(image: NSImage(named: NSImage.refreshTemplateName)!, target: nil, action: #selector(DatabaseViewController.refresh(_:)))
button.bezelStyle = .texturedRounded
item.view = button
return item
}
}