Офлайн режим, начало
This commit is contained in:
@@ -15,6 +15,7 @@ import chats.domain.model.Message
|
||||
import chats.domain.model.MediaType
|
||||
import chats.domain.repository.ChatRepository
|
||||
import core.database.data.ChatDatabase
|
||||
import core.database.data.ChatDao
|
||||
import core.database.data.MessageDao
|
||||
import core.database.data.MessageEntity
|
||||
import core.database.data.SyncStatus
|
||||
@@ -51,7 +52,8 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
private val api: ChatApi,
|
||||
private val tokenManager: TokenManager,
|
||||
private val serverConfig: ServerConfig,
|
||||
private val dao: MessageDao,
|
||||
private val messageDao: MessageDao,
|
||||
private val chatDao: ChatDao,
|
||||
private val database: ChatDatabase,
|
||||
private val hubClient: ChatHubClient,
|
||||
private val signalRHandler: MessageSignalRHandler,
|
||||
@@ -68,7 +70,43 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
|
||||
override suspend fun getChats(): List<Chat> {
|
||||
val currentUserId = tokenManager.getUserId() ?: ""
|
||||
return api.getChats().map { it.toDomain(currentUserId, baseUrl) }
|
||||
return try {
|
||||
// Пробуем загрузить из сети
|
||||
val chats = api.getChats().map { it.toDomain(currentUserId, baseUrl) }
|
||||
// Кэшируем в Room
|
||||
val entities = chats.map { it.toEntity() }
|
||||
chatDao.insertChats(entities)
|
||||
// Кэшируем последние сообщения
|
||||
chats.forEach { chat ->
|
||||
chat.lastMessage?.let { msg ->
|
||||
messageDao.upsertMessage(msg.toEntity(gson))
|
||||
}
|
||||
}
|
||||
android.util.Log.d(TAG, "Cached ${entities.size} chats with messages")
|
||||
chats
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.d(TAG, "Network load failed, using cache")
|
||||
// При ошибке - возвращаем из кэша с загрузкой последних сообщений
|
||||
chatDao.getAllChats().map { entity ->
|
||||
val lastMessage = entity.lastMessageId?.let { messageId ->
|
||||
messageDao.getMessageById(messageId)?.toDomain(baseUrl, gson)
|
||||
}
|
||||
entity.toDomain(currentUserId, baseUrl, lastMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getChatsFlow(): Flow<List<Chat>> {
|
||||
val currentUserId = tokenManager.getUserId() ?: ""
|
||||
return chatDao.getAllChatsFlow().map { entities ->
|
||||
entities.map { entity ->
|
||||
// Загружаем последнее сообщение из базы для каждого чата
|
||||
val lastMessage = entity.lastMessageId?.let { messageId ->
|
||||
messageDao.getMessageById(messageId)?.toDomain(baseUrl, gson)
|
||||
}
|
||||
entity.toDomain(currentUserId, baseUrl, lastMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMessagesPaging(chatId: String): Flow<PagingData<Message>> {
|
||||
@@ -78,15 +116,15 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
initialLoadSize = 50,
|
||||
enablePlaceholders = false
|
||||
)
|
||||
|
||||
|
||||
return Pager(
|
||||
config = pagingConfig,
|
||||
pagingSourceFactory = { dao.getMessagesPagingSource(chatId) },
|
||||
pagingSourceFactory = { messageDao.getMessagesPagingSource(chatId) },
|
||||
remoteMediator = MessageRemoteMediator(
|
||||
chatId = chatId,
|
||||
api = api,
|
||||
database = database,
|
||||
dao = dao,
|
||||
dao = messageDao,
|
||||
serverConfig = serverConfig,
|
||||
tokenManager = tokenManager
|
||||
)
|
||||
@@ -96,7 +134,7 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
}
|
||||
|
||||
override fun getMessagesFlow(chatId: String): Flow<List<Message>> {
|
||||
return dao.getMessages(chatId).map { entities ->
|
||||
return messageDao.getMessages(chatId).map { entities ->
|
||||
entities.map { it.toDomain(baseUrl, gson) }
|
||||
}
|
||||
}
|
||||
@@ -111,7 +149,7 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
|
||||
if (messages.isNotEmpty()) {
|
||||
val entities = messages.map { it.toEntity(baseUrl, currentUserId, gson) }
|
||||
dao.upsertMessages(entities)
|
||||
messageDao.upsertMessages(entities)
|
||||
Log.d(TAG, "Cached ${entities.size} messages")
|
||||
}
|
||||
|
||||
@@ -145,7 +183,7 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
editedContent = null, lastUpdated = currentTime
|
||||
)
|
||||
|
||||
dao.insertMessage(localMessage)
|
||||
messageDao.insertMessage(localMessage)
|
||||
Log.d(TAG, "Saved local message: $localId")
|
||||
MessageSyncWorker.scheduleSync(context)
|
||||
|
||||
@@ -191,20 +229,20 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error marking messages as read", e)
|
||||
}
|
||||
dao.markMessagesAsRead(chatId, lastReadSequenceId)
|
||||
messageDao.markMessagesAsRead(chatId, lastReadSequenceId)
|
||||
}
|
||||
|
||||
override suspend fun saveMessage(message: Message) {
|
||||
dao.insertMessage(message.toEntity(gson))
|
||||
messageDao.insertMessage(message.toEntity(gson))
|
||||
}
|
||||
|
||||
override suspend fun deleteLocalMessage(messageId: String) {
|
||||
dao.markAsDeletedLocally(messageId)
|
||||
messageDao.markAsDeletedLocally(messageId)
|
||||
MessageSyncWorker.scheduleSync(context)
|
||||
}
|
||||
|
||||
override suspend fun editLocalMessage(messageId: String, newContent: String) {
|
||||
dao.markAsEditedLocally(messageId, newContent)
|
||||
messageDao.markAsEditedLocally(messageId, newContent)
|
||||
MessageSyncWorker.scheduleSync(context)
|
||||
}
|
||||
|
||||
@@ -239,14 +277,14 @@ class ChatRepositoryImpl @Inject constructor(
|
||||
|
||||
override suspend fun deleteMessage(messageId: String, forEveryone: Boolean) {
|
||||
api.deleteMessage(messageId, forEveryone)
|
||||
dao.deleteMessage(messageId)
|
||||
messageDao.deleteMessage(messageId)
|
||||
}
|
||||
|
||||
override suspend fun editMessage(messageId: String, content: String): Message {
|
||||
val request = SendMessageRequest(content = content)
|
||||
val currentUserId = tokenManager.getUserId() ?: ""
|
||||
val response = api.editMessage(messageId, request)
|
||||
dao.insertMessage(response.toEntity(baseUrl, currentUserId, gson))
|
||||
messageDao.insertMessage(response.toEntity(baseUrl, currentUserId, gson))
|
||||
return response.toDomain(currentUserId, baseUrl)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user