From 98d8e0ca4d1f2da92b5518b178390bef7ebc9157 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Mon, 21 Sep 2026 21:49:52 +0700 Subject: [PATCH] fix --- src/components/ScreenPage.vue | 13 ++++++++++--- src/components/ScreenPreview.vue | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/ScreenPage.vue b/src/components/ScreenPage.vue index a8358a8..f257dc1 100644 --- a/src/components/ScreenPage.vue +++ b/src/components/ScreenPage.vue @@ -32,6 +32,7 @@ const bindSuccess = ref(false) const timerNow = ref(Date.now()) const timerRemainingAtSync = ref(0) const timerSyncedAt = ref(Date.now()) +const timerStateAtSync = ref() const introAudioElement = ref() const conclusionVideoElement = ref() let appliedCommandVersion = 0 @@ -55,11 +56,11 @@ const gameOptions = computed(() => const screenMode = computed(() => state.value?.mode || 'SCREEN_MODE_COVER') const timerRemainingSeconds = computed(() => { if (state.value?.timerState !== 'SCREEN_TIMER_STATE_RUNNING') return timerRemainingAtSync.value - return Math.max(0, timerRemainingAtSync.value - Math.floor((timerNow.value - timerSyncedAt.value) / 1000)) + return Math.max(0, timerRemainingAtSync.value - (timerNow.value - timerSyncedAt.value) / 1000) }) const timerDisplay = computed(() => { const minutes = Math.floor(timerRemainingSeconds.value / 60) - const seconds = timerRemainingSeconds.value % 60 + const seconds = Math.floor(timerRemainingSeconds.value % 60) return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}` }) const introAudio = computed(() => applicationFileURL(state.value?.introAudio)) @@ -74,8 +75,14 @@ function saveSession() { } function syncTimer(value: ScreenState | undefined) { - timerRemainingAtSync.value = Math.max(0, Math.floor(value?.timerRemainingSeconds || 0)) + const remaining = Math.max(0, Number(value?.timerRemainingSeconds || 0)) + if (value?.timerState === 'SCREEN_TIMER_STATE_RUNNING' && timerStateAtSync.value === value.timerState) { + const localRemaining = Math.max(0, timerRemainingAtSync.value - (Date.now() - timerSyncedAt.value) / 1000) + if (Math.abs(remaining - localRemaining) <= 0.5) return + } + timerRemainingAtSync.value = remaining timerSyncedAt.value = Date.now() + timerStateAtSync.value = value?.timerState } function readSession() { diff --git a/src/components/ScreenPreview.vue b/src/components/ScreenPreview.vue index 426ef3e..7070cb4 100644 --- a/src/components/ScreenPreview.vue +++ b/src/components/ScreenPreview.vue @@ -17,6 +17,7 @@ const props = defineProps<{ const timerNow = ref(Date.now()) const timerRemainingAtSync = ref(0) const timerSyncedAt = ref(Date.now()) +const timerStateAtSync = ref() let timerTick: number | null = null const screenBackground = computed(() => { @@ -27,11 +28,11 @@ const screenBackground = computed(() => { }) const timerRemainingSeconds = computed(() => { if (props.state.timerState !== 'SCREEN_TIMER_STATE_RUNNING') return timerRemainingAtSync.value - return Math.max(0, timerRemainingAtSync.value - Math.floor((timerNow.value - timerSyncedAt.value) / 1000)) + return Math.max(0, timerRemainingAtSync.value - (timerNow.value - timerSyncedAt.value) / 1000) }) const timerDisplay = computed(() => { const minutes = Math.floor(timerRemainingSeconds.value / 60) - const seconds = timerRemainingSeconds.value % 60 + const seconds = Math.floor(timerRemainingSeconds.value % 60) return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}` }) const introAudio = computed(() => applicationFileURL(props.state.introAudio)) @@ -40,8 +41,14 @@ const conclusionVideo = computed(() => applicationFileURL(props.state.conclusion watch( () => [props.state.timerRemainingSeconds, props.state.timerState, props.state.stateVersion], () => { - timerRemainingAtSync.value = Math.max(0, Math.floor(props.state.timerRemainingSeconds || 0)) + const remaining = Math.max(0, Number(props.state.timerRemainingSeconds || 0)) + if (props.state.timerState === 'SCREEN_TIMER_STATE_RUNNING' && timerStateAtSync.value === props.state.timerState) { + const localRemaining = Math.max(0, timerRemainingAtSync.value - (Date.now() - timerSyncedAt.value) / 1000) + if (Math.abs(remaining - localRemaining) <= 0.5) return + } + timerRemainingAtSync.value = remaining timerSyncedAt.value = Date.now() + timerStateAtSync.value = props.state.timerState }, { immediate: true }, )