Переглянути джерело

fix: song time remembering breaking randomly

Sv443 8 місяців тому
батько
коміт
80644f01a4
3 змінених файлів з 38 додано та 33 видалено
  1. 20 26
      src/features/behavior.ts
  2. 1 1
      src/features/index.ts
  3. 17 6
      src/utils/dom.ts

+ 20 - 26
src/features/behavior.ts

@@ -163,36 +163,30 @@ let remVidCheckTimeout: ReturnType<typeof setTimeout> | undefined;
 /** Only call once as this calls itself after a timeout! - Updates the currently playing video's entry in GM storage */
 async function remTimeStartUpdateLoop() {
   if(location.pathname.startsWith("/watch")) {
+    const watchID = getWatchId();
     const songTime = await getVideoTime() ?? 0;
 
-    if(songTime === lastSongTime)
-      return;
-    lastSongTime = songTime;
-
-    // TODO:FIXME: stops looping after a while
-    dbg("># looped, different songTime:", songTime);
+    if(watchID && songTime !== lastSongTime) {
+      lastSongTime = songTime;
 
-    const watchID = getWatchId();
-    if(!watchID)
-      return;
+      const paused = getVideoElement()?.paused ?? false;
 
-    const paused = getVideoElement()?.paused ?? false;
-
-    // don't immediately update to reduce race conditions and only update if the video is playing
-    // also it just sounds better if the song starts at the beginning if only a couple seconds have passed
-    if(songTime > getFeature("rememberSongTimeMinPlayTime") && !paused) {
-      const entry = {
-        watchID,
-        songTime,
-        updateTimestamp: Date.now(),
-      };
-      await remTimeUpsertEntry(entry);
-    }
-    // if the song is rewound to the beginning, update the entry accordingly
-    else if(!paused) {
-      const entry = remVidsCache.find(entry => entry.watchID === watchID);
-      if(entry && songTime <= entry.songTime)
-        await remTimeUpsertEntry({ ...entry, songTime, updateTimestamp: Date.now() });
+      // don't immediately update to reduce race conditions and only update if the video is playing
+      // also it just sounds better if the song starts at the beginning if only a couple seconds have passed
+      if(songTime > getFeature("rememberSongTimeMinPlayTime") && !paused) {
+        const entry = {
+          watchID,
+          songTime,
+          updateTimestamp: Date.now(),
+        };
+        await remTimeUpsertEntry(entry);
+      }
+      // if the song is rewound to the beginning, update the entry accordingly
+      else if(!paused) {
+        const entry = remVidsCache.find(entry => entry.watchID === watchID);
+        if(entry && songTime <= entry.songTime)
+          await remTimeUpsertEntry({ ...entry, songTime, updateTimestamp: Date.now() });
+      }
     }
   }
 

+ 1 - 1
src/features/index.ts

@@ -448,7 +448,7 @@ export const featInfo = {
   rememberSongTimeMinPlayTime: {
     type: "slider",
     category: "behavior",
-    min: 0.5,
+    min: 3,
     max: 30,
     step: 0.5,
     default: 10,

+ 17 - 6
src/utils/dom.ts

@@ -18,6 +18,8 @@ export function getVideoElement() {
   return document.querySelector<HTMLVideoElement>(getVideoSelector());
 }
 
+let vidElemReady = false;
+
 /**
  * Returns the current video time in seconds, with the given {@linkcode precision} (2 decimal digits by default).  
  * Rounds down if the precision is set to 0. The maximum average available precision on YTM is 6.  
@@ -26,23 +28,32 @@ export function getVideoElement() {
  */
 export function getVideoTime(precision = 2) {
   return new Promise<number | null>(async (res) => {
-    await waitVideoElementReady();
+    if(!vidElemReady) {
+      await waitVideoElementReady();
+      vidElemReady = true;
+    }
+
+    const resolveWithVal = (time: number | null) => res(
+      time && !isNaN(time)
+        ? Number(precision <= 0 ? Math.floor(time) : time.toFixed(precision))
+        : null
+    );
 
     try {
       if(getDomain() === "ytm") {
         const vidElem = getVideoElement();
         if(vidElem)
-          return res(Number(precision <= 0 ? Math.floor(vidElem.currentTime) : vidElem.currentTime.toFixed(precision)));
+          return resolveWithVal(vidElem.currentTime);
 
         addSelectorListener<HTMLProgressElement>("playerBar", "tp-yt-paper-slider#progress-bar tp-yt-paper-progress#sliderBar", {
           listener: (pbEl) =>
-            res(!isNaN(Number(pbEl.value)) ? Math.floor(Number(pbEl.value)) : null)
+            resolveWithVal(!isNaN(Number(pbEl.value)) ? Math.floor(Number(pbEl.value)) : null)
         });
       }
       else if(getDomain() === "yt") {
         const vidElem = getVideoElement();
         if(vidElem)
-          return res(Number(precision <= 0 ? Math.floor(vidElem.currentTime) : vidElem.currentTime.toFixed(precision)));
+          return resolveWithVal(vidElem.currentTime);
 
         // YT doesn't update the progress bar when it's hidden (contrary to YTM which never hides it)
         ytForceShowVideoTime();
@@ -62,12 +73,12 @@ export function getVideoTime(precision = 2) {
           });
 
           if(videoTime >= 0 && !isNaN(videoTime)) {
-            res(Math.floor(videoTime));
+            resolveWithVal(Math.floor(videoTime));
             mut.disconnect();
           }
           else
             setTimeout(() => {
-              res(videoTime >= 0 && !isNaN(videoTime) ? Math.floor(videoTime) : null);
+              resolveWithVal(videoTime >= 0 && !isNaN(videoTime) ? Math.floor(videoTime) : null);
               mut.disconnect();
             }, 500);
         };