From 90be4321b0cde192375b3d63b3cfcf8cb8d0eb9c Mon Sep 17 00:00:00 2001 From: maddiebaka Date: Wed, 7 Jun 2023 15:47:26 -0400 Subject: [PATCH] Notifications and UI color scheme update --- Soyuz.xcodeproj/project.pbxproj | 12 +++++- .../xcschemes/xcschememanagement.plist | 18 ++++++++ Soyuz/Info.plist | 2 + Soyuz/ViewModels/MoonrakerSocketManager.swift | 26 ++++++++---- .../ViewModels/UserNotificationHandler.swift | 42 +++++++++++++++++++ Soyuz/Views/SoyuzMenuBarExtraView.swift | 14 +++++-- 6 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 Soyuz/ViewModels/UserNotificationHandler.swift diff --git a/Soyuz.xcodeproj/project.pbxproj b/Soyuz.xcodeproj/project.pbxproj index bccc150..5bb98dc 100755 --- a/Soyuz.xcodeproj/project.pbxproj +++ b/Soyuz.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + C15B60A82A2423760052F712 /* UserNotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15B60A72A2423760052F712 /* UserNotificationHandler.swift */; }; C15F06A62A20198300C14CD8 /* Soyuz.help in Resources */ = {isa = PBXBuildFile; fileRef = C15F06A42A20171E00C14CD8 /* Soyuz.help */; }; E124B9D929941A4D00C0D2D2 /* PrinterConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E124B9D829941A4D00C0D2D2 /* PrinterConfigView.swift */; }; E16378B429A491E6002F05E9 /* MoonrakerSocketManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E16378B329A491E6002F05E9 /* MoonrakerSocketManagerTests.swift */; }; @@ -44,6 +45,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + C15B60A72A2423760052F712 /* UserNotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationHandler.swift; sourceTree = ""; }; C15F06A42A20171E00C14CD8 /* Soyuz.help */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Soyuz.help; sourceTree = ""; }; E124B9D72993FE5500C0D2D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; E124B9D829941A4D00C0D2D2 /* PrinterConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrinterConfigView.swift; sourceTree = ""; }; @@ -172,6 +174,7 @@ E180B61C2992D53700425DB0 /* PrinterObjectsQuery.swift */, E180B6212993256E00425DB0 /* MoonrakerSocketManager.swift */, E1A93C6629C932E200BAE750 /* BonjourBrowser.swift */, + C15B60A72A2423760052F712 /* UserNotificationHandler.swift */, ); path = ViewModels; sourceTree = ""; @@ -317,6 +320,7 @@ E180B5F52992CD9200425DB0 /* KlipperMon.xcdatamodeld in Sources */, E124B9D929941A4D00C0D2D2 /* PrinterConfigView.swift in Sources */, E180B5F22992CD9200425DB0 /* Persistence.swift in Sources */, + C15B60A82A2423760052F712 /* UserNotificationHandler.swift in Sources */, E1A93C6729C932E200BAE750 /* BonjourBrowser.swift in Sources */, E180B5E92992CD9100425DB0 /* SoyuzApp.swift in Sources */, E180B6222993256E00425DB0 /* MoonrakerSocketManager.swift in Sources */, @@ -477,17 +481,19 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = Soyuz/Soyuz.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "Soyuz/Preview\\ Content"; DEVELOPMENT_TEAM = W9ASV855X5; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Soyuz/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_LSUIElement = NO; INFOPLIST_KEY_NSHumanReadableCopyright = ""; LD_RUNPATH_SEARCH_PATHS = ( @@ -507,17 +513,19 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = Soyuz/Soyuz.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_ASSET_PATHS = "Soyuz/Preview\\ Content"; DEVELOPMENT_TEAM = W9ASV855X5; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Soyuz/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_LSUIElement = NO; INFOPLIST_KEY_NSHumanReadableCopyright = ""; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/Soyuz.xcodeproj/xcuserdata/madeline.xcuserdatad/xcschemes/xcschememanagement.plist b/Soyuz.xcodeproj/xcuserdata/madeline.xcuserdatad/xcschemes/xcschememanagement.plist index e0967e9..68e9325 100644 --- a/Soyuz.xcodeproj/xcuserdata/madeline.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Soyuz.xcodeproj/xcuserdata/madeline.xcuserdatad/xcschemes/xcschememanagement.plist @@ -10,5 +10,23 @@ 0 + SuppressBuildableAutocreation + + E180B5E42992CD9100425DB0 + + primary + + + E180B5FA2992CD9300425DB0 + + primary + + + E180B6042992CD9300425DB0 + + primary + + + diff --git a/Soyuz/Info.plist b/Soyuz/Info.plist index 0160f5a..4c8b9d3 100755 --- a/Soyuz/Info.plist +++ b/Soyuz/Info.plist @@ -2,6 +2,8 @@ + ITSAppUsesNonExemptEncryption + CFBundleHelpBookFolder Soyuz.help CFBundleHelpBookName diff --git a/Soyuz/ViewModels/MoonrakerSocketManager.swift b/Soyuz/ViewModels/MoonrakerSocketManager.swift index b50dc85..5d77303 100755 --- a/Soyuz/ViewModels/MoonrakerSocketManager.swift +++ b/Soyuz/ViewModels/MoonrakerSocketManager.swift @@ -29,6 +29,8 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate { @Published var connection: NWConnection? @Published var friendlyHostname: String = "" + var notification = UserNotificationHandler.shared + private var socket: WebSocket? private var lastPingDate = Date() private var starscreamEngine: Engine @@ -67,11 +69,11 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate { print("\(key): \(value)") }) -// if isConnected == true { -// connection?.cancel() -// socket?.disconnect() -// } -// + // if isConnected == true { + // connection?.cancel() + // socket?.disconnect() + // } + // if connection == nil { connection = NWConnection(to: endpoint, using: .tcp) } @@ -95,7 +97,7 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate { connection?.cancel() DispatchQueue.main.async { - friendlyHostname = endpoint.toFriendlyString() + self.friendlyHostname = endpoint.toFriendlyString() self.socketHost = sanitizedHost self.socketPort = "\(port)" self.openWebsocket() @@ -115,7 +117,7 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate { connection = nil socket?.disconnect() } - + // MARK: Private functions @@ -221,16 +223,22 @@ class MoonrakerSocketManager: ObservableObject, WebSocketDelegate { // Parse a JSON-RPC query-response message func parse_response(_ response: jsonRpcResponse) { state = response.result.status.print_stats?.state ?? "" + + progress = response.result.status.virtual_sdcard?.progress ?? 0.0 extruderTemperature = response.result.status.extruder?.temperature ?? 0.0 bedTemperature = response.result.status.heater_bed?.temperature ?? 0.0 - - print(response) } // Parse a JSON-RPC update message func parse_update(_ update: jsonRpcUpdate) { if let newState = update.params.status?.print_stats?.state { + print("Printer state: \(newState)") + // Issue a notification when state changes from printing to complete + // TODO: Handle this better + if newState == "complete" && state == "printing" { + notification.sendNotification(.printComplete) + } state = newState } if let newProgress = update.params.status?.virtual_sdcard?.progress { diff --git a/Soyuz/ViewModels/UserNotificationHandler.swift b/Soyuz/ViewModels/UserNotificationHandler.swift new file mode 100644 index 0000000..37a6656 --- /dev/null +++ b/Soyuz/ViewModels/UserNotificationHandler.swift @@ -0,0 +1,42 @@ +// +// UserNotificationProtocol.swift +// Soyuz +// +// Created by Madeline Pace on 5/28/23. +// + +import UserNotifications + +class UserNotificationHandler { + static var shared = UserNotificationHandler() + + private var center = UNUserNotificationCenter.current() + + enum NotificationType { + case printComplete + } + + private init() { + center.requestAuthorization(options: [.alert, .sound, .badge, .provisional]) { granted, error in + if let error = error { + print("Error requesting authorization: \(error)") + } + } + } + + func sendNotification(_ type: NotificationType) { + print("Sending notification.") + // Build notification request + let content = UNMutableNotificationContent() + // TODO: Replace this with localized strings + content.title = "Print Complete! 🎉" + let request = UNNotificationRequest(identifier: "Print Finished", content: content, trigger: nil) + + // Dispatch notification to system + center.add(request) { (error: Error?) in + if let theError = error { + print("Error: \(theError)") + } + } + } +} diff --git a/Soyuz/Views/SoyuzMenuBarExtraView.swift b/Soyuz/Views/SoyuzMenuBarExtraView.swift index 7635848..0793ab1 100755 --- a/Soyuz/Views/SoyuzMenuBarExtraView.swift +++ b/Soyuz/Views/SoyuzMenuBarExtraView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import UserNotifications import AppKit import Network @@ -21,6 +22,7 @@ struct SoyuzMenuBarExtraView: View { @State var printPercentage: Double = 0 @Binding var currentMenuBarIcon: String + var notification = UserNotificationHandler.shared @State var hotendHotTemp: Bool = false @State var bedHotTemp: Bool = false @@ -53,7 +55,7 @@ struct SoyuzMenuBarExtraView: View { // Hot-end temperature HStack { Image(systemName: "flame") - .foregroundColor( printerManager.extruderTemperature > DANGERTEMP ? .red : .white ) + .foregroundColor( printerManager.extruderTemperature > DANGERTEMP ? .red : Color(nsColor: .labelColor)) .opacity( printerManager.extruderTemperature > DANGERTEMP ? 1.0 : 0.3 ) Text("Hotend") .font(.headline) @@ -63,7 +65,7 @@ struct SoyuzMenuBarExtraView: View { // Bed temperature HStack { Image(systemName: "flame") - .foregroundColor( printerManager.bedTemperature > DANGERTEMP ? .red : .white ) + .foregroundColor( printerManager.bedTemperature > DANGERTEMP ? .red : Color(nsColor: .labelColor) ) .opacity( printerManager.bedTemperature > DANGERTEMP ? 1.0 : 0.3 ) Text("Plate") .font(.headline) @@ -79,12 +81,18 @@ struct SoyuzMenuBarExtraView: View { // Footer information HStack { Button { - print("Button pressed") openWindow(id: "soyuz_cfg") } label: { Text("Printers") .foregroundColor(Color("ButtonForegroundColor")) } + /* Debugging Stuff */ + Button { + notification.sendNotification(.printComplete) + } label: { + Text("Notify") + } + /* Debugging Stuff */ Spacer() if(printerManager.isConnected) { Image(systemName: "network")