chore: fix app crash when create new room via QR (#3)
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -68,8 +68,19 @@ fun ChatScreen(
|
|||||||
val snackbarHostState = LocalSnackbarHostState.current
|
val snackbarHostState = LocalSnackbarHostState.current
|
||||||
val viewModel = LocalNostrViewModel.current
|
val viewModel = LocalNostrViewModel.current
|
||||||
|
|
||||||
val room = viewModel.getChatRoom(id)
|
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
|
val chatRooms by viewModel.chatRooms.collectAsState()
|
||||||
|
val room = remember(chatRooms, id) { chatRooms.firstOrNull { it.id == id } }
|
||||||
|
|
||||||
|
if (room == null) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
LoadingIndicator()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val displayName by remember(room) { room.displayNameFlow(viewModel) }.collectAsState("Loading...")
|
val displayName by remember(room) { room.displayNameFlow(viewModel) }.collectAsState("Loading...")
|
||||||
val picture by remember(room) { room.pictureFlow(viewModel) }.collectAsState(null)
|
val picture by remember(room) { room.pictureFlow(viewModel) }.collectAsState(null)
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalClipboard
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import coop.composeapp.generated.resources.Res
|
import coop.composeapp.generated.resources.Res
|
||||||
@@ -85,7 +84,6 @@ fun HomeScreen(
|
|||||||
onOpenChat: (Long) -> Unit,
|
onOpenChat: (Long) -> Unit,
|
||||||
onNewChat: () -> Unit,
|
onNewChat: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val clipboard = LocalClipboard.current
|
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val snackbarHostState = LocalSnackbarHostState.current
|
val snackbarHostState = LocalSnackbarHostState.current
|
||||||
val viewModel = LocalNostrViewModel.current
|
val viewModel = LocalNostrViewModel.current
|
||||||
@@ -112,15 +110,21 @@ fun HomeScreen(
|
|||||||
?: remember { mutableStateOf(null) }
|
?: remember { mutableStateOf(null) }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.getChatRooms()
|
if (qrResult == null) {
|
||||||
|
viewModel.getChatRooms()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(qrResult) {
|
LaunchedEffect(qrResult) {
|
||||||
qrResult?.let { result ->
|
qrResult?.let { result ->
|
||||||
runCatching { PublicKey.parse(result) }
|
runCatching { PublicKey.parse(result) }
|
||||||
.onSuccess { pubkey ->
|
.onSuccess { pubkey ->
|
||||||
val roomId = viewModel.createChatRoom(listOf(pubkey))
|
try {
|
||||||
navController.navigate(Screen.Chat(roomId))
|
val roomId = viewModel.createChatRoom(listOf(pubkey))
|
||||||
|
navController.navigate(Screen.Chat(roomId))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.message?.let { snackbarHostState.showSnackbar(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onFailure { e -> println("Failed to parse QR: ${e.message}") }
|
.onFailure { e -> println("Failed to parse QR: ${e.message}") }
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ fun ScanScreen(
|
|||||||
ScannerWithPermissions(
|
ScannerWithPermissions(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
onScanned = {
|
onScanned = {
|
||||||
println("Scanned: $it");
|
|
||||||
onResult(it)
|
onResult(it)
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
@@ -406,20 +407,26 @@ class NostrViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createChatRoom(to: List<PublicKey>): Long {
|
fun createChatRoom(to: List<PublicKey>): Long {
|
||||||
if (nostr.signer.currentUser == null) throw IllegalStateException("User not signed in")
|
try {
|
||||||
if (to.isEmpty()) throw IllegalArgumentException("At least one recipient is required")
|
if (nostr.signer.currentUser == null) throw IllegalStateException("User not signed in")
|
||||||
|
if (to.isEmpty()) throw IllegalArgumentException("At least one recipient is required")
|
||||||
|
|
||||||
// Construct the rumor event
|
// Construct the rumor event
|
||||||
val rumor = EventBuilder
|
val rumor = EventBuilder
|
||||||
.privateMsgRumor(to.first(), "")
|
.privateMsgRumor(to.first(), "")
|
||||||
.tags(to.map { Tag.publicKey(it) })
|
.tags(to.map { Tag.publicKey(it) })
|
||||||
.build(nostr.signer.currentUser!!)
|
.build(nostr.signer.currentUser!!)
|
||||||
|
|
||||||
// Create a room from the rumor event
|
// Create a room from the rumor event
|
||||||
val room = Room.new(rumor, nostr.signer.currentUser!!)
|
val room = Room.new(rumor, nostr.signer.currentUser!!)
|
||||||
_chatRooms.value += room
|
_chatRooms.update { currentRooms ->
|
||||||
|
currentRooms + room
|
||||||
|
}
|
||||||
|
|
||||||
return room.id
|
return room.id
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw IllegalArgumentException("Failed to create room: ${e.message}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChatRoom(id: Long): Room {
|
fun getChatRoom(id: Long): Room {
|
||||||
@@ -429,10 +436,12 @@ class NostrViewModel(
|
|||||||
|
|
||||||
fun getChatRooms() {
|
fun getChatRooms() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
val rooms = nostr.getChatRooms() ?: emptySet()
|
||||||
_chatRooms.value = nostr.getChatRooms() ?: emptySet()
|
_chatRooms.update { currentRooms ->
|
||||||
} catch (e: Exception) {
|
val virtualRooms = currentRooms.filter { local ->
|
||||||
showError("Error: ${e.message}")
|
rooms.none { db -> db.id == local.id }
|
||||||
|
}
|
||||||
|
rooms + virtualRooms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user