Ver código fonte

feat: migrate welcome menu to bytmdialog class

Sv443 1 ano atrás
pai
commit
7e98290e93

+ 1 - 1
assets/translations/de_DE.json

@@ -92,7 +92,7 @@
     "welcome_text_line_1": "Vielen Dank für die Installation!",
     "welcome_text_line_2": "Ich hoffe, du hast genauso viel Spaß mit %1 wie ich beim Erstellen hatte 😃",
     "welcome_text_line_3": "Wenn dir %1 gefällt, hinterlasse bitte eine Bewertung auf %2GreasyFork%3 oder %4OpenUserJS%5",
-    "welcome_text_line_4": "Meine Arbeit hängt von Spenden ab, also bitte überlege zu %1spenden ❤️%2",
+    "welcome_text_line_4": "Meine Arbeit hängt von %1Spenden%2 ab, also bitte denke darüber nach, ob du spenden möchtest ❤️",
     "welcome_text_line_5": "Hast du einen Fehler gefunden oder möchtest ein Feature vorschlagen? Bitte %1öffne ein Issue auf GitHub%2",
 
     "list_button_placement_queue_only": "Nur Wiedergabeliste",

+ 50 - 0
src/dialogs/dialogs.css

@@ -94,3 +94,53 @@
 .bytm-warning-icon svg path {
   fill: var(--bytm-warning-col, #fff);
 }
+
+/* #SECTION welcome dialog */
+
+#bytm-welcome-menu-title-wrapper {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
+
+#bytm-welcome-menu-title-logo {
+  width: 32px;
+  height: 32px;
+  margin-right: 20px;
+}
+
+#bytm-welcome-menu-content-wrapper {
+  overflow-y: auto;
+}
+
+#bytm-welcome-menu-locale-cont {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: flex-start;
+}
+
+#bytm-welcome-menu-locale-img {
+  width: 80px;
+  height: 80px;
+  margin-bottom: 10px;
+}
+
+#bytm-welcome-menu-text-cont {
+  margin-top: 16px;
+}
+
+#bytm-welcome-menu-text {
+  font-size: 1.6rem;
+  line-height: 20px;
+}
+
+#bytm-welcome-menu-locale-select {
+  font-size: 1.6rem;
+}
+
+#bytm-welcome-menu-footer-cont {
+  display: flex;
+  justify-content: space-between;
+  border-radius: 0px 0px var(--bytm-menu-border-radius) var(--bytm-menu-border-radius);
+}

+ 8 - 3
src/dialogs/export.ts → src/dialogs/exportCfg.ts

