diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 0c6303e9..ed51b2ea 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -382,6 +382,11 @@ class ChatViewModel: ObservableObject, BitchatDelegate { @Published var showBluetoothAlert = false @Published var bluetoothAlertMessage = "" @Published var bluetoothState: CBManagerState = .unknown + + // Presentation state for privacy gating + @Published var isLocationChannelsSheetPresented: Bool = false + @Published var isAppInfoPresented: Bool = false + @Published var showScreenshotPrivacyWarning: Bool = false // Messages are naturally ephemeral - no persistent storage // Persist mesh public timeline across channel switches @@ -2588,6 +2593,17 @@ class ChatViewModel: ObservableObject, BitchatDelegate { @MainActor @objc private func userDidTakeScreenshot() { + // Respect privacy: do not broadcast screenshots taken from non-chat sheets + if isLocationChannelsSheetPresented { + // Show a warning about sharing location screenshots publicly + showScreenshotPrivacyWarning = true + return + } + if isAppInfoPresented { + // Silently ignore screenshots of app info + return + } + // Send screenshot notification based on current context let screenshotMessage = "* \(nickname) took a screenshot *" @@ -2607,7 +2623,7 @@ class ChatViewModel: ObservableObject, BitchatDelegate { } } - // Show local notification immediately as system message + // Show local notification immediately as system message (only in chat) let localNotification = BitchatMessage( sender: "system", content: "you took a screenshot", @@ -2658,7 +2674,7 @@ class ChatViewModel: ObservableObject, BitchatDelegate { } - // Show local notification immediately as system message + // Show local notification immediately as system message (only in chat) let localNotification = BitchatMessage( sender: "system", content: "you took a screenshot", diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index cc757ad7..83629553 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -165,6 +165,8 @@ struct ContentView: View { } .sheet(isPresented: $showAppInfo) { AppInfoView() + .onAppear { viewModel.isAppInfoPresented = true } + .onDisappear { viewModel.isAppInfoPresented = false } } .sheet(isPresented: Binding( get: { viewModel.showingFingerprintFor != nil }, @@ -1182,6 +1184,13 @@ struct ContentView: View { .padding(.horizontal, 12) .sheet(isPresented: $showLocationChannelsSheet) { LocationChannelsSheet(isPresented: $showLocationChannelsSheet) + .onAppear { viewModel.isLocationChannelsSheetPresented = true } + .onDisappear { viewModel.isLocationChannelsSheetPresented = false } + } + .alert("heads up", isPresented: $viewModel.showScreenshotPrivacyWarning) { + Button("ok", role: .cancel) {} + } message: { + Text("screenshots of location channels will reveal your location. think before sharing publicly.") } .background(backgroundColor.opacity(0.95)) } diff --git a/bitchat/Views/LocationChannelsSheet.swift b/bitchat/Views/LocationChannelsSheet.swift index 44a6438e..19ab4a26 100644 --- a/bitchat/Views/LocationChannelsSheet.swift +++ b/bitchat/Views/LocationChannelsSheet.swift @@ -304,22 +304,17 @@ struct LocationChannelsSheet: View { .foregroundColor(.secondary) } } - HStack(spacing: 0) { - Text(subtitlePrefix) - .font(.system(size: 12, design: .monospaced)) - .foregroundColor(.secondary) - if let name = subtitleName { - Text(" • ") - .font(.system(size: 12, design: .monospaced)) - .foregroundColor(.secondary) - Text(name) - .font(.system(size: 12, design: .monospaced)) - .fontWeight(subtitleNameBold ? .bold : .regular) - .foregroundColor(.secondary) - .lineLimit(1) - .truncationMode(.tail) - } + let subtitleFull: String = { + if let name = subtitleName, !name.isEmpty { + return subtitlePrefix + " • " + name } + return subtitlePrefix + }() + Text(subtitleFull) + .font(.system(size: 12, design: .monospaced)) + .foregroundColor(.secondary) + .lineLimit(1) + .truncationMode(.tail) } Spacer() if isSelected {