From a5865af29287e82ac0d03fbdeb355d70225fd283 Mon Sep 17 00:00:00 2001 From: jack Date: Tue, 8 Jul 2025 04:00:50 +0200 Subject: [PATCH] Add screenshot detection and notification feature - Detect when users take screenshots on iOS - Send system notification to all participants - Works in public chat, channels, and private messages - Display screenshot notifications as system messages --- bitchat/ViewModels/ChatViewModel.swift | 83 ++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index e86da2bb..d1d54595 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -130,6 +130,14 @@ class ChatViewModel: ObservableObject { name: UIApplication.didBecomeActiveNotification, object: nil ) + + // Add screenshot detection for iOS + NotificationCenter.default.addObserver( + self, + selector: #selector(userDidTakeScreenshot), + name: UIApplication.userDidTakeScreenshotNotification, + object: nil + ) #endif } @@ -1058,6 +1066,66 @@ class ChatViewModel: ObservableObject { } } + @objc private func userDidTakeScreenshot() { + // Send screenshot notification based on current context + let screenshotMessage = "* \(nickname) took a screenshot *" + + if let peerID = selectedPrivateChatPeer { + // In private chat - send to the other person + if let peerNickname = meshService.getPeerNicknames()[peerID] { + meshService.sendPrivateMessage(screenshotMessage, to: peerID, recipientNickname: peerNickname) + } + + // Also show locally + let localNotification = BitchatMessage( + sender: "system", + content: "you took a screenshot", + timestamp: Date(), + isRelay: false, + originalSender: nil, + isPrivate: true, + recipientNickname: meshService.getPeerNicknames()[peerID], + senderPeerID: meshService.myPeerID + ) + if privateChats[peerID] == nil { + privateChats[peerID] = [] + } + privateChats[peerID]?.append(localNotification) + + } else if let channel = currentChannel { + // In a channel - send to channel + meshService.sendMessage(screenshotMessage, channel: channel) + + // Also show locally + let localNotification = BitchatMessage( + sender: "system", + content: "you took a screenshot", + timestamp: Date(), + isRelay: false, + originalSender: nil, + isPrivate: false, + channel: channel + ) + if channelMessages[channel] == nil { + channelMessages[channel] = [] + } + channelMessages[channel]?.append(localNotification) + + } else { + // In public chat - send to everyone + meshService.sendMessage(screenshotMessage) + + // Also show locally + let localNotification = BitchatMessage( + sender: "system", + content: "you took a screenshot", + timestamp: Date(), + isRelay: false + ) + messages.append(localNotification) + } + } + func markPrivateMessagesAsRead(from peerID: String) { // Get the nickname for this peer let peerNickname = meshService.getPeerNicknames()[peerID] ?? "" @@ -2438,9 +2506,10 @@ extension ChatViewModel: BitchatDelegate { } } - // Check if this is a hug/slap action that should be converted to system message + // Check if this is an action that should be converted to system message let isActionMessage = messageToStore.content.hasPrefix("* ") && messageToStore.content.hasSuffix(" *") && - (messageToStore.content.contains("🫂") || messageToStore.content.contains("🐟")) + (messageToStore.content.contains("🫂") || messageToStore.content.contains("🐟") || + messageToStore.content.contains("took a screenshot")) if isActionMessage { // Convert to system message @@ -2621,9 +2690,10 @@ extension ChatViewModel: BitchatDelegate { } } - // Check if this is a hug/slap action that should be converted to system message + // Check if this is an action that should be converted to system message let isActionMessage = messageToAdd.content.hasPrefix("* ") && messageToAdd.content.hasSuffix(" *") && - (messageToAdd.content.contains("🫂") || messageToAdd.content.contains("🐟")) + (messageToAdd.content.contains("🫂") || messageToAdd.content.contains("🐟") || + messageToAdd.content.contains("took a screenshot")) let finalMessage: BitchatMessage if isActionMessage { @@ -2675,9 +2745,10 @@ extension ChatViewModel: BitchatDelegate { } else { // Regular public message (main chat) - // Check if this is a hug/slap action that should be converted to system message + // Check if this is an action that should be converted to system message let isActionMessage = message.content.hasPrefix("* ") && message.content.hasSuffix(" *") && - (message.content.contains("🫂") || message.content.contains("🐟")) + (message.content.contains("🫂") || message.content.contains("🐟") || + message.content.contains("took a screenshot")) if isActionMessage { // Convert to system message