diff --git a/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt b/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt index 6579fdc..9f4ffed 100644 --- a/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt +++ b/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt @@ -166,6 +166,10 @@ fun ChatScreen( if (errors.isNotEmpty()) { loadError = errors.joinToString(" · ") } + scope.launch { + val ids = chat.conversationRepo.allUnlockedIds() + chat.messageRepo.prefetchMissing(cfg.baseUrl, cfg.token, ids) + } } // Warm the HTTP/2 connection pool on every app resume (covers background → foreground diff --git a/app/src/main/java/dev/kaizen/app/db/ConversationDao.kt b/app/src/main/java/dev/kaizen/app/db/ConversationDao.kt index 644b523..01b5936 100644 --- a/app/src/main/java/dev/kaizen/app/db/ConversationDao.kt +++ b/app/src/main/java/dev/kaizen/app/db/ConversationDao.kt @@ -25,4 +25,7 @@ interface ConversationDao { @Query("SELECT cachedAt FROM conversations LIMIT 1") suspend fun lastCachedAt(): Long? + + @Query("SELECT id FROM conversations WHERE locked = 0") + suspend fun allUnlockedIds(): List } diff --git a/app/src/main/java/dev/kaizen/app/db/ConversationRepository.kt b/app/src/main/java/dev/kaizen/app/db/ConversationRepository.kt index 9558461..870074e 100644 --- a/app/src/main/java/dev/kaizen/app/db/ConversationRepository.kt +++ b/app/src/main/java/dev/kaizen/app/db/ConversationRepository.kt @@ -22,4 +22,6 @@ class ConversationRepository(private val dao: ConversationDao) { } suspend fun lastCachedAt(): Long? = dao.lastCachedAt() + + suspend fun allUnlockedIds(): List = dao.allUnlockedIds() } diff --git a/app/src/main/java/dev/kaizen/app/db/MessageDao.kt b/app/src/main/java/dev/kaizen/app/db/MessageDao.kt index 9e39e23..6f61fbf 100644 --- a/app/src/main/java/dev/kaizen/app/db/MessageDao.kt +++ b/app/src/main/java/dev/kaizen/app/db/MessageDao.kt @@ -18,4 +18,7 @@ interface MessageDao { @Query("DELETE FROM messages WHERE conversationId = :convId") suspend fun deleteByConversation(convId: String) + + @Query("SELECT DISTINCT conversationId FROM messages") + suspend fun cachedConversationIds(): List } diff --git a/app/src/main/java/dev/kaizen/app/db/MessageRepository.kt b/app/src/main/java/dev/kaizen/app/db/MessageRepository.kt index 1e5fa17..b90df6d 100644 --- a/app/src/main/java/dev/kaizen/app/db/MessageRepository.kt +++ b/app/src/main/java/dev/kaizen/app/db/MessageRepository.kt @@ -21,4 +21,14 @@ class MessageRepository(private val dao: MessageDao) { suspend fun cacheMessages(convId: String, messages: List) { dao.upsertAll(messages) } + + suspend fun prefetchMissing(baseUrl: String, token: String, conversationIds: List) { + val cached = dao.cachedConversationIds().toSet() + for (id in conversationIds) { + if (id in cached) continue + try { + fetchAndCache(baseUrl, token, id) + } catch (_: Exception) { } + } + } }