From 504e66f0c607df82ab0d6d89f6c33baad3019e98 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 23 Aug 2026 21:58:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=87=D0=BA=D0=B8:=20=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BD=D1=8B=D0=B9=20=D0=B8=D0=BD=D0=B4=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=B8=D0=BA=D1=80=D0=BE=D1=84=D0=BE=D0=BD=D0=B0=20=D0=B2?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B5=20=C2=AB=D1=81=D0=BB?= =?UTF-8?q?=D1=83=D1=88=D0=B0=D1=8E=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TASK-red-dot-recording.md | 50 +++++++++++++++++++ .../viewmate/glasses/ui/AssistantOverlay.kt | 12 +++++ 2 files changed, 62 insertions(+) create mode 100644 TASK-red-dot-recording.md diff --git a/TASK-red-dot-recording.md b/TASK-red-dot-recording.md new file mode 100644 index 0000000..5ef2693 --- /dev/null +++ b/TASK-red-dot-recording.md @@ -0,0 +1,50 @@ +# TASK-red-dot-recording.md — индикатор записи микрофона на очках + +## Контекст +Пользователь просит: когда на очках идёт запись микрофона (режим «слушаю», `listening=true`), +показывать в углу экрана красный кружок (индикатор записи, как у камер/диктофонов). +Только очки (app-glasses), только UI. Через опен-код, как всегда. + +## Где это живёт +- `app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/ui/AssistantOverlay.kt` +- `AssistantOverlay()` собирает `state` (listening/thinking/sttText/assistantText), затем + `overlayBox(app, state, chatHistory, scrollState)`. +- `overlayBox()` внутри `Binocular(scale=false)` рисует `Box` с чёрным затемнением + `Color.Black.copy(alpha = 0.72f)` и в нём `AssistantOverlayContent(...)`. +- Binocular рендерит контент дважды (левый/правый глаз) — кружок появится в каждом глазу, + это правильно (в каждой половине экрана свой индикатор). + +## Правка +В `overlayBox()`: внутри внешнего `Box` (тот, что с `.background(Color.Black.copy(alpha = 0.72f))`) +добавить поверх контента, когда `state.listening == true`, маленький красный круг в +верхнем правом углу (по центру своей половины экрана, т.е. с отступом от края): +```kotlin +if (state.listening) { + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .padding(top = 12.dp, end = 12.dp) + .size(16.dp) + .background(Color(0xFFFF3B30), CircleShape), + ) +} +``` +Нужные импорты добавить: `androidx.compose.foundation.shape.CircleShape`, +`androidx.compose.foundation.layout.size`, `Modifier.align` (уже есть `Alignment`). +Проверить, что `Box`-контейнер позволяет `align` (должен, т.к. это BoxScope). + +Кружок виден только в режиме «слушаю» (listening=true): при «думаю...» и при показе ответа — +не показывается (микрофон уже закрыт). Это соответствует смыслу: индикатор = идёт запись. + +Никаких изменений протокола, телефона, жестов, логики — только отрисовка индикатора. + +## Сборка, тесты, коммит +- `./gradlew :lib-core:build :app-glasses:assembleDebug :app-phone:assembleDebug` — BUILD SUCCESSFUL. +- `git add -A && git commit -m 'Очки: красный индикатор записи микрофона в режиме «слушаю»'` (БЕЗ push). + +## КРИТИЧЕСКИЕ ПРАВИЛА +- workspace = /root/WORK/view-mate. Пути ТОЛЬКО относительные от корня (app-glasses/...). + НИКОГДА /root/WORK/app-* (без view-mate) — external_directory, permission-guard отклонит. +- НЕ трогать: app-phone, lib-core, LocalLlm.kt (GPU), скорость, клавиатуру, автоименование, + AssistantGestures.kt, матрицу жестов, HostConnection.kt, MainActivity.kt, GlassesApp.kt. +- В конце — краткий отчёт: файлы, изменения, сборка, тесты. diff --git a/app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/ui/AssistantOverlay.kt b/app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/ui/AssistantOverlay.kt index d53d634..7a1a026 100644 --- a/app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/ui/AssistantOverlay.kt +++ b/app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/ui/AssistantOverlay.kt @@ -11,7 +11,9 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.ScrollState import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -102,6 +104,16 @@ private fun overlayBox( .background(Color.Black.copy(alpha = 0.72f)), ) { AssistantOverlayContent(state, chatHistory, scrollState) + + if (state.listening) { + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .padding(top = 12.dp, end = 12.dp) + .size(16.dp) + .background(Color(0xFFFF3B30), CircleShape), + ) + } } } }