Kaynağa Gözat

feat: new cfg options for autoScrollToActiveSong feature

Sv443 1 ay önce
ebeveyn
işleme
924b4020c5

+ 4 - 1
assets/translations/de-DE.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "Dunkler",
   "color_lightness_normal": "Normal",
   "color_lightness_lighter": "Heller",
+
   "auto_scroll_to_active_song_mode_never": "Nie",
   "auto_scroll_to_active_song_mode_initial_page_load": "Beim initialen Laden der Seite",
-  "auto_scroll_to_active_song_mode_video_change": "Bei jedem Video",
+  "auto_scroll_to_active_song_mode_video_change_all": "Bei jedem Video-Wechsel",
+  "auto_scroll_to_active_song_mode_video_change_manual": "Nur bei händischem Video-Wechsel",
+  "auto_scroll_to_active_song_mode_video_change_auto": "Nur beim Übergang zum nächsten Video",
 
   "plugin_list_title": "Plugin-Liste",
   "plugin_list_no_plugins": "Derzeit sind keine Plugins installiert.\nBesuche %1diese Seite%2 für mehr Informationen.",

+ 3 - 1
assets/translations/en-US.json

@@ -211,7 +211,9 @@
 
   "auto_scroll_to_active_song_mode_never": "Never",
   "auto_scroll_to_active_song_mode_initial_page_load": "On first page load only",
-  "auto_scroll_to_active_song_mode_video_change": "On every new video",
+  "auto_scroll_to_active_song_mode_video_change_all": "On every video change",
+  "auto_scroll_to_active_song_mode_video_change_manual": "Only when manually changing videos",
+  "auto_scroll_to_active_song_mode_video_change_auto": "Only on automatic video transitions",
 
   "plugin_list_title": "Plugin List",
   "plugin_list_no_plugins": "No plugins are currently installed.\nVisit %1this page%2 for more information.",

+ 4 - 1
assets/translations/es-ES.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "Más oscuro",
   "color_lightness_normal": "Normal",
   "color_lightness_lighter": "Más claro",
+
   "auto_scroll_to_active_song_mode_never": "Nunca",
   "auto_scroll_to_active_song_mode_initial_page_load": "Solo en la primera carga de la página",
-  "auto_scroll_to_active_song_mode_video_change": "En cada nuevo video",
+  "auto_scroll_to_active_song_mode_video_change_all": "En cada cambio de video",
+  "auto_scroll_to_active_song_mode_video_change_manual": "Solo al cambiar videos manualmente",
+  "auto_scroll_to_active_song_mode_video_change_auto": "Sólo durante la transición al siguiente vídeo",
 
   "plugin_list_title": "Lista de plugins",
   "plugin_list_no_plugins": "Actualmente no hay plugins instalados.\nVisite %1esta página%2 para obtener más información.",

+ 4 - 1
assets/translations/fr-FR.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "Plus foncé",
   "color_lightness_normal": "Normal",
   "color_lightness_lighter": "Plus clair",
+
   "auto_scroll_to_active_song_mode_never": "Jamais",
   "auto_scroll_to_active_song_mode_initial_page_load": "Au premier chargement de la page uniquement",
-  "auto_scroll_to_active_song_mode_video_change": "À chaque nouvelle vidéo",
+  "auto_scroll_to_active_song_mode_video_change_all": "À chaque changement de vidéo",
+  "auto_scroll_to_active_song_mode_video_change_manual": "Seulement lors du changement manuel de vidéos",
+  "auto_scroll_to_active_song_mode_video_change_auto": "Seulement lors du passage à la vidéo suivante",
 
   "plugin_list_title": "Liste des plugins",
   "plugin_list_no_plugins": "Aucun plugin n'est actuellement installé.\nVisitez %1cette page%2 pour plus d'informations.",

+ 4 - 1
assets/translations/hi-IN.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "गहरे",
   "color_lightness_normal": "सामान्य",
   "color_lightness_lighter": "हल्का",
+
   "auto_scroll_to_active_song_mode_never": "कभी नहीं",
   "auto_scroll_to_active_song_mode_initial_page_load": "पहले पृष्ठ लोड पर केवल",
