Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ interface RepositoryDashboard {
val getAllNotBlockedContacts: Flow<List<Contact>>
val getAllInvites: Flow<List<Invite>>
fun getContactById(contactId: ContactId): Flow<Contact?>
suspend fun getAllContactsByIds(contactIds: List<ContactId>): List<Contact>
var updatedContactIds: MutableList<ContactId>

fun getMessageById(messageId: MessageId): Flow<Message?>
fun getMessagesByIds(messageIds: List<MessageId>): Flow<List<Message?>>
fun getInviteById(inviteId: InviteId): Flow<Invite?>

suspend fun payForInvite(invite: Invite)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,8 +1001,6 @@ abstract class ChatViewModel<ARGS : NavArgs>(
messagesLoadJob = viewModelScope.launch(mainImmediate) {
if (isThreadChat()) {
messageRepository.getAllMessagesToShowByChatId(getChat().id, 0, getThreadUUID()).distinctUntilChanged().collect { messages ->
delay(200)

val originalMessage = messageRepository.getMessageByUUID(MessageUUID(getThreadUUID()?.value!!)).firstOrNull()
val completeThread = listOf(originalMessage) + messages.reversed()
val list = getMessageHolderViewStateList(completeThread.filterNotNull()).toList()
Expand All @@ -1015,14 +1013,10 @@ abstract class ChatViewModel<ARGS : NavArgs>(
}
} else {
messageRepository.getAllMessagesToShowByChatId(getChat().id, 100).firstOrNull()?.let { messages ->
delay(200)

messageHolderViewStateFlow.value = getMessageHolderViewStateList(messages).toList()
shimmerViewState.updateViewState(ShimmerViewState.Off)
}

delay(1000L)

messageRepository.getAllMessagesToShowByChatId(getChat().id, 1000).distinctUntilChanged().collect { messages ->
messageHolderViewStateFlow.value = getMessageHolderViewStateList(messages).toList()
shimmerViewState.updateViewState(ShimmerViewState.Off)
Expand Down Expand Up @@ -2461,4 +2455,3 @@ inline fun Bitmap.toInputStream(): InputStream? {
return ByteArrayInputStream(imageInByte)
}


Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import chat.sphinx.wrapper_chat.ChatType
import chat.sphinx.wrapper_chat.isConversation
import chat.sphinx.wrapper_common.chat.ChatUUID
import chat.sphinx.wrapper_common.dashboard.ContactId
import chat.sphinx.wrapper_common.dashboard.InviteId
import chat.sphinx.wrapper_common.message.MessageId
import chat.sphinx.wrapper_common.tribe.TribeJoinLink
import chat.sphinx.wrapper_common.tribe.toTribeJoinLink
import chat.sphinx.wrapper_contact.*
Expand Down Expand Up @@ -116,7 +118,7 @@ internal class ChatListViewModel @Inject constructor(
viewModelScope.launch(mainImmediate) {
delay(25L)

var allChats = when (args.argChatListType) {
val allChats = when (args.argChatListType) {
ChatType.CONVERSATION -> {
repositoryDashboard.getAllContactChats.distinctUntilChanged()
}
Expand All @@ -132,19 +134,31 @@ internal class ChatListViewModel @Inject constructor(
collectionLock.withLock {
chatsCollectionInitialized = true
val newList = ArrayList<DashboardChat>(chats.size)
val contactsAdded = mutableListOf<ContactId>()
val contactsAdded = mutableSetOf<ContactId>()
val latestMessagesById = getLatestMessagesById(chats)
val contactsById = getContactsById(
chats.mapNotNull { chat ->
if (chat.type.isConversation()) {
chat.contactIds.lastOrNull()
} else {
null
}
}
)
val invitesById = if (contactsCollectionInitialized) {
getInvitesById()
} else {
emptyMap()
}

withContext(default) {
for (chat in chats) {
val message: Message? = chat.latestMessageId?.let {
repositoryDashboard.getMessageById(it).firstOrNull()
}
val message: Message? = chat.latestMessageId?.let(latestMessagesById::get)

if (chat.type.isConversation()) {
val contactId: ContactId = chat.contactIds.lastOrNull() ?: continue

val contact: Contact = repositoryDashboard.getContactById(contactId)
.firstOrNull() ?: continue
val contact: Contact = contactsById[contactId] ?: continue

if (!contact.isBlocked()) {
contactsAdded.add(contactId)
Expand Down Expand Up @@ -178,13 +192,7 @@ internal class ChatListViewModel @Inject constructor(

if (!contactsAdded.contains(contact.id)) {
if (contact.isInviteContact()) {
var contactInvite: Invite? = null

contact.inviteId?.let { inviteId ->
contactInvite = withContext(io) {
repositoryDashboard.getInviteById(inviteId).firstOrNull()
}
}
val contactInvite = contact.inviteId?.let(invitesById::get)
if (contactInvite != null) {
newList.add(
DashboardChat.Inactive.Invite(contact, contactInvite)
Expand Down Expand Up @@ -259,7 +267,7 @@ internal class ChatListViewModel @Inject constructor(
}

val newList = ArrayList<Contact>(contacts.size)
val contactIds = ArrayList<ContactId>(contacts.size)
val contactIds = mutableSetOf<ContactId>()

withContext(default) {
for (contact in contacts) {
Expand All @@ -280,9 +288,20 @@ internal class ChatListViewModel @Inject constructor(
return@withLock
}

val invitesById = getInvitesById()
val conversations = withContext(io) {
repositoryDashboard.getAllContactChats.firstOrNull().orEmpty()
}
val conversationsByContactId = conversations.mapNotNull { chat ->
chat.contactIds.lastOrNull()?.let { contactId ->
contactId to chat
}
}.toMap()
val latestMessagesById = getLatestMessagesById(conversations)

withContext(default) {
val currentChats = currentChatViewState.originalList.toMutableList()
val chatContactIds = mutableListOf<ContactId>()
val chatContactIds = mutableSetOf<ContactId>()

var updateChatViewState = false
for (chat in currentChatViewState.originalList) {
Expand Down Expand Up @@ -330,13 +349,7 @@ internal class ChatListViewModel @Inject constructor(
updateChatViewState = true

if (contact.isInviteContact()) {
var contactInvite: Invite? = null

contact.inviteId?.let { inviteId ->
contactInvite = withContext(io) {
repositoryDashboard.getInviteById(inviteId).firstOrNull()
}
}
val contactInvite = contact.inviteId?.let(invitesById::get)
if (contactInvite != null) {
currentChats.add(
DashboardChat.Inactive.Invite(contact, contactInvite)
Expand All @@ -362,10 +375,8 @@ internal class ChatListViewModel @Inject constructor(

if (updatedContactChat is DashboardChat.Inactive.Conversation) {
//Contact unblocked
repositoryDashboard.getConversationByContactId(contact.id).firstOrNull()?.let { contactChat ->
val message: Message? = contactChat.latestMessageId?.let {
repositoryDashboard.getMessageById(it).firstOrNull()
}
conversationsByContactId[contact.id]?.let { contactChat ->
val message: Message? = contactChat.latestMessageId?.let(latestMessagesById::get)

updatedContactChat = DashboardChat.Active.Conversation(
contactChat,
Expand All @@ -388,6 +399,41 @@ internal class ChatListViewModel @Inject constructor(
}
}

private suspend fun getLatestMessagesById(chats: Collection<Chat>): Map<MessageId, Message> {
val messageIds = chats.mapNotNull { it.latestMessageId }.distinct()
if (messageIds.isEmpty()) {
return emptyMap()
}

return withContext(io) {
repositoryDashboard.getMessagesByIds(messageIds)
.firstOrNull()
.orEmpty()
.filterNotNull()
.associateBy { it.id }
}
}

private suspend fun getContactsById(contactIds: Collection<ContactId>): Map<ContactId, Contact> {
val uniqueContactIds = contactIds.distinct()
if (uniqueContactIds.isEmpty()) {
return emptyMap()
}

return withContext(io) {
repositoryDashboard.getAllContactsByIds(uniqueContactIds)
.associateBy { it.id }
}
}

private suspend fun getInvitesById(): Map<InviteId, Invite> =
withContext(io) {
repositoryDashboard.getAllInvites
.firstOrNull()
.orEmpty()
.associateBy { it.id }
}

suspend fun payForInvite(invite: Invite) {
getAccountBalance().firstOrNull()?.let { balance ->
if (balance.balance.value < (invite.price?.value ?: 0)) {
Expand Down