diff --git a/client-mobile/.gradle/8.5/executionHistory/executionHistory.bin b/client-mobile/.gradle/8.5/executionHistory/executionHistory.bin index 4fed1e8..96fbddb 100644 Binary files a/client-mobile/.gradle/8.5/executionHistory/executionHistory.bin and b/client-mobile/.gradle/8.5/executionHistory/executionHistory.bin differ diff --git a/client-mobile/.gradle/8.5/executionHistory/executionHistory.lock b/client-mobile/.gradle/8.5/executionHistory/executionHistory.lock index 5072469..3499052 100644 Binary files a/client-mobile/.gradle/8.5/executionHistory/executionHistory.lock and b/client-mobile/.gradle/8.5/executionHistory/executionHistory.lock differ diff --git a/client-mobile/.gradle/8.5/fileHashes/fileHashes.bin b/client-mobile/.gradle/8.5/fileHashes/fileHashes.bin index cbcb994..e2f5b50 100644 Binary files a/client-mobile/.gradle/8.5/fileHashes/fileHashes.bin and b/client-mobile/.gradle/8.5/fileHashes/fileHashes.bin differ diff --git a/client-mobile/.gradle/8.5/fileHashes/fileHashes.lock b/client-mobile/.gradle/8.5/fileHashes/fileHashes.lock index 13e7c18..67f399e 100644 Binary files a/client-mobile/.gradle/8.5/fileHashes/fileHashes.lock and b/client-mobile/.gradle/8.5/fileHashes/fileHashes.lock differ diff --git a/client-mobile/.gradle/8.5/fileHashes/resourceHashesCache.bin b/client-mobile/.gradle/8.5/fileHashes/resourceHashesCache.bin index 9779b4d..aa72534 100644 Binary files a/client-mobile/.gradle/8.5/fileHashes/resourceHashesCache.bin and b/client-mobile/.gradle/8.5/fileHashes/resourceHashesCache.bin differ diff --git a/client-mobile/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/client-mobile/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 2948f8a..ccbd187 100644 Binary files a/client-mobile/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/client-mobile/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/client-mobile/.gradle/buildOutputCleanup/outputFiles.bin b/client-mobile/.gradle/buildOutputCleanup/outputFiles.bin index 27dadd9..cf8f8f1 100644 Binary files a/client-mobile/.gradle/buildOutputCleanup/outputFiles.bin and b/client-mobile/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/client-mobile/chats/data/remote/api/ChatApi.kt b/client-mobile/chats/data/remote/api/ChatApi.kt index b5535cb..3921e71 100644 --- a/client-mobile/chats/data/remote/api/ChatApi.kt +++ b/client-mobile/chats/data/remote/api/ChatApi.kt @@ -27,6 +27,7 @@ interface ChatApi { suspend fun getMessages( @Path("chatId") chatId: String, @Query("cursor") cursor: String? = null, + @Query("pivot") pivot: Long? = null, @Query("limit") limit: Int? = 50 ): List diff --git a/client-mobile/chats/data/repository/ChatRepositoryImpl.kt b/client-mobile/chats/data/repository/ChatRepositoryImpl.kt index 114885d..276d75f 100644 --- a/client-mobile/chats/data/repository/ChatRepositoryImpl.kt +++ b/client-mobile/chats/data/repository/ChatRepositoryImpl.kt @@ -41,27 +41,24 @@ class ChatRepositoryImpl @Inject constructor( } } - override suspend fun getMessages(chatId: String, cursor: String?, limit: Int?): List { + override suspend fun getMessages(chatId: String, cursor: String?, pivot: Long?, limit: Int?): List { val baseUrl = serverConfig.getBaseUrl().removeSuffix("/api/") val currentUserId = tokenManager.getUserId() ?: "" return try { - val chats = api.getChats() - val chatDto = chats.find { it.id == chatId } - val unreadCount = chatDto?.unreadCount ?: 0 - - android.util.Log.d("ChatRepo", "Fetching messages from network for chat: $chatId, cursor: $cursor") + android.util.Log.d("ChatRepo", "FETCH: chatId=$chatId, cursor=$cursor, limit=$limit") val messages = api.getMessages(chatId, cursor = cursor, limit = limit) + if (messages.isNotEmpty()) { - android.util.Log.d("ChatRepo", "Received ${messages.size} messages. First: ${messages.first().createdAt}, Last: ${messages.last().createdAt}") + android.util.Log.d("ChatRepo", "Received ${messages.size} messages. TopSeq: ${messages.first().sequenceId}, BottomSeq: ${messages.last().sequenceId}") } - // Определяем, какие сообщения считаются прочитанными - val mappedMessages = messages.mapIndexed { index, msg -> - val isUnread = (messages.size - index) <= unreadCount && msg.senderId != currentUserId - msg.toDomain(currentUserId, baseUrl).copy(isRead = !isUnread) + // Мапим в доменные модели. По умолчанию считаем прочитанными, + // так как unreadCount нам тут не критичен для истории. + messages.map { msg -> + msg.toDomain(currentUserId, baseUrl).copy(isRead = true) } - mappedMessages } catch (e: Exception) { + android.util.Log.e("ChatRepo", "Fetch messages failed", e) emptyList() } } diff --git a/client-mobile/chats/domain/repository/ChatRepository.kt b/client-mobile/chats/domain/repository/ChatRepository.kt index e652abd..1411ea5 100644 --- a/client-mobile/chats/domain/repository/ChatRepository.kt +++ b/client-mobile/chats/domain/repository/ChatRepository.kt @@ -6,7 +6,7 @@ import chats.domain.model.Message interface ChatRepository { suspend fun getChats(): List fun getMessagesFlow(chatId: String): kotlinx.coroutines.flow.Flow> - suspend fun getMessages(chatId: String, cursor: String? = null, limit: Int? = null): List + suspend fun getMessages(chatId: String, cursor: String? = null, pivot: Long? = null, limit: Int? = null): List suspend fun sendMessage( chatId: String, content: String?, diff --git a/client-mobile/chats/presentation/chat_detail/ChatDetailScreen.kt b/client-mobile/chats/presentation/chat_detail/ChatDetailScreen.kt index b6a30d0..4c08912 100644 --- a/client-mobile/chats/presentation/chat_detail/ChatDetailScreen.kt +++ b/client-mobile/chats/presentation/chat_detail/ChatDetailScreen.kt @@ -221,14 +221,18 @@ fun ChatDetailScreen( } // Подгрузка истории при прокрутке вверх - LaunchedEffect(listState) { - snapshotFlow { listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index } - .collect { lastVisibleIndex -> - if (lastVisibleIndex != null && lastVisibleIndex >= listItems.size - 10 && listItems.size >= 15) { - android.util.Log.d("ChatDetailScreen", "TRIGGER LOAD MORE: index $lastVisibleIndex, size ${listItems.size}") - viewModel.loadMoreMessages() - } + LaunchedEffect(listState, state.messages.size) { + snapshotFlow { + val lastIndex = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 + val totalCount = listState.layoutInfo.totalItemsCount + lastIndex to totalCount + } + .collect { (lastVisibleIndex, totalCount) -> + if (totalCount > 0 && lastVisibleIndex >= totalCount - 20 && !state.isLoadingMore) { + android.util.Log.d("ChatDetailScreen", "TRIGGER LOAD MORE: index $lastVisibleIndex, total $totalCount") + viewModel.loadMoreMessages() } + } } val unreadCount = remember(state.messages) {