-  "auto_scroll_to_active_song_mode_video_change": "हर नए वीडियो पर",
+  "auto_scroll_to_active_song_mode_video_change_all": "हर वीडियो पर",
+  "auto_scroll_to_active_song_mode_video_change_manual": "केवल मैन्युअल वीडियो परिवर्तन पर",
+  "auto_scroll_to_active_song_mode_video_change_auto": "केवल अगले वीडियो पर जाते समय",
 
   "plugin_list_title": "प्लगइन सूची",
   "plugin_list_no_plugins": "कोई प्लगइन वर्तमान में स्थापित नहीं हैं।\nअधिक जानकारी के लिए %1इस पृष्ठ%2 पर जाएं।",

+ 4 - 1
assets/translations/ja-JP.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "暗い",
   "color_lightness_normal": "通常",
   "color_lightness_lighter": "明るい",
+
   "auto_scroll_to_active_song_mode_never": "しない",
   "auto_scroll_to_active_song_mode_initial_page_load": "初回のみ",
-  "auto_scroll_to_active_song_mode_video_change": "新しいビデオごと",
+  "auto_scroll_to_active_song_mode_video_change_all": "すべてのビデオの変更時",
+  "auto_scroll_to_active_song_mode_video_change_manual": "手動でビデオを変更するときのみ",
+  "auto_scroll_to_active_song_mode_video_change_auto": "次のビデオへの移行時のみ",
 
   "plugin_list_title": "プラグインリスト",
   "plugin_list_no_plugins": "現在インストールされているプラグインはありません。\n詳細については %1このページ%2 をご覧ください。",

+ 4 - 1
assets/translations/pt-BR.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "Mais escuro",
   "color_lightness_normal": "Normal",
   "color_lightness_lighter": "Mais claro",
+
   "auto_scroll_to_active_song_mode_never": "Nunca",
   "auto_scroll_to_active_song_mode_initial_page_load": "Apenas na primeira carga da página",
-  "auto_scroll_to_active_song_mode_video_change": "Em cada novo vídeo",
+  "auto_scroll_to_active_song_mode_video_change_all": "Em cada mudança de vídeo",
+  "auto_scroll_to_active_song_mode_video_change_manual": "Apenas ao mudar manualmente os vídeos",
+  "auto_scroll_to_active_song_mode_video_change_auto": "Somente durante a transição para o próximo vídeo",
 
   "plugin_list_title": "Lista de plugins",
   "plugin_list_no_plugins": "Nenhum plugin está atualmente instalado.\nVisite %1esta página%2 para mais informações.",

+ 4 - 1
assets/translations/zh-CN.json

@@ -208,9 +208,12 @@
   "color_lightness_darker": "更暗",
   "color_lightness_normal": "正常",
   "color_lightness_lighter": "更亮",
+
   "auto_scroll_to_active_song_mode_never": "从不",
   "auto_scroll_to_active_song_mode_initial_page_load": "仅在第一次加载页面时",
-  "auto_scroll_to_active_song_mode_video_change": "在每个新视频上",
+  "auto_scroll_to_active_song_mode_video_change_all": "在每个视频更改时",
+  "auto_scroll_to_active_song_mode_video_change_manual": "仅在手动更改视频时",
+  "auto_scroll_to_active_song_mode_video_change_auto": "仅在过渡到下一个视频时",
 
   "plugin_list_title": "插件列表",
   "plugin_list_no_plugins": "当前未安装任何插件。\n访问 %1此页面%2 以获取更多信息。",

+ 18 - 2
src/features/behavior.ts

