Sv443 1 рік тому
батько
коміт
5db98f4925
4 змінених файлів з 43 додано та 10 видалено
  1. 4 0
      src/features/layout.css
  2. 31 6
      src/features/versionCheck.ts
  3. 6 4
      src/interface.ts
  4. 2 0
      src/menu/menu_old.ts

+ 4 - 0
src/features/layout.css

@@ -136,6 +136,10 @@ button[disabled] {
   cursor: not-allowed;
 }
 
+button[disabled].bytm-busy {
+  cursor: wait;
+}
+
 /* #MARKER menu */
 
 .bytm-cfg-menu-option {

+ 31 - 6
src/features/versionCheck.ts

@@ -5,6 +5,7 @@ import { getVersionNotifDialog } from "../dialogs";
 
 const releaseURL = "https://github.com/Sv443/BetterYTM/releases/latest";
 
+/** Initializes the version check feature */
 export async function initVersionCheck() {
   try {
     if(getFeatures().versionCheck === false)
@@ -21,6 +22,10 @@ export async function initVersionCheck() {
   }
 }
 
+/**
+ * Checks for a new version of the script and shows a dialog.  
+ * If {@linkcode notifyNoUpdatesFound} is set to true, a dialog is also shown if no updates were found.
+ */
 export async function doVersionCheck(notifyNoUpdatesFound = false) {
   await GM.setValue("bytm-version-check", Date.now());
 
@@ -51,18 +56,38 @@ export async function doVersionCheck(notifyNoUpdatesFound = false) {
 
 /**
  * Crudely compares two semver version strings.  
- * @returns Returns 1 if a > b or -1 if a < b or 0 if a == b
+ * The format is assumed to *always* be `MAJOR.MINOR.PATCH`, where each part is a number.
+ * @returns Returns 1 if `a > b`, or -1 if `a < b`, or 0 if `a == b`
  */
-function compareVersions(a: string, b: string) {
+export function compareVersions(a: string, b: string) {
   const pa = a.split(".");
   const pb = b.split(".");
   for(let i = 0; i < 3; i++) {
     const na = Number(pa[i]);
     const nb = Number(pb[i]);
-    if(na > nb) return 1;
-    if(nb > na) return -1;
-    if(!isNaN(na) && isNaN(nb)) return 1;
-    if(isNaN(na) && !isNaN(nb)) return -1;
+    if(na > nb)
+      return 1;
+    if(nb > na)
+      return -1;
+    if(!isNaN(na) && isNaN(nb))
+      return 1;
+    if(isNaN(na) && !isNaN(nb))
+      return -1;
+  }
+  return 0;
+}
+
+/**
+ * Compares two version arrays.  
+ * The format is assumed to *always* be `[MAJOR, MINOR, PATCH]`, where each part is a number.
+ * @returns Returns 1 if `a > b`, or -1 if `a < b`, or 0 if `a == b`
+ */
+export function compareVersionArrays(a: [major: number, minor: number, patch: number], b: [major: number, minor: number, patch: number]) {
+  for(let i = 0; i < 3; i++) {
+    if(a[i] > b[i])
+      return 1;
+    if(b[i] > a[i])
+      return -1;
   }
   return 0;
 }

+ 6 - 4
src/interface.ts

@@ -1,13 +1,13 @@
 import * as UserUtils from "@sv443-network/userutils";
+import { createNanoEvents } from "nanoevents";
 import { mode, branch, host, buildNumber, compressionFormat, scriptInfo } from "./constants";
 import { getResourceUrl, getSessionId, getVideoTime, log, setLocale, getLocale, hasKey, hasKeyFor, NanoEmitter, t, tp, type TrLocale, info, error } from "./utils";
 import { addSelectorListener } from "./observers";
 import { getFeatures, setFeatures } from "./config";
-import { featInfo, fetchLyricsUrlTop, getLyricsCacheEntry, sanitizeArtists, sanitizeSong, type LyricsCache } from "./features";
+import { compareVersionArrays, compareVersions, featInfo, fetchLyricsUrlTop, getLyricsCacheEntry, sanitizeArtists, sanitizeSong, type LyricsCache } from "./features";
 import { allSiteEvents, siteEvents, type SiteEventsMap } from "./siteEvents";
 import { LogLevel, type FeatureConfig, type FeatureInfo, type LyricsCacheEntry, type PluginDef, type PluginInfo, type PluginRegisterResult, type PluginDefResolvable, type PluginEventMap, type PluginItem } from "./types";
 import { BytmDialog, createHotkeyInput, createToggleInput } from "./components";
-import { createNanoEvents } from "nanoevents";
 
 const { getUnsafeWindow } = UserUtils;
 
@@ -32,7 +32,7 @@ export type InterfaceEvents = {
 
   /** Emitted when a dialog was opened - returns the dialog's instance */
   "bytm:dialogOpened": BytmDialog;
-  /** Emitted when the dialog with the specified ID was opened - returns the dialog's instance - use `as "bytm:dialogOpened:id"` in TS to make the error go away */
+  /** Emitted when the dialog with the specified ID was opened - returns the dialog's instance - in TS, use `"..." as "bytm:dialogOpened:id"` to make the error go away */
   "bytm:dialogOpened:id": BytmDialog;
 
   /** Emitted whenever the lyrics URL for a song is loaded */
@@ -41,7 +41,7 @@ export type InterfaceEvents = {
   "bytm:lyricsCacheReady": LyricsCache;
   /** Emitted when the lyrics cache has been cleared */
   "bytm:lyricsCacheCleared": undefined;
-  /** Emitted when an entry is added to the lyrics cache - "penalized" entries have a lower TTL because they were less related in lyrics lookups, as opposed to the "best" entries */
+  /** Emitted when an entry is added to the lyrics cache - "penalized" entries get removed from cache faster because they were less related in lyrics lookups, opposite to the "best" entries */
   "bytm:lyricsCacheEntryAdded": { type: "best" | "penalized", entry: LyricsCacheEntry };
 
   // additionally all events from SiteEventsMap in `src/siteEvents.ts`
@@ -70,6 +70,8 @@ const globalFuncs = {
   getLyricsCacheEntry,
   sanitizeArtists,
   sanitizeSong,
+  compareVersions,
+  compareVersionArrays,
 };
 
 /** Plugins that are queued up for registration */

+ 2 - 0
src/menu/menu_old.ts

@@ -566,6 +566,7 @@ async function addCfgMenu() {
               const res = ftInfo.click();
 
               (wrapperElem as HTMLButtonElement).disabled = true;
+              wrapperElem!.classList.add("bytm-busy");
               wrapperElem!.textContent = wrapperElem!.ariaLabel = wrapperElem!.title = hasKey(`feature_btn_${featKey}_running`) ? t(`feature_btn_${featKey}_running`) : t("trigger_btn_action_running");
 
               if(res instanceof Promise)
@@ -573,6 +574,7 @@ async function addCfgMenu() {
 
               const finalize = () => {
                 (wrapperElem as HTMLButtonElement).disabled = false;
+                wrapperElem!.classList.remove("bytm-busy");
                 wrapperElem!.textContent = wrapperElem!.ariaLabel = wrapperElem!.title = hasKey(`feature_btn_${featKey}`) ? t(`feature_btn_${featKey}`) : t("trigger_btn_action");
               };