@@ -71,10 +71,15 @@ async function renderBody() {
   textAreaElem.value = t("click_to_reveal_sensitive_info");
   textAreaElem.setAttribute("revealed", "false");
 
-  const textAreaInteraction = async () => {
+  const textAreaInteraction = async ({ shiftKey }: MouseEvent | KeyboardEvent) => {
     const cfgString = JSON.stringify({ formatVersion, data: getFeatures() });
     lastUncompressedCfgString = JSON.stringify({ formatVersion, data: getFeatures() }, undefined, 2);
-    textAreaElem.value = canCompress ? await compress(cfgString, compressionFormat, "string") : cfgString;
+    textAreaElem.value = shiftKey
+      ? lastUncompressedCfgString
+      : (canCompress
+        ? await compress(cfgString, compressionFormat, "string")
+        : cfgString
+      );
     textAreaElem.setAttribute("revealed", "true");
   };
 
@@ -115,7 +120,7 @@ async function renderFooter() {
 
   onInteraction(copyBtnElem, async (evt: MouseEvent | KeyboardEvent) => {
     evt?.bubbles && evt.stopPropagation();
-    GM.setClipboard(String(evt?.shiftKey || evt?.ctrlKey ? lastUncompressedCfgString : await compress(JSON.stringify({ formatVersion, data: getFeatures() }), compressionFormat, "string")));
+    GM.setClipboard(String(evt?.shiftKey ? lastUncompressedCfgString : await compress(JSON.stringify({ formatVersion, data: getFeatures() }), compressionFormat, "string")));
     copiedTextElem.style.display = "inline-block";
     if(typeof copiedTxtTimeout === "undefined") {
       copiedTxtTimeout = setTimeout(() => {

+ 0 - 0
src/dialogs/import.ts → src/dialogs/importCfg.ts


+ 3 - 2
src/dialogs/index.ts

@@ -1,7 +1,8 @@
 import "./dialogs.css";
 
 export * from "./changelog";
-export * from "./export";
+export * from "./exportCfg";
 export * from "./featHelp";
-export * from "./import";
+export * from "./importCfg";
 export * from "./versionNotif";
+export * from "./welcome";

+ 65 - 123
src/menu/welcomeMenu.ts → src/dialogs/welcome.ts

@@ -1,35 +1,35 @@
-import { getResourceUrl, warn, type TrLocale, initTranslations, setLocale, t } from "../utils";
-import { getFeatures, setFeatures } from "../config";
-import { siteEvents } from "../siteEvents";
+import { getResourceUrl, initTranslations, setLocale, t, warn, type TrLocale } from "../utils";
+import { BytmDialog } from "../components";
+import { openCfgMenu } from "../menu/menu_old";
 import { scriptInfo } from "../constants";
-import { openCfgMenu } from "./menu_old";
-import locales from "../../assets/locales.json" assert { type: "json" };
+import { getFeatures, setFeatures } from "../config";
+import { getChangelogDialog } from ".";
 import pkg from "../../package.json" assert { type: "json" };
-import "./welcomeMenu.css";
-import { getChangelogDialog } from "src/dialogs";
-
-//#MARKER menu
-
-let isWelcomeMenuOpen = false;
-
-/** Adds the welcome menu to the DOM */
-export async function addWelcomeMenu() {
-  //#SECTION backdrop & menu container
-  const backgroundElem = document.createElement("div");
-  backgroundElem.id = "bytm-welcome-menu-bg";
-  backgroundElem.classList.add("bytm-menu-bg");
-  backgroundElem.style.visibility = "hidden";
-  backgroundElem.style.display = "none";
-
-  const menuContainer = document.createElement("div");
-  menuContainer.ariaLabel = menuContainer.title = ""; // prevent bg title from propagating downwards
-  menuContainer.classList.add("bytm-menu");
-  menuContainer.id = "bytm-welcome-menu";
+import locales from "../../assets/locales.json" assert { type: "json" };
 
-  //#SECTION title bar
-  const headerElem = document.createElement("div");
-  headerElem.classList.add("bytm-menu-header");
+let welcomeDialog: BytmDialog | null = null;
+
+/** Creates and/or returns the import dialog */
+export async function getWelcomeDialog() {
+  if(!welcomeDialog) {
+    welcomeDialog = new BytmDialog({
+      id: "welcome",
+      width: 700,
+      height: 500,
+      closeBtnEnabled: true,
+      closeOnBgClick: true,
+      closeOnEscPress: true,
+      destroyOnClose: true,
+      renderHeader,
+      renderBody,
+      renderFooter,
+    });
+    welcomeDialog.on("render", retranslateWelcomeMenu);
+  }
+  return welcomeDialog;
+}
 
+async function renderHeader() {
   const titleWrapperElem = document.createElement("div");
   titleWrapperElem.id = "bytm-welcome-menu-title-wrapper";
 
@@ -40,55 +40,17 @@ export async function addWelcomeMenu() {
 
   const titleElem = document.createElement("h2");
   titleElem.id = "bytm-welcome-menu-title";
-  titleElem.className = "bytm-menu-title";
+  titleElem.classList.add("bytm-dialog-title");
   titleElem.role = "heading";
   titleElem.ariaLevel = "1";
 
   titleWrapperElem.appendChild(titleLogoElem);
   titleWrapperElem.appendChild(titleElem);
 
-  headerElem.appendChild(titleWrapperElem);
-
-  //#SECTION footer
-  const footerCont = document.createElement("div");
-  footerCont.id = "bytm-welcome-menu-footer-cont";
-  footerCont.className = "bytm-menu-footer-cont";
-
-  const openCfgElem = document.createElement("button");
-  openCfgElem.id = "bytm-welcome-menu-open-cfg";
-  openCfgElem.classList.add("bytm-btn");
-  openCfgElem.addEventListener("click", () => {
-    closeWelcomeMenu();
-    openCfgMenu();
-  });
-
-  const openChangelogElem = document.createElement("button");
-  openChangelogElem.id = "bytm-welcome-menu-open-changelog";
-  openChangelogElem.classList.add("bytm-btn");
-  openChangelogElem.addEventListener("click", async () => {
-    const dlg = await getChangelogDialog();
-    await dlg.mount();
-    closeWelcomeMenu();
-    await dlg.open();
-  });
-
-  const closeBtnElem = document.createElement("button");
-  closeBtnElem.id = "bytm-welcome-menu-footer-close";
-  closeBtnElem.classList.add("bytm-btn");
-  closeBtnElem.addEventListener("click", async () => {
-    closeWelcomeMenu();
-  });
-
-  const leftButtonsCont = document.createElement("div");
-  leftButtonsCont.id = "bytm-menu-footer-left-buttons-cont";
-
-  leftButtonsCont.appendChild(openCfgElem);
-  leftButtonsCont.appendChild(openChangelogElem);
-
-  footerCont.appendChild(leftButtonsCont);
-  footerCont.appendChild(closeBtnElem);
+  return titleWrapperElem;
+}
 
-  //#SECTION content
+async function renderBody() {
   const contentWrapper = document.createElement("div");
   contentWrapper.id = "bytm-welcome-menu-content-wrapper";
 
@@ -179,19 +141,9 @@ export async function addWelcomeMenu() {
   textCont.appendChild(textElem);
   contentWrapper.appendChild(textCont);
 
-  //#SECTION finalize
-  menuContainer.appendChild(headerElem);
-  menuContainer.appendChild(contentWrapper);
-  menuContainer.appendChild(footerCont);
-
-  backgroundElem.appendChild(menuContainer);
-
-  document.body.appendChild(backgroundElem);
-  retranslateWelcomeMenu();
+  return contentWrapper;
 }
 
-//#MARKER (re-)translate
-
 /** Retranslates all elements inside the welcome menu */
 function retranslateWelcomeMenu() {
   const getLink = (href: string): [string, string] => {
@@ -231,53 +183,43 @@ function retranslateWelcomeMenu() {
   }
 }
 
-/** Closes the welcome menu if it is open. If a bubbling event is passed, its propagation will be prevented. */
-export function closeWelcomeMenu(evt?: MouseEvent | KeyboardEvent) {
-  if(!isWelcomeMenuOpen)
-    return;
-  isWelcomeMenuOpen = false;
-  evt?.bubbles && evt.stopPropagation();
-
-  document.body.classList.remove("bytm-disable-scroll");
-  document.querySelector("ytmusic-app")?.removeAttribute("inert");
-  const menuBg = document.querySelector<HTMLElement>("#bytm-welcome-menu-bg");
-
-  siteEvents.emit("welcomeMenuClosed");
-
-  if(!menuBg)
-    return warn("Couldn't find welcome menu background element");
-
-  menuBg.style.visibility = "hidden";
-  menuBg.style.display = "none";
-}
+async function renderFooter() {
+  const footerCont = document.createElement("div");
+  footerCont.id = "bytm-welcome-menu-footer-cont";
 
-//#MARKER open, show & close
+  const openCfgElem = document.createElement("button");
+  openCfgElem.id = "bytm-welcome-menu-open-cfg";
+  openCfgElem.classList.add("bytm-btn");
+  openCfgElem.addEventListener("click", () => {
+    welcomeDialog?.close();
+    openCfgMenu();
+  });
 
-/** Opens the welcome menu if it is closed */
-export function openWelcomeMenu() {
-  if(isWelcomeMenuOpen)
-    return;
-  isWelcomeMenuOpen = true;
+  const openChangelogElem = document.createElement("button");
+  openChangelogElem.id = "bytm-welcome-menu-open-changelog";
+  openChangelogElem.classList.add("bytm-btn");
+  openChangelogElem.addEventListener("click", async () => {
+    const dlg = await getChangelogDialog();
+    await dlg.mount();
+    welcomeDialog?.close();
+    await dlg.open();
+  });
 
-  document.body.classList.add("bytm-disable-scroll");
-  document.querySelector("ytmusic-app")?.setAttribute("inert", "true");
-  const menuBg = document.querySelector<HTMLElement>("#bytm-welcome-menu-bg");
+  const closeBtnElem = document.createElement("button");
+  closeBtnElem.id = "bytm-welcome-menu-footer-close";
+  closeBtnElem.classList.add("bytm-btn");
+  closeBtnElem.addEventListener("click", async () => {
+    welcomeDialog?.close();
+  });
 
-  if(!menuBg)
-    return warn("Couldn't find welcome menu background element");
+  const leftButtonsCont = document.createElement("div");
+  leftButtonsCont.id = "bytm-menu-footer-left-buttons-cont";
 
-  menuBg.style.visibility = "visible";
-  menuBg.style.display = "block";
-}
+  leftButtonsCont.appendChild(openCfgElem);
+  leftButtonsCont.appendChild(openChangelogElem);
 
-/** Shows the welcome menu and returns a promise that resolves when the menu is closed */
-export function showWelcomeMenu() {
-  return new Promise<void>((resolve) => {
-    const unsub = siteEvents.on("welcomeMenuClosed", () => {
-      unsub();
-      resolve();
-    });
+  footerCont.appendChild(leftButtonsCont);
+  footerCont.appendChild(closeBtnElem);
 
-    openWelcomeMenu();
-  });
+  return footerCont;
 }

+ 5 - 4
src/index.ts

@@ -5,7 +5,6 @@ import { buildNumber, compressionFormat, defaultLogLevel, mode, scriptInfo } fro
 import { error, getDomain, info, getSessionId, log, setLogLevel, initTranslations, setLocale } from "./utils";
 import { initSiteEvents } from "./siteEvents";
 import { emitInterface, initInterface, initPlugins } from "./interface";
-import { addWelcomeMenu, showWelcomeMenu } from "./menu/welcomeMenu";
 import { initObservers, addSelectorListener, globservers } from "./observers";
 import {
   // layout
@@ -31,6 +30,7 @@ import {
   // other
   initVersionCheck, initLyricsCache,
 } from "./features/index";
+import { getWelcomeDialog } from "./dialogs";
 
 {
   // console watermark with sexy gradient
@@ -139,10 +139,11 @@ async function onDomLoad() {
 
       if(typeof await GM.getValue("bytm-installed") !== "string") {
         // open welcome menu with language selector
-        await addWelcomeMenu();
+        const dlg = await getWelcomeDialog();
+        dlg.on("close", () => GM.setValue("bytm-installed", JSON.stringify({ timestamp: Date.now(), version: scriptInfo.version })));
+        await dlg.mount();
         info("Showing welcome menu");
-        await showWelcomeMenu();
-        await GM.setValue("bytm-installed", JSON.stringify({ timestamp: Date.now(), version: scriptInfo.version }));
+        await dlg.open();
       }
 
       addSelectorListener("body", "tp-yt-iron-dropdown #contentWrapper ytd-multi-page-menu-renderer #container.menu-container", {

+ 0 - 5
src/menu/updateMenu.css

@@ -1,5 +0,0 @@
-#bytm-update-menu-bg {
-  --bytm-menu-height-max: 500px;
-  --bytm-menu-width-max: 600px;
-}
-

+ 0 - 78
src/menu/updateMenu.ts

@@ -1,78 +0,0 @@
-import { warn } from "../utils";
-import "./updateMenu.css";
-import menuTemplateHtml from "./new/menuTemplate.html";
-
-// TODO: implement using BytmMenu class
-
-let isUpdateMenuOpen = false;
-
-export function createUpdateMenu() {
-  const bgElem = document.createElement("div");
-  bgElem.id = "bytm-update-menu-bg";
-  bgElem.innerHTML = menuTemplateHtml;
-  bgElem.classList.add("bytm-menu-bg");
-  bgElem.style.visibility = "hidden";
-  bgElem.style.display = "none";
-
-  document.body.appendChild(bgElem);
-
-  const menuContElem = bgElem.querySelector(".bytm-menu");
-  if(menuContElem) {
-    menuContElem.id = "bytm-update-menu";
-  }
-}
-
-/** Closes the update menu if it is open. If a bubbling event is passed, its propagation will be prevented. */
-function closeUpdateMenu(evt?: MouseEvent | KeyboardEvent) {
-  if(!isUpdateMenuOpen)
-    return;
-  isUpdateMenuOpen = false;
-  evt?.bubbles && evt.stopPropagation();
-
-  document.body.classList.remove("bytm-disable-scroll");
-  document.querySelector("ytmusic-app")?.removeAttribute("inert");
-  const menuBg = document.querySelector<HTMLElement>("#bytm-update-menu-bg");
-
-  if(!menuBg)
-    return warn("Couldn't find update menu background element");
-
-  menuBg.style.visibility = "hidden";
-  menuBg.style.display = "none";
-}
-
-void closeUpdateMenu;
-
-/** Opens the update menu if it is closed */
-export function openUpdateMenu(newVersion: string) {
-  if(isUpdateMenuOpen)
-    return;
-  isUpdateMenuOpen = true;
-
-  document.body.classList.add("bytm-disable-scroll");
-  document.querySelector("ytmusic-app")?.setAttribute("inert", "true");
-  const menuBg = document.querySelector<HTMLElement>("#bytm-update-menu-bg");
-
-  if(!menuBg)
-    return warn("Couldn't find update menu background element");
-
-  const changes = {
-    "#update-menu-version": (el: HTMLElement) => el.textContent = newVersion,
-    "#update-menu-changelog-url": (el: HTMLAnchorElement) => {
-      el.href = `https://github.com/Sv443/BetterYTM/blob/main/changelog.md#${newVersion.replace(/\./g, "")}`;
-    },
-  };
-
-  for(const [selector, cb] of Object.entries(changes)) {
-    const elem = document.querySelector<HTMLElement>(selector);
-    if(!elem) {
-      warn(`Couldn't find element ${selector} in welcome menu`);
-      continue;
-    }
-
-    // @ts-ignore
-    cb(elem);
-  }
-
-  menuBg.style.visibility = "visible";
-  menuBg.style.display = "block";
-}

+ 0 - 49
src/menu/welcomeMenu.css

@@ -1,49 +0,0 @@
-#bytm-welcome-menu-bg {
-  --bytm-menu-height-max: 500px;
-  --bytm-menu-width-max: 700px;
-}
-
-#bytm-welcome-menu-title-wrapper {
-  display: flex;
-  flex-direction: row;
-  align-items: center;
-}
-
-#bytm-welcome-menu-title-logo {
-  width: 32px;
-  height: 32px;
-  margin-right: 20px;
-}
-
-#bytm-welcome-menu-content-wrapper {
-  overflow-y: auto;
-}
-
-#bytm-welcome-menu-locale-cont {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: flex-start;
-}
-
-#bytm-welcome-menu-locale-img {
-  width: 80px;
-  height: 80px;
-  margin-bottom: 10px;
-}
-
-#bytm-welcome-menu-text {
-  font-size: 1.6em;
-  padding: 8px 20px;
-  margin: 10px 0px;
-  line-height: 20px;
-}
-
-#bytm-welcome-menu-locale-select {
-  font-size: 1.6em;
-}
-
-#bytm-welcome-menu-footer-cont {
-  border-radius: 0px 0px var(--bytm-menu-border-radius) var(--bytm-menu-border-radius);
-  padding: 20px;
-}