Add ChatRoomDetailScreen
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
package at.torch.compose.ui.composable
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.icons.filled.DeleteForever
|
||||
import androidx.compose.material.icons.filled.PersonAdd
|
||||
import androidx.compose.material.icons.filled.Unsubscribe
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import at.torch.compose.database.model.ChatRoom
|
||||
import at.torch.compose.database.model.Participant
|
||||
import at.torch.compose.database.model.Profile
|
||||
import at.torch.compose.database.model.intermdiate.LocalChatRoom
|
||||
import at.torch.compose.database.model.intermdiate.LocalParticipant
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.composable.navigation.routes.ImplementationPendingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.Route
|
||||
import at.torch.compose.ui.composable.navigation.routes.SearchMemberToAddToChatRoomRoute
|
||||
import at.torch.compose.ui.composable.widgets.LoadingDataIndicator
|
||||
import at.torch.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
import at.torch.compose.ui.theme.TorchTheme
|
||||
import at.torch.compose.ui.view.model.ChatRoomDetailViewModel
|
||||
import at.torch.compose.ui.view.state.ChatRoomDetailUIState
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ChatRoomDetailScreen(
|
||||
activeUserPublicKey: HexKey,
|
||||
chatRoomId: String,
|
||||
relayHint: String?,
|
||||
initialChatRoomDetailUIState: ChatRoomDetailUIState = ChatRoomDetailUIState.Loading,
|
||||
nostrRepository: NostrRepository,
|
||||
chatRepository: ChatRepository,
|
||||
onNavigateToRoute: (Route) -> Unit,
|
||||
) {
|
||||
val chatRoomDetailViewModel: ChatRoomDetailViewModel = viewModel(
|
||||
factory = ChatRoomDetailViewModel.factory(
|
||||
chatRoomId = chatRoomId,
|
||||
relayHint = relayHint,
|
||||
initialChatRoomDetailUIState = initialChatRoomDetailUIState,
|
||||
nostrRepository = nostrRepository,
|
||||
chatRepository = chatRepository,
|
||||
activeUserPublicKey = activeUserPublicKey
|
||||
)
|
||||
)
|
||||
|
||||
when (val chatRoomDetailUIState = chatRoomDetailViewModel.chatRoomDetailUIState) {
|
||||
is ChatRoomDetailUIState.Error -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Spacer(
|
||||
modifier = Modifier.height(50.dp)
|
||||
)
|
||||
Text(
|
||||
text = chatRoomDetailUIState.message,
|
||||
)
|
||||
}
|
||||
}
|
||||
is ChatRoomDetailUIState.Loaded -> {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
chatRoomDetailUIState.localChatRoom.RenderChatRoomTitleText()
|
||||
},
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier.padding(innerPadding).fillMaxSize()
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
// TODO: Add Description...
|
||||
// item {
|
||||
// chatRoomDetailUIState.localChatRoom.chatRoom.subject?.let {
|
||||
// Text(
|
||||
// text = it
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
item {
|
||||
// Media and such should be here...
|
||||
}
|
||||
item {
|
||||
Text("members")
|
||||
}
|
||||
|
||||
item {
|
||||
TextButton(
|
||||
onClick = {
|
||||
// Navigate to the invite user screen...
|
||||
onNavigateToRoute.invoke(
|
||||
SearchMemberToAddToChatRoomRoute(
|
||||
chatRoomId = chatRoomId,
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
relayHint = relayHint
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
|
||||
Icon(
|
||||
Icons.Default.PersonAdd,
|
||||
contentDescription = "Invite new member"
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.width(10.dp)
|
||||
)
|
||||
|
||||
Text("Invite New Member")
|
||||
}
|
||||
}
|
||||
|
||||
items(
|
||||
items = chatRoomDetailUIState.localChatRoom.localParticipants,
|
||||
key = { localParticipant -> localParticipant.participant.participantPublicKey}
|
||||
) { localParticipant ->
|
||||
|
||||
Card(
|
||||
onClick = {
|
||||
onNavigateToRoute.invoke(
|
||||
ImplementationPendingRoute(
|
||||
"Profile detail"
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
ListItem(
|
||||
leadingContent = {
|
||||
ProfileAvatar(
|
||||
publicKey = localParticipant.participant.participantPublicKey,
|
||||
profile = localParticipant.profile
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
Icon(
|
||||
Icons.Default.ChevronRight,
|
||||
contentDescription = "View profile"
|
||||
)
|
||||
},
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = localParticipant.profile?.humanReadableNameOrPubkey() ?: localParticipant.participant.participantPublicKey
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
localParticipant.profile?.about?.let {
|
||||
Text(
|
||||
text = it
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
item {
|
||||
HorizontalDivider()
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
TextButton(
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
contentColor = MaterialTheme.colorScheme.secondary
|
||||
),
|
||||
enabled = true, // Disable after we leave group...
|
||||
onClick = {
|
||||
onNavigateToRoute.invoke(
|
||||
ImplementationPendingRoute(
|
||||
"Leave Group"
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Unsubscribe,
|
||||
contentDescription = "Leave Group"
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.width(10.dp)
|
||||
)
|
||||
|
||||
Text("Leave Group")
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
TextButton(
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
contentColor = MaterialTheme.colorScheme.error
|
||||
),
|
||||
enabled = true, // TODO: Only enabled after we leave group...
|
||||
onClick = {
|
||||
onNavigateToRoute.invoke(
|
||||
ImplementationPendingRoute(
|
||||
"Delete Group"
|
||||
)
|
||||
)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.DeleteForever,
|
||||
contentDescription = "Delete Group"
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.width(10.dp)
|
||||
)
|
||||
|
||||
Text("Delete Group")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChatRoomDetailUIState.Loading -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
20.dp
|
||||
),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp)
|
||||
) {
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
Text(
|
||||
text = "Direct Message Detail",
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Direct message functionality will be here.",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
LoadingDataIndicator(
|
||||
fillScreen = false
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.weight(2f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(true) {
|
||||
if (initialChatRoomDetailUIState == ChatRoomDetailUIState.Loading) {
|
||||
chatRoomDetailViewModel.initiateChatRoomDetail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun ChatRoomMessagingScreenPreview() {
|
||||
TorchTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
ChatRoomDetailScreen(
|
||||
activeUserPublicKey = "",
|
||||
chatRoomId = "publicKey",
|
||||
relayHint = null,
|
||||
initialChatRoomDetailUIState = ChatRoomDetailUIState.Loaded(
|
||||
localChatRoom = LocalChatRoom(
|
||||
chatRoom = ChatRoom(
|
||||
id = "",
|
||||
userPublicKey = "",
|
||||
subject = "Message title",
|
||||
initialGiftWrapPayloadId = "sdfaer",
|
||||
mlsGroupState = null
|
||||
),
|
||||
localParticipants = listOf(
|
||||
LocalParticipant(
|
||||
participant = Participant(
|
||||
id = 2,
|
||||
participantPublicKey = "gex",
|
||||
chatRoomId = "chatRoomId",
|
||||
relayHint = null
|
||||
),
|
||||
profile = Profile(
|
||||
publicKey = "gex",
|
||||
displayName = "Gexie",
|
||||
nostrEventId = "nosrtEventId"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY,
|
||||
chatRepository = ChatRepository.NO_OP_CHAT_REPOSITORY,
|
||||
onNavigateToRoute = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Mic
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.PersonAdd
|
||||
import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.material3.BottomAppBarDefaults
|
||||
@@ -41,6 +42,7 @@ import at.torch.compose.database.model.ChatRoom
|
||||
import at.torch.compose.database.model.intermdiate.LocalChatRoom
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.Route
|
||||
import at.torch.compose.ui.composable.navigation.routes.SearchMemberToAddToChatRoomRoute
|
||||
import at.torch.compose.ui.composable.widgets.LoadingDataIndicator
|
||||
@@ -108,7 +110,7 @@ fun ChatRoomMessagingScreen(
|
||||
onClick = {
|
||||
// Navigate to the invite user screen...
|
||||
onNavigateToRoute.invoke(
|
||||
SearchMemberToAddToChatRoomRoute(
|
||||
ChatRoomDetailRoute(
|
||||
chatRoomId = chatRoomId,
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
relayHint = relayHint
|
||||
@@ -117,8 +119,8 @@ fun ChatRoomMessagingScreen(
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.PersonAdd,
|
||||
contentDescription = "Invite memeber"
|
||||
Icons.Default.MoreVert,
|
||||
contentDescription = "View details..."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import at.torch.compose.managers.AuxDatabaseManager
|
||||
import at.torch.compose.ui.composable.ActiveProfileScreen
|
||||
import at.torch.compose.ui.composable.AddMemberToChatRoomConfirmationScreen
|
||||
import at.torch.compose.ui.composable.ChatRoomCreationScreen
|
||||
import at.torch.compose.ui.composable.ChatRoomDetailScreen
|
||||
import at.torch.compose.ui.composable.ChatRoomMessagingScreen
|
||||
import at.torch.compose.ui.composable.CreateProfileScreen
|
||||
import at.torch.compose.ui.composable.HomeScreen
|
||||
@@ -48,6 +49,7 @@ import at.torch.compose.ui.composable.navigation.routes.AddMemberToChatRoomConfi
|
||||
import at.torch.compose.ui.composable.navigation.routes.BlankRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomCreationRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomMessagingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.CreateProfileRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.FeedRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ImplementationPendingRoute
|
||||
@@ -554,8 +556,8 @@ fun TorchNavHost(
|
||||
}
|
||||
)
|
||||
}
|
||||
composable<ChatRoomDetailRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<ChatRoomDetailRoute>()
|
||||
composable<ChatRoomMessagingRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<ChatRoomMessagingRoute>()
|
||||
|
||||
ChatRoomMessagingScreen(
|
||||
activeUserPublicKey = route.activeUserPublicKey,
|
||||
@@ -579,6 +581,22 @@ fun TorchNavHost(
|
||||
}
|
||||
)
|
||||
}
|
||||
composable<ChatRoomDetailRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<ChatRoomDetailRoute>()
|
||||
|
||||
ChatRoomDetailScreen(
|
||||
activeUserPublicKey = route.activeUserPublicKey,
|
||||
chatRoomId = route.chatRoomId,
|
||||
relayHint = route.relayHint,
|
||||
nostrRepository = databaseNostrRepository,
|
||||
chatRepository = databaseChatRepository,
|
||||
onNavigateToRoute = { actionRoute ->
|
||||
navController.navigate(
|
||||
route = actionRoute
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
composable<SearchMemberToAddToChatRoomRoute> { backStackEntry ->
|
||||
val route = backStackEntry.toRoute<SearchMemberToAddToChatRoomRoute>()
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package at.torch.compose.ui.composable.navigation.routes
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ChatRoomMessagingRoute(
|
||||
val activeUserPublicKey: String,
|
||||
val chatRoomId: String, // TODO: have this as a publicKey
|
||||
val relayHint: String?
|
||||
): Route()
|
||||
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBackIosNew
|
||||
@@ -27,10 +26,8 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LargeTopAppBar
|
||||
import androidx.compose.material3.LoadingIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.PrimaryScrollableTabRow
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
@@ -50,7 +47,7 @@ import at.torch.compose.database.model.NostrEvent
|
||||
import at.torch.compose.database.model.Profile
|
||||
import at.torch.compose.database.model.intermdiate.LocalNostrEvent
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomMessagingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ImplementationPendingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.Route
|
||||
import at.torch.compose.ui.composable.widgets.profile.ProfileAvatar
|
||||
@@ -60,7 +57,6 @@ import at.torch.compose.ui.view.model.MetadataEventDetailViewModel
|
||||
import at.torch.compose.ui.view.state.MetadataEventDetailUIState
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
@@ -284,7 +280,7 @@ fun MetadataEventDetail(
|
||||
Button(
|
||||
onClick = {
|
||||
onNavigateToChatRoom.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
chatRoomId = localNostrEvent.nostrEvent.pubKey,
|
||||
relayHint = localNostrEvent.nostrEvent.relayUrl,
|
||||
|
||||
@@ -11,7 +11,7 @@ import at.torch.compose.extensions.toHex
|
||||
import at.torch.compose.nostr.Relays
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomMessagingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ImplementationPendingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.Route
|
||||
import at.torch.compose.ui.view.state.form.ChatRoomCreationFormState
|
||||
@@ -93,7 +93,7 @@ class ChatRoomCreationViewModel(
|
||||
|
||||
// TODO: Navigate to invitation screen...
|
||||
onNavigateToChatRoom.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = keyPair.pubKey.toHexKey(),
|
||||
chatRoomId = localChatRoom.chatRoom.id,
|
||||
relayHint = null
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package at.torch.compose.ui.view.model
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.view.state.ChatRoomDetailUIState
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ChatRoomDetailViewModel(
|
||||
val chatRoomId: String,
|
||||
val activeUserPublicKey: HexKey,
|
||||
val relayHint: String?,
|
||||
initialChatRoomDetailUIState: ChatRoomDetailUIState,
|
||||
val nostrRepository: NostrRepository,
|
||||
val chatRepository: ChatRepository
|
||||
): ViewModel() {
|
||||
|
||||
var chatRoomDetailUIState: ChatRoomDetailUIState by mutableStateOf(initialChatRoomDetailUIState)
|
||||
private set
|
||||
|
||||
|
||||
|
||||
private val logger = Logger.withTag(TAG)
|
||||
|
||||
val isActionPending: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
fun initiateChatRoomDetail() {
|
||||
logger.d("compressed (most likely chat room): $chatRoomId")
|
||||
// Get ChatRoomById
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val localChatRoom = chatRepository.getChatRoomByIdentifier(chatRoomId)
|
||||
|
||||
chatRoomDetailUIState = if (localChatRoom == null) {
|
||||
// Initiate new chat... and navigate to new chat...
|
||||
ChatRoomDetailUIState.Error("Missing chat room")
|
||||
} else {
|
||||
ChatRoomDetailUIState.Loaded(
|
||||
localChatRoom = localChatRoom
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ChatRoomDetailViewModel"
|
||||
|
||||
fun factory(
|
||||
activeUserPublicKey: HexKey,
|
||||
chatRoomId: String,
|
||||
relayHint: String?,
|
||||
initialChatRoomDetailUIState: ChatRoomDetailUIState = ChatRoomDetailUIState.Loading,
|
||||
nostrRepository: NostrRepository,
|
||||
chatRepository: ChatRepository
|
||||
): ViewModelProvider.Factory = viewModelFactory {
|
||||
initializer {
|
||||
ChatRoomDetailViewModel(
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
chatRoomId = chatRoomId,
|
||||
relayHint = relayHint,
|
||||
initialChatRoomDetailUIState = initialChatRoomDetailUIState,
|
||||
nostrRepository = nostrRepository,
|
||||
chatRepository = chatRepository
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,15 +30,10 @@ import at.torch.compose.database.model.types.SynchronizationFilter
|
||||
import at.torch.compose.nostr.Relays
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.vitorpamplona.quartz.marmot.mip03GroupMessages.GroupEvent
|
||||
import com.vitorpamplona.quartz.marmot.mls.group.MlsGroup
|
||||
import com.vitorpamplona.quartz.marmot.mls.group.MlsGroupState
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import io.ktor.utils.io.core.toByteArray
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.log
|
||||
import kotlin.time.Instant
|
||||
|
||||
class ChatRoomListViewModel(
|
||||
initialChatRoomListUIState: at.torch.compose.ui.view.state.ChatRoomListUIState,
|
||||
@@ -179,7 +174,7 @@ class ChatRoomListViewModel(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
onNavigateToDirectMessageDetail.invoke(
|
||||
_root_ide_package_.at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute(
|
||||
_root_ide_package_.at.torch.compose.ui.composable.navigation.routes.ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = publicKey,
|
||||
chatRoomId = localChatRoom.chatRoom.id,
|
||||
relayHint = localChatRoom.localParticipants.firstOrNull { it.participant.participantPublicKey != localChatRoom.chatRoom.userPublicKey }?.participant?.relayHint
|
||||
|
||||
@@ -11,7 +11,7 @@ import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import at.torch.compose.repository.ChatRepository
|
||||
import at.torch.compose.repository.NostrRepository
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomDetailRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.ChatRoomMessagingRoute
|
||||
import at.torch.compose.ui.composable.navigation.routes.Route
|
||||
import at.torch.compose.ui.view.state.ChatRoomMessagingUIState
|
||||
import co.touchlab.kermit.Logger
|
||||
@@ -73,7 +73,7 @@ class ChatRoomMessagingViewModel(
|
||||
// TODO: navigateToTheChat...
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
onNavigateToChat.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
chatRoomId = localChatRoom.chatRoom.id,
|
||||
relayHint = relayHint
|
||||
@@ -89,7 +89,7 @@ class ChatRoomMessagingViewModel(
|
||||
// We have found the chat we are looking for...
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
onNavigateToChat.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
chatRoomId = localChatRoom.chatRoom.id,
|
||||
relayHint = relayHint
|
||||
@@ -121,7 +121,7 @@ class ChatRoomMessagingViewModel(
|
||||
)
|
||||
|
||||
onNavigateToChat.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
ChatRoomMessagingRoute(
|
||||
activeUserPublicKey = activeUserPublicKey,
|
||||
chatRoomId = chatRoomId,
|
||||
relayHint = relayHint
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package at.torch.compose.ui.view.state
|
||||
|
||||
import at.torch.compose.database.model.intermdiate.LocalChatRoom
|
||||
|
||||
sealed interface ChatRoomDetailUIState {
|
||||
data class Loaded(
|
||||
val localChatRoom: LocalChatRoom
|
||||
): ChatRoomDetailUIState
|
||||
|
||||
data class Error(
|
||||
val message: String
|
||||
): ChatRoomDetailUIState
|
||||
data object Loading: ChatRoomDetailUIState
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user