Show LocalChatMessage.kt instead of localChatRoom on chat detail message list
This commit is contained in:
@@ -2,6 +2,7 @@ package ac.cord.auxiliary.compose.database.dao
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.ChatMessage
|
||||
import ac.cord.auxiliary.compose.database.model.Relay
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
|
||||
import androidx.room3.Dao
|
||||
import androidx.room3.Query
|
||||
import androidx.room3.Upsert
|
||||
@@ -10,7 +11,10 @@ import kotlinx.coroutines.flow.Flow
|
||||
@Dao
|
||||
interface ChatMessageDao {
|
||||
@Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId")
|
||||
fun observeChatMessagesByChatRoomId(chatRoomId: String): Flow<List<ChatMessage>>
|
||||
fun observeChatMessagesByChatRoomId(chatRoomId: String): Flow<List<LocalChatMessage>>
|
||||
|
||||
@Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId")
|
||||
fun getChatMessagesByChatRoomId(chatRoomId: String): List<LocalChatMessage>
|
||||
|
||||
@Upsert
|
||||
suspend fun upsert(chatMessage: ChatMessage)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package ac.cord.auxiliary.compose.database.model.intermdiate
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.ChatMessage
|
||||
import ac.cord.auxiliary.compose.database.model.ChatRoom
|
||||
import ac.cord.auxiliary.compose.database.model.Mention
|
||||
import ac.cord.auxiliary.compose.database.model.Participant
|
||||
import ac.cord.auxiliary.compose.database.model.Post
|
||||
import ac.cord.auxiliary.compose.database.model.Profile
|
||||
import androidx.room3.Embedded
|
||||
import androidx.room3.Relation
|
||||
|
||||
data class LocalChatMessage(
|
||||
@Embedded val chatMessage: ChatMessage,
|
||||
|
||||
)
|
||||
@@ -2,10 +2,12 @@ package ac.cord.auxiliary.compose.database.repository
|
||||
|
||||
import ac.cord.auxiliary.compose.database.AuxDatabase
|
||||
import ac.cord.auxiliary.compose.database.model.ChatRoom
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatRoom
|
||||
import ac.cord.auxiliary.compose.repository.ChatRepository
|
||||
import co.touchlab.kermit.Logger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class DatabaseChatRepository(
|
||||
private val database: AuxDatabase,
|
||||
@@ -21,6 +23,15 @@ class DatabaseChatRepository(
|
||||
return database.chatRoomDao().findChatRoomById(id)
|
||||
}
|
||||
|
||||
override suspend fun getChatMessageListByChatRoomId(chatRoomId: String): List<LocalChatMessage> {
|
||||
return database.chatMessageDao().getChatMessagesByChatRoomId(chatRoomId)
|
||||
}
|
||||
|
||||
override suspend fun observeChatMessageListByChatRoomId(chatRoomId: String): Flow<List<LocalChatMessage>> {
|
||||
return database.chatMessageDao().observeChatMessagesByChatRoomId(chatRoomId)
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getOrCreateChatRoom(publicKey: String, defaultSubject: String?): LocalChatRoom? = try {
|
||||
return database.nostrNip17Dao().getOrCreateChatRoom(
|
||||
publicKey,
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package ac.cord.auxiliary.compose.repository
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.ChatRoom
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatRoom
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
interface ChatRepository {
|
||||
suspend fun getChatRoomListByPublicKey(publicKey: String): List<LocalChatRoom>
|
||||
|
||||
suspend fun getChatRoomByIdentifier(id: String): LocalChatRoom?
|
||||
|
||||
suspend fun getChatMessageListByChatRoomId(chatRoomId: String): List<LocalChatMessage>
|
||||
|
||||
suspend fun observeChatMessageListByChatRoomId(chatRoomId: String): Flow<List<LocalChatMessage>>
|
||||
|
||||
suspend fun getOrCreateChatRoom(publicKey: String, defaultSubject: String? = null): LocalChatRoom?
|
||||
|
||||
fun updateChatRoomSubject(publicKey: String, subject: String): ChatRoom?
|
||||
@@ -22,6 +29,15 @@ interface ChatRepository {
|
||||
return null
|
||||
}
|
||||
|
||||
override suspend fun getChatMessageListByChatRoomId(chatRoomId: String): List<LocalChatMessage> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override suspend fun observeChatMessageListByChatRoomId(chatRoomId: String): Flow<List<LocalChatMessage>> {
|
||||
return flow {
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getOrCreateChatRoom(publicKey: String, defaultSubject: String?): LocalChatRoom? {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -56,8 +56,11 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
@@ -132,9 +135,7 @@ fun ChatRoomDetailScreen(
|
||||
modifier = Modifier.weight(1f).fillMaxWidth()
|
||||
) {
|
||||
key(true) {
|
||||
chatRoomDetailMessageListViewModel.RenderMessages(
|
||||
onNavigateToDirectMessageDetail = {}
|
||||
)
|
||||
chatRoomDetailMessageListViewModel.RenderMessages()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,54 +194,54 @@ fun ChatRoomDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(4.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.InsertEmoticon,
|
||||
contentDescription = "Add emoji"
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.AlternateEmail,
|
||||
contentDescription = "Mention profile"
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Collections,
|
||||
contentDescription = "Attach media"
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.LocationOn,
|
||||
contentDescription = "Send location"
|
||||
)
|
||||
}
|
||||
}
|
||||
// Row(
|
||||
// modifier = Modifier.padding(4.dp),
|
||||
// horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
// ) {
|
||||
// IconButton(
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// ) {
|
||||
// Icon(
|
||||
// Icons.Default.InsertEmoticon,
|
||||
// contentDescription = "Add emoji"
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// IconButton(
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// ) {
|
||||
// Icon(
|
||||
// Icons.Default.AlternateEmail,
|
||||
// contentDescription = "Mention profile"
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// IconButton(
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// ) {
|
||||
// Icon(
|
||||
// Icons.Default.Collections,
|
||||
// contentDescription = "Attach media"
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// IconButton(
|
||||
// onClick = {
|
||||
//
|
||||
// }
|
||||
// ) {
|
||||
// Icon(
|
||||
// Icons.Default.LocationOn,
|
||||
// contentDescription = "Send location"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import co.touchlab.kermit.Logger
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ChatRoomDetailMessageListViewModel(
|
||||
@@ -55,12 +56,12 @@ class ChatRoomDetailMessageListViewModel(
|
||||
fun observeChatRoomFeed() {
|
||||
logger.d("observeChatRoomFeed")
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
chatRepository.getChatRoomListByPublicKey(
|
||||
chatRepository.observeChatMessageListByChatRoomId(
|
||||
localChatRoom.chatRoom.userPublicKey
|
||||
).let { chatRooms ->
|
||||
logger.d("ChatRoomList: $chatRooms")
|
||||
).distinctUntilChanged().collect { chatMessages ->
|
||||
logger.d("getChatMessageListByChatRoomId: $chatMessages")
|
||||
chatRoomDetailMessageListUIState = ChatRoomDetailMessageListUIState.Loaded(
|
||||
chatRoomList = chatRooms
|
||||
chatMessageList = chatMessages
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -89,9 +90,8 @@ class ChatRoomDetailMessageListViewModel(
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun RenderMessages(
|
||||
onNavigateToDirectMessageDetail: (Route) -> Unit
|
||||
) {
|
||||
fun RenderMessages() {
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
@@ -111,52 +111,56 @@ class ChatRoomDetailMessageListViewModel(
|
||||
}
|
||||
}
|
||||
is ChatRoomDetailMessageListUIState.Loaded -> {
|
||||
Spacer(
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
|
||||
if (chatRoomDetailMessageListUIState.chatRoomList.isEmpty()) {
|
||||
if (chatRoomDetailMessageListUIState.chatMessageList.isEmpty()) {
|
||||
Spacer(
|
||||
modifier = Modifier.height(20.dp)
|
||||
)
|
||||
Text(
|
||||
text = "No messages. Go to a profile and send them a message."
|
||||
modifier = Modifier.padding(20.dp),
|
||||
text = "Currently no messages have been shared.\nBreak the ice.",
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(
|
||||
modifier = Modifier.height(20.dp)
|
||||
)
|
||||
} else {
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier = Modifier.fillMaxWidth().padding(5.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
reverseLayout = true
|
||||
) {
|
||||
items(
|
||||
items = chatRoomDetailMessageListUIState.chatRoomList,
|
||||
key = { it.chatRoom.id }
|
||||
) { localChatRoom ->
|
||||
items = chatRoomDetailMessageListUIState.chatMessageList,
|
||||
key = { it.chatMessage.id }
|
||||
) { localChatMessage ->
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
onNavigateToDirectMessageDetail.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
directMessageIdentifier = localChatRoom.chatRoom.id
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(20.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (localChatRoom.participants.size == 1) {
|
||||
Text(
|
||||
text = "Note to Self (${localChatRoom.participants.first().profile?.humanReadableNameOrPubkey()})"
|
||||
)
|
||||
} else {
|
||||
// Remove the active user publicKey from participants...
|
||||
val participantNames = localChatRoom.participants.filter { it.participant.participantPublicKey != localChatRoom.chatRoom.userPublicKey }.map { it.profile?.humanReadableNameOrPubkey() ?: "unknown participant" }
|
||||
|
||||
Text(
|
||||
text = localChatRoom.chatRoom.subject ?: participantNames.joinToString()
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = localChatMessage.chatMessage.senderPublicKey // TODO: Get send name...
|
||||
)
|
||||
Text(
|
||||
text = localChatMessage.chatMessage.content
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package ac.cord.auxiliary.compose.ui.view.state
|
||||
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatRoom
|
||||
import ac.cord.auxiliary.compose.database.model.intermdiate.LocalChatMessage
|
||||
|
||||
sealed interface ChatRoomDetailMessageListUIState {
|
||||
data class Loaded(
|
||||
val chatRoomList: List<LocalChatRoom>
|
||||
val chatMessageList: List<LocalChatMessage>
|
||||
): ChatRoomDetailMessageListUIState
|
||||
|
||||
data object Error: ChatRoomDetailMessageListUIState
|
||||
|
||||
Reference in New Issue
Block a user