diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 48e02d76..7f6c7b8e 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -48,6 +48,7 @@ class ChatViewModel: ObservableObject { @Published var roomKeyCommitments: [String: String] = [:] // room -> SHA256(derivedKey) for verification @Published var showPasswordPrompt: Bool = false @Published var passwordPromptRoom: String? = nil + @Published var savedRooms: Set = [] // Rooms saved for message retention let meshService = BluetoothMeshService() private let userDefaults = UserDefaults.standard @@ -70,6 +71,7 @@ class ChatViewModel: ObservableObject { loadFavorites() loadJoinedRooms() loadRoomData() + savedRooms = MessageRetentionService.shared.getFavoriteRooms() meshService.delegate = self // Log startup info @@ -930,6 +932,7 @@ class ChatViewModel: ObservableObject { // Clear all retained messages MessageRetentionService.shared.deleteAllStoredMessages() + savedRooms.removeAll() // Clear message retry queue MessageRetryService.shared.clearRetryQueue() @@ -1590,6 +1593,13 @@ extension ChatViewModel: BitchatDelegate { let isFavorite = MessageRetentionService.shared.toggleFavoriteRoom(room) let status = isFavorite ? "saved" : "unsaved" + // Update published property + if isFavorite { + savedRooms.insert(room) + } else { + savedRooms.remove(room) + } + // If just marked as favorite, load any previously saved messages if isFavorite { let savedMessages = MessageRetentionService.shared.loadMessagesForRoom(room) diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index 947bd2fd..261152df 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -296,6 +296,16 @@ struct ContentView: View { Spacer() HStack(spacing: 8) { + // Save button + Button(action: { + viewModel.sendMessage("/save") + }) { + Image(systemName: viewModel.savedRooms.contains(currentRoom) ? "bookmark.fill" : "bookmark") + .font(.system(size: 16)) + .foregroundColor(viewModel.savedRooms.contains(currentRoom) ? Color.yellow : textColor) + } + .buttonStyle(.plain) + // Password button for room creator only if viewModel.roomCreators[currentRoom] == viewModel.meshService.myPeerID { Button(action: {