From f90f292c426e7da34e4dc64339075bdb63b415eb Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Sun, 6 Oct 2024 10:21:35 -0700 Subject: [PATCH] Added Save Channel Settings Intent --- Localizable.xcstrings | 12 ++++ Meshtastic.xcodeproj/project.pbxproj | 4 ++ .../SaveChannelSettingsIntent.swift | 62 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 Meshtastic/AppIntents/SaveChannelSettingsIntent.swift diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 11d7c54b..886adafa 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -2782,6 +2782,9 @@ }, "Channel Role" : { + }, + "Channel URL" : { + }, "Channel Utilization %@%% " : { @@ -18850,6 +18853,9 @@ }, "Save" : { + }, + "Save Channel Settings" : { + }, "Save User Config to %@?" : { @@ -20399,6 +20405,9 @@ }, "Supported I2C Connected sensors will be detected automatically, sensors are BMP280, BME280, BME680, MCP9808, INA219, INA260, LPS22 and SHTC3." : { + }, + "Takes a Meshtastic channel URL and saves the channel settings." : { + }, "tapback" : { "localizations" : { @@ -21099,6 +21108,9 @@ }, "The state of the LED (on/off)" : { + }, + "The URL for the channel settings" : { + }, "There has been no response to a request for device metadata over the admin channel for this node." : { diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index d9146f08..c49ade1b 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 6DEDA55C2A9592F900321D2E /* MessageEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */; }; B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B399E8A32B6F486400E4488E /* RetryButton.swift */; }; B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; }; + BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */; }; BCB613812C67290800485544 /* SendWaypointIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613802C67290800485544 /* SendWaypointIntent.swift */; }; BCB613832C672A2600485544 /* MessageChannelIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613822C672A2600485544 /* MessageChannelIntent.swift */; }; BCB613852C68703800485544 /* NodePositionIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613842C68703800485544 /* NodePositionIntent.swift */; }; @@ -276,6 +277,7 @@ 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageEntityExtension.swift; sourceTree = ""; }; B399E8A32B6F486400E4488E /* RetryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetryButton.swift; sourceTree = ""; }; B3E905B02B71F7F300654D07 /* TextMessageField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageField.swift; sourceTree = ""; }; + BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveChannelSettingsIntent.swift; sourceTree = ""; }; BCB613802C67290800485544 /* SendWaypointIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendWaypointIntent.swift; sourceTree = ""; }; BCB613822C672A2600485544 /* MessageChannelIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageChannelIntent.swift; sourceTree = ""; }; BCB613842C68703800485544 /* NodePositionIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodePositionIntent.swift; sourceTree = ""; }; @@ -590,6 +592,7 @@ BCE2D3C42C7AE369008E6199 /* RestartNodeIntent.swift */, BCE2D3C82C7C377F008E6199 /* FactoryResetNodeIntent.swift */, BCE2D3C62C7B0D0A008E6199 /* ShortcutsProvider.swift */, + BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */, ); path = AppIntents; sourceTree = ""; @@ -1474,6 +1477,7 @@ DDDB444429F8A8DD00EE2349 /* Float.swift in Sources */, DDAB580F2B0DAFBC00147258 /* LocationEntityExtension.swift in Sources */, B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */, + BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */, D93068D72B8146690066FBC8 /* MessageText.swift in Sources */, DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */, ); diff --git a/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift new file mode 100644 index 00000000..56f21458 --- /dev/null +++ b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift @@ -0,0 +1,62 @@ +// +// SaveChannelSettingsIntent.swift +// Meshtastic +// +// Created by Benjamin Faershtein on 10/6/24. +// + +import Foundation +import AppIntents + +// Define the AppIntent for saving channel settings from a URL +struct SaveChannelSettingsIntent: AppIntent { + // Define a title and description for the intent + static var title: LocalizedStringResource = "Save Channel Settings" + static var description: IntentDescription = "Takes a Meshtastic channel URL and saves the channel settings." + + // Define the input for the intent (the channel URL) + @Parameter(title: "Channel URL", description: "The URL for the channel settings") + var channelUrl: URL + + // Define the function that performs the main logic + func perform() async throws -> some IntentResult { + // Ensure the BLE Manager is connected + if !BLEManager.shared.isConnected { + throw AppIntentErrors.AppIntentError.notConnected + } + + // Ensure the URL contains the expected "meshtastic.org/e/#" structure + if channelUrl.absoluteString.lowercased().contains("meshtastic.org/e/#") { + // Split the URL to get the portion after "#" + let components = channelUrl.absoluteString.components(separatedBy: "#") + + // Add channels flag based on the URL query parameter (if present) + let addChannels = Bool(channelUrl["add"] ?? "false") ?? false + + var channelSettings: String? + + // Extract the Base64 encoded channel settings (after "#") + if let lastComponent = components.last { + channelSettings = lastComponent.components(separatedBy: "?").first // Ignore any query parameters + } + + // If valid channel settings are extracted, attempt to save them + if let channelSettings = channelSettings { + print(channelSettings) + // Call the BLEManager to save the channel settings + let saveResult = BLEManager.shared.saveChannelSet(base64UrlString: channelSettings, addChannels: addChannels) + + if !saveResult { + throw AppIntentErrors.AppIntentError.message("Failed to save the channel settings.") + } + } else { + throw AppIntentErrors.AppIntentError.message("Invalid Channel URL: Unable to extract settings.") + } + + // Return a success result + return .result() + } else { + throw AppIntentErrors.AppIntentError.message("The URL is not a valid Meshtastic channel link.") + } + } +}