fix: Pomodoro timer no longer advances while the page is closed - #66
Open
Punnawit9285 wants to merge 6 commits into
Open
fix: Pomodoro timer no longer advances while the page is closed#66Punnawit9285 wants to merge 6 commits into
Punnawit9285 wants to merge 6 commits into
Conversation
interval(1000) is throttled once a tab is hidden, so counting one second per tick made the countdown and the phase-change chime drift behind real time. Derive the remaining time from a wall-clock anchor instead, so a throttled or delayed tick corrects itself. Also unlock the AudioContext from the start/resume gesture and keep it suspended between chimes. iOS blocks a context first resumed from a timer callback, and holding an active audio session for the life of the page was observed to interrupt the lecture video playing alongside it.
Restoring a saved timer treated the wall-clock gap since the tab closed as elapsed study time, walking phase by phase to catch up and crediting a completed session on each pass. Reopening after three days took the session count from 2 to 494. The catch-up loop also tested the saved phase rather than the one it was advancing, so break phases were counted as completed study sessions too. The timer only advances while the page is open, so drop the catch-up along with the 12-hour cap that tried to bound it. A closed tab now resumes paused at the second it stopped, in the same phase, with the session count untouched. Switching tabs is unaffected: a hidden page keeps ticking. Flush the timer on visibilitychange and pagehide so a tab closed mid-phase resumes from where it actually stopped rather than from the last phase change, and make the periodic save a 5-second wall-clock throttle, since the old modulo gate can be skipped now that the countdown is wall-clock derived.
Member
|
Isn’t the timer should be stopped when the tab is closed? |
A hidden page kept ticking, so time spent reading something in another tab counted as study time. Pause on visibilitychange instead, and resume as soon as the page comes back. Only a pause this handler caused is resumed automatically: a deliberate pause stays paused, and so does a tab that was closed rather than hidden, since the flag does not survive the reload. pause() now settles the countdown from the wall-clock anchor rather than the last tick. That was accurate enough when pausing was a button press, but it now happens on every tab switch, often just as a hidden tab's interval is throttled. Session counts are also tagged with the study day they were earned on and cleared once it changes. The boundary is 04:00 rather than midnight so a session running at 2am still counts towards that night. The rollover is checked on each tick, on restore, and when a tab becomes visible again, since an idle tab is not ticking and would otherwise miss it.
Ionic sets "contain: layout" on .ion-page, which makes it the containing block for position:fixed descendants. The notification therefore resolved against the page box instead of the viewport, so it drifted by however much the two disagree. In the in-app browsers used by the Google and Chrome apps that gap is the height of their dynamic toolbar, which dropped the notification down over the course list. Move it out of the component and attach it to document.body, where fixed positioning means the viewport again. While an element is fullscreen the browser paints only that element's subtree, so it follows the fullscreen element in and out for the duration. Its styles move to global.scss along with it, since the element no longer sits inside the component's view encapsulation. The DOM handling lives in its own class rather than the component so it can be driven directly in a browser test, without Angular or Ionic. The entry transition is restarted with a synchronous reflow rather than a pair of animation frames: a second frame never arrives in a tab that is not compositing, which left the notification invisible. Its top offset clears the toolbar so it cannot straddle the header, and the title and body are set as text, never markup.
On iOS the lecture video was handed to Apple's native fullscreen player, which renders outside the web view. Nothing in the DOM can be drawn over it, so the Pomodoro phase notification never appeared while a video was fullscreen. Set playsinline so playback stays in the page, and preferFullWindow so video.js uses its own full-window mode instead of the native player. preferFullWindow is only consulted when the browser exposes no Fullscreen API, which is exactly the iPhone and in-app web view case; browsers that have the API are unaffected and fullscreen the player element as before, with the notification placed inside it. The trade is that fullscreen on those browsers is now a full-window page rather than the native player, so its AirPlay and picture-in-picture affordances are not available there. An overlay cannot be drawn over a native player at all, so this is the only way to show the notification.
Collaborator
Author
|
The timer is stopped when user switch tab as you suggested now, which timer will resume immediately after user return to Flick Also I make timer progress reset at everyday 4 a.m. too so that it won't show user excessively high cycle count number like in the status quo. |
Member
|
The timer should not reset at a specific time, for example a user might start using the timer at 03:00. |
Pausing on a tab switch is right when the lecture being timed is on this page, and wrong when the studying is happening on another site. Neither default suits both, so the session type is now the user's choice: watching lectures pauses on leaving, studying elsewhere keeps running. The control is a segment on the timer card with a line stating what the current choice does, so the behaviour is visible rather than something to discover by switching tabs. Options come from SESSION_MODES so the labels live beside the phases and duration fields rather than in the template. Defaults to watching lectures, which is the existing behaviour, and the choice is saved with the other preferences.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A closed tab reopens paused at the second it stopped.
Switching tabs is unaffected. A hidden page keeps ticking.