mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: initialized Notification settings view for the modules
This commit is contained in:
@@ -67,7 +67,7 @@ public enum ModuleType: Int {
|
||||
case bluetooth
|
||||
case clock
|
||||
|
||||
var rawValue: String {
|
||||
public var rawValue: String {
|
||||
switch self {
|
||||
case .CPU: return "CPU"
|
||||
case .RAM: return "RAM"
|
||||
|
||||
@@ -95,6 +95,7 @@ open class Module: Module_p {
|
||||
private var settingsView: Settings_v? = nil
|
||||
private var popup: PopupWindow? = nil
|
||||
private var popupView: Popup_p? = nil
|
||||
private var notificationsView: NotificationsWrapper? = nil
|
||||
|
||||
private let log: NextLog
|
||||
private var readers: [Reader_p] = []
|
||||
@@ -108,13 +109,14 @@ open class Module: Module_p {
|
||||
}
|
||||
}
|
||||
|
||||
public init(popup: Popup_p? = nil, settings: Settings_v? = nil, portal: Portal_p? = nil) {
|
||||
public init(popup: Popup_p? = nil, settings: Settings_v? = nil, portal: Portal_p? = nil, notifications: NotificationsWrapper? = nil) {
|
||||
self.portal = portal
|
||||
self.config = module_c(in: Bundle(for: type(of: self)).path(forResource: "config", ofType: "plist")!)
|
||||
|
||||
self.log = NextLog.shared.copy(category: self.config.name)
|
||||
self.settingsView = settings
|
||||
self.popupView = popup
|
||||
self.notificationsView = notifications
|
||||
self.menuBar = MenuBar(moduleName: self.config.name)
|
||||
self.available = self.isAvailable()
|
||||
self.enabled = Store.shared.bool(key: "\(self.config.name)_state", defaultValue: self.config.defaultState)
|
||||
@@ -150,7 +152,8 @@ open class Module: Module_p {
|
||||
widgets: &self.menuBar.widgets,
|
||||
enabled: self.enabled,
|
||||
moduleSettings: self.settingsView,
|
||||
popupSettings: self.popupView
|
||||
popupSettings: self.popupView,
|
||||
notificationsSettings: self.notificationsView
|
||||
)
|
||||
|
||||
self.popup = PopupWindow(title: self.config.name, view: self.popupView, visibilityCallback: self.visibilityCallback)
|
||||
|
||||
83
Kit/module/notifications.swift
Normal file
83
Kit/module/notifications.swift
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// notifications.swift
|
||||
// Kit
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 04/12/2023
|
||||
// Using Swift 5.0
|
||||
// Running on macOS 14.1
|
||||
//
|
||||
// Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import UserNotifications
|
||||
|
||||
open class NotificationsWrapper: NSStackView {
|
||||
public let module: String
|
||||
|
||||
private var ids: [String: Bool?] = [:]
|
||||
|
||||
public init(_ module: ModuleType, _ ids: [String] = []) {
|
||||
self.module = module.rawValue
|
||||
super.init(frame: NSRect.zero)
|
||||
self.initIDs(ids)
|
||||
|
||||
self.orientation = .vertical
|
||||
self.distribution = .gravityAreas
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.edgeInsets = NSEdgeInsets(
|
||||
top: Constants.Settings.margin,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: Constants.Settings.margin,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
self.spacing = Constants.Settings.margin
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func initIDs(_ ids: [String]) {
|
||||
for id in ids {
|
||||
let notificationID = "Stats_\(self.module)_\(id)"
|
||||
self.ids[notificationID] = nil
|
||||
removeNotification(notificationID)
|
||||
}
|
||||
}
|
||||
|
||||
public func checkDouble(id rid: String, value: Double, threshold: Double, title: String, subtitle: String, less: Bool = false) {
|
||||
let id = "Stats_\(self.module)_\(rid)"
|
||||
let first = less ? value > threshold : value < threshold
|
||||
let second = less ? value <= threshold : value >= threshold
|
||||
|
||||
if self.ids[id] != nil, first {
|
||||
removeNotification(id)
|
||||
self.ids[id] = nil
|
||||
}
|
||||
|
||||
if self.ids[id] == nil && second {
|
||||
self.showNotification(id: id, title: title, subtitle: subtitle)
|
||||
self.ids[id] = true
|
||||
}
|
||||
}
|
||||
|
||||
private func showNotification(id: String, title: String, subtitle: String? = nil) {
|
||||
let content = UNMutableNotificationContent()
|
||||
content.title = title
|
||||
if let value = subtitle {
|
||||
content.subtitle = value
|
||||
}
|
||||
content.sound = UNNotificationSound.default
|
||||
|
||||
let request = UNNotificationRequest(identifier: id, content: content, trigger: nil)
|
||||
let center = UNUserNotificationCenter.current()
|
||||
|
||||
center.requestAuthorization(options: [.alert, .sound]) { _, _ in }
|
||||
center.add(request) { (error: Error?) in
|
||||
if let err = error {
|
||||
print(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,16 +25,19 @@ open class Settings: NSStackView, Settings_p {
|
||||
private var widgets: [Widget]
|
||||
private var moduleSettings: Settings_v?
|
||||
private var popupSettings: Popup_p?
|
||||
private var notificationsSettings: NotificationsWrapper?
|
||||
|
||||
private var moduleSettingsContainer: NSStackView?
|
||||
private var widgetSettingsContainer: NSStackView?
|
||||
private var popupSettingsContainer: NSStackView?
|
||||
private var notificationsSettingsContainer: NSStackView?
|
||||
|
||||
private var enableControl: NSControl?
|
||||
private var oneViewRow: NSView?
|
||||
|
||||
private let noWidgetsView: EmptyView = EmptyView(msg: localizedString("No available widgets to configure"))
|
||||
private let noPopupSettingsView: EmptyView = EmptyView(msg: localizedString("No options to configure for the popup in this module"))
|
||||
private let noNotificationsView: EmptyView = EmptyView(msg: localizedString("No notifications available in this module"))
|
||||
|
||||
private var globalOneView: Bool {
|
||||
Store.shared.bool(key: "OneView", defaultValue: false)
|
||||
@@ -48,11 +51,12 @@ open class Settings: NSStackView, Settings_p {
|
||||
}
|
||||
}
|
||||
|
||||
init(config: UnsafePointer<module_c>, widgets: UnsafeMutablePointer<[Widget]>, enabled: Bool, moduleSettings: Settings_v?, popupSettings: Popup_p?) {
|
||||
init(config: UnsafePointer<module_c>, widgets: UnsafeMutablePointer<[Widget]>, enabled: Bool, moduleSettings: Settings_v?, popupSettings: Popup_p?, notificationsSettings: NotificationsWrapper?) {
|
||||
self.config = config
|
||||
self.widgets = widgets.pointee
|
||||
self.moduleSettings = moduleSettings
|
||||
self.popupSettings = popupSettings
|
||||
self.notificationsSettings = notificationsSettings
|
||||
|
||||
super.init(frame: NSRect.zero)
|
||||
|
||||
@@ -107,9 +111,20 @@ open class Settings: NSStackView, Settings_p {
|
||||
return view
|
||||
}()
|
||||
|
||||
let notificationsTab: NSTabViewItem = NSTabViewItem()
|
||||
notificationsTab.label = localizedString("Notifications")
|
||||
notificationsTab.view = {
|
||||
let view = ScrollableStackView(frame: tabView.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.notificationsSettingsContainer = view.stackView
|
||||
self.loadNotificationsSettings()
|
||||
return view
|
||||
}()
|
||||
|
||||
tabView.addTabViewItem(moduleTab)
|
||||
tabView.addTabViewItem(widgetTab)
|
||||
tabView.addTabViewItem(popupTab)
|
||||
tabView.addTabViewItem(notificationsTab)
|
||||
|
||||
self.addArrangedSubview(widgetSelector)
|
||||
self.addArrangedSubview(tabView)
|
||||
@@ -200,6 +215,16 @@ open class Settings: NSStackView, Settings_p {
|
||||
}
|
||||
}
|
||||
|
||||
private func loadNotificationsSettings() {
|
||||
self.notificationsSettingsContainer?.subviews.forEach{ $0.removeFromSuperview() }
|
||||
|
||||
if let notificationsView = self.notificationsSettings {
|
||||
self.notificationsSettingsContainer?.addArrangedSubview(notificationsView)
|
||||
} else {
|
||||
self.notificationsSettingsContainer?.addArrangedSubview(self.noNotificationsView)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func toggleOneView(_ sender: NSControl) {
|
||||
guard !self.globalOneView else { return }
|
||||
self.oneViewState = controlState(sender)
|
||||
|
||||
Reference in New Issue
Block a user