Skip to content

Commit

Permalink
Merge pull request #156 from canopas/update-seen-by-id-field-in-messa…
Browse files Browse the repository at this point in the history
…ge-threads

Update seen by id field in message threads
  • Loading branch information
kaushiksaliya authored Jan 7, 2025
2 parents f0f6ddd + def5a1d commit cd11194
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ fun MessagesContent(modifier: Modifier) {
state.newMessagesToAppend,
state.threadMembers,
state.currentUserId,
state.thread,
loadMore = { viewModel.loadMore() }
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.canopas.yourspace.ui.navigation.AppDestinations.ThreadMessages.KEY_TH
import com.canopas.yourspace.ui.navigation.AppNavigator
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
Expand Down Expand Up @@ -86,26 +87,23 @@ class MessagesViewModel @Inject constructor(
newMessagesToAppend = appendedMessages,
messagesByDate = newMessages.groupMessagesByDate()
)
markMessagesAsSeen(filter)
markMessagesAsSeen()
}
}
}
}

private fun markMessagesAsSeen(messages: List<ApiThreadMessage>) =
private fun markMessagesAsSeen() =
viewModelScope.launch(appDispatcher.IO) {
delay(2000)
try {
val unreadMessages = messages.distinct()
.filter { !it.seen_by.contains(state.value.currentUserId) }
.map { it.id }

if (unreadMessages.isNotEmpty()) {
messagesRepository.markMessagesAsSeen(
threadId,
unreadMessages,
state.value.currentUserId
)
val thread = state.value.thread ?: return@launch
val userId = state.value.currentUserId
if (thread.seen_by_ids.contains(userId)) {
return@launch
}

messagesRepository.markMessagesAsSeen(threadId, userId)
} catch (e: Exception) {
Timber.e(e, "Error marking messages as seen")
}
Expand Down Expand Up @@ -140,7 +138,6 @@ class MessagesViewModel @Inject constructor(
error = null
)
)
markMessagesAsSeen(newMessages)
loadingData = false
} catch (e: Exception) {
Timber.e(e, "Error loading messages")
Expand Down Expand Up @@ -312,7 +309,10 @@ class MessagesViewModel @Inject constructor(
val newMessage = messagesRepository.generateMessage(message, userId, threadId)
val newMessages = state.value.newMessagesToAppend.toMutableList()
newMessages.add(newMessage)
_state.emit(_state.value.copy(newMessagesToAppend = newMessages))

val thread = state.value.thread?.copy(seen_by_ids = emptyList())
_state.emit(_state.value.copy(newMessagesToAppend = newMessages, thread = thread))

messagesRepository.sendMessage(newMessage)
} catch (e: Exception) {
Timber.e(e, "Failed to send message")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.canopas.yourspace.R
import com.canopas.yourspace.data.models.messages.ApiThread
import com.canopas.yourspace.data.models.messages.ApiThreadMessage
import com.canopas.yourspace.data.models.user.UserInfo
import com.canopas.yourspace.domain.utils.formattedMessageDateHeader
Expand All @@ -55,6 +56,7 @@ fun ColumnScope.MessageList(
newMessagesToAppend: List<ApiThreadMessage>,
members: List<UserInfo>,
currentUserId: String,
thread: ApiThread?,
loadMore: () -> Unit
) {
val reachedBottom by remember {
Expand Down Expand Up @@ -98,11 +100,15 @@ fun ColumnScope.MessageList(
itemsIndexed(messages, key = { _, item -> item.id }) { index, message ->
val by = members.firstOrNull { it.user.id == message.sender_id }

val seenBy =
members.filter { message.seen_by.contains(it.user.id) && it.user.id != currentUserId }
val seenBy = if (thread != null) {
members.filter { thread.seen_by_ids.contains(it.user.id) && it.user.id != currentUserId }
} else {
emptyList()
}

val myLatestMsg =
messages.firstOrNull { it.sender_id == currentUserId }?.id == message.id

MessageContent(
previousMessage = if (index < messages.size - 1) messages[index + 1] else null,
nextMessage = if (index > 0 && index < messages.size - 1) messages[index - 1] else null,
Expand Down Expand Up @@ -231,6 +237,11 @@ fun MessageBubble(
} else {
AppTheme.colorScheme.containerLow
}
val messageTextColor = if (isSender) {
AppTheme.colorScheme.textInversePrimary
} else {
AppTheme.colorScheme.textPrimary
}

val shape = if (isSender) {
RoundedCornerShape(
Expand Down Expand Up @@ -278,7 +289,7 @@ fun MessageBubble(
}
Text(
text = message,
style = AppTheme.appTypography.subTitle3.copy(color = AppTheme.colorScheme.textInversePrimary)
style = AppTheme.appTypography.subTitle3.copy(color = messageTextColor)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private fun LazyItemScope.ThreadItem(
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically
) {
val hasUnreadMsg = message?.seen_by?.contains(currentUser?.id) == false
val hasUnreadMsg = !threadInfo.thread.seen_by_ids.contains(currentUser?.id)
Text(
text = message?.createdAtMs?.formattedMessageTimeString(
LocalContext.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ data class ApiThread(
val id: String = UUID.randomUUID().toString(),
val admin_id: String = "",
val space_id: String = "",
val last_message: String = "",
val member_ids: List<String> = emptyList(),
val seen_by_ids: List<String> = emptyList(),
val archived_for: Map<String, Long> = emptyMap<String, Long>(),
val created_at: Long = System.currentTimeMillis()
val created_at: Long = System.currentTimeMillis(),
val last_message_at: Date? = null
) {
@get:Exclude
val isGroup: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ class MessagesRepository @Inject constructor(
fun getLatestMessages(threadId: String, limit: Int) =
apiMessagesService.getLatestMessages(threadId, limit)

suspend fun markMessagesAsSeen(
threadId: String,
messageIds: List<String>,
currentUserId: String
) {
apiMessagesService.markMessagesAsSeen(threadId, messageIds, currentUserId)
suspend fun markMessagesAsSeen(threadId: String, currentUserId: String) {
apiMessagesService.markMessagesAsSeen(threadId, currentUserId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ class ApiMessagesService @Inject constructor(
id = docRef.id,
thread_id = threadId,
sender_id = senderId,
message = message,
seen_by = listOf(senderId)
message = message
)
docRef.set(threadMessage).await()
}
Expand All @@ -105,8 +104,7 @@ class ApiMessagesService @Inject constructor(
id = docRef.id,
thread_id = threadId,
sender_id = senderId,
message = message,
seen_by = listOf(senderId)
message = message
)
}

Expand All @@ -115,16 +113,8 @@ class ApiMessagesService @Inject constructor(
docRef.set(message).await()
}

suspend fun markMessagesAsSeen(threadId: String, messageIds: List<String>, userId: String) {
db.runBatch { batch ->
messageIds.forEach { id ->
batch.update(
threadMessagesRef(threadId).document(id),
"seen_by",
FieldValue.arrayUnion(userId)
)
}
}.await()
suspend fun markMessagesAsSeen(threadId: String, userId: String) {
threadRef.document(threadId).update("seen_by_ids", FieldValue.arrayUnion(userId)).await()
}

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down

0 comments on commit cd11194

Please sign in to comment.