Files
forkmessager/client-mobile/chats/data/paging/MessagePagingSource.kt
Халимов Рустам 7c66e1c0c0 Кэш чатов
2026-04-20 00:25:40 +03:00

81 lines
3.6 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package chats.data.paging
import androidx.paging.PagingSource
import androidx.paging.PagingState
import core.database.data.MessageDao
import core.database.data.MessageEntity
import android.util.Log
/**
* PagingSource для загрузки сообщений из локальной базы Room
* Данные сортируются по sequenceId DESC (новые сообщения первыми)
*/
class MessagePagingSource(
private val dao: MessageDao,
private val chatId: String
) : PagingSource<Int, MessageEntity>() {
companion object {
private const val TAG = "MessagePagingSource"
}
override fun getRefreshKey(state: PagingState<Int, MessageEntity>): Int? {
Log.d(TAG, "getRefreshKey() called")
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MessageEntity> {
Log.d(TAG, ">>> load() called with: position=${params.key}, loadSize=${params.loadSize}")
return try {
// При DESC порядке:
// - key = sequenceId последнего сообщения в текущей странице
// - APPEND = загружаем сообщения С МЕНЬШИМ sequenceId (старые)
// - PREPEND = загружаем сообщения С БОЛЬШИМ sequenceId (новые)
val position = params.key // sequenceId граничного сообщения
val loadSize = params.loadSize
Log.d(TAG, "Loading: chatId=$chatId, position=$position, loadSize=$loadSize")
val messages = if (position == null) {
// Первая загрузка - получаем самые последние сообщения (включая maxSeq)
val maxSeq = dao.getMaxSequenceId(chatId)
Log.d(TAG, "First load: maxSeq=$maxSeq")
if (maxSeq == null) {
Log.d(TAG, "No messages in database")
emptyList()
} else {
// Используем <= чтобы включить самое последнее сообщение
dao.getMessagesUpToAndIncluding(chatId, maxSeq, loadSize)
}
} else {
// Загружаем сообщения с sequenceId < position (старые)
Log.d(TAG, "Append: loading messages before sequenceId=$position")
dao.getMessagesBefore(chatId, position, loadSize)
}
Log.d(TAG, "Loaded ${messages.size} messages, first=${messages.firstOrNull()?.sequenceId}, last=${messages.lastOrNull()?.sequenceId}")
// Для DESC порядка:
// - prevKey = максимальный sequenceId в странице (для загрузки новых)
// - nextKey = минимальный sequenceId в странице (для загрузки старых)
val prevKey = messages.firstOrNull()?.sequenceId?.plus(1)
val nextKey = messages.lastOrNull()?.sequenceId?.minus(1)
Log.d(TAG, "prevKey=$prevKey, nextKey=$nextKey")
LoadResult.Page(
data = messages,
prevKey = prevKey,
nextKey = nextKey
)
} catch (e: Exception) {
Log.e(TAG, "Error loading messages", e)
LoadResult.Error(e)
}
}
}