Implement message retention, retry mechanism, and app updates

- Add KeychainManager for secure password storage
- Implement MessageRetentionService for encrypted local storage of favorite room messages
- Add MessageRetryService for automatic retry of failed messages
- Add /favorite command to toggle room retention
- Add /discover command to find active rooms
- Fix all force unwrapped optionals in BluetoothMeshService
- Update app info screen with new features
- Integrate all services with proper cleanup on panic
This commit is contained in:
jack
2025-07-05 19:35:37 +02:00
parent 7151896102
commit 506c2bc7cb
8 changed files with 940 additions and 63 deletions
+28 -2
View File
@@ -64,6 +64,15 @@ struct AppInfoView: View {
FeatureRow(icon: "at", title: "Mentions",
description: "Use @nickname to notify specific users")
FeatureRow(icon: "number", title: "Rooms",
description: "Create #rooms for topic-based conversations")
FeatureRow(icon: "lock.fill", title: "Password Rooms",
description: "Secure rooms with passwords and AES encryption")
FeatureRow(icon: "mic.fill", title: "Voice Notes",
description: "Push-to-talk voice messages with compression")
}
// Privacy
@@ -86,9 +95,10 @@ struct AppInfoView: View {
VStack(alignment: .leading, spacing: 8) {
Text("• Set your nickname in the header")
Text("Tap the people counter to see connected peers")
Text("Swipe left or tap room name for sidebar")
Text("• Tap a peer to start a private chat")
Text("• Use @nickname to mention someone")
Text("• Use #roomname to create/join rooms")
Text("• Triple-tap the logo for panic mode")
}
.font(.system(size: 14, design: .monospaced))
@@ -106,6 +116,9 @@ struct AppInfoView: View {
Text("Store & Forward: 12h for all, ∞ for favorites")
Text("Battery: Adaptive scanning based on level")
Text("Platform: Universal (iOS, iPadOS, macOS)")
Text("Rooms: Password-protected with key commitments")
Text("Commands: /j /m /w /list /pass /favorite /discover")
Text("Storage: Keychain for passwords, encrypted retention")
}
.font(.system(size: 14, design: .monospaced))
.foregroundColor(textColor)
@@ -184,6 +197,15 @@ struct AppInfoView: View {
FeatureRow(icon: "at", title: "Mentions",
description: "Use @nickname to notify specific users")
FeatureRow(icon: "number", title: "Rooms",
description: "Create #rooms for topic-based conversations")
FeatureRow(icon: "lock.fill", title: "Password Rooms",
description: "Secure rooms with passwords and AES encryption")
FeatureRow(icon: "mic.fill", title: "Voice Notes",
description: "Push-to-talk voice messages with compression")
}
// Privacy
@@ -206,9 +228,10 @@ struct AppInfoView: View {
VStack(alignment: .leading, spacing: 8) {
Text("• Set your nickname in the header")
Text("Tap the people counter to see connected peers")
Text("Swipe left or tap room name for sidebar")
Text("• Tap a peer to start a private chat")
Text("• Use @nickname to mention someone")
Text("• Use #roomname to create/join rooms")
Text("• Triple-tap the logo for panic mode")
}
.font(.system(size: 14, design: .monospaced))
@@ -226,6 +249,9 @@ struct AppInfoView: View {
Text("Store & Forward: 12h for all, ∞ for favorites")
Text("Battery: Adaptive scanning based on level")
Text("Platform: Universal (iOS, iPadOS, macOS)")
Text("Rooms: Password-protected with key commitments")
Text("Commands: /j /m /w /list /pass /favorite /discover")
Text("Storage: Keychain for passwords, encrypted retention")
}
.font(.system(size: 14, design: .monospaced))
.foregroundColor(textColor)
+6 -2
View File
@@ -513,7 +513,9 @@ struct ContentView: View {
"/m": "send private message",
"/clear": "clear chat messages",
"/transfer": "transfer room ownership",
"/pass": "change room password"
"/pass": "change room password",
"/favorite": "toggle room retention",
"/discover": "find active rooms"
]
ForEach(commandSuggestions, id: \.self) { command in
@@ -595,7 +597,9 @@ struct ContentView: View {
("/m", "send private message"),
("/clear", "clear chat messages"),
("/transfer", "transfer room ownership"),
("/pass", "change room password")
("/pass", "change room password"),
("/favorite", "toggle room retention"),
("/discover", "find active rooms")
]
let input = newValue.lowercased()
commandSuggestions = commandDescriptions