@@ -79,13 +79,29 @@ export async function initAutoCloseToasts() {
 
 let initialAutoScrollToActiveSong = true;
 
+let prevVidMaxTime = Infinity;
+let prevTime = -1;
+
 /** Initializes the autoScrollToActiveSong feature */
 export async function initAutoScrollToActiveSong() {
-  siteEvents.on("watchIdChanged", () => getFeature("autoScrollToActiveSongMode") === "videoChange" && scrollToCurrentSongInQueue());
+  setInterval(() => {
+    prevTime = getVideoElement()?.currentTime ?? -1;
+    prevVidMaxTime = getVideoElement()?.duration ?? Infinity;
+  }, 50);
+
+  siteEvents.on("watchIdChanged", (_, oldId) => {
+    if(!oldId)
+      return;
+    const isManualChange = prevTime < prevVidMaxTime - 1;
+    if(["videoChangeManual", "videoChangeAll"].includes(getFeature("autoScrollToActiveSongMode")) && isManualChange)
+      scrollToCurrentSongInQueue();
+    else if(["videoChangeAuto", "videoChangeAll"].includes(getFeature("autoScrollToActiveSongMode")) && !isManualChange)
+      scrollToCurrentSongInQueue();
+  });
 
   if(getFeature("autoScrollToActiveSongMode") !== "never" && initialAutoScrollToActiveSong) {
     initialAutoScrollToActiveSong = false;
-    waitVideoElementReady().then(() => scrollToCurrentSongInQueue());
+    scrollToCurrentSongInQueue();
   }
 }
 

+ 3 - 1
src/features/index.ts

@@ -483,7 +483,9 @@ export const featInfo = {
     options: () => [
       { value: "never", label: t("auto_scroll_to_active_song_mode_never") },
       { value: "initialPageLoad", label: t("auto_scroll_to_active_song_mode_initial_page_load") },
-      { value: "videoChange", label: t("auto_scroll_to_active_song_mode_video_change") },
+      { value: "videoChangeAll", label: t("auto_scroll_to_active_song_mode_video_change_all") },
+      { value: "videoChangeManual", label: t("auto_scroll_to_active_song_mode_video_change_manual") },
+      { value: "videoChangeAuto", label: t("auto_scroll_to_active_song_mode_video_change_auto") },
     ],
     default: "initialPageLoad",
     reloadRequired: false,

+ 1 - 1
src/types.ts

@@ -580,7 +580,7 @@ export interface FeatureConfig {
   /** Whether the above queue button container should use sticky positioning */
   aboveQueueBtnsSticky: boolean;
   /** Whether and when to automatically scroll to the active song in the queue */
-  autoScrollToActiveSongMode: "never" | "initialPageLoad" | "videoChange";
+  autoScrollToActiveSongMode: "never" | "initialPageLoad" | "videoChangeAll" | "videoChangeManual" | "videoChangeAuto";
 
   //#region input
   /** Arrow keys skip forwards and backwards */

+ 12 - 11
src/utils/misc.ts

@@ -7,6 +7,7 @@ import { enableDiscardBeforeUnload } from "../features/behavior.js";
 import { getFeature } from "../config.js";
 import langMapping from "../../assets/locales.json" with { type: "json" };
 import resourcesJson from "../../assets/resources.json" with { type: "json" };
+import { addSelectorListener } from "src/observers.js";
 
 //#region misc
 
@@ -251,19 +252,19 @@ export function isStringGen(val: unknown): val is StringGen {
     || val instanceof Promise;
 }
 
-/** Scrolls to the current song in the queue if it's available */
+/** Scrolls to the currently playing queue item in the queue once it's available */
 export function scrollToCurrentSongInQueue(evt?: MouseEvent | KeyboardEvent) {
-  const activeItem = document.querySelector<HTMLElement>("#side-panel .ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"loading\"], #side-panel .ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"playing\"], #side-panel .ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"paused\"]");
-  if(!activeItem)
-    return false;
-
-  activeItem.scrollIntoView({
-    behavior: evt?.shiftKey ? "instant" : "smooth",
-    block: evt?.ctrlKey || evt?.altKey ? "start" : "center",
-    inline: "center",
+  addSelectorListener("sidePanel", "ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"loading\"], ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"playing\"], ytmusic-player-queue ytmusic-player-queue-item[play-button-state=\"paused\"]", {
+    listener(activeItem) {
+      activeItem.scrollIntoView({
+        behavior: evt?.shiftKey ? "instant" : "smooth",
+        block: evt?.ctrlKey || evt?.altKey ? "start" : "center",
+        inline: "center",
+      });
+
+      log("Scrolled to active song in queue:", activeItem);
+    }
   });
-
-  return true;
 }
 
 //#region resources