Merge pull request #1284 from meshtastic/persistent_tips

Persistent tips
This commit is contained in:
Garth Vander Houwen 2025-06-19 23:54:26 -07:00 committed by GitHub
commit c248451a7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 57 additions and 201 deletions

View file

@ -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" : {
},
@ -4366,33 +4331,8 @@
}
}
},
"BLE RSSI: %lld" : {
"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 RSSI %lld" : {
},
"BLE: %@" : {
"localizations" : {
@ -11809,6 +11749,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" : {
@ -16247,40 +16190,6 @@
}
}
},
"Long Name: %@" : {
"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" : {
@ -19830,9 +19739,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" : {
@ -20046,34 +19952,6 @@
}
}
},
"Num: %@" : {
"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" : {
@ -27289,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" : {
@ -28154,40 +28003,6 @@
}
}
},
"Short Name: %@" : {
"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" : {

View file

@ -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 = "<group>"; };
DD1BEF4B2E030D240090CE24 /* KeyBackupStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupStatus.swift; sourceTree = "<group>"; };
DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsHelp.swift; sourceTree = "<group>"; };
DD1BEF4F2E0528A80090CE24 /* PersistantTips.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistantTips.swift; sourceTree = "<group>"; };
DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = "<group>"; };
DD2160AE28C5552500C17253 /* MQTTConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTConfig.swift; sourceTree = "<group>"; };
DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = "<group>"; };
@ -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 */,

View file

@ -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(

View file

@ -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)
}
}

View file

@ -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) {
@ -104,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 {
@ -123,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,
@ -136,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")
}

View file

@ -64,6 +64,7 @@ struct Messages: View {
}
TipView(MessagesTip(), arrowEdge: .top)
.tipViewStyle(PersistentTip())
}
.navigationTitle("Messages")
.navigationBarTitleDisplayMode(.large)

View file

@ -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)
}

View file

@ -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)")