Ver código fonte

feat: remove share url tracking parameter

Sv443 1 ano atrás
pai
commit
68f460fe77
5 arquivos alterados com 51 adições e 14 exclusões
  1. 11 3
      src/config.ts
  2. 6 0
      src/features/index.ts
  3. 31 10
      src/features/layout.ts
  4. 1 1
      src/features/menu/menu_old.css
  5. 2 0
      src/types.ts

+ 11 - 3
src/config.ts

@@ -1,12 +1,12 @@
-import { ConfigManager, ConfigManagerOptions } from "@sv443-network/userutils";
+import { ConfigManager, ConfigMigrationsDict } from "@sv443-network/userutils";
 import { featInfo } from "./features/index";
 import { FeatureConfig } from "./types";
 import { info, log } from "./utils";
 
 /** If this number is incremented, the features object data will be migrated to the new format */
-const formatVersion = 2;
+const formatVersion = 3;
 
-const migrations: ConfigManagerOptions<typeof defaultConfig>["migrations"] = {
+const migrations: ConfigMigrationsDict = {
   // 1 -> 2
   2: (oldData: Record<string, unknown>) => {
     const queueBtnsEnabled = Boolean(oldData.queueButtons);
@@ -17,6 +17,11 @@ const migrations: ConfigManagerOptions<typeof defaultConfig>["migrations"] = {
       lyricsQueueButton: queueBtnsEnabled,
     };
   },
+  // 2 -> 3
+  3: (oldData: Record<string, unknown>) => ({
+    ...oldData,
+    removeShareTrackingParam: true,
+  }),
 };
 
 export const defaultConfig = (Object.keys(featInfo) as (keyof typeof featInfo)[])
@@ -34,8 +39,11 @@ const cfgMgr = new ConfigManager({
 
 /** Initializes the ConfigManager instance and loads persistent data into memory */
 export async function initConfig() {
+  const oldFmtVer = await GM.getValue(`_uucfgver-${cfgMgr.id}`, -1);
   const data = await cfgMgr.loadData();
   log(`Initialized ConfigManager (format version = ${cfgMgr.formatVersion})`);
+  if(oldFmtVer !== cfgMgr.formatVersion)
+    info(`Config data migrated from version ${oldFmtVer} to ${cfgMgr.formatVersion}`);
   return data;
 }
 

+ 6 - 0
src/features/index.ts

@@ -75,6 +75,12 @@ export const featInfo = {
     default: 0,
     unit: "s",
   },
+  removeShareTrackingParam: {
+    desc: "Remove the tracking parameter (&si=...) from links in the share popup",
+    type: "toggle",
+    category: "layout",
+    default: true,
+  },
 
   //#SECTION input
   arrowKeySupport: {

+ 31 - 10
src/features/layout.ts

@@ -1,9 +1,8 @@
-import type { Event as BillEvent } from "@billjs/event-emitter";
 import { addGlobalStyle, addParent, autoPlural, fetchAdvanced, insertAfter, onSelector, openInNewTab, pauseFor } from "@sv443-network/userutils";
 import type { FeatureConfig } from "../types";
 import { scriptInfo } from "../constants";
-import { error, getResourceUrl, log } from "../utils";
-import { getEvtData, siteEvents } from "../events";
+import { error, getResourceUrl, log, warn } from "../utils";
+import { SiteEventsMap, siteEvents } from "../events";
 import { openMenu } from "./menu/menu_old";
 import { getGeniusUrl, createLyricsBtn, sanitizeArtists, sanitizeSong, getLyricsCacheEntry, splitVideoTitle } from "./lyrics";
 import { featInfo } from "./index";
@@ -279,9 +278,11 @@ function setVolSliderStep(sliderElem: HTMLInputElement) {
 //#MARKER queue buttons
 
 export function initQueueButtons() {
-  const addQueueBtns = (evt: BillEvent) => {
+  const addQueueBtns = (
+    evt: Parameters<SiteEventsMap["queueChanged" | "autoplayQueueChanged"]>[0],
+  ) => {
     let amt = 0;
-    for(const queueItm of getEvtData<HTMLElement>(evt).childNodes as NodeListOf<HTMLElement>) {
+    for(const queueItm of evt.childNodes as NodeListOf<HTMLElement>) {
       if(!queueItm.classList.contains("bytm-has-queue-btns")) {
         addQueueButtons(queueItm);
         amt++;
@@ -481,11 +482,8 @@ export function addAnchorImprovements() {
     });
 
     // every shelf that's loaded by scrolling:
-    siteEvents.on("carouselShelvesChanged", (evt) => {
-      const { addedNodes, removedNodes } = getEvtData<Record<"addedNodes" | "removedNodes", NodeListOf<HTMLElement>>>(evt);
-      void removedNodes;
-
-      if(addedNodes.length > 0)
+    siteEvents.on("carouselShelvesChanged", ({ addedNodes }) => {
+      if(addedNodes && addedNodes.length > 0)
         addedNodes.forEach(condCarouselImprovements);
     });
 
@@ -660,3 +658,26 @@ export function initAutoCloseToasts() {
     error("Error in automatic toast closing:", err);
   }
 }
+
+//#MARKER remove share tracking param
+
+/** Continuously removes the ?si tracking parameter from share URLs */
+export function removeShareTrackingParam() {
+  onSelector<HTMLInputElement>("yt-copy-link-renderer input#share-url", {
+    continuous: true,
+    listener: (inputElem) => {
+      try {
+        const url = new URL(inputElem.value);
+        if(!url.searchParams.has("si"))
+          return;
+
+        url.searchParams.delete("si");
+        inputElem.value = String(url);
+        log(`Removed tracking parameter from share link: ${url}`);
+      }
+      catch(err) {
+        warn("Couldn't remove tracking parameter from share link due to error:", err);
+      }
+    },
+  });
+}

+ 1 - 1
src/features/menu/menu_old.css

@@ -153,5 +153,5 @@
 }
 
 .bytm-ftconf-input[type=number] {
-  width: 100px;
+  width: 75px;
 }

+ 2 - 0
src/types.ts

@@ -41,6 +41,8 @@ export interface FeatureConfig {
   deleteFromQueueButton: boolean;
   /** After how many milliseconds to close permanent toasts */
   closeToastsTimeout: number;
+  /** Remove the "si" tracking parameter from links in the share popup */
+  removeShareTrackingParam: boolean;
 
   //#SECTION lyrics
   /** Add a button to the media controls to open the current song's lyrics on genius.com in a new tab */