Browse Source

feat: full size watch page feature

Sv443 5 days ago
parent
commit
20a5160fab

+ 1 - 0
assets/resources.json

@@ -13,6 +13,7 @@
     "css-hide_themesong_logo": "style/hideThemeSongLogo.css",
     "css-show_votes": "style/showVotes.css",
     "css-vol_slider_size": "style/volSliderSize.css",
+    "css-watch_page_full_size": "style/watchPageFullSize.css",
     "doc-license": {
       "path": "/LICENSE.txt",
       "ref": "$BRANCH",

+ 7 - 0
assets/style/watchPageFullSize.css

@@ -0,0 +1,7 @@
+ytmusic-player-page > .content {
+  padding: 16px !important;
+}
+
+ytmusic-player-page > .content #side-panel {
+  margin-left: 24px !important;
+}

+ 9 - 9
assets/translations/README.md

@@ -16,15 +16,15 @@ To submit or edit a translation, please follow [this guide](../../contributing.m
 ### Translation progress:
 |   | Locale | Translated keys | Based on |
 | :----: | ------ | --------------- | :------: |
-|  | [`en-US`](./en-US.json) | `345` (default locale) |  |
-| ✅ | [`de-DE`](./de-DE.json) | `345/345` (100%) | ─ |
-|  | [`en-GB`](./en-GB.json) | `345/345` (100%) | `en-US` |
-| ⚠ | [`es-ES`](./es-ES.json) | `337/345` (97.7%) | ─ |
-| ⚠ | [`fr-FR`](./fr-FR.json) | `337/345` (97.7%) | ─ |
-| ⚠ | [`hi-IN`](./hi-IN.json) | `337/345` (97.7%) | ─ |
-| ⚠ | [`ja-JP`](./ja-JP.json) | `337/345` (97.7%) | ─ |
-| ⚠ | [`pt-BR`](./pt-BR.json) | `337/345` (97.7%) | ─ |
-| ⚠ | [`zh-CN`](./zh-CN.json) | `337/345` (97.7%) | ─ |
+|  | [`en-US`](./en-US.json) | `346` (default locale) |  |
+| ✅ | [`de-DE`](./de-DE.json) | `346/346` (100%) | ─ |
+|  | [`en-GB`](./en-GB.json) | `346/346` (100%) | `en-US` |
+| ⚠ | [`es-ES`](./es-ES.json) | `337/346` (97.4%) | ─ |
+| ⚠ | [`fr-FR`](./fr-FR.json) | `337/346` (97.4%) | ─ |
+| ⚠ | [`hi-IN`](./hi-IN.json) | `337/346` (97.4%) | ─ |
+| ⚠ | [`ja-JP`](./ja-JP.json) | `337/346` (97.4%) | ─ |
+| ⚠ | [`pt-BR`](./pt-BR.json) | `337/346` (97.4%) | ─ |
+| ⚠ | [`zh-CN`](./zh-CN.json) | `337/346` (97.4%) | ─ |
 
 <sub>
 ✅ - Fully translated

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

@@ -278,6 +278,7 @@
   "feature_desc_showVotes": "Zeige die Anzahl der Likes und Dislikes auf dem aktuell spielenden Song",
   "feature_helptext_showVotes": "Dieses Feature ist dank Return YouTube Dislike möglich. Es zeigt die ungefähre Anzahl von Likes und Dislikes auf dem aktuell spielenden Song an.",
   "feature_desc_numbersFormat": "Wie sollen Zahlen formatiert werden?",
+  "feature_desc_watchPageFullSize": "Vergrößere den Hauptinhalt auf der /watch-Seite, um den gesamt verfügbaren Platz zu nutzen",
 
   "feature_desc_volumeSliderLabel": "Füge eine Prozent-Beschriftung neben dem Lautstärkeregler hinzu",
   "feature_desc_volumeSliderSize": "Die Breite des Lautstärkereglers in Pixeln",

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

@@ -278,6 +278,7 @@
   "feature_desc_showVotes": "Show the amount of likes and dislikes on the currently playing song",
   "feature_helptext_showVotes": "This feature is powered by Return YouTube Dislike and will show the approximate amount of likes and dislikes on the currently playing song.",
   "feature_desc_numbersFormat": "How should numbers be formatted?",
+  "feature_desc_watchPageFullSize": "Make the main content on the /watch page use all available space",
 
   "feature_desc_volumeSliderLabel": "Add a percentage label next to the volume slider",
   "feature_desc_volumeSliderSize": "The width of the volume slider in pixels",

+ 1 - 0
src/config.ts

@@ -140,6 +140,7 @@ export const migrations: DataMigrationsDict = {
     useDefaultConfig(oldData, [
       "aboveQueueBtnsSticky", "autoScrollToActiveSongMode",
       "frameSkip", "frameSkipWhilePlaying",
+      "watchPageFullSize",
     ]), [
       { key: "lyricsCacheMaxSize", oldDefault: 2000 },
     ],

+ 7 - 2
src/features/index.ts

@@ -281,8 +281,13 @@ export const featInfo = {
     default: true,
     textAdornment: adornments.reload,
   },
-  // archived idea for future version
-  // (shows a bar under the like/dislike buttons that shows the ratio of likes to dislikes)
+  watchPageFullSize: {
+    type: "toggle",
+    category: "layout",
+    default: false,
+    textAdornment: adornments.reload,
+  },
+  // archived idea for future version (shows a bar under the like/dislike buttons that shows the ratio of likes to dislikes):
   // showVoteRatio: {
   //   type: "select",
   //   category: "layout",

+ 10 - 0
src/features/layout.ts

@@ -825,3 +825,13 @@ function upsertVoteBtnLabels(parentEl: HTMLElement, likesLabelText: string, disl
   if(dislikeBtn)
     dislikeBtn.title = dislikeBtn.ariaLabel = dislikesLabelText;
 };
+
+//#region watch page full size
+
+/** Makes the watch page full size */
+export async function initWatchPageFullSize() {
+  if(!await addStyleFromResource("css-watch_page_full_size"))
+    error("Couldn't load stylesheet to make watch page full size");
+  else
+    log("Made watch page full size");
+}

+ 4 - 1
src/index.ts

@@ -15,7 +15,7 @@ import {
   addWatermark, initRemShareTrackParam,
   fixSpacing, initThumbnailOverlay,
   initHideCursorOnIdle, fixHdrIssues,
-  initShowVotes,
+  initShowVotes, initWatchPageFullSize,
   // volume category:
   initVolumeFeatures,
   // song lists category:
@@ -200,6 +200,9 @@ async function onDomLoad() {
       if(feats.showVotes)
         ftInit.push(["showVotes", initShowVotes()]);
 
+      if(feats.watchPageFullSize)
+        ftInit.push(["watchPageFullSize", initWatchPageFullSize()]);
+
       //#region (ytm) volume
 
       ftInit.push(["volumeFeatures", initVolumeFeatures()]);

+ 5 - 0
src/types.ts

@@ -50,6 +50,9 @@ export type SiteSelectionOrNone = SiteSelection | "none";
 /** Key of a resource in `assets/resources.json` and extra keys defined by `tools/post-build.ts` */
 export type ResourceKey = keyof typeof resources["resources"] | `trans-${keyof typeof locales}`;
 
+/** Key of a CSS resource in `assets/resources.json` */
+export type StyleResourceKey = ResourceKey & `css-${string}`;
+
 /** Describes a single hotkey */
 export type HotkeyObj = {
   code: string,
@@ -533,6 +536,8 @@ export interface FeatureConfig {
   showVotes: boolean;
   /** Which format to use for the like/dislike ratio on the currently playing song */
   numbersFormat: NumberLengthFormat;
+  /** Whether to remove all padding around the main content on the /watch page on YTM */
+  watchPageFullSize: boolean;
 
   //#region volume
   /** Add a percentage label to the volume slider */

+ 2 - 2
src/utils/dom.ts

@@ -2,7 +2,7 @@ import { addGlobalStyle, consumeStringGen, getUnsafeWindow, isDomLoaded, randomI
 import DOMPurify from "dompurify";
 import { error, fetchCss, getDomain, t } from "./index.js";
 import { addSelectorListener } from "../observers.js";
-import type { ResourceKey, TTPolicy } from "../types.js";
+import type { StyleResourceKey, TTPolicy } from "../types.js";
 import { siteEvents } from "../siteEvents.js";
 import { showPrompt } from "../dialogs/prompt.js";
 
@@ -183,7 +183,7 @@ export async function addStyle(css: StringGen, ref?: string, transform: (css: st
  * Adds a global style element with the contents fetched from the specified resource starting with `css-`  
  * The CSS can be transformed using the provided function before being added to the DOM.
  */
-export async function addStyleFromResource(key: ResourceKey & `css-${string}`, transform: (css: string) => Stringifiable = (c) => c) {
+export async function addStyleFromResource(key: StyleResourceKey, transform: (css: string) => Stringifiable = (c) => c) {
   const css = await fetchCss(key);
   if(css) {
     await addStyle(String(transform(css)), key.slice(4));

+ 2 - 2
src/utils/xhr.ts

@@ -1,5 +1,5 @@
 import { fetchAdvanced, type Stringifiable } from "@sv443-network/userutils";
-import type { RYDVotesObj, ResourceKey, VideoVotesObj } from "../types.js";
+import type { RYDVotesObj, StyleResourceKey, VideoVotesObj } from "../types.js";
 import { getResourceUrl } from "./misc.js";
 import { error, info } from "./logging.js";
 
@@ -46,7 +46,7 @@ export function sendRequest<T = any>(details: GM.Request<T>) {
 }
 
 /** Fetches a CSS file from the specified resource with a key starting with `css-` */
-export async function fetchCss(key: ResourceKey & `css-${string}`) {
+export async function fetchCss(key: StyleResourceKey) {
   try {
     const css = await (await fetchAdvanced(await getResourceUrl(key))).text();
     return css ?? undefined;