Add eruda plugin, stylize navbar elements to be better, and patch some issues with marketplace manifests
This commit is contained in:
parent
b0760dd553
commit
a05e112de9
17 changed files with 95 additions and 317 deletions
3
public/img/nav/close.svg
Normal file
3
public/img/nav/close.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512">
|
||||||
|
<path fill="#fc847c" d="M376.6 84.5c11.3-13.6 9.5-33.8-4.1-45.1s-33.8-9.5-45.1 4.1L192 206 56.6 43.5C45.3 29.9 25.1 28.1 11.5 39.4S-3.9 70.9 7.4 84.5L150.3 256 7.4 427.5c-11.3 13.6-9.5 33.8 4.1 45.1s33.8 9.5 45.1-4.1L192 306 327.4 468.5c11.3 13.6 31.5 15.4 45.1 4.1s15.4-31.5 4.1-45.1L233.7 256 376.6 84.5z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 384 B |
BIN
public/marketplace/eruda/banner.png
Normal file
BIN
public/marketplace/eruda/banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
1
public/marketplace/eruda/eruda.js
Normal file
1
public/marketplace/eruda/eruda.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,19 +0,0 @@
|
||||||
self.vencordExt = {};
|
|
||||||
|
|
||||||
async function loadVC() {
|
|
||||||
console.log("Loading Vencord...");
|
|
||||||
const vencordJS = await fetch("/marketplace/vencord/bundle/browser.js");
|
|
||||||
const vencordCSS = await fetch("https://raw.githubusercontent.com/Vencord/builds/main/browser.css");
|
|
||||||
self.vencordJS = await vencordJS.text();
|
|
||||||
self.vencordCSS = await vencordCSS.text();
|
|
||||||
if (uv.config.inject === undefined) {
|
|
||||||
uv.config.inject = [];
|
|
||||||
};
|
|
||||||
uv.config.inject.push({
|
|
||||||
"host": "discord.com",
|
|
||||||
"html": `<script>${self.vencordJS}</script><style>${self.vencordCSS}</style>`,
|
|
||||||
"injectTo": "head",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self.vencordExt.loadVC = loadVC;
|
|
||||||
|
|
@ -15,9 +15,13 @@ function loadExtensionScripts() {
|
||||||
let store = transaction.objectStore("InstalledExtensions");
|
let store = transaction.objectStore("InstalledExtensions");
|
||||||
let request = store.getAll();
|
let request = store.getAll();
|
||||||
request.onsuccess = () => {
|
request.onsuccess = () => {
|
||||||
let extensions = request.result.filter((extension) => extension.type != "theme");
|
let extensions = request.result.filter((extension) => extension.type == "serviceWorker");
|
||||||
extensions.forEach((extension) => {
|
extensions.forEach((extension) => {
|
||||||
eval(atob(extension.scriptCopy));
|
const decoder = new TextDecoder();
|
||||||
|
const contents = decoder.decode(extension.script);
|
||||||
|
|
||||||
|
|
||||||
|
eval(contents);
|
||||||
const func = self[extension.entryNamespace][extension.entryFunc];
|
const func = self[extension.entryNamespace][extension.entryFunc];
|
||||||
switch (extension.type) {
|
switch (extension.type) {
|
||||||
case "serviceWorker":
|
case "serviceWorker":
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
const iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
|
const iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
|
||||||
const topbar = document.getElementById("top-bar") as HTMLDivElement;
|
const topbar = document.getElementById("top-bar") as HTMLDivElement;
|
||||||
const closeButton = document.getElementById("close-button")!;
|
const closeButton = document.getElementById("nav-close")!;
|
||||||
const backwardsButton = document.getElementById("nav-backwards")!;
|
const backwardsButton = document.getElementById("nav-backwards")!;
|
||||||
const forwardsButton = document.getElementById("nav-forwards")!;
|
const forwardsButton = document.getElementById("nav-forwards")!;
|
||||||
const reloadButton = document.getElementById("nav-reload")!;
|
const reloadButton = document.getElementById("nav-reload")!;
|
||||||
|
|
@ -168,7 +168,7 @@
|
||||||
position: { x: "right", y: "bottom" },
|
position: { x: "right", y: "bottom" },
|
||||||
dismissible: true,
|
dismissible: true,
|
||||||
ripple: true,
|
ripple: true,
|
||||||
}).success("Copied to clipboard!");
|
}).success("Copied URL to clipboard!");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,10 @@ type Props = {
|
||||||
type: ExtType;
|
type: ExtType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const abbrTitle = type === "theme" ? "Theme" : "Script";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="marketplace-icon">
|
<div class="marketplace-icon">
|
||||||
<abbr title={abbrTitle}>
|
<abbr title={type === "theme" ? "Theme" : "Script"}>
|
||||||
{type === "theme" ? <Paintbrush class="icon" /> : <Scroll class="icon" />}
|
{type === "theme" ? <Paintbrush class="icon" /> : <Scroll class="icon" />}
|
||||||
</abbr>
|
</abbr>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
15
src/components/frame/IFrameNav.astro
Normal file
15
src/components/frame/IFrameNav.astro
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div id="top-bar">
|
||||||
|
<div class="top-bar-left">
|
||||||
|
<img id="proxied-favicon" alt="favicon" />
|
||||||
|
<span id="url-text"></span>
|
||||||
|
</div>
|
||||||
|
<div class="top-bar-right">
|
||||||
|
<div class="nav-container">
|
||||||
|
<img width="32px" height="32px" id="nav-backwards" src="/img/nav/backwards.svg" alt="Backward" />
|
||||||
|
<img width="32px" height="32px" id="nav-forwards" src="/img/nav/forwards.svg" alt="Forward" />
|
||||||
|
<img width="26px" height="28px" id="nav-reload" src="/img/nav/reload.svg" alt="Reload Page" />
|
||||||
|
<img width="25px" height="26px" id="nav-share" src="/img/nav/share.svg" alt="Share Page" />
|
||||||
|
<img width="30px" height="30px" id="nav-close" src="/img/nav/close.svg" alt="Close Page" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
30
src/components/loaders/PageScriptLoader.astro
Normal file
30
src/components/loaders/PageScriptLoader.astro
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<script>
|
||||||
|
import IDBManager from "@components/ts/IDBManager";
|
||||||
|
const idb = IDBManager.loadIDB("AluDB", 1)
|
||||||
|
|
||||||
|
idb.onsuccess = () => {
|
||||||
|
IDBManager.GetStore("InstalledExtensions", "readonly").getAll().onsuccess = (event) => {
|
||||||
|
// TODO: Get rid of this ugly type assertion!!
|
||||||
|
const result = (event.target as IDBRequest).result;
|
||||||
|
if (result) {
|
||||||
|
result.forEach((extension: ExtensionMetadata) => {
|
||||||
|
if (extension.type === "page") {
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const script = decoder.decode(extension.scriptCopy!);
|
||||||
|
const scriptEl = document.createElement("script");
|
||||||
|
scriptEl.textContent = script;
|
||||||
|
document.head.appendChild(scriptEl);
|
||||||
|
|
||||||
|
// Call extension.init if it exists
|
||||||
|
if (extension.init) {
|
||||||
|
const init = new Function(extension.init);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
function switchTheme() {
|
function switchTheme() {
|
||||||
const currentTheme = Alu.store.get("theme");
|
const currentTheme = Alu.store.get("theme");
|
||||||
document.documentElement.setAttribute("data-theme", currentTheme.value);
|
document.documentElement.setAttribute("data-theme", currentTheme.value!);
|
||||||
}
|
}
|
||||||
|
|
||||||
switchTheme();
|
switchTheme();
|
||||||
|
|
@ -20,17 +20,21 @@
|
||||||
result.forEach((extension: ExtensionMetadata) => {
|
result.forEach((extension: ExtensionMetadata) => {
|
||||||
if (extension.type === "theme" && extension.themeName) {
|
if (extension.type === "theme" && extension.themeName) {
|
||||||
// Load theme CSS
|
// Load theme CSS
|
||||||
loadStyleFromAtob(atob(extension.scriptCopy!));
|
const decoder = new TextDecoder();
|
||||||
|
const style = decoder.decode(extension.scriptCopy!);
|
||||||
|
|
||||||
|
|
||||||
|
loadStyleFromString(style);
|
||||||
|
|
||||||
document.addEventListener("astro:after-swap", () => {
|
document.addEventListener("astro:after-swap", () => {
|
||||||
loadStyleFromAtob(atob(extension.scriptCopy!));
|
loadStyleFromString(style);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
function loadStyleFromAtob(style: string) {
|
function loadStyleFromString(style: string) {
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
styleEl.textContent = style;
|
styleEl.textContent = style;
|
||||||
document.head.appendChild(styleEl);
|
document.head.appendChild(styleEl);
|
||||||
|
|
@ -79,7 +79,13 @@ Array.from(installButtons).forEach((btn) => {
|
||||||
|
|
||||||
async function getMarketplaceObj(slug: string): Promise<ExtensionMetadata> {
|
async function getMarketplaceObj(slug: string): Promise<ExtensionMetadata> {
|
||||||
const manifest = extManifest[slug];
|
const manifest = extManifest[slug];
|
||||||
manifest.scriptCopy = btoa(await fetch(manifest.script).then((res) => res.text()));
|
if (manifest == null) {
|
||||||
|
throw new Error("Extension not found!");
|
||||||
|
}
|
||||||
|
// This is for the scriptCopy field, which is a uint8 array of the script
|
||||||
|
const contents = await fetch(manifest.script).then((res) => res.text());
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
manifest.scriptCopy = encoder.encode(contents);
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,15 @@
|
||||||
"entryNamespace": "adblockExt",
|
"entryNamespace": "adblockExt",
|
||||||
"entryFunc": "filterRequest"
|
"entryFunc": "filterRequest"
|
||||||
},
|
},
|
||||||
|
"dev.wearr.eruda": {
|
||||||
|
"title": "Eruda",
|
||||||
|
"description": "Eruda provides a complete inspect element experience for devices where it is not available.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"image": "/marketplace/eruda/banner.png",
|
||||||
|
"script": "/marketplace/eruda/eruda.js",
|
||||||
|
"type": "page",
|
||||||
|
"init": "eruda.init()"
|
||||||
|
},
|
||||||
"dev.wearr.oled-theme": {
|
"dev.wearr.oled-theme": {
|
||||||
"title": "OLED Theme",
|
"title": "OLED Theme",
|
||||||
"description": "A beautiful OLED theme for Alu.",
|
"description": "A beautiful OLED theme for Alu.",
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
import { ViewTransitions } from "astro:transitions";
|
import { ViewTransitions } from "astro:transitions";
|
||||||
import Header from "@components/UI/Header.astro";
|
import Header from "@components/UI/Header.astro";
|
||||||
import Footer from "@components/UI/Footer.astro";
|
import Footer from "@components/UI/Footer.astro";
|
||||||
import ThemeLoader from "@components/ThemeLoader.astro";
|
import ThemeLoader from "@components/loaders/ThemeLoader.astro";
|
||||||
import CloakLoader from "@components/CloakLoader.astro";
|
import CloakLoader from "@components/loaders/CloakLoader.astro";
|
||||||
|
import PageScriptLoader from "@components/loaders/PageScriptLoader.astro";
|
||||||
import WelcomeLogging from "@components/WelcomeLogging.astro";
|
import WelcomeLogging from "@components/WelcomeLogging.astro";
|
||||||
import SchemaData from "@components/SchemaData.astro";
|
import SchemaData from "@components/SchemaData.astro";
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -23,6 +24,7 @@ const DESCRIPTION =
|
||||||
<link href="/varela-round.css" rel="stylesheet" />
|
<link href="/varela-round.css" rel="stylesheet" />
|
||||||
<ThemeLoader transition:persist />
|
<ThemeLoader transition:persist />
|
||||||
<CloakLoader transition:persist />
|
<CloakLoader transition:persist />
|
||||||
|
<PageScriptLoader transition:persist />
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="title" content="Alu" />
|
<meta name="title" content="Alu" />
|
||||||
|
|
@ -259,18 +261,13 @@ const DESCRIPTION =
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
#close-button {
|
|
||||||
padding: 5px;
|
|
||||||
padding-inline: 40px;
|
|
||||||
border: none;
|
|
||||||
background-color: var(--background-highlight);
|
|
||||||
color: var(--text-color-accent);
|
|
||||||
border-radius: 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
margin-top: 5px;
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
@media (max-width: 484px) {
|
@media (max-width: 484px) {
|
||||||
.nav-container {
|
.nav-container {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import Link from "@components/UI/Link.astro";
|
||||||
import ProxyRegistrar from "@components/ProxyRegistrar.astro";
|
import ProxyRegistrar from "@components/ProxyRegistrar.astro";
|
||||||
import Input from "@components/UI/Input.astro";
|
import Input from "@components/UI/Input.astro";
|
||||||
import FaqCard from "@components/FaqCard.astro";
|
import FaqCard from "@components/FaqCard.astro";
|
||||||
|
import IFrameNav from "@components/frame/IFrameNav.astro";
|
||||||
|
|
||||||
const t = i18n.inferLangUseTranslations(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
|
|
||||||
|
|
@ -27,21 +28,7 @@ export function getStaticPaths() {
|
||||||
<div id="search-suggestions"></div>
|
<div id="search-suggestions"></div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div id="top-bar">
|
<IFrameNav />
|
||||||
<div class="top-bar-left">
|
|
||||||
<img id="proxied-favicon" alt="favicon" />
|
|
||||||
<span id="url-text"></span>
|
|
||||||
</div>
|
|
||||||
<div class="top-bar-right">
|
|
||||||
<div class="nav-container">
|
|
||||||
<img width="32px" height="32px" id="nav-backwards" src="/img/nav/backwards.svg" alt="Backward" />
|
|
||||||
<img width="32px" height="32px" id="nav-forwards" src="/img/nav/forwards.svg" alt="Forward" />
|
|
||||||
<img width="28px" height="32px" id="nav-reload" src="/img/nav/reload.svg" alt="Reload Page" />
|
|
||||||
<img width="28px" height="32px" id="nav-share" src="/img/nav/share.svg" alt="Share Page" />
|
|
||||||
</div>
|
|
||||||
<button id="close-button">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<iframe title="proxy-iframe" id="proxy-frame"></iframe>
|
<iframe title="proxy-iframe" id="proxy-frame"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
3
src/types.d.ts
vendored
3
src/types.d.ts
vendored
|
|
@ -39,7 +39,8 @@ interface ExtensionMetadata {
|
||||||
pages?: string[];
|
pages?: string[];
|
||||||
entryNamespace?: string;
|
entryNamespace?: string;
|
||||||
entryFunc?: string;
|
entryFunc?: string;
|
||||||
scriptCopy?: string;
|
init?: string;
|
||||||
|
scriptCopy?: Uint8Array | null;
|
||||||
type: ExtType;
|
type: ExtType;
|
||||||
themeName?: string;
|
themeName?: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue