feat(chat): add animated GIF rendering with tap-to-play animation (#721) (#731)

* feat(chat): add animated GIF rendering with tap-to-play animation

Closes #721

* fix(#721): add missing GifImageThumbnail component and format ktlint

* fix(analytics): resolve ktlint indentation error in itemsIndexed

* feat(chat): add interactive play/pause toggle for animated GIFs

* fix(chat): control GIF playback via Animatable start and stop
This commit is contained in:
M57 authored and GitHub committed 2026-07-27 18:32:45 +03:00
1 parent c7f7d1dd45
commit 5c1492a80e
32 files changed
+370 -118

No files matched your search

@@ -92,18 +92,17 @@ class ChatMessageMapperTest {
assertNull(createEntityWithToolStatus(null).toUiModel().toolStatus)
}
private fun createEntityWithRole(role: String): ChatMessageEntity {
return ChatMessageEntity(
private fun createEntityWithRole(role: String): ChatMessageEntity =
ChatMessageEntity(
id = "id",
sessionId = "session",
role = role,
content = "content",
timestamp = 0L,
)
}
private fun createEntityWithToolStatus(status: String?): ChatMessageEntity {
return ChatMessageEntity(
private fun createEntityWithToolStatus(status: String?): ChatMessageEntity =
ChatMessageEntity(
id = "id",
sessionId = "session",
role = "TOOL",
@@ -111,7 +110,6 @@ class ChatMessageMapperTest {
timestamp = 0L,
toolStatus = status,
)
}
@Test
fun entityToUiModelCarriesReasoningText() {
@@ -22,7 +22,8 @@ class CallExtTest {
val call = mockk<Call>()
val request = Request.Builder().url("http://localhost").build()
val response =
Response.Builder()
Response
.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(200)
@@ -26,9 +26,7 @@ class CookieManagerTest {
return jar
}
private fun ep(host: String): ServerEndpoint {
return ServerEndpoint.fromLegacy(host, 9119)
}
private fun ep(host: String): ServerEndpoint = ServerEndpoint.fromLegacy(host, 9119)
private fun httpsEp(
host: String,
@@ -53,7 +53,8 @@ class HermesWsClientTest {
every { AuthManager.serverStore } returns
mockk<com.m57.hermescontrol.data.config.ServerStore>().also {
every { it.getLatestState() } returns
com.m57.hermescontrol.data.config.ServerStoreState()
com.m57.hermescontrol.data.config
.ServerStoreState()
}
// Issue #470: clients are built through OkHttpProvider, which now
@@ -496,7 +497,8 @@ class HermesWsClientTest {
every { AuthManager.serverStore } returns
mockk<com.m57.hermescontrol.data.config.ServerStore>().also {
every { it.getLatestState() } returns
com.m57.hermescontrol.data.config.ServerStoreState(wsAuthParam = "ticket")
com.m57.hermescontrol.data.config
.ServerStoreState(wsAuthParam = "ticket")
}
// No bare-name session cookie present (the prefixed one is server-side).
every { AuthManager.getSessionCookie() } returns null