Fix paused timer auto-resuming on page navigation
applySnapshot was always setting isPaused = false and blockStartedAt = Date.now() regardless of the actual timer state, causing a paused block to appear running whenever the dashboard was reloaded. - Add is_paused field to DashboardSnapshot schema - Dashboard endpoint derives is_paused by checking whether the last start/resume/pause event for the current block is a pause - applySnapshot now reads is_paused from the snapshot instead of resetting to false, and only sets blockStartedAt when the block is actually running (not paused) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,7 +70,8 @@ async def get_dashboard(child_id: int, db: AsyncSession = Depends(get_db)):
|
|||||||
)
|
)
|
||||||
completed_ids = [e.block_id for e in events_result.scalars().all() if e.block_id]
|
completed_ids = [e.block_id for e in events_result.scalars().all() if e.block_id]
|
||||||
|
|
||||||
# Compute elapsed seconds for the current block from timer_events
|
# Compute elapsed seconds and paused state for the current block from timer_events
|
||||||
|
is_paused = False
|
||||||
if session and session.current_block_id:
|
if session and session.current_block_id:
|
||||||
tick_result = await db.execute(
|
tick_result = await db.execute(
|
||||||
select(TimerEvent)
|
select(TimerEvent)
|
||||||
@@ -93,6 +94,8 @@ async def get_dashboard(child_id: int, db: AsyncSession = Depends(get_db)):
|
|||||||
if last_start:
|
if last_start:
|
||||||
elapsed += (datetime.utcnow() - last_start).total_seconds()
|
elapsed += (datetime.utcnow() - last_start).total_seconds()
|
||||||
block_elapsed_seconds = int(elapsed)
|
block_elapsed_seconds = int(elapsed)
|
||||||
|
# Paused if the last tick event was a pause (last_start is None but events exist)
|
||||||
|
is_paused = bool(tick_events) and tick_events[-1].event_type == "pause"
|
||||||
|
|
||||||
return DashboardSnapshot(
|
return DashboardSnapshot(
|
||||||
session=session,
|
session=session,
|
||||||
@@ -100,6 +103,7 @@ async def get_dashboard(child_id: int, db: AsyncSession = Depends(get_db)):
|
|||||||
blocks=blocks,
|
blocks=blocks,
|
||||||
completed_block_ids=completed_ids,
|
completed_block_ids=completed_ids,
|
||||||
block_elapsed_seconds=block_elapsed_seconds,
|
block_elapsed_seconds=block_elapsed_seconds,
|
||||||
|
is_paused=is_paused,
|
||||||
day_start_time=day_start_time,
|
day_start_time=day_start_time,
|
||||||
day_end_time=day_end_time,
|
day_end_time=day_end_time,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,5 +43,6 @@ class DashboardSnapshot(BaseModel):
|
|||||||
blocks: list[ScheduleBlockOut] = []
|
blocks: list[ScheduleBlockOut] = []
|
||||||
completed_block_ids: list[int] = []
|
completed_block_ids: list[int] = []
|
||||||
block_elapsed_seconds: int = 0 # seconds already elapsed for the current block
|
block_elapsed_seconds: int = 0 # seconds already elapsed for the current block
|
||||||
|
is_paused: bool = False # whether the current block's timer is paused
|
||||||
day_start_time: time | None = None
|
day_start_time: time | None = None
|
||||||
day_end_time: time | None = None
|
day_end_time: time | None = None
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
session.value = snapshot.session
|
session.value = snapshot.session
|
||||||
blocks.value = sortBlocksByTime(snapshot.blocks)
|
blocks.value = sortBlocksByTime(snapshot.blocks)
|
||||||
completedBlockIds.value = snapshot.completed_block_ids || []
|
completedBlockIds.value = snapshot.completed_block_ids || []
|
||||||
isPaused.value = false
|
isPaused.value = snapshot.is_paused || false
|
||||||
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
|
||||||
@@ -43,7 +43,8 @@ export const useScheduleStore = defineStore('schedule', () => {
|
|||||||
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) {
|
||||||
blockElapsedOffset.value = serverElapsed
|
blockElapsedOffset.value = serverElapsed
|
||||||
blockStartedAt.value = Date.now()
|
// Only start the live counter if the block is actually running (not paused)
|
||||||
|
blockStartedAt.value = isPaused.value ? null : Date.now()
|
||||||
} else {
|
} else {
|
||||||
blockElapsedOffset.value = 0
|
blockElapsedOffset.value = 0
|
||||||
blockStartedAt.value = null
|
blockStartedAt.value = null
|
||||||
|
|||||||
Reference in New Issue
Block a user