Movie watch progression tracking (#63)

* feat: Add movie playback progress display and API

Co-authored-by: mathieumoran1 <[email protected]>

* Add padding to bottom of movies page

Co-authored-by: mathieumoran1 <[email protected]>

* Fix: Hide resume/progress bar when near end of video

Co-authored-by: mathieumoran1 <[email protected]>

---------

Co-authored-by: Cursor Agent <[email protected]>
This commit was merged in pull request #63.
This commit is contained in:
Mathieu Moran
2025-12-22 19:58:37 -05:00
committed by GitHub
co-authored by Cursor Agent
parent 79b9f4a5a3
commit e0d5531041
4 changed files with 134 additions and 3 deletions
+13 -1
View File
@@ -220,6 +220,8 @@ function setupVideoProgress({ videoEl, movieId, token, userId, imdbId }) {
let lastSaveStatus = '—';
let seekSaveTimer = null;
let savedUiTimer = null;
let startedOnce = false;
let startSaveTimer = null;
function getSnapshot() {
const t = Number(videoEl.currentTime);
@@ -348,7 +350,16 @@ function setupVideoProgress({ videoEl, movieId, token, userId, imdbId }) {
intervalId = null;
}
const onPlay = () => startInterval();
const onPlay = () => {
startInterval();
// Ensure we create/refresh a progress row as soon as playback starts
// (so the movies page can show a "resume" state quickly).
if (!startedOnce) {
startedOnce = true;
if (startSaveTimer) window.clearTimeout(startSaveTimer);
startSaveTimer = window.setTimeout(() => { void persist({ force: true }); }, 650);
}
};
const onPause = () => { stopInterval(); void persist({ force: true }); };
const onSeeking = () => {
// While scrubbing, browsers fire many events; debounce a forced save so it lands quickly.
@@ -396,6 +407,7 @@ function setupVideoProgress({ videoEl, movieId, token, userId, imdbId }) {
stopInterval();
if (seekSaveTimer) window.clearTimeout(seekSaveTimer);
if (savedUiTimer) window.clearTimeout(savedUiTimer);
if (startSaveTimer) window.clearTimeout(startSaveTimer);
videoEl.removeEventListener('play', onPlay);
videoEl.removeEventListener('pause', onPause);
videoEl.removeEventListener('seeking', onSeeking);