Implement handshake request notifications for pending messages (#321)

- Add handshakeRequest packet type (0x25) to notify recipients about queued messages
- Create HandshakeRequest struct with binary encoding for efficient transmission
- Send handshake requests when messages are queued due to missing session
- Display notifications when someone wants to send messages
- Fix verification persistence bug by adding forceSave on app termination
- Update UI to handle optional encryption icons (hide when no handshake attempted)

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
jack
2025-07-25 14:55:26 +02:00
committed by GitHub
co-authored by jack
parent 07c5e2e097
commit 3513228736
7 changed files with 416 additions and 149 deletions
+17 -13
View File
@@ -669,13 +669,15 @@ struct ContentView: View {
.foregroundColor(peerNicknames[peer.id] != nil ? textColor : secondaryTextColor)
// Encryption status icon (after peer name)
Image(systemName: peer.encryptionStatus.icon)
.font(.system(size: 10))
.foregroundColor(peer.encryptionStatus == .noiseVerified ? Color.green :
peer.encryptionStatus == .noiseSecured ? textColor :
peer.encryptionStatus == .noiseHandshaking ? Color.orange :
Color.red)
.accessibilityLabel("Encryption: \(peer.encryptionStatus == .noiseVerified ? "verified" : peer.encryptionStatus == .noiseSecured ? "secured" : peer.encryptionStatus == .noiseHandshaking ? "establishing" : "none")")
if let icon = peer.encryptionStatus.icon {
Image(systemName: icon)
.font(.system(size: 10))
.foregroundColor(peer.encryptionStatus == .noiseVerified ? Color.green :
peer.encryptionStatus == .noiseSecured ? textColor :
peer.encryptionStatus == .noiseHandshaking ? Color.orange :
Color.red)
.accessibilityLabel("Encryption: \(peer.encryptionStatus == .noiseVerified ? "verified" : peer.encryptionStatus == .noiseSecured ? "secured" : peer.encryptionStatus == .noiseHandshaking ? "establishing" : "none")")
}
Spacer()
@@ -897,12 +899,14 @@ struct ContentView: View {
.foregroundColor(Color.orange)
// Dynamic encryption status icon
let encryptionStatus = viewModel.getEncryptionStatus(for: privatePeerID)
Image(systemName: encryptionStatus.icon)
.font(.system(size: 14))
.foregroundColor(encryptionStatus == .noiseVerified ? Color.green :
encryptionStatus == .noiseSecured ? Color.orange :
Color.red)
.accessibilityLabel("Encryption status: \(encryptionStatus == .noiseVerified ? "verified" : encryptionStatus == .noiseSecured ? "secured" : "not encrypted")")
if let icon = encryptionStatus.icon {
Image(systemName: icon)
.font(.system(size: 14))
.foregroundColor(encryptionStatus == .noiseVerified ? Color.green :
encryptionStatus == .noiseSecured ? Color.orange :
Color.red)
.accessibilityLabel("Encryption status: \(encryptionStatus == .noiseVerified ? "verified" : encryptionStatus == .noiseSecured ? "secured" : "not encrypted")")
}
}
.frame(maxWidth: .infinity)
.accessibilityLabel("Private chat with \(privatePeerNick)")