feat: added portal to the Clock module (#1748)

This commit is contained in:
Serhiy Mytrovtsiy
2023-12-30 18:08:41 +01:00
parent 3d214a3571
commit 72e38f426c
4 changed files with 156 additions and 10 deletions

View File

@@ -55,11 +55,12 @@ internal class ClockReader: Reader<Date> {
public class Clock: Module {
private let popupView: Popup = Popup()
private let portalView: Portal
private let settingsView: Settings = Settings()
private var reader: ClockReader = ClockReader(.clock)
private var list: [Clock_t] {
static var list: [Clock_t] {
if let objects = Store.shared.data(key: "\(Clock.title)_list") {
let decoder = JSONDecoder()
if let objectsDecoded = try? decoder.decode(Array.self, from: objects) as [Clock_t] {
@@ -70,9 +71,12 @@ public class Clock: Module {
}
public init() {
self.portalView = Portal("Clock", list: Clock.list)
super.init(
popup: self.popupView,
settings: self.settingsView
settings: self.settingsView,
portal: self.portalView
)
guard self.available else { return }
@@ -88,7 +92,7 @@ public class Clock: Module {
}
private func callback(_ value: Date) {
var clocks: [Clock_t] = self.list
var clocks: [Clock_t] = Clock.list
var widgetList: [Stack_t] = []
for (i, c) in clocks.enumerated() {
@@ -100,6 +104,7 @@ public class Clock: Module {
DispatchQueue.main.async(execute: {
self.popupView.callback(clocks)
self.portalView.callback(clocks)
})
self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in

125
Modules/Clock/portal.swift Normal file
View File

@@ -0,0 +1,125 @@
//
// portal.swift
// Clock
//
// Created by Serhiy Mytrovtsiy on 28/12/2023
// Using Swift 5.0
// Running on macOS 14.2
//
// Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved.
//
import AppKit
import Kit
public class Portal: NSStackView, Portal_p {
public var name: String
private var initialized: Bool = false
private var oneContainer: NSGridView = NSGridView()
private var multiplyContainer: ScrollableStackView = ScrollableStackView(orientation: .horizontal)
init(_ name: String, list: [Clock_t]) {
self.name = name
super.init(frame: NSRect.zero)
self.wantsLayer = true
self.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor
self.layer?.cornerRadius = 3
self.orientation = .vertical
self.distribution = .fillEqually
self.spacing = Constants.Popup.spacing*2
self.edgeInsets = NSEdgeInsets(
top: Constants.Popup.spacing*2,
left: Constants.Popup.spacing*2,
bottom: Constants.Popup.spacing*2,
right: Constants.Popup.spacing*2
)
self.addArrangedSubview(PortalHeader(name))
self.oneContainer.rowSpacing = 0
self.oneContainer.yPlacement = .center
self.oneContainer.xPlacement = .center
self.addArrangedSubview(self.oneContainer)
self.addArrangedSubview(self.multiplyContainer)
self.callback(list)
self.heightAnchor.constraint(equalToConstant: Constants.Popup.portalHeight).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func updateLayer() {
self.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor
}
public func callback(_ list: [Clock_t]) {
let list = list.filter({ $0.popupState })
if (self.window?.isVisible ?? false) || !self.initialized {
if list.count == 1, let c = list.first {
self.loadOne(c)
} else {
self.loadMultiply(list)
}
self.initialized = true
}
}
private func loadOne(_ clock: Clock_t) {
self.addArrangedSubview(self.oneContainer)
self.multiplyContainer.removeFromSuperview()
let views = self.oneContainer.subviews.compactMap{ $0 as? ClockChart }
if let view = views.first(where: { $0.identifier?.rawValue == clock.id }) {
if let value = clock.value {
view.setValue(value.convertToTimeZone(TimeZone(fromUTC: clock.tz)))
}
} else {
self.oneContainer.addRow(with: [self.clockView(clock)])
}
}
private func loadMultiply(_ list: [Clock_t]) {
self.addArrangedSubview(self.multiplyContainer)
self.oneContainer.removeFromSuperview()
let sorted = list.sorted(by: { $0.popupIndex < $1.popupIndex })
var views = self.multiplyContainer.stackView.subviews.compactMap{ $0 as? ClockChart }
if sorted.count < views.count && !views.isEmpty {
views.forEach{ $0.removeFromSuperview() }
views = []
}
sorted.forEach { (c: Clock_t) in
if let view = views.first(where: { $0.identifier?.rawValue == c.id }) {
if let value = c.value {
view.setValue(value.convertToTimeZone(TimeZone(fromUTC: c.tz)))
}
} else {
self.multiplyContainer.stackView.addArrangedSubview(clockView(c))
}
}
}
private func clockView(_ clock: Clock_t) -> ClockChart {
let view = ClockChart(frame: NSRect(x: 0, y: 0, width: 57, height: 57))
view.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
view.heightAnchor.constraint(equalToConstant: view.frame.height).isActive = true
view.identifier = NSUserInterfaceItemIdentifier(clock.id)
if let value = clock.value {
view.setValue(value.convertToTimeZone(TimeZone(fromUTC: clock.tz)))
}
return view
}
}