Добавляем индикатор рассинхронизации звука и видео в статус-панели очков
This commit is contained in:
@@ -102,6 +102,13 @@ class GlassesApp : Application() {
|
||||
*/
|
||||
val answerScrollDelta = MutableStateFlow(0f)
|
||||
|
||||
/**
|
||||
* Индикатор аудио-синхронизации для статус-панели: |звук − видео| в мс
|
||||
* (AudioSyncInfo от телефона каждый sync-цикл ~5с). null — не выводить
|
||||
* (видео на очках не играет / данных ещё нет).
|
||||
*/
|
||||
val audioSyncDiffMs = MutableStateFlow<Int?>(null)
|
||||
|
||||
/** Текущая Activity (для закрытия приложения по команде с телефона). */
|
||||
var mainActivity: MainActivity? = null
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import pw.binom.viewmate.core.MediaCommand
|
||||
import pw.binom.viewmate.core.net.GlassesTransport
|
||||
import pw.binom.viewmate.core.net.WifiGlassesTransport
|
||||
import pw.binom.viewmate.core.protocol.AssistantStateMsg
|
||||
import pw.binom.viewmate.core.protocol.AudioSyncInfo
|
||||
import pw.binom.viewmate.core.protocol.ChatHistoryItem
|
||||
import pw.binom.viewmate.core.protocol.ChatHistoryMsg
|
||||
import pw.binom.viewmate.core.protocol.ChatSessionMsg
|
||||
@@ -338,6 +339,16 @@ class HostConnection(
|
||||
downloadManager.handleDeleteFiles(msg.itemId)
|
||||
}
|
||||
|
||||
is AudioSyncInfo -> {
|
||||
// Индикатор |звук − видео| для статус-панели; active=false (видео не играет) — скрываем.
|
||||
val prev = GlassesApp.instance.audioSyncDiffMs.value
|
||||
GlassesApp.instance.audioSyncDiffMs.value = if (msg.active) msg.diffMs else null
|
||||
// Диагностика: скачок diff (по часам очков) — для корреляции с logcat BT-стека телефона за ту же секунду.
|
||||
if (msg.active && prev != null && msg.diffMs - prev >= 300) {
|
||||
log("audio", "diff скачок $prev→${msg.diffMs} мс")
|
||||
}
|
||||
}
|
||||
|
||||
is AssistantStateMsg -> addMessage("AssistantState: ${msg.state} (${msg.recordingSeconds}с)")
|
||||
|
||||
is ShowText -> {
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -18,6 +19,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import pw.binom.viewmate.glasses.GlassesApp
|
||||
|
||||
/**
|
||||
* Композ-панель статуса (время + заряд). Вызывается внутри [Binocular] content,
|
||||
@@ -36,12 +38,20 @@ fun StatusPanelCompose(modifier: Modifier = Modifier, scale: Float = 1f) {
|
||||
val d = data ?: return
|
||||
val baseStyle = MaterialTheme.typography.bodyMedium
|
||||
val style = baseStyle.copy(fontSize = baseStyle.fontSize * scale)
|
||||
// Индикатор |звук − видео| (мс): только когда видео играет на очках (MovieController.movieActive
|
||||
// + свежее значение от телефона); без видео — ничего не выводить.
|
||||
val diffMs = GlassesApp.instance.audioSyncDiffMs.collectAsState()
|
||||
val movieActive = GlassesApp.instance.movieController.movieActive.collectAsState()
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(Color(0x99000000)) // полупрозрачный чёрный
|
||||
.padding(horizontal = 10.dp * scale, vertical = 4.dp * scale),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
if (movieActive.value && diffMs.value != null) {
|
||||
Text("${diffMs.value} мс", color = Color(0xFF999999), style = style)
|
||||
Spacer(Modifier.width(6.dp * scale))
|
||||
}
|
||||
Text(d.time, color = Color.White, style = style)
|
||||
Spacer(Modifier.width(6.dp * scale))
|
||||
// Процент — цветом статуса заряда (зелёный/белый/красный), без квадратика.
|
||||
|
||||
Reference in New Issue
Block a user