From fff71755874a0b2a9ab3b660a2ad16288bfa61b0 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Jun 2025 17:47:02 -0700 Subject: [PATCH 1/4] Update purge nodes description --- Meshtastic/Views/Settings/AppSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Settings/AppSettings.swift b/Meshtastic/Views/Settings/AppSettings.swift index 7bf044e6..93d1e8da 100644 --- a/Meshtastic/Views/Settings/AppSettings.swift +++ b/Meshtastic/Views/Settings/AppSettings.swift @@ -72,7 +72,7 @@ struct AppSettings: View { Text("180") } } - Text("Nodes without PKI keys are cleared from the app database on the schedule set by the user, nodes with PKI keys are cleared only if the interval is set to 7 days or longer. This feature only purges nodes from the app that are not stored in the device node database.") + Text("Favorited and ignored nodes are always retained. Nodes without PKC keys are cleared from the app database on the schedule set by the user, nodes with PKC keys are cleared only if the interval is set to 7 days or longer. This feature only purges nodes from the app that are not stored in the device node database.") .foregroundStyle(.secondary) .font(idiom == .phone ? .caption : .callout) } From d7ad7a7e7278fc096e900d6dd1f93304bd64f933 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Jun 2025 23:17:40 -0700 Subject: [PATCH 2/4] Persistent Tip style for bluetooth, messages and administration --- Localizable.xcstrings | 6 ++-- Meshtastic.xcodeproj/project.pbxproj | 4 +++ Meshtastic/MeshtasticApp.swift | 7 ++--- Meshtastic/Tips/PersistantTips.swift | 37 ++++++++++++++++++++++++ Meshtastic/Views/Bluetooth/Connect.swift | 3 +- Meshtastic/Views/Messages/Messages.swift | 1 + Meshtastic/Views/Settings/Settings.swift | 1 + 7 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 Meshtastic/Tips/PersistantTips.swift diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 99f6dd10..e5553909 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -11809,6 +11809,9 @@ } } } + }, + "Favorited and ignored nodes are always retained. Nodes without PKC keys are cleared from the app database on the schedule set by the user, nodes with PKC keys are cleared only if the interval is set to 7 days or longer. This feature only purges nodes from the app that are not stored in the device node database." : { + }, "Favorites" : { "localizations" : { @@ -19830,9 +19833,6 @@ } } } - }, - "Nodes without PKI keys are cleared from the app database on the schedule set by the user, nodes with PKI keys are cleared only if the interval is set to 7 days or longer. This feature only purges nodes from the app that are not stored in the device node database." : { - }, "None" : { "localizations" : { diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 883f3571..07cc1fb3 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -100,6 +100,7 @@ DD1BEF4A2E0292320090CE24 /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF492E0292220090CE24 /* KeychainHelper.swift */; }; DD1BEF4C2E030D310090CE24 /* KeyBackupStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF4B2E030D240090CE24 /* KeyBackupStatus.swift */; }; DD1BEF4E2E03916A0090CE24 /* ChannelsHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */; }; + DD1BEF502E0528AA0090CE24 /* PersistantTips.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF4F2E0528A80090CE24 /* PersistantTips.swift */; }; DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */; }; DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2160AE28C5552500C17253 /* MQTTConfig.swift */; }; DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; }; @@ -378,6 +379,7 @@ DD1BEF492E0292220090CE24 /* KeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainHelper.swift; sourceTree = ""; }; DD1BEF4B2E030D240090CE24 /* KeyBackupStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupStatus.swift; sourceTree = ""; }; DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsHelp.swift; sourceTree = ""; }; + DD1BEF4F2E0528A80090CE24 /* PersistantTips.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistantTips.swift; sourceTree = ""; }; DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = ""; }; DD2160AE28C5552500C17253 /* MQTTConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTConfig.swift; sourceTree = ""; }; DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = ""; }; @@ -863,6 +865,7 @@ DD7709392AA1ABA1007A8BF0 /* Tips */ = { isa = PBXGroup; children = ( + DD1BEF4F2E0528A80090CE24 /* PersistantTips.swift */, DD77093A2AA1ABB8007A8BF0 /* BluetoothTips.swift */, DD77093C2AA1AFA3007A8BF0 /* ChannelTips.swift */, DDC1B8192AB5377B00C71E39 /* MessagesTips.swift */, @@ -1439,6 +1442,7 @@ 25F5D5BE2C3F6D87008036E3 /* NavigationState.swift in Sources */, 2373AE152D0A24930086C749 /* MetricsSeriesList.swift in Sources */, DD354FD92BD96A0B0061A25F /* IAQScale.swift in Sources */, + DD1BEF502E0528AA0090CE24 /* PersistantTips.swift in Sources */, DDDB445429F8AD1600EE2349 /* Data.swift in Sources */, DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */, DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */, diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 9a0e9165..1512cae2 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -28,17 +28,16 @@ struct MeshtasticAppleApp: App { router: Router() ) self._appState = ObservedObject(wrappedValue: appState) - // Initialize the BLEManager singleton with the necessary dependencies BLEManager.setup(appState: appState, context: persistenceController.container.viewContext) self.persistenceController = persistenceController - // Wire up router self.appDelegate.router = appState.router - // Show Tips + #if DEBUG + // Show tips in development try? Tips.resetDatastore() + #endif } - var body: some Scene { WindowGroup { ContentView( diff --git a/Meshtastic/Tips/PersistantTips.swift b/Meshtastic/Tips/PersistantTips.swift new file mode 100644 index 00000000..24093285 --- /dev/null +++ b/Meshtastic/Tips/PersistantTips.swift @@ -0,0 +1,37 @@ +// +// Untitled.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 6/19/25. +// +import TipKit + +struct PersistentTip: TipViewStyle { + func makeBody(configuration: Configuration) -> some View { + VStack { + HStack(alignment: .top) { + if let image = configuration.image { + image + .font(.system(size: 42)) + .foregroundColor(.accentColor) + .padding(.trailing, 5) + } + VStack(alignment: .leading) { + if let title = configuration.title { + title + .bold() + .font(.headline) + } + if let message = configuration.message { + message + .foregroundStyle(.secondary) + .font(.callout) + } + } + } + } + .frame(maxWidth: .infinity) + .backgroundStyle(.thinMaterial) + .padding(.top, 5) + } +} diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 1176241a..37ca7966 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -46,9 +46,10 @@ struct Connect: View { VStack { List { if bleManager.isSwitchedOn { - Section(header: Text("Connected Radio").font(.title)) { + Section { if let connectedPeripheral = bleManager.connectedPeripheral, connectedPeripheral.peripheral.state == .connected { TipView(BluetoothConnectionTip(), arrowEdge: .bottom) + .tipViewStyle(PersistentTip()) VStack(alignment: .leading) { HStack { VStack(alignment: .center) { diff --git a/Meshtastic/Views/Messages/Messages.swift b/Meshtastic/Views/Messages/Messages.swift index cb6947c0..8a75faf7 100644 --- a/Meshtastic/Views/Messages/Messages.swift +++ b/Meshtastic/Views/Messages/Messages.swift @@ -64,6 +64,7 @@ struct Messages: View { } TipView(MessagesTip(), arrowEdge: .top) + .tipViewStyle(PersistentTip()) } .navigationTitle("Messages") .navigationBarTitleDisplayMode(.large) diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index a4b664b9..426d95e9 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -440,6 +440,7 @@ struct Settings: View { } } TipView(AdminChannelTip(), arrowEdge: .top) + .tipViewStyle(PersistentTip()) } else { if bleManager.connectedPeripheral != nil { Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") From b1aa91778451e82d59386b5377e44e3d60f0a138 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Jun 2025 23:49:23 -0700 Subject: [PATCH 3/4] Clean up context menu on connnected radio --- Localizable.xcstrings | 7 +++++++ Meshtastic/Views/Bluetooth/Connect.swift | 8 +++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index e5553909..bd3e50bc 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -4365,8 +4365,12 @@ } } } + }, + "BLE RSSI %lld" : { + }, "BLE RSSI: %lld" : { + "extractionState" : "stale", "localizations" : { "it" : { "stringUnit" : { @@ -16251,6 +16255,7 @@ } }, "Long Name: %@" : { + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -20047,6 +20052,7 @@ } }, "Num: %@" : { + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -28155,6 +28161,7 @@ } }, "Short Name: %@" : { + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 37ca7966..53e27ae6 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -105,6 +105,8 @@ struct Connect: View { .contextMenu { if node != nil { + Label("\(String(node!.num))", systemImage: "number") + Label("BLE RSSI \(connectedPeripheral.rssi)", systemImage: "cellularbars") #if !targetEnvironment(macCatalyst) if bleManager.isSubscribed { Button { @@ -124,10 +126,6 @@ struct Connect: View { } } #endif - Text("Num: \(String(node!.num))") - Text("Short Name: \(node?.user?.shortName ?? "?")") - Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") - Text("BLE RSSI: \(connectedPeripheral.rssi)") if bleManager.allowDisconnect { Button(role: .destructive) { if let connectedPeripheral = bleManager.connectedPeripheral, @@ -137,7 +135,7 @@ struct Connect: View { } label: { Label("Disconnect", systemImage: "antenna.radiowaves.left.and.right.slash") } - Button { + Button(role: .destructive) { if !bleManager.sendShutdown(fromUser: node!.user!, toUser: node!.user!) { Logger.mesh.error("Shutdown Failed") } From 942b72dd99667d167dfd266e0a2dc01e00c11d99 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 19 Jun 2025 23:51:52 -0700 Subject: [PATCH 4/4] Remove stale translations --- Localizable.xcstrings | 192 ------------------------------------------ 1 file changed, 192 deletions(-) diff --git a/Localizable.xcstrings b/Localizable.xcstrings index bd3e50bc..37f31711 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -2268,41 +2268,6 @@ } } }, - "Admin & Direct Message Keys" : { - "extractionState" : "stale", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Schlüssel für Administrator und Direktnachrichten" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tasti amministratore e messaggi diretti" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Админ и кључеви директних порука" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "管理员 & 私信密钥" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "管理與直接訊息加密金鑰" - } - } - } - }, "Admin Keys" : { }, @@ -4368,35 +4333,6 @@ }, "BLE RSSI %lld" : { - }, - "BLE RSSI: %lld" : { - "extractionState" : "stale", - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "RSSI BLE: %lld" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "BLE RSSI: %lld" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "BLE RSSI: %lld" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "藍牙訊號強度(RSSI):%lld" - } - } - } }, "BLE: %@" : { "localizations" : { @@ -16254,41 +16190,6 @@ } } }, - "Long Name: %@" : { - "extractionState" : "stale", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Langer Name: %@" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nome lungo: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дуго име: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "长名称: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "完整名稱:%@" - } - } - } - }, "Long press to favorite or mute the contact or delete a conversation." : { "localizations" : { "it" : { @@ -20051,35 +19952,6 @@ } } }, - "Num: %@" : { - "extractionState" : "stale", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Anzahl: %@" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Num: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Број: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Num: %@" - } - } - } - }, "Number of hops" : { "localizations" : { "de" : { @@ -27295,35 +27167,6 @@ } } }, - "Sent out to other nodes on the mesh to allow them to compute a shared secret key." : { - "extractionState" : "stale", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wird an andere Knoten im Netz gesendet, damit diese einen gemeinsamen geheimen Schlüssel berechnen können." - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inviato agli altri nodi della rete per consentire loro di calcolare una chiave segreta condivisa." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Послато другим чворовима на меш мрежи како би им омогућило да израчунају заједнички тајни кључ." - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "傳送到網路上的其他節點,以便共同計算一組共享私鑰。" - } - } - } - }, "Sequence number" : { "localizations" : { "de" : { @@ -28160,41 +28003,6 @@ } } }, - "Short Name: %@" : { - "extractionState" : "stale", - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Kurzname: %@" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nome breve: %@" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Кратко име: %@" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "短名称: %@" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "簡短名稱:%@" - } - } - } - }, "Short Range - Fast" : { "localizations" : { "it" : {