From 10ac39b46f2e84e321395cc4179713aeeda9aa4b Mon Sep 17 00:00:00 2001 From: wearrrrr Date: Sun, 24 Nov 2024 00:42:35 -0600 Subject: [PATCH] General code refactoring, move Notyf code into toast.ts --- .eslintrc.cjs | 4 +- index.js | 2 +- public/sw.js | 2 +- src/alu.d.ts | 7 -- src/components/UI/MarketplaceIcon.astro | 1 - src/components/frame/IFrameNav.astro | 26 ++-- src/components/loaders/PageScriptLoader.astro | 52 ++++---- src/components/loaders/ThemeLoader.astro | 1 - src/components/ts/marketplace.ts | 119 ++++++------------ src/components/ts/toast.ts | 38 ++++++ src/pages/[lang]/marketplace.astro | 4 +- src/pages/game/[game].astro | 3 +- src/types.d.ts | 4 + 13 files changed, 127 insertions(+), 136 deletions(-) create mode 100644 src/components/ts/toast.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index feddea3..c9691c3 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -13,7 +13,7 @@ module.exports = { "no-unused-vars": "error", "no-undef": "off", "prefer-const": "error", - "no-case-declarations": "off" + "no-case-declarations": "off", }, ignorePatterns: ["env.d.ts", "middleware/", "public/"], overrides: [ @@ -35,7 +35,7 @@ module.exports = { extends: ["plugin:@typescript-eslint/recommended"], rules: { "@typescript-eslint/no-explicit-any": "off", - } + }, }, { // Define the configuration for ` \ No newline at end of file + }; + diff --git a/src/components/loaders/ThemeLoader.astro b/src/components/loaders/ThemeLoader.astro index ec05fdd..8e8083c 100644 --- a/src/components/loaders/ThemeLoader.astro +++ b/src/components/loaders/ThemeLoader.astro @@ -23,7 +23,6 @@ const decoder = new TextDecoder(); const style = decoder.decode(extension.scriptCopy!); - loadStyleFromString(style); document.addEventListener("astro:after-swap", () => { diff --git a/src/components/ts/marketplace.ts b/src/components/ts/marketplace.ts index 48c5b59..38fc724 100644 --- a/src/components/ts/marketplace.ts +++ b/src/components/ts/marketplace.ts @@ -1,83 +1,51 @@ -import "notyf/notyf.min.css"; -import { Notyf } from "notyf"; import marketplaceManifest from "../../json/marketplace.json"; import IDBManager, { loadIDBPromise } from "./IDBManager"; +import Toast from "./toast"; const installButtons = document.getElementsByClassName("btn-install"); const extManifest = marketplaceManifest as ExtensionMetadataJSON; -// This just makes it shorter to type -interface HTMLButton extends HTMLButtonElement {} - -enum EXT_RETURN { - ACTION_SUCCESS = 0, - INSTALL_FAILED = -1, - ALREADY_INSTALLED = 1, +const EXT_RETURN = { + INSTALL_FAILED: -1, + INSTALL_SUCCESS: 0, + ALREADY_INSTALLED: 1, } Array.from(installButtons).forEach((btn) => { btn.addEventListener("click", async (event) => { const ele = event.target as HTMLButton; const title = ele.dataset.title; - const notification = new Notyf({ - duration: 999999, - position: { x: "right", y: "bottom" }, - dismissible: true, - ripple: true, - }); - const installNotif = notification.success(`Installing ${title}...`); if (ele.dataset.slug) { - const obj = await getMarketplaceObj(ele.dataset.slug); - installExtension(obj, ele.dataset.slug) - .then((ret) => { - let notifMessage: string; - let timeout = 2000; - switch (ret.code) { - case EXT_RETURN.ACTION_SUCCESS: - notifMessage = `Installed ${title} Successfully!`; - // Unregister the service worker if it's a service worker - if (obj.type === "serviceWorker") { - navigator.serviceWorker.getRegistration().then((reg) => { - if (reg) { - reg.unregister().then(() => { - console.log("Service worker unregistered!"); - }); - } - }); + const ext = await getMarketplaceExt(ele.dataset.slug); + const install = await installExtension(ext, ele.dataset.slug) + switch (install.code) { + case EXT_RETURN.INSTALL_SUCCESS: + Toast.success(`Installed ${title} Successfully!`); + if (ext.type === "serviceWorker") { + navigator.serviceWorker.getRegistration().then((reg) => { + if (reg) { + // Unregister the SW so that the installed plugin is loaded when the page is refreshed (automatically) + reg.unregister(); } - break; - case EXT_RETURN.ALREADY_INSTALLED: - notifMessage = `${title} is already installed!`; - timeout = 0; - break; - case EXT_RETURN.INSTALL_FAILED: - // We should NEVER get here, but just in case. - notifMessage = `Failed to install ${title}!`; - break; + }); } - setTimeout(() => { - notification.dismiss(installNotif); - notification.options.duration = 2000; - notification.success(notifMessage); - setTimeout(() => { - window.location.reload(); - }, 1000); - notification.options.duration = 999999; - const btn = document.querySelector(`button[data-slug="${ret.slug}"]`) as HTMLButton; - setInstallBtnText(btn); - }, timeout); - }) - .catch(() => { - notification.dismiss(installNotif); - notification.options.duration = 2000; - notification.error(`Failed to install ${title}!`); - notification.options.duration = 999999; - }); + break; + case EXT_RETURN.ALREADY_INSTALLED: + Toast.success(`${title} is already installed!`); + break; + case EXT_RETURN.INSTALL_FAILED: + Toast.error(`Failed to install ${title}!`); + } + setTimeout(() => { + window.location.reload(); + }, 1500); + const btn = document.querySelector(`button[data-slug="${install.slug}"]`) as HTMLButton; + setInstallBtnText(btn); } }); }); -async function getMarketplaceObj(slug: string): Promise { +async function getMarketplaceExt(slug: string) { const manifest = extManifest[slug]; if (manifest == null) { throw new Error("Extension not found!"); @@ -89,7 +57,7 @@ async function getMarketplaceObj(slug: string): Promise { return manifest; } -async function installExtension(ext: ExtensionMetadata, slug: string): Promise { +async function installExtension(ext: ExtensionMetadata, slug: string) { return new Promise((resolve, reject) => { const request = IDBManager.GetIDB(); const transaction = request.transaction("InstalledExtensions", "readwrite"); @@ -99,18 +67,18 @@ async function installExtension(ext: ExtensionMetadata, slug: string): Promise { - if (slugCheck.result != null) { - resolve({ code: EXT_RETURN.ALREADY_INSTALLED, slug: slug }); - } else { + slugCheck.onsuccess = () => { + if (slugCheck.result == null) { const addRequest = store.add(extensionObject); addRequest.onerror = () => { console.error(`Error installing ${slug}!`); reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug }); }; addRequest.onsuccess = () => { - resolve({ code: EXT_RETURN.ACTION_SUCCESS, slug: slug }); + resolve({ code: EXT_RETURN.INSTALL_SUCCESS, slug: slug }); }; + } else { + resolve({ code: EXT_RETURN.ALREADY_INSTALLED, slug: slug }); } }; }); @@ -122,16 +90,11 @@ function addUninstallEventListeners() { if (!confirm("Are you sure you want to uninstall this extension?")) { return; } - const uninst = await uninstallExtension((event.target as HTMLButton).dataset.uninstallSlug!); - const notification = new Notyf({ - duration: 999999, - position: { x: "right", y: "bottom" }, - dismissible: true, - ripple: true, - }); + const button = event.target as HTMLButton; + const uninst = await uninstallExtension(button.dataset.uninstallSlug!); switch (uninst.code) { - case EXT_RETURN.ACTION_SUCCESS: - notification.success(`Uninstalled ${uninst.title}!`); + case EXT_RETURN.INSTALL_SUCCESS: + Toast.success(`Uninstalled ${uninst.title}!`); const btn = document.querySelector(`button[data-slug="${uninst.slug}"]`) as HTMLButton; btn.disabled = false; btn.textContent = "Install"; @@ -139,7 +102,7 @@ function addUninstallEventListeners() { (event.target as HTMLButton).classList.add("btn-hidden"); break; case EXT_RETURN.INSTALL_FAILED: - notification.error(`Failed to uninstall ${uninst.title}!`); + Toast.error(`Failed to uninstall ${uninst.title}!`); break; } setTimeout(() => { @@ -187,7 +150,7 @@ async function uninstallExtension(slug: string): Promise { }); } }); - resolve({ code: EXT_RETURN.ACTION_SUCCESS, slug: slug, title: ext.result.title }); + resolve({ code: EXT_RETURN.INSTALL_SUCCESS, slug: slug, title: ext.result.title }); }; }; }); diff --git a/src/components/ts/toast.ts b/src/components/ts/toast.ts new file mode 100644 index 0000000..d8e7923 --- /dev/null +++ b/src/components/ts/toast.ts @@ -0,0 +1,38 @@ +import "notyf/notyf.min.css"; +import { Notyf, NotyfNotification } from "notyf"; + +export default class Toast { + private static notyf = new Notyf({ + duration: 999999, + position: { x: "right", y: "bottom" }, + dismissible: true, + ripple: true, + }); + + public static get(): Notyf { + return this.notyf; + } + + public static setDuration(duration: number) { + this.notyf.options.duration = duration; + } + + public static success(message: string) { + return this.notyf.success(message); + } + + public static error(message: string) { + return this.notyf.error(message); + } + + public static info(message: string) { + return this.notyf.open({ + type: "info", + message: message, + }); + } + + public static dismiss(toast: NotyfNotification) { + this.notyf.dismiss(toast); + } +} \ No newline at end of file diff --git a/src/pages/[lang]/marketplace.astro b/src/pages/[lang]/marketplace.astro index d966897..b2fab10 100644 --- a/src/pages/[lang]/marketplace.astro +++ b/src/pages/[lang]/marketplace.astro @@ -102,9 +102,7 @@ export const getStaticPaths = () => { width: 80%; margin: 0 auto; overflow: hidden; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - height: 40px; + height: 80px; } .marketplace-btn-container { diff --git a/src/pages/game/[game].astro b/src/pages/game/[game].astro index 28fdaaf..b161f0a 100644 --- a/src/pages/game/[game].astro +++ b/src/pages/game/[game].astro @@ -9,9 +9,8 @@ const gamesList = games as GameList; sitemap(async ({ setSitemap }) => { const gamesList = games as GameList; - const urls = Object.keys(gamesList); setSitemap( - urls.map((game) => ({ + Object.keys(gamesList).map((game) => ({ sitemap: true, params: { game: game, diff --git a/src/types.d.ts b/src/types.d.ts index 73b1a89..ca6e9a7 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -17,8 +17,12 @@ type Extension = { name: string; script: string; type: ExtType; + }; +// This just makes it shorter to type +type HTMLButton = HTMLButtonElement; + /* - title: The title of the extension - description: A description of the extension