Compare commits

..
Author SHA1 Message Date
jack 0bc5cbe0b7 QR verification: speed + persistence + UX
- Inject live Noise into VerificationService; prewarm QR on app start
- Keep camera active; remove intermediate responder toast
- One-shot/dupe guards and deferred send on handshake
- Persist verified status immediately; standardize fingerprint (SHA-256)
- Show verified badge for offline favorites; mutual verification toast
- VERIFY sheet styling to match peer sheet; UI polish
- Logs to diagnose verified load + favorites mapping
2025-08-24 23:11:20 +02:00
jack 77f0fa46c7 QR: make NoisePayloadType exhaustive in ChatViewModel switches by ignoring verifyChallenge/verifyResponse for now (placeholder) 2025-08-24 18:26:19 +02:00
jack 81fa77b761 QR: add iOS camera scanner using AVFoundation; integrate into Scan view; add NSCameraUsageDescription to Info.plist 2025-08-24 18:23:37 +02:00
jack 0c7054ce30 QR: fix SwiftUI modifiers — apply .interpolation(.none) and .resizable() to platform Image inside ImageWrapper; remove from wrapper usage 2025-08-24 18:16:42 +02:00
jack 921b9f1be6 QR: render actual QR images with CoreImage; add copy button; keep scanner placeholder for now 2025-08-24 18:13:55 +02:00
jack e86dbc8d38 QR: fix VerificationQR mutability (sigHex var) and remove duplicate Data hex helpers to resolve redeclaration; wire signed payload assembly 2025-08-24 18:09:24 +02:00
jack 652deab8a5 QR verification scaffold: add Noise verify payload types, VerificationService with QR schema/signing, placeholder MyQR/Scan views, and UI entry points in header 2025-08-24 18:06:22 +02:00
+1 -17
View File
@@ -3183,28 +3183,12 @@ class ChatViewModel: ObservableObject, BitchatDelegate {
let token = String(matchText.dropFirst()).lowercased()
let allowed = Set("0123456789bcdefghjkmnpqrstuvwxyz")
let isGeohash = (2...12).contains(token.count) && token.allSatisfy { allowed.contains($0) }
// Do not link if this hashtag is directly attached to an @mention (e.g., @name#geohash)
let attachedToMention: Bool = {
// nsRange is the Range<String.Index> for this match within content
// Walk left until whitespace/newline; if we encounter '@' first, treat as part of mention
if nsRange.lowerBound > content.startIndex {
var i = content.index(before: nsRange.lowerBound)
while true {
let ch = content[i]
if ch.isWhitespace || ch.isNewline { break }
if ch == "@" { return true }
if i == content.startIndex { break }
i = content.index(before: i)
}
}
return false
}()
var tagStyle = AttributeContainer()
tagStyle.font = isSelf
? .system(size: 14, weight: .bold, design: .monospaced)
: .system(size: 14, design: .monospaced)
tagStyle.foregroundColor = baseColor
if isGeohash && !attachedToMention, let url = URL(string: "bitchat://geohash/\(token)") {
if isGeohash, let url = URL(string: "bitchat://geohash/\(token)") {
tagStyle.link = url
tagStyle.underlineStyle = .single
}