Fix room UI and membership tracking issues

- Add lock icon to room header for password management
- Change "leave" to "leave room" for clarity
- Fix bug where non-members appeared in room member list
- Only process room messages if user has joined the room
- Initialize room data structures on app launch
- Prevent auto-join when just mentioning a room
This commit is contained in:
jack
2025-07-05 19:35:37 +02:00
parent 8d553adc0c
commit cfded8c4df
2 changed files with 61 additions and 27 deletions
+15 -5
View File
@@ -112,6 +112,15 @@ class ChatViewModel: ObservableObject {
private func loadJoinedRooms() { private func loadJoinedRooms() {
if let savedRooms = userDefaults.stringArray(forKey: joinedRoomsKey) { if let savedRooms = userDefaults.stringArray(forKey: joinedRoomsKey) {
joinedRooms = Set(savedRooms) joinedRooms = Set(savedRooms)
// Initialize empty data structures for joined rooms
for room in joinedRooms {
if roomMessages[room] == nil {
roomMessages[room] = []
}
if roomMembers[room] == nil {
roomMembers[room] = []
}
}
} }
} }
@@ -856,11 +865,8 @@ extension ChatViewModel: BitchatDelegate {
} else if let room = message.room { } else if let room = message.room {
// Room message // Room message
// Auto-join room if we see a message for it // Only process room messages if we've joined this room
if !joinedRooms.contains(room) { if joinedRooms.contains(room) {
joinRoom(room)
}
// Add to room messages // Add to room messages
if roomMessages[room] == nil { if roomMessages[room] == nil {
roomMessages[room] = [] roomMessages[room] = []
@@ -883,6 +889,10 @@ extension ChatViewModel: BitchatDelegate {
if currentRoom != room { if currentRoom != room {
unreadRoomMessages[room] = (unreadRoomMessages[room] ?? 0) + 1 unreadRoomMessages[room] = (unreadRoomMessages[room] ?? 0) + 1
} }
} else {
// We're not in this room, ignore the message
bitchatLog("Ignoring message for room \(room) - not joined", category: "room")
}
} else { } else {
// Regular public message (main chat) // Regular public message (main chat)
messages.append(message) messages.append(message)
+26 -2
View File
@@ -259,11 +259,35 @@ struct ContentView: View {
Spacer() Spacer()
// Password button for room creator
if viewModel.roomCreators[currentRoom] == viewModel.meshService.myPeerID || viewModel.roomCreators[currentRoom] == nil {
Button(action: {
// Toggle password protection
if viewModel.passwordProtectedRooms.contains(currentRoom) {
viewModel.removeRoomPassword(for: currentRoom)
} else {
// Show password input
showPasswordInput = true
passwordInputRoom = currentRoom
}
}) {
Image(systemName: viewModel.passwordProtectedRooms.contains(currentRoom) ? "lock.open" : "lock")
.font(.system(size: 14))
.foregroundColor(secondaryTextColor)
.padding(6)
.overlay(
RoundedRectangle(cornerRadius: 4)
.stroke(secondaryTextColor.opacity(0.5), lineWidth: 1)
)
}
.buttonStyle(.plain)
}
// Leave room button // Leave room button
Button(action: { Button(action: {
viewModel.leaveRoom(currentRoom) viewModel.leaveRoom(currentRoom)
}) { }) {
Text("leave") Text("leave room")
.font(.system(size: 12, design: .monospaced)) .font(.system(size: 12, design: .monospaced))
.foregroundColor(Color.red) .foregroundColor(Color.red)
.padding(.horizontal, 8) .padding(.horizontal, 8)
@@ -611,7 +635,7 @@ struct ContentView: View {
Button(action: { Button(action: {
viewModel.leaveRoom(room) viewModel.leaveRoom(room)
}) { }) {
Text("leave") Text("leave room")
.font(.system(size: 10, design: .monospaced)) .font(.system(size: 10, design: .monospaced))
.foregroundColor(secondaryTextColor) .foregroundColor(secondaryTextColor)
.padding(.horizontal, 8) .padding(.horizontal, 8)