Make eslint a bit stricter, and lint + format.

This commit is contained in:
wearrrrr 2024-07-27 01:47:16 -05:00
parent 622855db01
commit 3806d64f66
24 changed files with 2104 additions and 2109 deletions

View file

@ -12,7 +12,10 @@ module.exports = {
rules: { rules: {
"no-unused-vars": "error", "no-unused-vars": "error",
"no-undef": "off", "no-undef": "off",
"prefer-const": "error",
"no-case-declarations": "off",
}, },
ignorePatterns: ["env.d.ts"],
overrides: [ overrides: [
{ {
files: ["*.astro"], files: ["*.astro"],
@ -22,6 +25,17 @@ module.exports = {
extraFileExtensions: [".astro"], extraFileExtensions: [".astro"],
}, },
}, },
{
files: ["*.ts", "*.tsx"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
},
plugins: ["@typescript-eslint"],
extends: [
"plugin:@typescript-eslint/recommended",
],
},
{ {
// Define the configuration for `<script>` tag. // Define the configuration for `<script>` tag.
// Script in `<script>` is assigned a virtual file name with the `.js` extension. // Script in `<script>` is assigned a virtual file name with the `.js` extension.

View file

@ -132,7 +132,7 @@ app.get("*", (req, res) => {
res.sendFile(path.join(process.cwd(), "dist/client/404.html")); res.sendFile(path.join(process.cwd(), "dist/client/404.html"));
}); });
let server = createServer(); const server = createServer();
server.on("request", (req, res) => { server.on("request", (req, res) => {
if (bare.shouldRoute(req)) { if (bare.shouldRoute(req)) {
bare.routeRequest(req, res); bare.routeRequest(req, res);

View file

@ -1,7 +1,7 @@
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
export async function masqrCheck(config, htmlFile) { export async function masqrCheck(config, htmlFile) {
let loadedHTMLFile = fs.readFileSync(htmlFile, "utf8"); const loadedHTMLFile = fs.readFileSync(htmlFile, "utf8");
return async (req, res, next) => { return async (req, res, next) => {
if (req.headers.host && config.whitelist.includes(req.headers.host)) { if (req.headers.host && config.whitelist.includes(req.headers.host)) {
next(); next();
@ -37,8 +37,8 @@ async function MasqFail(req, res, failureFile) {
return; return;
} }
const unsafeSuffix = req.headers.host + ".html"; const unsafeSuffix = req.headers.host + ".html";
let safeSuffix = path.normalize(unsafeSuffix).replace(/^(\.\.(\/|\\|$))+/, ""); const safeSuffix = path.normalize(unsafeSuffix).replace(/^(\.\.(\/|\\|$))+/, "");
let safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix); const safeJoin = path.join(process.cwd() + "/Masqrd", safeSuffix);
try { try {
await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail" await fs.promises.access(safeJoin); // man do I wish this was an if-then instead of a "exception on fail"
const failureFileLocal = await fs.promises.readFile(safeJoin, "utf8"); const failureFileLocal = await fs.promises.readFile(safeJoin, "utf8");

View file

@ -8,7 +8,8 @@
"build": "astro build", "build": "astro build",
"format": "prettier --write .", "format": "prettier --write .",
"format:check": "prettier --check .", "format:check": "prettier --check .",
"lint": "eslint ." "lint": "eslint .",
"lint:fix": "eslint --fix ."
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^8.2.5", "@astrojs/node": "^8.2.5",

2045
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
<script> <script>
function loadCloak() { function loadCloak() {
let localStorageCloak = localStorage.getItem("alu__selectedCloak"); const localStorageCloak = localStorage.getItem("alu__selectedCloak");
if (localStorageCloak) { if (localStorageCloak) {
let parsedCloak = JSON.parse(localStorageCloak); const parsedCloak = JSON.parse(localStorageCloak);
if (parsedCloak) { if (parsedCloak) {
if (parsedCloak.name != "None") { if (parsedCloak.name != "None") {
document.title = parsedCloak.name; document.title = parsedCloak.name;

View file

@ -4,11 +4,11 @@
import { Notyf } from "notyf"; import { Notyf } from "notyf";
import { loadIDB, GetStore, ValidateStoreExists, CreateStore } from "./ts/IDBManager"; import { loadIDB, GetStore, ValidateStoreExists, CreateStore } from "./ts/IDBManager";
let form = document.querySelector("form"); const form = document.querySelector("form");
let input = document.querySelector("input"); let input = document.querySelector("input");
document.addEventListener("astro:after-swap", initForm); document.addEventListener("astro:after-swap", initForm);
function initForm() { function initForm() {
let formEle = document.querySelector("form"); const formEle = document.querySelector("form");
input = document.querySelector("input"); input = document.querySelector("input");
if (formEle) formEle.addEventListener("submit", formEventListener); if (formEle) formEle.addEventListener("submit", formEventListener);
} }
@ -17,7 +17,7 @@
} }
setInterval(() => { setInterval(() => {
let iframe = document.getElementById("proxy-frame") as HTMLIFrameElement; const iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
if (iframe && iframe.src != "") { if (iframe && iframe.src != "") {
updateProxiedFavicon(iframe); updateProxiedFavicon(iframe);
updateTopbarTitle(iframe); updateTopbarTitle(iframe);
@ -25,7 +25,7 @@
}, 500); }, 500);
async function getProxyURL() { async function getProxyURL() {
let preference = getProxyPreference(); const preference = getProxyPreference();
let url = input!.value.trim(); let url = input!.value.trim();
if (!isUrl(url)) url = getSearchEngine() + url; if (!isUrl(url)) url = getSearchEngine() + url;
else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url; else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url;
@ -33,10 +33,10 @@
return window.__uv$config.prefix + window.__uv$config.encodeUrl(url); return window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
} else if (preference == "rammerhead") { } else if (preference == "rammerhead") {
// Check if rammerhead-session exists in cookies // Check if rammerhead-session exists in cookies
let rammerheadSession = getCookie("rammerhead-session"); const rammerheadSession = getCookie("rammerhead-session");
if (!rammerheadSession) { if (!rammerheadSession) {
let session = await fetch("/newsession"); const session = await fetch("/newsession");
let sessionID = await session.text(); const sessionID = await session.text();
await fetch("/editsession?id=" + sessionID + "&enableShuffling=0"); await fetch("/editsession?id=" + sessionID + "&enableShuffling=0");
// Now save it in a cookie that expires in 72 hours. // Now save it in a cookie that expires in 72 hours.
document.cookie = `rammerhead-session=${sessionID}; max-age=${60 * 60 * 72}; path=/`; document.cookie = `rammerhead-session=${sessionID}; max-age=${60 * 60 * 72}; path=/`;
@ -54,16 +54,16 @@
async function loadPageExtensions() { async function loadPageExtensions() {
try { try {
let iframe = document.getElementById("proxy-frame") as HTMLIFrameElement; const iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
if (!ValidateStoreExists("InstalledExtensions")) { if (!ValidateStoreExists("InstalledExtensions")) {
CreateStore("InstalledExtensions", { keyPath: "slug" }); CreateStore("InstalledExtensions", { keyPath: "slug" });
} }
let db = loadIDB("AluDB", 1); const db = loadIDB("AluDB", 1);
db.onsuccess = () => { db.onsuccess = () => {
let store = GetStore("InstalledExtensions", "readonly"); const store = GetStore("InstalledExtensions", "readonly");
let request = store.getAll(); const request = store.getAll();
request.onsuccess = () => { request.onsuccess = () => {
let extensions = request.result; const extensions = request.result;
extensions.forEach((extension: IExtensionMetadata) => { extensions.forEach((extension: IExtensionMetadata) => {
// Eval the extension script inside of the iframe // Eval the extension script inside of the iframe
if (!(extension.type == "page")) return; if (!(extension.type == "page")) return;
@ -73,8 +73,8 @@
console.log(url); console.log(url);
console.log(iframe.contentWindow!.__uv$location.host); console.log(iframe.contentWindow!.__uv$location.host);
if (iframe.contentWindow!.__uv$location.host.includes(url)) { if (iframe.contentWindow!.__uv$location.host.includes(url)) {
let script = extension.script; const script = extension.script;
let scriptElement = document.createElement("script"); const scriptElement = document.createElement("script");
scriptElement.src = script; scriptElement.src = script;
scriptElement.type = "module"; scriptElement.type = "module";
iframe.contentDocument!.head.appendChild(scriptElement); iframe.contentDocument!.head.appendChild(scriptElement);
@ -89,30 +89,30 @@
} }
} }
async function loadContent() { async function loadContent(): Promise<void> {
await initTransport(); await initTransport();
await loadPageExtensions(); await loadPageExtensions();
// The setTimeout is because service workers are a little silly and can take a while longer to register despite .then being called, which causes a bug on the first load. // The setTimeout is because service workers are a little silly and can take a while longer to register despite .then being called, which causes a bug on the first load.
setTimeout(async () => { setTimeout(async () => {
let openWith = localStorage.getItem("alu__selectedOpenWith"); const openWith = localStorage.getItem("alu__selectedOpenWith");
let currentProxy = localStorage.getItem("alu__selectedProxy"); const currentProxy = localStorage.getItem("alu__selectedProxy");
let url = input!.value.trim(); let url = input!.value.trim();
if (!isUrl(url)) url = getSearchEngine() + url; if (!isUrl(url)) url = getSearchEngine() + url;
else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url; else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url;
if (openWith) { if (openWith) {
let openWithParsed = JSON.parse(openWith); const openWithParsed = JSON.parse(openWith);
if (openWithParsed.value === "newTab" || (currentProxy && JSON.parse(currentProxy).value === "rammerhead")) { if (openWithParsed.value === "newTab" || (currentProxy && JSON.parse(currentProxy).value === "rammerhead")) {
window.open(await getProxyURL(), "_blank"); window.open(await getProxyURL(), "_blank");
return; return;
} }
if (openWithParsed.value === "about:blank") { if (openWithParsed.value === "about:blank") {
// Open about:blank window and inject iframe into it // Open about:blank window and inject iframe into it
let newWindow = window.open("about:blank", "_blank"); const newWindow = window.open("about:blank", "_blank");
let newWindowDocument = newWindow!.document; const newWindowDocument = newWindow!.document;
let iframe = newWindowDocument.createElement("iframe"); const iframe = newWindowDocument.createElement("iframe");
iframe.src = await getProxyURL(); iframe.src = await getProxyURL();
// Inject css into the iframe // Inject css into the iframe
let css = newWindowDocument.createElement("link"); const css = newWindowDocument.createElement("link");
css.rel = "stylesheet"; css.rel = "stylesheet";
css.href = "/iframe.css"; css.href = "/iframe.css";
newWindowDocument.head.appendChild(css); newWindowDocument.head.appendChild(css);
@ -120,24 +120,24 @@
return; return;
} }
} }
let loadingContent = document.getElementById("loading-content") as HTMLElement; const loadingContent = document.getElementById("loading-content") as HTMLElement;
if (loadingContent) loadingContent.style.opacity = "1"; if (loadingContent) loadingContent.style.opacity = "1";
let iframe = document.getElementById("proxy-frame") as HTMLIFrameElement; const iframe = document.getElementById("proxy-frame") as HTMLIFrameElement;
let topbar = document.getElementById("top-bar") as HTMLDivElement; const topbar = document.getElementById("top-bar") as HTMLDivElement;
let closeButton = document.getElementById("close-button") as HTMLButtonElement; const closeButton = document.getElementById("close-button") as HTMLButtonElement;
let backwardsButton = document.getElementById("nav-backwards") as HTMLImageElement; const backwardsButton = document.getElementById("nav-backwards") as HTMLImageElement;
let forwardsButton = document.getElementById("nav-forwards") as HTMLImageElement; const forwardsButton = document.getElementById("nav-forwards") as HTMLImageElement;
let shareButton = document.getElementById("nav-share") as HTMLImageElement; const shareButton = document.getElementById("nav-share") as HTMLImageElement;
let preference = getProxyPreference(); const preference = getProxyPreference();
if (preference === "ultraviolet") { if (preference === "ultraviolet") {
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url); iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
} else if (preference == "rammerhead") { } else if (preference == "rammerhead") {
// Check if rammerhead-session exists in cookies // Check if rammerhead-session exists in cookies
let rammerheadSession = getCookie("rammerhead-session"); const rammerheadSession = getCookie("rammerhead-session");
if (!rammerheadSession) { if (!rammerheadSession) {
let session = await fetch("/newsession"); const session = await fetch("/newsession");
let sessionID = await session.text(); const sessionID = await session.text();
// Disable URL shuffling on rewrite, eventually I'll try and figure out how it works, but for now, it's disabled. // Disable URL shuffling on rewrite, eventually I'll try and figure out how it works, but for now, it's disabled.
await fetch("/editsession?id=" + sessionID + "&enableShuffling=0"); await fetch("/editsession?id=" + sessionID + "&enableShuffling=0");
// Now save it in a cookie that expires in 72 hours. // Now save it in a cookie that expires in 72 hours.
@ -192,8 +192,8 @@
} }
}; };
shareButton.onclick = () => { shareButton.onclick = () => {
let currentProxy = localStorage.getItem("alu__selectedProxy"); const currentProxy = localStorage.getItem("alu__selectedProxy");
let proxyFrame = document.getElementById("proxy-frame") as HTMLIFrameElement; const proxyFrame = document.getElementById("proxy-frame") as HTMLIFrameElement;
if (currentProxy && JSON.parse(currentProxy).value === "rammerhead") { if (currentProxy && JSON.parse(currentProxy).value === "rammerhead") {
navigator.clipboard.writeText(window.location.origin + "/" + getCookie("rammerhead-session") + "/" + input!.value.trim()); navigator.clipboard.writeText(window.location.origin + "/" + getCookie("rammerhead-session") + "/" + input!.value.trim());
} else { } else {
@ -239,7 +239,7 @@
} }
function getSearchEngine() { function getSearchEngine() {
let localStorageSearchEngine = localStorage.getItem("alu__search_engine"); const localStorageSearchEngine = localStorage.getItem("alu__search_engine");
if (!localStorageSearchEngine) { if (!localStorageSearchEngine) {
return "https://google.com/search?q="; return "https://google.com/search?q=";
} }
@ -269,7 +269,7 @@
} }
function getProxyPreference() { function getProxyPreference() {
let localStorageItem = localStorage.getItem("alu__selectedProxy"); const localStorageItem = localStorage.getItem("alu__selectedProxy");
if (!localStorageItem) return "uv"; if (!localStorageItem) return "uv";
@ -285,15 +285,15 @@
function updateProxiedFavicon(iframe: HTMLIFrameElement) { function updateProxiedFavicon(iframe: HTMLIFrameElement) {
if (!iframe) return; if (!iframe) return;
let proxiedFavicon = document.getElementById("proxied-favicon") as HTMLImageElement; const proxiedFavicon = document.getElementById("proxied-favicon") as HTMLImageElement;
if (iframe) { if (iframe) {
if (iframe.contentDocument) { if (iframe.contentDocument) {
let favicon = (iframe.contentDocument.querySelector("link[rel='icon']") as HTMLLinkElement) || (iframe.contentDocument.querySelector("link[rel*='icon']") as HTMLLinkElement); const favicon = (iframe.contentDocument.querySelector("link[rel='icon']") as HTMLLinkElement) || (iframe.contentDocument.querySelector("link[rel*='icon']") as HTMLLinkElement);
if (favicon && favicon.href.includes("data:image")) { if (favicon && favicon.href.includes("data:image")) {
proxiedFavicon.src = favicon.href; proxiedFavicon.src = favicon.href;
return; return;
} }
let UVURL = getUVProxyURL(iframe); const UVURL = getUVProxyURL(iframe);
if (proxiedFavicon.src == `${window.location.origin}/custom-favicon?url=${UVURL}`) return; if (proxiedFavicon.src == `${window.location.origin}/custom-favicon?url=${UVURL}`) return;
proxiedFavicon.src = `/custom-favicon?url=${UVURL}`; proxiedFavicon.src = `/custom-favicon?url=${UVURL}`;
loadPageExtensions(); loadPageExtensions();
@ -302,7 +302,7 @@
} }
function updateTopbarTitle(iframe: HTMLIFrameElement) { function updateTopbarTitle(iframe: HTMLIFrameElement) {
if (!iframe.contentDocument) return; if (!iframe.contentDocument) return;
let topbarTitle = document.getElementById("url-text") as HTMLElement; const topbarTitle = document.getElementById("url-text") as HTMLElement;
if (iframe.contentDocument.title == "") { if (iframe.contentDocument.title == "") {
topbarTitle.innerText = "Loading..."; topbarTitle.innerText = "Loading...";
} else { } else {

View file

@ -14,7 +14,7 @@ const themeList = [
const languageList = [ const languageList = [
{ name: "English", value: "en" }, { name: "English", value: "en" },
{ name: "日本語", value: "jp" }, { name: "日本語", value: "jp" },
{ name: "Français", value: "fr"} { name: "Français", value: "fr" },
]; ];
--- ---

View file

@ -2,11 +2,11 @@
import IDBManager from "@components/ts/IDBManager"; import IDBManager from "@components/ts/IDBManager";
function switchTheme() { function switchTheme() {
let currentTheme = localStorage.getItem("alu__selectedTheme"); const currentTheme = localStorage.getItem("alu__selectedTheme");
if (currentTheme) { if (currentTheme) {
document.documentElement.setAttribute("data-theme", JSON.parse(currentTheme).value.toLowerCase()); document.documentElement.setAttribute("data-theme", JSON.parse(currentTheme).value.toLowerCase());
let footer = document.getElementById("footer"); const footer = document.getElementById("footer");
if (footer) { if (footer) {
footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase(); footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase();
} }
@ -23,7 +23,7 @@
const idb = IDBManager.loadIDB("AluDB", 1); const idb = IDBManager.loadIDB("AluDB", 1);
idb.onsuccess = () => { idb.onsuccess = () => {
let store = IDBManager.GetStore("InstalledExtensions", "readonly"); const store = IDBManager.GetStore("InstalledExtensions", "readonly");
store.getAll().onsuccess = (event) => { store.getAll().onsuccess = (event) => {
const result = (event.target as IDBRequest).result; const result = (event.target as IDBRequest).result;
if (result) { if (result) {

View file

@ -10,16 +10,21 @@ if (defaultStyles) {
interface Props { interface Props {
inputName: string; inputName: string;
defaultTextContent?: string; defaultTextContent?: string;
height: string; height?: string;
placeholder?: string; placeholder?: string;
className?: string; className?: string;
defaultStyles?: boolean; defaultStyles?: boolean;
autocomplete?: string; autocomplete?: string;
} }
let inputHeight = height;
if (!height) {
inputHeight = "3rem";
}
--- ---
<input <input
style={`height: ${height}`} style={`height: ${inputHeight}`}
id={inputName + "-input"} id={inputName + "-input"}
placeholder={placeholder || ""} placeholder={placeholder || ""}
value={defaultTextContent || ""} value={defaultTextContent || ""}

View file

@ -1,6 +1,6 @@
<script> <script>
let primaryColor = "#8c25fa"; const primaryColor = "#8c25fa";
let secondaryColor = "#601aab"; const secondaryColor = "#601aab";
console.log("%cWelcome to Alu", `color: ${primaryColor}; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 0 ${secondaryColor};`); console.log("%cWelcome to Alu", `color: ${primaryColor}; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 0 ${secondaryColor};`);
console.log("%cSystem Information: ", `color: ${primaryColor}; font-size: 1rem; font-weight: bold;`); console.log("%cSystem Information: ", `color: ${primaryColor}; font-size: 1rem; font-weight: bold;`);

View file

@ -12,13 +12,13 @@ export function loadIDBPromise(name: string, version: number): Promise<IDBDataba
reject(event); reject(event);
}; };
request.onsuccess = (event) => { request.onsuccess = () => {
const idb = request.result; const idb = request.result;
CurrentIDB = idb; CurrentIDB = idb;
resolve(idb); resolve(idb);
}; };
request.onupgradeneeded = (event) => { request.onupgradeneeded = () => {
const idb = request.result; const idb = request.result;
CurrentIDB = idb; CurrentIDB = idb;
resolve(idb); resolve(idb);
@ -34,7 +34,7 @@ export function loadIDBPromise(name: string, version: number): Promise<IDBDataba
export function loadIDB(name: string, version: number): IDBOpenDBRequest { export function loadIDB(name: string, version: number): IDBOpenDBRequest {
const request = window.indexedDB.open(name, version); const request = window.indexedDB.open(name, version);
request.onblocked = (event) => { request.onblocked = () => {
console.error("Database upgrade is blocked by another connection"); console.error("Database upgrade is blocked by another connection");
}; };
@ -74,7 +74,7 @@ export function DeleteIDB(name: string): Promise<IDBOpenDBRequest | Event> {
reject(event); reject(event);
}; };
request.onsuccess = (event) => { request.onsuccess = () => {
resolve(request); resolve(request);
}; };
}); });

View file

@ -10,7 +10,7 @@ type transportConfig =
export const wispURLDefault = (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/"; export const wispURLDefault = (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/";
export default class TransportManager { export default class TransportManager {
connection: BareMuxConnection; connection: BareMuxConnection;
private transport = "/epoxy/index.mjs"; private transport: string = "/epoxy/index.mjs";
constructor(transport?: string) { constructor(transport?: string) {
this.connection = new BareMuxConnection("/baremux/worker.js"); this.connection = new BareMuxConnection("/baremux/worker.js");
@ -18,7 +18,8 @@ export default class TransportManager {
this.transport = transport; this.transport = transport;
} }
if (localStorage.getItem("alu__selectedTransport") != null && !transport) { if (localStorage.getItem("alu__selectedTransport") != null && !transport) {
this.transport = JSON.parse(localStorage.getItem("alu__selectedTransport")!).value; const selectedTransport = JSON.parse(localStorage.getItem("alu__selectedTransport")!) as { value: string };
this.transport = selectedTransport.value;
} }
if (localStorage.getItem("alu__selectedTransport") == null) { if (localStorage.getItem("alu__selectedTransport") == null) {
// Set the default transport for the next reload. // Set the default transport for the next reload.
@ -27,10 +28,11 @@ export default class TransportManager {
} }
async updateTransport() { async updateTransport() {
try { try {
await this.setTransport(JSON.parse(localStorage.getItem("alu__selectedTransport")!).value); const selectedTransport = JSON.parse(localStorage.getItem("alu__selectedTransport")!) as { value: string };
await this.setTransport(selectedTransport.value);
} catch { } catch {
console.log("Failed to update transport! Falling back to old transport."); console.log("Failed to update transport! Falling back to old transport.");
this.setTransport(this.transport); await this.setTransport(this.transport);
} }
} }
@ -52,20 +54,18 @@ export default class TransportManager {
export const TransportMgr = new TransportManager(); export const TransportMgr = new TransportManager();
export async function registerAndUpdateSW() { export async function registerAndUpdateSW(): Promise<void> {
return new Promise(async (resolve) => { try {
navigator.serviceWorker const reg = await navigator.serviceWorker.register("/sw.js", {
.register("/sw.js", {
updateViaCache: "none", updateViaCache: "none",
}) });
.then(async (reg) => {
console.log("Service worker registered!"); console.log("Service worker registered!");
reg.update(); await reg.update();
} catch (err) {
resolve(null); console.error("Service worker registration failed: ", err);
});
});
} }
}
export async function initTransport() { export async function initTransport() {
await TransportMgr.setTransport(TransportMgr.getTransport(), localStorage.getItem("alu__wispUrl") || wispURLDefault); await TransportMgr.setTransport(TransportMgr.getTransport(), localStorage.getItem("alu__wispUrl") || wispURLDefault);

View file

@ -1,17 +1,17 @@
export async function testWispServers(servers: WispServer[]): Promise<WispData[]> { export async function testWispServers(servers: WispServer[]): Promise<WispData[]> {
let wispData: WispData[] = []; const wispData: WispData[] = [];
for (const server of servers) { for (const server of servers) {
let start = performance.now(); const start = performance.now();
try { try {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
let socket = new WebSocket(server.url); const socket = new WebSocket(server.url);
socket.onopen = () => { socket.onopen = () => {
let end = performance.now(); const end = performance.now();
console.log(`Connected to ${server.url} in ${end - start}ms`); console.log(`Connected to ${server.url} in ${end - start}ms`);
let data = { const data = {
server: server, server: server,
time: end - start, time: end - start,
}; };

View file

@ -1,19 +0,0 @@
export async function retrieveExtensions(type: ExtType) {
const extensionsArr: Array<Extension> = [];
const db = await new Promise<IDBDatabase>((resolve, reject) => {
const request = indexedDB.open("AluDB", 1);
request.onsuccess = () => resolve(request.result);
request.onerror = reject;
});
const transaction = db.transaction("InstalledExtensions", "readwrite");
const objectStore = transaction.objectStore("InstalledExtensions");
const extensions: Array<Extension> = await new Promise((resolve, reject) => {
const request = objectStore.getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = reject;
});
extensions.forEach(async (extension: Extension) => {});
return extensionsArr;
}

View file

@ -19,15 +19,15 @@ Array.from(installButtons).forEach((btn) => {
btn.addEventListener("click", async (event) => { btn.addEventListener("click", async (event) => {
const ele = event.target as HTMLButton; const ele = event.target as HTMLButton;
const title = ele.dataset.title; const title = ele.dataset.title;
let notification = new Notyf({ const notification = new Notyf({
duration: 999999, duration: 999999,
position: { x: "right", y: "bottom" }, position: { x: "right", y: "bottom" },
dismissible: true, dismissible: true,
ripple: true, ripple: true,
}); });
let installNotif = notification.success(`Installing ${title}...`); const installNotif = notification.success(`Installing ${title}...`);
if (ele.dataset.slug) { if (ele.dataset.slug) {
let obj = await getMarketplaceObj(ele.dataset.slug); const obj = await getMarketplaceObj(ele.dataset.slug);
installExtension(obj, ele.dataset.slug) installExtension(obj, ele.dataset.slug)
.then((ret) => { .then((ret) => {
let notifMessage: string; let notifMessage: string;
@ -63,7 +63,7 @@ Array.from(installButtons).forEach((btn) => {
window.location.reload(); window.location.reload();
}, 1000); }, 1000);
notification.options.duration = 999999; notification.options.duration = 999999;
let btn = document.querySelector(`button[data-slug="${ret.slug}"]`) as HTMLButton; const btn = document.querySelector(`button[data-slug="${ret.slug}"]`) as HTMLButton;
setInstallBtnText(btn); setInstallBtnText(btn);
}, timeout); }, timeout);
}) })
@ -96,7 +96,7 @@ async function installExtension(ext: IExtensionMetadata, slug: string): Promise<
slug: slug, slug: slug,
...ext, ...ext,
}; };
let slugCheck = store.get(slug); const slugCheck = store.get(slug);
slugCheck.onsuccess = async () => { slugCheck.onsuccess = async () => {
if (slugCheck.result != null) { if (slugCheck.result != null) {
resolve({ code: EXT_RETURN.ALREADY_INSTALLED, slug: slug }); resolve({ code: EXT_RETURN.ALREADY_INSTALLED, slug: slug });
@ -120,8 +120,8 @@ function addUninstallEventListeners() {
if (!confirm("Are you sure you want to uninstall this extension?")) { if (!confirm("Are you sure you want to uninstall this extension?")) {
return; return;
} }
let uninst = await uninstallExtension((event.target as HTMLButton).dataset.uninstallSlug!); const uninst = await uninstallExtension((event.target as HTMLButton).dataset.uninstallSlug!);
let notification = new Notyf({ const notification = new Notyf({
duration: 999999, duration: 999999,
position: { x: "right", y: "bottom" }, position: { x: "right", y: "bottom" },
dismissible: true, dismissible: true,
@ -130,7 +130,7 @@ function addUninstallEventListeners() {
switch (uninst.code) { switch (uninst.code) {
case EXT_RETURN.ACTION_SUCCESS: case EXT_RETURN.ACTION_SUCCESS:
notification.success(`Uninstalled ${uninst.title}!`); notification.success(`Uninstalled ${uninst.title}!`);
let btn = document.querySelector(`button[data-slug="${uninst.slug}"]`) as HTMLButton; const btn = document.querySelector(`button[data-slug="${uninst.slug}"]`) as HTMLButton;
btn.disabled = false; btn.disabled = false;
btn.textContent = "Install"; btn.textContent = "Install";
btn.classList.remove("installed"); btn.classList.remove("installed");
@ -161,15 +161,15 @@ async function uninstallExtension(slug: string): Promise<InstallReturn> {
const transaction = request.transaction("InstalledExtensions", "readwrite"); const transaction = request.transaction("InstalledExtensions", "readwrite");
const store = transaction.objectStore("InstalledExtensions"); const store = transaction.objectStore("InstalledExtensions");
let ext = store.get(slug); const ext = store.get(slug);
ext.onsuccess = async () => { ext.onsuccess = async () => {
if (ext.result == null) { if (ext.result == null) {
reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug }); reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug });
} }
if (ext.result.type === "theme") { if (ext.result.type === "theme") {
let currTheme = localStorage.getItem("alu__selectedTheme"); const currTheme = localStorage.getItem("alu__selectedTheme");
if (currTheme) { if (currTheme) {
if (JSON.parse(currTheme!).value == ext.result.themeName) { if (JSON.parse(currTheme).value == ext.result.themeName) {
console.log("Reverting theme to default!"); console.log("Reverting theme to default!");
localStorage.setItem("alu__selectedTheme", JSON.stringify({ name: "Alu", value: "alu" })); localStorage.setItem("alu__selectedTheme", JSON.stringify({ name: "Alu", value: "alu" }));
} }
@ -201,17 +201,18 @@ function setInstallBtnText(btn: HTMLButton) {
} }
function getInstallStatus() { function getInstallStatus() {
let installBtns = document.querySelectorAll("button[data-slug]") as NodeListOf<HTMLButton>; const installBtns = document.querySelectorAll("button[data-slug]");
let transaction = IDBManager.GetStore("InstalledExtensions", "readonly").transaction; const transaction = IDBManager.GetStore("InstalledExtensions", "readonly").transaction;
let store = transaction.objectStore("InstalledExtensions"); const store = transaction.objectStore("InstalledExtensions");
let cursor = store.openCursor(); const cursor = store.openCursor();
cursor.onsuccess = () => { cursor.onsuccess = () => {
let res = cursor.result; const res = cursor.result;
if (res) { if (res) {
let slug = res.value.slug; const slug = res.value.slug;
installBtns.forEach((btn) => { installBtns.forEach((btn) => {
if (btn.dataset.slug == slug) { const button = btn as HTMLButton;
setInstallBtnText(btn); if (button.dataset.slug == slug) {
setInstallBtnText(button);
document.querySelector(`button[data-uninstall-slug="${slug}"]`)!.classList.remove("btn-hidden"); document.querySelector(`button[data-uninstall-slug="${slug}"]`)!.classList.remove("btn-hidden");
} }
}); });

View file

@ -19,7 +19,7 @@ function inferLangUseTranslations(url: URL) {
function useTranslations(lang: LanguageKeys) { function useTranslations(lang: LanguageKeys) {
return function t(translationKey: TranslationKeys) { return function t(translationKey: TranslationKeys) {
let key = ui[lang][translationKey]; const key = ui[lang][translationKey];
if (key) return key; if (key) return key;
else return ui[defaultLang][translationKey]; else return ui[defaultLang][translationKey];
}; };

View file

@ -22,6 +22,7 @@ const { title, optionalPreloads } = Astro.props;
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<link href="/varela-round.css" rel="stylesheet" />
<ThemeLoader transition:persist /> <ThemeLoader transition:persist />
<CloakLoader transition:persist /> <CloakLoader transition:persist />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
@ -39,7 +40,6 @@ const { title, optionalPreloads } = Astro.props;
<meta property="twitter:description" content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization." /> <meta property="twitter:description" content="Alu is a sleek web proxy supporting multiple standards of communication, and wide levels of customization." />
<meta property="twitter:image" content="/logo.png" /> <meta property="twitter:image" content="/logo.png" />
<link rel="sitemap" href="/sitemap-index.xml" /> <link rel="sitemap" href="/sitemap-index.xml" />
<link href="/varela-round.css" rel="stylesheet" as="style" />
{ {
optionalPreloads?.map((item) => { optionalPreloads?.map((item) => {
return <link rel="preload" href={item.href} as={item.as} />; return <link rel="preload" href={item.href} as={item.as} />;
@ -58,12 +58,11 @@ const { title, optionalPreloads } = Astro.props;
<script> <script>
import IDBManager from "@components/ts/IDBManager"; import IDBManager from "@components/ts/IDBManager";
if (!window.idb) { if (!window.idb) {
let db = await IDBManager.loadIDBPromise("AluDB", 1); const db = await IDBManager.loadIDBPromise("AluDB", 1);
if (db instanceof IDBDatabase) { if (db instanceof IDBDatabase) {
window.idb = db; window.idb = db;
} }
} }
</script> </script>
<meta name="generator" content={Astro.generator} /> <meta name="generator" content={Astro.generator} />
<title>{title}</title> <title>{title}</title>
@ -110,6 +109,39 @@ const { title, optionalPreloads } = Astro.props;
color: var(--text-color); color: var(--text-color);
} }
.url-input-form {
border: none;
padding: 0;
}
.url-input.search-results {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border-bottom: 0;
}
.url-input::placeholder {
color: var(--text-color);
}
.url-input {
display: block;
background: transparent url(/img/search.svg) no-repeat 1rem center;
background-color: var(--dropdown-background-color);
color: var(--text-color);
border: 2px solid var(--text-color);
padding: 1rem;
border-radius: 10px;
width: 100%;
text-align: center;
transition: 0.25s ease-in-out;
outline: none;
font-family:
Varela Round,
sans-serif;
font-size: 16px;
}
[data-theme="mocha"] { [data-theme="mocha"] {
/* Catppucin Mocha theme */ /* Catppucin Mocha theme */
--background-color: #1e1e2e; --background-color: #1e1e2e;
@ -266,7 +298,6 @@ const { title, optionalPreloads } = Astro.props;
} }
.nav-container > img { .nav-container > img {
height: 32px;
cursor: pointer; cursor: pointer;
transition: 250ms ease-in-out; transition: 250ms ease-in-out;
} }

View file

@ -29,15 +29,15 @@ export function getStaticPaths() {
</Layout> </Layout>
<script> <script>
let search = document.getElementById("games-search-input") as HTMLInputElement; const search = document.getElementById("games-search-input") as HTMLInputElement;
let mainContent = document.getElementById("main-content") as HTMLDivElement; const mainContent = document.getElementById("main-content") as HTMLDivElement;
search.addEventListener("input", () => { search.addEventListener("input", () => {
let filter = search.value.toUpperCase(); const filter = search.value.toUpperCase();
let games = mainContent.children; const games = mainContent.children;
let results = 0; let results = 0;
for (let i = 0; i < games.length; i++) { for (let i = 0; i < games.length; i++) {
let game = games[i] as HTMLDivElement; const game = games[i] as HTMLDivElement;
let name = game.getAttribute("data-name")!; const name = game.getAttribute("data-name")!;
if (name.toUpperCase().indexOf(filter) > -1) { if (name.toUpperCase().indexOf(filter) > -1) {
game.style.display = ""; game.style.display = "";
results++; results++;
@ -47,13 +47,13 @@ export function getStaticPaths() {
} }
console.log(results); console.log(results);
if (results === 0) { if (results === 0) {
let noResults = document.querySelector(".no-results") as HTMLDivElement; const noResults = document.querySelector(".no-results") as HTMLDivElement;
if (noResults) { if (noResults) {
noResults.style.display = "block"; noResults.style.display = "block";
noResults.innerHTML = "No results found"; noResults.innerHTML = "No results found";
} }
} else { } else {
let noResults = document.querySelector(".no-results") as HTMLDivElement; const noResults = document.querySelector(".no-results") as HTMLDivElement;
if (noResults) { if (noResults) {
noResults.style.display = "none"; noResults.style.display = "none";
} }

View file

@ -18,7 +18,7 @@ export function getStaticPaths() {
<section id="proxy-input"> <section id="proxy-input">
<div class="form-wrapper"> <div class="form-wrapper">
<form class="url-input-form" id="url-input-form"> <form class="url-input-form" id="url-input-form">
<Input className="url-input" inputName="url" height="50px" placeholder={t("menu.search")} defaultStyles={false} transition:persist autocomplete="off" /> <Input className="url-input" inputName="url" placeholder={t("menu.search")} defaultStyles={false} transition:persist autocomplete="off" />
<div id="search-suggestions"></div> <div id="search-suggestions"></div>
<div id="loading-content">Loading...</div> <div id="loading-content">Loading...</div>
</form> </form>
@ -26,9 +26,9 @@ export function getStaticPaths() {
<div class="top-bar-left"> <div class="top-bar-left">
<button id="close-button">Close</button> <button id="close-button">Close</button>
<div class="nav-container"> <div class="nav-container">
<img id="nav-backwards" src="/img/nav/backwards.svg" alt="Backwards Arrow" /> <img width="32px" height="32px" id="nav-backwards" src="/img/nav/backwards.svg" alt="Backwards Arrow" />
<img id="nav-forwards" src="/img/nav/forwards.svg" alt="Forwards Arrow" /> <img width="32px" height="32px" id="nav-forwards" src="/img/nav/forwards.svg" alt="Forwards Arrow" />
<img id="nav-share" src="/img/nav/share.svg" alt="Share Page" /> <img width="32px" height="32px" id="nav-share" src="/img/nav/share.svg" alt="Share Page" />
</div> </div>
</div> </div>
<div class="top-bar-right"> <div class="top-bar-right">
@ -73,20 +73,19 @@ export function getStaticPaths() {
async function sendAPIRequest(urlInput: HTMLInputElement, searchSuggestions: HTMLDivElement) { async function sendAPIRequest(urlInput: HTMLInputElement, searchSuggestions: HTMLDivElement) {
if (!urlInput) throw new Error("urlInput is null"); if (!urlInput) throw new Error("urlInput is null");
if (!searchSuggestions) throw new Error("searchSuggestions is null"); if (!searchSuggestions) throw new Error("searchSuggestions is null");
let url = urlInput.value; const url = urlInput.value;
let request = await fetch("/search?query=" + url); const request = await fetch("/search?query=" + url);
let data = await request.json(); const data = await request.json();
searchSuggestions.innerHTML = ""; searchSuggestions.innerHTML = "";
data.map((suggestion: Suggestion) => { data.map((suggestion: Suggestion) => {
let suggestionElement = document.createElement("div"); const suggestionElement = document.createElement("div");
// For some reason css classes weren't working T^T. // For some reason css classes weren't working T^T.
suggestionElement.style.cursor = "pointer"; suggestionElement.style.cursor = "pointer";
suggestionElement.style.marginTop = "5px"; suggestionElement.style.marginTop = "5px";
suggestionElement.innerText = suggestion.phrase; suggestionElement.innerText = suggestion.phrase;
suggestionElement.addEventListener("click", async () => { suggestionElement.addEventListener("click", async () => {
urlInput.value = suggestion.phrase; urlInput.value = suggestion.phrase;
if (window.loadSelectedTransport) await window.loadSelectedTransport(); if (window.loadFormContent) window.loadFormContent();
if (window.loadFormContent) window.loadFormContent(suggestion.phrase);
}); });
searchSuggestions.appendChild(suggestionElement); searchSuggestions.appendChild(suggestionElement);
}); });
@ -100,8 +99,8 @@ export function getStaticPaths() {
} }
function addEventListeners() { function addEventListeners() {
let urlInput = document.getElementById("url-input") as HTMLInputElement; const urlInput = document.getElementById("url-input") as HTMLInputElement;
let searchSuggestions = document.getElementById("search-suggestions") as HTMLDivElement; const searchSuggestions = document.getElementById("search-suggestions") as HTMLDivElement;
// Silently return if the required elements aren't found, this prevents the console from getting cluttered with errors. // Silently return if the required elements aren't found, this prevents the console from getting cluttered with errors.
if (!urlInput || !searchSuggestions) return; if (!urlInput || !searchSuggestions) return;
urlInput.addEventListener("focus", () => { urlInput.addEventListener("focus", () => {
@ -145,39 +144,8 @@ export function getStaticPaths() {
justify-content: center; justify-content: center;
} }
form { form {
width: 350px; width: 30%;
height: 56px; height: 4rem;
}
.url-input-form {
border: none;
padding: 0;
}
.url-input {
display: block;
background: transparent url("/img/search.svg") no-repeat 13px center;
background-color: var(--dropdown-background-color);
color: var(--text-color);
border: 3px solid var(--text-color);
border-radius: 30px;
padding: 15px;
width: 100%;
text-align: center;
transition: 250ms ease-in-out;
outline: none;
font-family: "Varela Round", sans-serif;
font-size: 16px;
}
.url-input.search-results {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border-bottom: 0;
}
.url-input::placeholder {
color: var(--text-color);
} }
#search-suggestions { #search-suggestions {

View file

@ -63,7 +63,7 @@ export function getStaticPaths() {
window.currentlySelectedTab = ""; window.currentlySelectedTab = "";
}); });
Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => { Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
let contentToLoad = document.getElementById("content-" + tab.id); const contentToLoad = document.getElementById("content-" + tab.id);
if (contentToLoad) { if (contentToLoad) {
window.loadedContentStorage[tab.id] = contentToLoad.innerHTML; window.loadedContentStorage[tab.id] = contentToLoad.innerHTML;
contentToLoad.remove(); contentToLoad.remove();
@ -77,7 +77,7 @@ export function getStaticPaths() {
function loadContent(tabID) { function loadContent(tabID) {
if (window.currentlySelectedTab == tabID) return; if (window.currentlySelectedTab == tabID) return;
else window.currentlySelectedTab = tabID; else window.currentlySelectedTab = tabID;
let currentContent = document.getElementById("current-content"); const currentContent = document.getElementById("current-content");
if (currentContent) { if (currentContent) {
currentContent.style.opacity = "0"; currentContent.style.opacity = "0";
setTimeout(() => { setTimeout(() => {
@ -89,7 +89,7 @@ export function getStaticPaths() {
} }
function addDropdownListener() { function addDropdownListener() {
let dropdown_toggles = document.getElementsByClassName("dropdown-toggle"); const dropdown_toggles = document.getElementsByClassName("dropdown-toggle");
Array.from(dropdown_toggles).forEach((toggle) => { Array.from(dropdown_toggles).forEach((toggle) => {
toggle.onclick = function () { toggle.onclick = function () {
closeOtherDropdowns(toggle.id); closeOtherDropdowns(toggle.id);
@ -99,7 +99,7 @@ export function getStaticPaths() {
} }
function toggleDropdown(toggle) { function toggleDropdown(toggle) {
let dropdown = document.getElementById(toggle.id + "-menu"); const dropdown = document.getElementById(toggle.id + "-menu");
if (dropdown.style.maxHeight == "0px" || dropdown.style.maxHeight == "") { if (dropdown.style.maxHeight == "0px" || dropdown.style.maxHeight == "") {
dropdown.style.maxHeight = dropdown.scrollHeight + "px"; dropdown.style.maxHeight = dropdown.scrollHeight + "px";
toggle.style.borderRadius = "10px 10px 0 0"; toggle.style.borderRadius = "10px 10px 0 0";
@ -120,12 +120,12 @@ export function getStaticPaths() {
} }
function closeOtherDropdowns(dropdownIDToExclude) { function closeOtherDropdowns(dropdownIDToExclude) {
let dropdowns = document.getElementsByClassName("dropdown-menu"); const dropdowns = document.getElementsByClassName("dropdown-menu");
Array.from(dropdowns).forEach((dropdown) => { Array.from(dropdowns).forEach((dropdown) => {
dropdown.style.maxHeight = "0px"; dropdown.style.maxHeight = "0px";
setTimeout(() => { setTimeout(() => {
if (dropdown.id != dropdownIDToExclude + "-menu") { if (dropdown.id != dropdownIDToExclude + "-menu") {
let dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", "")); const dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", ""));
dropdown_toggle.style.borderRadius = "10px"; dropdown_toggle.style.borderRadius = "10px";
} }
}, 300); }, 300);
@ -133,11 +133,11 @@ export function getStaticPaths() {
} }
function closeDropdown(dropdownID) { function closeDropdown(dropdownID) {
let dropdown = document.getElementById(dropdownID); const dropdown = document.getElementById(dropdownID);
if (dropdown) { if (dropdown) {
dropdown.style.maxHeight = "0px"; dropdown.style.maxHeight = "0px";
setTimeout(() => { setTimeout(() => {
let dropdown_toggle = document.getElementById(dropdownID.replace("-menu", "")); const dropdown_toggle = document.getElementById(dropdownID.replace("-menu", ""));
dropdown_toggle.style.borderRadius = "10px"; dropdown_toggle.style.borderRadius = "10px";
}, 300); }, 300);
} }
@ -145,12 +145,12 @@ export function getStaticPaths() {
function getLocalStorageValue(localStorageItem, dropdownID) { function getLocalStorageValue(localStorageItem, dropdownID) {
// I was kinda dumb for not doing this earlier. // I was kinda dumb for not doing this earlier.
let dropdown = document.getElementById(dropdownID); const dropdown = document.getElementById(dropdownID);
let dropdownMenu = document.getElementById(dropdownID + "-menu"); const dropdownMenu = document.getElementById(dropdownID + "-menu");
if (dropdown && dropdownMenu) { if (dropdown && dropdownMenu) {
// Now we find the child that matches localStorageItem.value. // Now we find the child that matches localStorageItem.value.
let dropdownItem = Array.from(dropdownMenu.children).find((item) => { const dropdownItem = Array.from(dropdownMenu.children).find((item) => {
return JSON.parse(localStorage.getItem(localStorageItem)).value == item.dataset.setting; return JSON.parse(localStorage.getItem(localStorageItem)).value == item.dataset.setting;
}); });
// Now set the inner text to the name in the dropdownItem. // Now set the inner text to the name in the dropdownItem.
@ -160,7 +160,7 @@ export function getStaticPaths() {
function applySavedLocalStorage(localStorageItem, dropdownID) { function applySavedLocalStorage(localStorageItem, dropdownID) {
if (localStorage.getItem(localStorageItem)) { if (localStorage.getItem(localStorageItem)) {
let dropdown_toggle = document.getElementById(dropdownID); const dropdown_toggle = document.getElementById(dropdownID);
if (dropdown_toggle) { if (dropdown_toggle) {
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID); dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID);
} }
@ -168,11 +168,11 @@ export function getStaticPaths() {
} }
function applyDropdownEventListeners(dropdown, optionalCallback) { function applyDropdownEventListeners(dropdown, optionalCallback) {
let dropdownSibling = document.getElementById(dropdown.id + "-menu"); const dropdownSibling = document.getElementById(dropdown.id + "-menu");
let localStorageItem = dropdown.dataset.localStorageKey; const localStorageItem = dropdown.dataset.localStorageKey;
Array.from(dropdownSibling.children).forEach((child) => { Array.from(dropdownSibling.children).forEach((child) => {
child.onclick = () => { child.onclick = () => {
let localStorageItemContent = { const localStorageItemContent = {
name: child.innerText, name: child.innerText,
value: child.dataset.setting, value: child.dataset.setting,
}; };
@ -194,15 +194,15 @@ export function getStaticPaths() {
} }
function addThemeToDropdown(extension) { function addThemeToDropdown(extension) {
let dropdown = document.getElementById("dropdown__selected-theme-menu"); const dropdown = document.getElementById("dropdown__selected-theme-menu");
if (dropdown) { if (dropdown) {
// TODO: Figure out why addThemeToDropdown is being called 6 times // TODO: Figure out why addThemeToDropdown is being called 6 times
// This when you go from another page and back to settings->customization. // This when you go from another page and back to settings->customization.
let duplicateItem = Array.from(dropdown.children).find((item) => { const duplicateItem = Array.from(dropdown.children).find((item) => {
return item.dataset.setting == extension.themeName; return item.dataset.setting == extension.themeName;
}); });
if (duplicateItem) return; if (duplicateItem) return;
let themeItem = document.createElement("li"); const themeItem = document.createElement("li");
themeItem.classList.add("dropdown-item"); themeItem.classList.add("dropdown-item");
themeItem.dataset.setting = extension.themeName; themeItem.dataset.setting = extension.themeName;
themeItem.textContent = extension.title; themeItem.textContent = extension.title;
@ -215,7 +215,7 @@ export function getStaticPaths() {
loadContent("setting-tab-proxy"); loadContent("setting-tab-proxy");
function setupCustomizationSettings() { function setupCustomizationSettings() {
let store = window.idb.transaction("InstalledExtensions", "readonly").objectStore("InstalledExtensions"); const store = window.idb.transaction("InstalledExtensions", "readonly").objectStore("InstalledExtensions");
store.getAll().onsuccess = (event) => { store.getAll().onsuccess = (event) => {
const result = event.target.result; const result = event.target.result;
if (result) { if (result) {
@ -229,8 +229,8 @@ export function getStaticPaths() {
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme"); applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language"); applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language");
let themeDropdown = document.getElementById("dropdown__selected-theme"); const themeDropdown = document.getElementById("dropdown__selected-theme");
let languageDropdown = document.getElementById("dropdown__selected-language"); const languageDropdown = document.getElementById("dropdown__selected-language");
applyDropdownEventListeners(themeDropdown, changeTheme); applyDropdownEventListeners(themeDropdown, changeTheme);
applyDropdownEventListeners(languageDropdown, navigateToNewLangaugePage); applyDropdownEventListeners(languageDropdown, navigateToNewLangaugePage);
}; };
@ -242,7 +242,7 @@ export function getStaticPaths() {
let cloakName = cloak.dataset.cloakName; let cloakName = cloak.dataset.cloakName;
let cloakIcon = cloak.dataset.cloakIcon; let cloakIcon = cloak.dataset.cloakIcon;
let localStorageItem = { const localStorageItem = {
name: cloakName, name: cloakName,
icon: cloakIcon, icon: cloakIcon,
isCustom: false, isCustom: false,
@ -272,10 +272,10 @@ export function getStaticPaths() {
}); });
}); });
let customNameInput = document.getElementById("cloak-custom-name-input"); const customNameInput = document.getElementById("cloak-custom-name-input");
let customFaviconInput = document.getElementById("cloak-custom-favicon-input"); const customFaviconInput = document.getElementById("cloak-custom-favicon-input");
if (localStorage.getItem("alu__selectedCloak")) { if (localStorage.getItem("alu__selectedCloak")) {
let selectedCloak = JSON.parse(localStorage.getItem("alu__selectedCloak")); const selectedCloak = JSON.parse(localStorage.getItem("alu__selectedCloak"));
if (selectedCloak.isCustom) { if (selectedCloak.isCustom) {
customNameInput.value = selectedCloak.name; customNameInput.value = selectedCloak.name;
customFaviconInput.value = selectedCloak.icon; customFaviconInput.value = selectedCloak.icon;
@ -285,7 +285,7 @@ export function getStaticPaths() {
document.getElementById("cloak-custom-button").addEventListener("click", () => { document.getElementById("cloak-custom-button").addEventListener("click", () => {
let cloakName = document.getElementById("cloak-custom-name-input").value; let cloakName = document.getElementById("cloak-custom-name-input").value;
let cloakIcon = document.getElementById("cloak-custom-favicon-input").value; let cloakIcon = document.getElementById("cloak-custom-favicon-input").value;
let localStorageItem = { const localStorageItem = {
name: cloakName, name: cloakName,
icon: cloakIcon, icon: cloakIcon,
isCustom: true, isCustom: true,
@ -308,10 +308,10 @@ export function getStaticPaths() {
} }
function changeTheme() { function changeTheme() {
let theme = JSON.parse(localStorage.getItem("alu__selectedTheme")).value; const theme = JSON.parse(localStorage.getItem("alu__selectedTheme")).value;
if (theme) { if (theme) {
document.documentElement.setAttribute("data-theme", theme.toLowerCase()); document.documentElement.setAttribute("data-theme", theme.toLowerCase());
let footer = document.getElementById("footer"); const footer = document.getElementById("footer");
if (footer) { if (footer) {
footer.dataset.theme = theme.toLowerCase(); footer.dataset.theme = theme.toLowerCase();
} }
@ -325,16 +325,16 @@ export function getStaticPaths() {
applySavedLocalStorage("alu__selectedOpenWith", "dropdown__open-with"); applySavedLocalStorage("alu__selectedOpenWith", "dropdown__open-with");
applySavedLocalStorage("alu__selectedTransport", "dropdown__transport"); applySavedLocalStorage("alu__selectedTransport", "dropdown__transport");
// Dropdowns // Dropdowns
let selectedProxyDropdown = document.getElementById("dropdown__selected-proxy"); const selectedProxyDropdown = document.getElementById("dropdown__selected-proxy");
let searchEngineDropdown = document.getElementById("dropdown__search-engine"); const searchEngineDropdown = document.getElementById("dropdown__search-engine");
let openWithDropdown = document.getElementById("dropdown__open-with"); const openWithDropdown = document.getElementById("dropdown__open-with");
let currentTransportDropdown = document.getElementById("dropdown__transport"); const currentTransportDropdown = document.getElementById("dropdown__transport");
let wispURLDropdown = document.getElementById("dropdown__wisp-url"); const wispURLDropdown = document.getElementById("dropdown__wisp-url");
// Inputs // Inputs
let searxngUrlInput = document.getElementById("searxng-url-input"); const searxngUrlInput = document.getElementById("searxng-url-input");
let bareURLInput = document.getElementById("bare-url-input"); const bareURLInput = document.getElementById("bare-url-input");
let savedSearxngUrl = localStorage.getItem("alu__searxngUrl"); const savedSearxngUrl = localStorage.getItem("alu__searxngUrl");
if (savedSearxngUrl != null) { if (savedSearxngUrl != null) {
if (savedSearxngUrl == "") localStorage.setItem("alu__searxngUrl", "https://searxng.site/"); if (savedSearxngUrl == "") localStorage.setItem("alu__searxngUrl", "https://searxng.site/");
searxngUrlInput.value = localStorage.getItem("alu__searxngUrl"); searxngUrlInput.value = localStorage.getItem("alu__searxngUrl");
@ -343,7 +343,7 @@ export function getStaticPaths() {
// const webSocketProtocol = useWss ? "wss://" : "ws://"; // const webSocketProtocol = useWss ? "wss://" : "ws://";
// let savedWispUrl = localStorage.getItem("alu__wispUrl"); // let savedWispUrl = localStorage.getItem("alu__wispUrl");
// if (savedWispUrl == null || savedWispUrl == "") localStorage.setItem("alu__wispUrl", webSocketProtocol + location.host + "/wisp/"); // if (savedWispUrl == null || savedWispUrl == "") localStorage.setItem("alu__wispUrl", webSocketProtocol + location.host + "/wisp/");
let savedBareUrl = localStorage.getItem("alu__bareUrl"); const savedBareUrl = localStorage.getItem("alu__bareUrl");
if (savedBareUrl == null || savedBareUrl == "") localStorage.setItem("alu__bareUrl", location.origin + "/bare/"); if (savedBareUrl == null || savedBareUrl == "") localStorage.setItem("alu__bareUrl", location.origin + "/bare/");
bareURLInput.value = localStorage.getItem("alu__bareUrl"); bareURLInput.value = localStorage.getItem("alu__bareUrl");
@ -365,7 +365,7 @@ export function getStaticPaths() {
function checkSearxng() { function checkSearxng() {
// This function checks if the "searxng" option was clicked, display an additional option if so. // This function checks if the "searxng" option was clicked, display an additional option if so.
let search_engine = JSON.parse(localStorage.getItem("alu__search_engine")); const search_engine = JSON.parse(localStorage.getItem("alu__search_engine"));
if (search_engine) { if (search_engine) {
if (search_engine.value.toLowerCase() == "searx") { if (search_engine.value.toLowerCase() == "searx") {
document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "1"; document.getElementsByClassName("setting__searxng-url")[0].style.opacity = "1";
@ -378,8 +378,8 @@ export function getStaticPaths() {
document.addEventListener("setting-tabLoad", setupSettings); document.addEventListener("setting-tabLoad", setupSettings);
function navigateToNewLangaugePage() { function navigateToNewLangaugePage() {
let value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value; const value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value;
let currentLanguage = window.location.pathname.split("/")[1]; const currentLanguage = window.location.pathname.split("/")[1];
// Do nothing.. because we're already on the page. // Do nothing.. because we're already on the page.
if (value == currentLanguage) return; if (value == currentLanguage) return;
window.location.href = `/${value}/settings`; window.location.href = `/${value}/settings`;

View file

@ -3,10 +3,10 @@ export const prerender = false;
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
import games from "../../json/games.json"; import games from "../../json/games.json";
let gamesList = games as GameList; const gamesList = games as GameList;
// get the current game based on the information in the url // get the current game based on the information in the url
let game = Astro.params.game; const game = Astro.params.game;
if (!game) { if (!game) {
Astro.redirect("/en/games/"); Astro.redirect("/en/games/");
return; return;
@ -16,7 +16,7 @@ function isValidGameKey(key: string) {
return key in gamesList; return key in gamesList;
} }
let gameData = isValidGameKey(game) ? gamesList[game] : null; const gameData = isValidGameKey(game) ? gamesList[game] : null;
if (!gameData) { if (!gameData) {
return Astro.redirect("/en/games/"); return Astro.redirect("/en/games/");
@ -95,7 +95,7 @@ if (!gameData) {
</style> </style>
<script> <script>
let iframe = document.getElementById("game-frame") as HTMLIFrameElement; const iframe = document.getElementById("game-frame") as HTMLIFrameElement;
iframe.contentWindow?.focus(); iframe.contentWindow?.focus();
iframe?.addEventListener("load", () => { iframe?.addEventListener("load", () => {
@ -107,11 +107,11 @@ if (!gameData) {
}); });
document.addEventListener("astro:after-swap", () => { document.addEventListener("astro:after-swap", () => {
let iframe = document.getElementById("game-frame") as HTMLIFrameElement; const iframe = document.getElementById("game-frame") as HTMLIFrameElement;
iframe?.contentWindow?.focus(); iframe?.contentWindow?.focus();
}); });
let fullscreen = document.getElementById("game-fullscreen") as HTMLImageElement; const fullscreen = document.getElementById("game-fullscreen") as HTMLImageElement;
fullscreen.addEventListener("click", () => { fullscreen.addEventListener("click", () => {
if (iframe.requestFullscreen) { if (iframe.requestFullscreen) {

View file

@ -21,11 +21,11 @@ import { ViewTransitions } from "astro:transitions";
<meta property="twitter:image" content="/logo.png" /> <meta property="twitter:image" content="/logo.png" />
<ViewTransitions /> <ViewTransitions />
<script> <script>
let currentLang = localStorage.getItem("alu__selectedLanguage"); const currentLang = localStorage.getItem("alu__selectedLanguage");
const redirect = (loc: string) => (window.location.href = loc); const redirect = (loc: string) => (window.location.href = loc);
if (currentLang) { if (currentLang) {
try { try {
let parsed = JSON.parse(currentLang).value; const parsed = JSON.parse(currentLang).value;
redirect(`/${parsed}/`); redirect(`/${parsed}/`);
} catch { } catch {
localStorage.clear(); localStorage.clear();

5
src/types.d.ts vendored
View file

@ -5,11 +5,8 @@ interface Window {
decodeUrl: (url: string) => string; decodeUrl: (url: string) => string;
}; };
__uv$location: Location; __uv$location: Location;
loadFormContent: Function | null; loadFormContent: () => Promise<void> | null;
loadSelectedTransport: Function | null;
loadedThemeAtob: string;
idb: IDBDatabase; idb: IDBDatabase;
URLPattern: URLPattern | null;
// Why is this not already on Window? // Why is this not already on Window?
eval(string): void; eval(string): void;
wispData: WispData[]; wispData: WispData[];