Fix timer reset on refresh and sync between dashboard and TV view
- Backend computes block_elapsed_seconds server-side from timer_events - Store tracks blockStartedAt (ms) + blockElapsedOffset (seconds) instead of a client-side counter; updated correctly on start/pause/resume/end - TimerDisplay derives elapsed from store props so both views always agree - Add compact timer display to dashboard session card - Add isPaused/pause-resume logic to dashboard Pause/Resume buttons Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,9 @@ export const useScheduleStore = defineStore('schedule', () => {
|
||||
const blocks = ref([])
|
||||
const completedBlockIds = ref([])
|
||||
const child = ref(null)
|
||||
const isPaused = ref(false)
|
||||
const blockStartedAt = ref(null) // Date.now() ms when current counting period started
|
||||
const blockElapsedOffset = ref(0) // seconds already elapsed before blockStartedAt
|
||||
|
||||
const currentBlock = computed(() =>
|
||||
session.value?.current_block_id
|
||||
@@ -23,7 +26,17 @@ export const useScheduleStore = defineStore('schedule', () => {
|
||||
session.value = snapshot.session
|
||||
blocks.value = snapshot.blocks || []
|
||||
completedBlockIds.value = snapshot.completed_block_ids || []
|
||||
isPaused.value = false
|
||||
if (snapshot.child) child.value = snapshot.child
|
||||
// Restore elapsed time from server-computed value
|
||||
const serverElapsed = snapshot.block_elapsed_seconds || 0
|
||||
if (snapshot.session?.current_block_id && serverElapsed > 0) {
|
||||
blockElapsedOffset.value = serverElapsed
|
||||
blockStartedAt.value = Date.now()
|
||||
} else {
|
||||
blockElapsedOffset.value = 0
|
||||
blockStartedAt.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function applyWsEvent(event) {
|
||||
@@ -34,8 +47,30 @@ export const useScheduleStore = defineStore('schedule', () => {
|
||||
// Session ended
|
||||
if (event.is_active === false) {
|
||||
session.value = null
|
||||
isPaused.value = false
|
||||
blockStartedAt.value = null
|
||||
blockElapsedOffset.value = 0
|
||||
return
|
||||
}
|
||||
// Pause — accumulate elapsed, stop counting
|
||||
if (event.event === 'pause') {
|
||||
if (blockStartedAt.value) {
|
||||
blockElapsedOffset.value += Math.floor((Date.now() - blockStartedAt.value) / 1000)
|
||||
}
|
||||
blockStartedAt.value = null
|
||||
isPaused.value = true
|
||||
}
|
||||
// Start (new block) — reset elapsed, begin counting
|
||||
if (event.event === 'start') {
|
||||
blockElapsedOffset.value = 0
|
||||
blockStartedAt.value = Date.now()
|
||||
isPaused.value = false
|
||||
}
|
||||
// Resume — continue from where we left off
|
||||
if (event.event === 'resume') {
|
||||
blockStartedAt.value = Date.now()
|
||||
isPaused.value = false
|
||||
}
|
||||
// Timer events update session state
|
||||
if (event.current_block_id !== undefined && session.value) {
|
||||
session.value.current_block_id = event.current_block_id
|
||||
@@ -73,6 +108,9 @@ export const useScheduleStore = defineStore('schedule', () => {
|
||||
blocks,
|
||||
completedBlockIds,
|
||||
child,
|
||||
isPaused,
|
||||
blockStartedAt,
|
||||
blockElapsedOffset,
|
||||
currentBlock,
|
||||
progressPercent,
|
||||
applySnapshot,
|
||||
|
||||
Reference in New Issue
Block a user