Preserve elapsed time when switching between schedule blocks
Previously, clicking a different block always fired 'start' which reset elapsed to zero — returning to a block lost all accumulated time. Store changes: - Add blockElapsedCache (blockId → elapsed seconds) that persists across block switches within a session - On 'pause' WS event: write the block's total elapsed into the cache - On 'start' WS event: restore elapsed from cache (0 if never worked) - On applySnapshot: seed cache with server-computed elapsed for the current block (so reloading preserves state correctly) - Clear cache when the session ends Dashboard selectBlock changes: - Auto-pause the currently running block before switching to another - Clicking the active block while paused now sends 'resume' instead of doing nothing - Clicking the already-running active block is a no-op Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
const isPaused = ref(false)
|
const isPaused = ref(false)
|
||||||
const blockStartedAt = ref(null) // Date.now() ms when current counting period started
|
const blockStartedAt = ref(null) // Date.now() ms when current counting period started
|
||||||
const blockElapsedOffset = ref(0) // seconds already elapsed before blockStartedAt
|
const blockElapsedOffset = ref(0) // seconds already elapsed before blockStartedAt
|
||||||
|
const blockElapsedCache = ref({}) // blockId → total elapsed seconds (survives block switches)
|
||||||
const dayStartTime = ref(null) // "HH:MM:SS" string or null
|
const dayStartTime = ref(null) // "HH:MM:SS" string or null
|
||||||
const dayEndTime = ref(null) // "HH:MM:SS" string or null
|
const dayEndTime = ref(null) // "HH:MM:SS" string or null
|
||||||
|
|
||||||
@@ -39,9 +40,10 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
if (snapshot.child) child.value = snapshot.child
|
if (snapshot.child) child.value = snapshot.child
|
||||||
dayStartTime.value = snapshot.day_start_time || null
|
dayStartTime.value = snapshot.day_start_time || null
|
||||||
dayEndTime.value = snapshot.day_end_time || null
|
dayEndTime.value = snapshot.day_end_time || null
|
||||||
// Restore elapsed time from server-computed value
|
// Restore elapsed time from server-computed value and seed the per-block cache
|
||||||
const serverElapsed = snapshot.block_elapsed_seconds || 0
|
const serverElapsed = snapshot.block_elapsed_seconds || 0
|
||||||
if (snapshot.session?.current_block_id && serverElapsed > 0) {
|
if (snapshot.session?.current_block_id && serverElapsed > 0) {
|
||||||
|
blockElapsedCache.value[snapshot.session.current_block_id] = serverElapsed
|
||||||
blockElapsedOffset.value = serverElapsed
|
blockElapsedOffset.value = serverElapsed
|
||||||
// Only start the live counter if the block is actually running (not paused)
|
// Only start the live counter if the block is actually running (not paused)
|
||||||
blockStartedAt.value = isPaused.value ? null : Date.now()
|
blockStartedAt.value = isPaused.value ? null : Date.now()
|
||||||
@@ -68,21 +70,25 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
isPaused.value = false
|
isPaused.value = false
|
||||||
blockStartedAt.value = null
|
blockStartedAt.value = null
|
||||||
blockElapsedOffset.value = 0
|
blockElapsedOffset.value = 0
|
||||||
|
blockElapsedCache.value = {}
|
||||||
dayStartTime.value = null
|
dayStartTime.value = null
|
||||||
dayEndTime.value = null
|
dayEndTime.value = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Pause — accumulate elapsed, stop counting
|
// Pause — accumulate elapsed, save to cache, stop counting
|
||||||
if (event.event === 'pause') {
|
if (event.event === 'pause') {
|
||||||
if (blockStartedAt.value) {
|
if (blockStartedAt.value) {
|
||||||
blockElapsedOffset.value += Math.floor((Date.now() - blockStartedAt.value) / 1000)
|
blockElapsedOffset.value += Math.floor((Date.now() - blockStartedAt.value) / 1000)
|
||||||
}
|
}
|
||||||
|
if (event.block_id) {
|
||||||
|
blockElapsedCache.value[event.block_id] = blockElapsedOffset.value
|
||||||
|
}
|
||||||
blockStartedAt.value = null
|
blockStartedAt.value = null
|
||||||
isPaused.value = true
|
isPaused.value = true
|
||||||
}
|
}
|
||||||
// Start (new block) — reset elapsed, begin counting
|
// Start — restore cached elapsed if returning to a previously worked block
|
||||||
if (event.event === 'start') {
|
if (event.event === 'start') {
|
||||||
blockElapsedOffset.value = 0
|
blockElapsedOffset.value = blockElapsedCache.value[event.block_id] || 0
|
||||||
blockStartedAt.value = Date.now()
|
blockStartedAt.value = Date.now()
|
||||||
isPaused.value = false
|
isPaused.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,10 +217,25 @@ async function sendAction(type) {
|
|||||||
await scheduleStore.sendTimerAction(scheduleStore.session.id, type)
|
await scheduleStore.sendTimerAction(scheduleStore.session.id, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectBlock(block) {
|
async function selectBlock(block) {
|
||||||
if (!scheduleStore.session) return
|
if (!scheduleStore.session) return
|
||||||
scheduleStore.session.current_block_id = block.id
|
|
||||||
scheduleStore.isPaused = false
|
const currentId = scheduleStore.session.current_block_id
|
||||||
|
|
||||||
|
// Clicking the current block while paused → resume it
|
||||||
|
if (block.id === currentId && scheduleStore.isPaused) {
|
||||||
|
scheduleStore.sendTimerAction(scheduleStore.session.id, 'resume')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clicking the current block while running → do nothing
|
||||||
|
if (block.id === currentId) return
|
||||||
|
|
||||||
|
// Switching to a different block — pause the current one first if it's running
|
||||||
|
if (currentId && !scheduleStore.isPaused) {
|
||||||
|
await scheduleStore.sendTimerAction(scheduleStore.session.id, 'pause', currentId)
|
||||||
|
}
|
||||||
|
|
||||||
scheduleStore.sendTimerAction(scheduleStore.session.id, 'start', block.id)
|
scheduleStore.sendTimerAction(scheduleStore.session.id, 'start', block.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user