Add path aliases, optimize adding i18n to a page, and general cleanup.
This commit is contained in:
parent
ece900b353
commit
e54858620b
25 changed files with 125 additions and 311 deletions
6
index.js
6
index.js
|
|
@ -14,7 +14,7 @@ import dotenv from "dotenv";
|
||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
import wisp from "wisp-server-node";
|
import wisp from "wisp-server-node";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import fetch from 'node-fetch';
|
import fetch from "node-fetch";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license=";
|
const LICENSE_SERVER_URL = "https://license.mercurywork.shop/validate?license=";
|
||||||
|
|
@ -137,8 +137,8 @@ app.use("/custom-favicon", async (req, res) => {
|
||||||
const response = await fetch(url).then((apiRes) => apiRes.buffer());
|
const response = await fetch(url).then((apiRes) => apiRes.buffer());
|
||||||
res.send(response);
|
res.send(response);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
res.send("Error")
|
res.send("Error");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.use("/", express.static("dist/client/"));
|
app.use("/", express.static("dist/client/"));
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
? factory(exports)
|
? factory(exports)
|
||||||
: typeof define === "function" && define.amd
|
: typeof define === "function" && define.amd
|
||||||
? define(["exports"], factory)
|
? define(["exports"], factory)
|
||||||
: ((global =
|
: ((global = typeof globalThis !== "undefined" ? globalThis : global || self),
|
||||||
typeof globalThis !== "undefined" ? globalThis : global || self),
|
|
||||||
factory((global.BareMod = {})));
|
factory((global.BareMod = {})));
|
||||||
})(this, function (exports) {
|
})(this, function (exports) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
@ -17,12 +16,12 @@
|
||||||
const WebSocket = globalThis.WebSocket;
|
const WebSocket = globalThis.WebSocket;
|
||||||
const WebSocketFields = {
|
const WebSocketFields = {
|
||||||
prototype: {
|
prototype: {
|
||||||
send: WebSocket.prototype.send
|
send: WebSocket.prototype.send,
|
||||||
},
|
},
|
||||||
CLOSED: WebSocket.CLOSED,
|
CLOSED: WebSocket.CLOSED,
|
||||||
CLOSING: WebSocket.CLOSING,
|
CLOSING: WebSocket.CLOSING,
|
||||||
CONNECTING: WebSocket.CONNECTING,
|
CONNECTING: WebSocket.CONNECTING,
|
||||||
OPEN: WebSocket.OPEN
|
OPEN: WebSocket.OPEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BareError extends Error {
|
class BareError extends Error {
|
||||||
|
|
@ -441,7 +440,7 @@
|
||||||
throw new BareError(400, {
|
throw new BareError(400, {
|
||||||
code: "INVALID_BARE_HEADER",
|
code: "INVALID_BARE_HEADER",
|
||||||
id: `request.headers.${header}`,
|
id: `request.headers.${header}`,
|
||||||
message: `Value didn't begin with semi-colon.`
|
message: `Value didn't begin with semi-colon.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const id = parseInt(header.slice(prefix.length + 1));
|
const id = parseInt(header.slice(prefix.length + 1));
|
||||||
|
|
@ -473,16 +472,7 @@
|
||||||
async init() {
|
async init() {
|
||||||
this.ready = true;
|
this.ready = true;
|
||||||
}
|
}
|
||||||
connect(
|
connect(url, origin, protocols, requestHeaders, onopen, onmessage, onclose, onerror) {
|
||||||
url,
|
|
||||||
origin,
|
|
||||||
protocols,
|
|
||||||
requestHeaders,
|
|
||||||
onopen,
|
|
||||||
onmessage,
|
|
||||||
onclose,
|
|
||||||
onerror
|
|
||||||
) {
|
|
||||||
const ws = new WebSocket(this.ws);
|
const ws = new WebSocket(this.ws);
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
ws.removeEventListener("close", closeListener);
|
ws.removeEventListener("close", closeListener);
|
||||||
|
|
@ -495,13 +485,10 @@
|
||||||
cleanup();
|
cleanup();
|
||||||
// ws.binaryType is irrelevant when sending text
|
// ws.binaryType is irrelevant when sending text
|
||||||
if (typeof event.data !== "string")
|
if (typeof event.data !== "string")
|
||||||
throw new TypeError(
|
throw new TypeError("the first websocket message was not a text frame");
|
||||||
"the first websocket message was not a text frame"
|
|
||||||
);
|
|
||||||
const message = JSON.parse(event.data);
|
const message = JSON.parse(event.data);
|
||||||
// finally
|
// finally
|
||||||
if (message.type !== "open")
|
if (message.type !== "open") throw new TypeError("message was not of open type");
|
||||||
throw new TypeError("message was not of open type");
|
|
||||||
// onMeta({
|
// onMeta({
|
||||||
// protocol: message.protocol,
|
// protocol: message.protocol,
|
||||||
// setCookies: message.setCookies,
|
// setCookies: message.setCookies,
|
||||||
|
|
@ -526,7 +513,7 @@
|
||||||
remote: url.toString(),
|
remote: url.toString(),
|
||||||
protocols,
|
protocols,
|
||||||
headers: requestHeaders,
|
headers: requestHeaders,
|
||||||
forwardHeaders: []
|
forwardHeaders: [],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
// );
|
// );
|
||||||
|
|
@ -540,16 +527,13 @@
|
||||||
const options = {
|
const options = {
|
||||||
credentials: "omit",
|
credentials: "omit",
|
||||||
method: method,
|
method: method,
|
||||||
signal
|
signal,
|
||||||
};
|
};
|
||||||
if (body !== undefined) {
|
if (body !== undefined) {
|
||||||
options.body = body;
|
options.body = body;
|
||||||
}
|
}
|
||||||
options.headers = this.createBareHeaders(remote, headers);
|
options.headers = this.createBareHeaders(remote, headers);
|
||||||
const response = await fetch(
|
const response = await fetch(this.http + "?cache=" + md5(remote.toString()), options);
|
||||||
this.http + "?cache=" + md5(remote.toString()),
|
|
||||||
options
|
|
||||||
);
|
|
||||||
const readResponse = await this.readBareResponse(response);
|
const readResponse = await this.readBareResponse(response);
|
||||||
// const result: Response & Partial<BareResponse> = new Response(
|
// const result: Response & Partial<BareResponse> = new Response(
|
||||||
// statusEmpty.includes(readResponse.status!) ? undefined : response.body,
|
// statusEmpty.includes(readResponse.status!) ? undefined : response.body,
|
||||||
|
|
@ -566,7 +550,7 @@
|
||||||
body: response.body,
|
body: response.body,
|
||||||
headers: readResponse.headers,
|
headers: readResponse.headers,
|
||||||
status: readResponse.status,
|
status: readResponse.status,
|
||||||
statusText: readResponse.statusText
|
statusText: readResponse.statusText,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async readBareResponse(response) {
|
async readBareResponse(response) {
|
||||||
|
|
@ -583,13 +567,7 @@
|
||||||
if (xBareHeaders !== null) result.headers = JSON.parse(xBareHeaders);
|
if (xBareHeaders !== null) result.headers = JSON.parse(xBareHeaders);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
createBareHeaders(
|
createBareHeaders(remote, bareHeaders, forwardHeaders = [], passHeaders = [], passStatus = []) {
|
||||||
remote,
|
|
||||||
bareHeaders,
|
|
||||||
forwardHeaders = [],
|
|
||||||
passHeaders = [],
|
|
||||||
passStatus = []
|
|
||||||
) {
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
headers.set("x-bare-url", remote.toString());
|
headers.set("x-bare-url", remote.toString());
|
||||||
headers.set("x-bare-headers", JSON.stringify(bareHeaders));
|
headers.set("x-bare-headers", JSON.stringify(bareHeaders));
|
||||||
|
|
@ -608,4 +586,4 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.BareClient = ClientV3;
|
exports.BareClient = ClientV3;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
importScripts("/libcurl/index.js");
|
importScripts("/libcurl/index.js");
|
||||||
importScripts("/epoxy/index.js");
|
importScripts("/epoxy/index.js");
|
||||||
importScripts("/bare_transport.js")
|
importScripts("/bare_transport.js");
|
||||||
importScripts("/uv/uv.bundle.js");
|
importScripts("/uv/uv.bundle.js");
|
||||||
importScripts("/uv.config.js");
|
importScripts("/uv.config.js");
|
||||||
importScripts(__uv$config.sw);
|
importScripts(__uv$config.sw);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<script src="/uv/uv.bundle.js" transition:persist is:inline></script>
|
<script src="/uv/uv.bundle.js" transition:persist is:inline defer></script>
|
||||||
<script src="/uv.config.js" transition:persist is:inline></script>
|
<script src="/uv.config.js" transition:persist is:inline defer></script>
|
||||||
<script src="/epoxy/index.js" transition:persist is:inline></script>
|
<script src="/epoxy/index.js" transition:persist is:inline defer></script>
|
||||||
<script src="/libcurl/index.js" transition:persist is:inline></script>
|
<script src="/libcurl/index.js" transition:persist is:inline defer></script>
|
||||||
<script src="/bare_transport.js" transition:persist is:inline></script>
|
<script src="/bare_transport.js" transition:persist is:inline defer></script>
|
||||||
<script>
|
<script>
|
||||||
import { initTransport } from "./ts/TransportManager";
|
import { initTransport } from "./ts/TransportManager";
|
||||||
|
|
||||||
let form = document.querySelector("form");
|
let form = document.querySelector("form");
|
||||||
let input = document.querySelector("input");
|
let input = document.querySelector("input");
|
||||||
|
|
@ -39,7 +39,7 @@ import { initTransport } from "./ts/TransportManager";
|
||||||
if (!rammerheadSession) {
|
if (!rammerheadSession) {
|
||||||
let session = await fetch("/newsession");
|
let session = await fetch("/newsession");
|
||||||
let sessionID = await session.text();
|
let 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=/`;
|
||||||
// Now add an origin_proxy cookie for our domain
|
// Now add an origin_proxy cookie for our domain
|
||||||
|
|
@ -61,7 +61,10 @@ import { initTransport } from "./ts/TransportManager";
|
||||||
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);
|
let 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;
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +116,12 @@ import { initTransport } from "./ts/TransportManager";
|
||||||
const boundIFrameLoad = iframeLoad.bind(null, iframe, loadingContent, topbar, closeButton);
|
const boundIFrameLoad = iframeLoad.bind(null, iframe, loadingContent, topbar, closeButton);
|
||||||
iframe.addEventListener("load", boundIFrameLoad);
|
iframe.addEventListener("load", boundIFrameLoad);
|
||||||
|
|
||||||
function iframeLoad(iframe: HTMLIFrameElement, loadingContent: HTMLElement, topbar: HTMLDivElement, closeButton: HTMLButtonElement) {
|
function iframeLoad(
|
||||||
|
iframe: HTMLIFrameElement,
|
||||||
|
loadingContent: HTMLElement,
|
||||||
|
topbar: HTMLDivElement,
|
||||||
|
closeButton: HTMLButtonElement
|
||||||
|
) {
|
||||||
loadingContent.style.opacity = "0";
|
loadingContent.style.opacity = "0";
|
||||||
iframe.style.opacity = "1";
|
iframe.style.opacity = "1";
|
||||||
topbar.style.opacity = "1";
|
topbar.style.opacity = "1";
|
||||||
|
|
@ -216,11 +224,16 @@ import { initTransport } from "./ts/TransportManager";
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
if (iframe.contentDocument) {
|
if (iframe.contentDocument) {
|
||||||
let favicon =
|
let favicon =
|
||||||
iframe.contentDocument.querySelector("link[rel='icon']") as HTMLLinkElement ||
|
(iframe.contentDocument.querySelector("link[rel='icon']") as HTMLLinkElement) ||
|
||||||
iframe.contentDocument.querySelector("link[rel*='icon']") as HTMLLinkElement;
|
(iframe.contentDocument.querySelector("link[rel*='icon']") as HTMLLinkElement);
|
||||||
if(favicon && favicon.href) {
|
if (favicon && favicon.href) {
|
||||||
if (proxiedFavicon.src == `${window.location.origin}/custom-favicon?url=${encodeURIComponent(favicon.href)}` || hasErrored) return;
|
if (
|
||||||
}
|
proxiedFavicon.src ==
|
||||||
|
`${window.location.origin}/custom-favicon?url=${encodeURIComponent(favicon.href)}` ||
|
||||||
|
hasErrored
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (favicon) {
|
if (favicon) {
|
||||||
proxiedFavicon.src = `/custom-favicon?url=${encodeURIComponent(favicon.href)}`;
|
proxiedFavicon.src = `/custom-favicon?url=${encodeURIComponent(favicon.href)}`;
|
||||||
proxiedFavicon.addEventListener("error", () => {
|
proxiedFavicon.addEventListener("error", () => {
|
||||||
|
|
@ -247,6 +260,5 @@ import { initTransport } from "./ts/TransportManager";
|
||||||
}
|
}
|
||||||
topbarTitle.innerText = iframe.contentDocument.title;
|
topbarTitle.innerText = iframe.contentDocument.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
---
|
---
|
||||||
import Input from "../Input.astro";
|
import Input from "@components/UI/Input.astro";
|
||||||
|
import { i18n } from "@i18n/utils";
|
||||||
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
|
|
||||||
const presetCloaks = [
|
const presetCloaks = [
|
||||||
{
|
{
|
||||||
|
|
@ -8,8 +10,7 @@ const presetCloaks = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cloakTitle: "Google",
|
cloakTitle: "Google",
|
||||||
favicon:
|
favicon: "/icons/google.png",
|
||||||
"/icons/google.png",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cloakTitle: "Canvas",
|
cloakTitle: "Canvas",
|
||||||
|
|
@ -21,8 +22,7 @@ const presetCloaks = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cloakTitle: "Classlink",
|
cloakTitle: "Classlink",
|
||||||
favicon:
|
favicon: "/icons/classlink.png",
|
||||||
"/icons/classlink.png",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cloakTitle: "Google Drive",
|
cloakTitle: "Google Drive",
|
||||||
|
|
@ -58,7 +58,7 @@ const presetCloaks = [
|
||||||
<div class="cloak-custom-override">
|
<div class="cloak-custom-override">
|
||||||
<Input inputName="cloak-custom-name" placeholder="Custom Name" height="30px" />
|
<Input inputName="cloak-custom-name" placeholder="Custom Name" height="30px" />
|
||||||
<Input inputName="cloak-custom-favicon" placeholder="Custom Favicon" height="30px" />
|
<Input inputName="cloak-custom-favicon" placeholder="Custom Favicon" height="30px" />
|
||||||
<button id="cloak-custom-button">Update Cloak</button>
|
<button id="cloak-custom-button">{t("settings.cloaking.updateCloak")}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
import { getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="settings-container">
|
<div class="settings-container">
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
---
|
---
|
||||||
import Dropdown from "../Dropdown.astro";
|
import Dropdown from "@components/UI/Dropdown.astro";
|
||||||
|
|
||||||
import { getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
const themeList = [
|
const themeList = [
|
||||||
{ name: t("settings.customization.theme.Alu"), value: "alu" },
|
{ name: t("settings.customization.theme.Alu"), value: "alu" },
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
---
|
---
|
||||||
import Input from "../Input.astro";
|
import Input from "@components/UI/Input.astro";
|
||||||
import Dropdown from "../Dropdown.astro";
|
import Dropdown from "@components/UI/Dropdown.astro";
|
||||||
|
|
||||||
import { getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
const proxyList = [
|
const proxyList = [
|
||||||
{ name: t("settings.proxy.auto"), value: "auto" },
|
{ name: t("settings.proxy.auto"), value: "auto" },
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
---
|
---
|
||||||
import ProxyTab from "./SettingsContent/ProxyTab.astro";
|
import ProxyTab from "./SettingsContent/ProxyTab.astro";
|
||||||
import CustomizationTab from "./SettingsContent/CustomizationTab.astro";
|
import CustomizationTab from "./SettingsContent/CustomizationTab.astro";
|
||||||
|
|
||||||
import { getLangFromUrl, useTranslations } from "../i18n/utils";
|
|
||||||
import CloakingTab from "./SettingsContent/CloakingTab.astro";
|
import CloakingTab from "./SettingsContent/CloakingTab.astro";
|
||||||
import CreditsTab from "./SettingsContent/CreditsTab.astro";
|
import CreditsTab from "./SettingsContent/CreditsTab.astro";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
|
||||||
const t = useTranslations(lang);
|
import { i18n } from "@i18n/utils";
|
||||||
|
const lang = i18n.getLangFromUrl(Astro.url);
|
||||||
|
const t = i18n.useTranslations(lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="content-hidden">
|
<div class="content-hidden">
|
||||||
|
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
---
|
|
||||||
const { inputID } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<label class="switch">
|
|
||||||
<input id={inputID} checked="" type="checkbox" />
|
|
||||||
<div class="slider">
|
|
||||||
<div class="circle">
|
|
||||||
<svg
|
|
||||||
class="cross"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 512 512"
|
|
||||||
viewBox="0 0 365.696 365.696"
|
|
||||||
y="0"
|
|
||||||
x="0"
|
|
||||||
height="6"
|
|
||||||
width="6"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
data-original="#000000"
|
|
||||||
fill="currentColor"
|
|
||||||
d="M243.188 182.86 356.32 69.726c12.5-12.5 12.5-32.766 0-45.247L341.238 9.398c-12.504-12.503-32.77-12.503-45.25 0L182.86 122.528 69.727 9.374c-12.5-12.5-32.766-12.5-45.247 0L9.375 24.457c-12.5 12.504-12.5 32.77 0 45.25l113.152 113.152L9.398 295.99c-12.503 12.503-12.503 32.769 0 45.25L24.48 356.32c12.5 12.5 32.766 12.5 45.247 0l113.132-113.132L295.99 356.32c12.503 12.5 32.769 12.5 45.25 0l15.081-15.082c12.5-12.504 12.5-32.77 0-45.25zm0 0"
|
|
||||||
></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
class="checkmark"
|
|
||||||
xml:space="preserve"
|
|
||||||
style="enable-background:new 0 0 512 512"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
y="0"
|
|
||||||
x="0"
|
|
||||||
height="10"
|
|
||||||
width="10"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
class=""
|
|
||||||
data-original="#000000"
|
|
||||||
fill="currentColor"
|
|
||||||
d="M9.707 19.121a.997.997 0 0 1-1.414 0l-5.646-5.647a1.5 1.5 0 0 1 0-2.121l.707-.707a1.5 1.5 0 0 1 2.121 0L9 14.171l9.525-9.525a1.5 1.5 0 0 1 2.121 0l.707.707a1.5 1.5 0 0 1 0 2.121z"
|
|
||||||
></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.switch {
|
|
||||||
--switch-width: 46px;
|
|
||||||
--switch-height: 24px;
|
|
||||||
--switch-bg: rgb(131, 131, 131);
|
|
||||||
--switch-checked-bg: rgb(0, 218, 80);
|
|
||||||
--switch-offset: calc((var(--switch-height) - var(--circle-diameter)) / 2);
|
|
||||||
--switch-transition: all 0.2s cubic-bezier(0.27, 0.2, 0.25, 1.51);
|
|
||||||
--circle-diameter: 18px;
|
|
||||||
--circle-bg: #fff;
|
|
||||||
--circle-shadow: 1px 1px 2px rgba(146, 146, 146, 0.45);
|
|
||||||
--circle-checked-shadow: -1px 1px 2px rgba(163, 163, 163, 0.45);
|
|
||||||
--circle-transition: var(--switch-transition);
|
|
||||||
--icon-transition: all 0.2s cubic-bezier(0.27, 0.2, 0.25, 1.51);
|
|
||||||
--icon-cross-color: var(--switch-bg);
|
|
||||||
--icon-cross-size: 6px;
|
|
||||||
--icon-checkmark-color: var(--switch-checked-bg);
|
|
||||||
--icon-checkmark-size: 10px;
|
|
||||||
--effect-width: calc(var(--circle-diameter) / 2);
|
|
||||||
--effect-height: calc(var(--effect-width) / 2 - 1px);
|
|
||||||
--effect-bg: var(--circle-bg);
|
|
||||||
--effect-border-radius: 1px;
|
|
||||||
--effect-transition: all 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch svg {
|
|
||||||
-webkit-transition: var(--icon-transition);
|
|
||||||
-o-transition: var(--icon-transition);
|
|
||||||
transition: var(--icon-transition);
|
|
||||||
position: absolute;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch .checkmark {
|
|
||||||
width: var(--icon-checkmark-size);
|
|
||||||
color: var(--icon-checkmark-color);
|
|
||||||
-webkit-transform: scale(0);
|
|
||||||
-ms-transform: scale(0);
|
|
||||||
transform: scale(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch .cross {
|
|
||||||
width: var(--icon-cross-size);
|
|
||||||
color: var(--icon-cross-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: var(--switch-width);
|
|
||||||
height: var(--switch-height);
|
|
||||||
background: var(--switch-bg);
|
|
||||||
border-radius: 999px;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
-webkit-transition: var(--switch-transition);
|
|
||||||
-o-transition: var(--switch-transition);
|
|
||||||
transition: var(--switch-transition);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.circle {
|
|
||||||
width: var(--circle-diameter);
|
|
||||||
height: var(--circle-diameter);
|
|
||||||
background: var(--circle-bg);
|
|
||||||
border-radius: inherit;
|
|
||||||
-webkit-box-shadow: var(--circle-shadow);
|
|
||||||
box-shadow: var(--circle-shadow);
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
-webkit-transition: var(--circle-transition);
|
|
||||||
-o-transition: var(--circle-transition);
|
|
||||||
transition: var(--circle-transition);
|
|
||||||
z-index: 1;
|
|
||||||
position: absolute;
|
|
||||||
left: var(--switch-offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: var(--effect-width);
|
|
||||||
height: var(--effect-height);
|
|
||||||
left: calc(var(--switch-offset) + (var(--effect-width) / 2));
|
|
||||||
background: var(--effect-bg);
|
|
||||||
border-radius: var(--effect-border-radius);
|
|
||||||
-webkit-transition: var(--effect-transition);
|
|
||||||
-o-transition: var(--effect-transition);
|
|
||||||
transition: var(--effect-transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* actions */
|
|
||||||
|
|
||||||
.switch input:checked + .slider {
|
|
||||||
background: var(--switch-checked-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input:checked + .slider .checkmark {
|
|
||||||
-webkit-transform: scale(1);
|
|
||||||
-ms-transform: scale(1);
|
|
||||||
transform: scale(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input:checked + .slider .cross {
|
|
||||||
-webkit-transform: scale(0);
|
|
||||||
-ms-transform: scale(0);
|
|
||||||
transform: scale(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input:checked + .slider::before {
|
|
||||||
left: calc(100% - var(--effect-width) - (var(--effect-width) / 2) - var(--switch-offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch input:checked + .slider .circle {
|
|
||||||
left: calc(100% - var(--circle-diameter) - var(--switch-offset));
|
|
||||||
-webkit-box-shadow: var(--circle-checked-shadow);
|
|
||||||
box-shadow: var(--circle-checked-shadow);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
---
|
---
|
||||||
import { getLangFromUrl, useTranslations } from "../i18n/utils";
|
import { i18n } from "@i18n/utils";
|
||||||
import Link from "./Link.astro";
|
import Link from "./Link.astro";
|
||||||
import WaveSVG from "./WaveSVG.astro";
|
import WaveSVG from "../WaveSVG.astro";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
import { getLangFromUrl, useTranslations } from "../i18n/utils";
|
import { i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const lang = i18n.getLangFromUrl(Astro.url);
|
||||||
const t = useTranslations(lang);
|
const t = i18n.useTranslations(lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="top-header">
|
<div class="top-header">
|
||||||
|
|
@ -12,10 +12,12 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type transportConfig = {
|
type transportConfig =
|
||||||
wisp: string;
|
| {
|
||||||
wasm?: string;
|
wisp: string;
|
||||||
} | string;
|
wasm?: string;
|
||||||
|
}
|
||||||
|
| string;
|
||||||
|
|
||||||
export const wispURLDefault =
|
export const wispURLDefault =
|
||||||
(location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/";
|
(location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/";
|
||||||
|
|
@ -40,12 +42,11 @@ export default class TransportManager {
|
||||||
updateTransport() {
|
updateTransport() {
|
||||||
try {
|
try {
|
||||||
this.setTransport(JSON.parse(localStorage.getItem("alu__selectedTransport")!).value);
|
this.setTransport(JSON.parse(localStorage.getItem("alu__selectedTransport")!).value);
|
||||||
console.log(this.transport)
|
console.log(this.transport);
|
||||||
} 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);
|
this.setTransport(this.transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTransport() {
|
getTransport() {
|
||||||
|
|
@ -82,5 +83,4 @@ export async function initTransport() {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
"settings.cloaking": "Cloaking",
|
"settings.cloaking": "Cloaking",
|
||||||
"settings.cloaking.subtext": "Change how your tab looks...",
|
"settings.cloaking.subtext": "Change how your tab looks...",
|
||||||
|
"settings.cloaking.updateCloak": "Update Cloak",
|
||||||
|
|
||||||
"settings.credits": "Credits",
|
"settings.credits": "Credits",
|
||||||
"settings.credits.mochaandmacchiatothemes": "Mocha & Macchiato Themes",
|
"settings.credits.mochaandmacchiatothemes": "Mocha & Macchiato Themes",
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
"settings.cloaking": "クローキング",
|
"settings.cloaking": "クローキング",
|
||||||
"settings.cloaking.subtext": "タブの外観を変更します...",
|
"settings.cloaking.subtext": "タブの外観を変更します...",
|
||||||
|
"settings.cloaking.updateCloak": "クロークを更新",
|
||||||
|
|
||||||
"settings.credits": "クレジット",
|
"settings.credits": "クレジット",
|
||||||
"settings.credits.mochaandmacchiatothemes": "モカとマキアートテーマ",
|
"settings.credits.mochaandmacchiatothemes": "モカとマキアートテーマ",
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,23 @@ import { ui, defaultLang } from "./ui";
|
||||||
|
|
||||||
export const STATIC_PATHS = [{ params: { lang: "en" } }, { params: { lang: "jp" } }];
|
export const STATIC_PATHS = [{ params: { lang: "en" } }, { params: { lang: "jp" } }];
|
||||||
|
|
||||||
export function getLangFromUrl(url: URL) {
|
function getLangFromUrl(url: URL) {
|
||||||
// comma lol
|
// comma lol
|
||||||
const [, lang] = url.pathname.split("/");
|
const [, lang] = url.pathname.split("/");
|
||||||
if (lang in ui) return lang as keyof typeof ui;
|
if (lang in ui) return lang as keyof typeof ui;
|
||||||
return defaultLang;
|
return defaultLang;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useTranslations(lang: keyof typeof ui) {
|
function inferLangUseTranslations(url: URL) {
|
||||||
|
const lang = getLangFromUrl(url);
|
||||||
|
return useTranslations(lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function useTranslations(lang: keyof typeof ui) {
|
||||||
return function t(translationKey: keyof (typeof ui)[typeof defaultLang]) {
|
return function t(translationKey: keyof (typeof ui)[typeof defaultLang]) {
|
||||||
if (ui[lang][translationKey]) return ui[lang][translationKey];
|
if (ui[lang][translationKey]) return ui[lang][translationKey];
|
||||||
else return ui[defaultLang][translationKey];
|
else return ui[defaultLang][translationKey];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const i18n = { getLangFromUrl, useTranslations, inferLangUseTranslations };
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
---
|
---
|
||||||
import { ViewTransitions } from "astro:transitions";
|
import { ViewTransitions } from "astro:transitions";
|
||||||
import Header from "../components/Header.astro";
|
import Header from "@components/UI/Header.astro";
|
||||||
import Footer from "../components/Footer.astro";
|
import Footer from "@components/UI/Footer.astro";
|
||||||
import ThemeLoader from "../components/ThemeLoader.astro";
|
import ThemeLoader from "@components/ThemeLoader.astro";
|
||||||
import CloakLoader from "../components/CloakLoader.astro";
|
import CloakLoader from "@components/CloakLoader.astro";
|
||||||
import WelcomeLogging from "../components/WelcomeLogging.astro";
|
import WelcomeLogging from "@components/WelcomeLogging.astro";
|
||||||
import UVRegistrar from "../components/ProxyRegistrar.astro";
|
import ProxyRegistrar from "@components/ProxyRegistrar.astro";
|
||||||
|
|
||||||
type Preload = {
|
type Preload = {
|
||||||
href: string;
|
href: string;
|
||||||
|
|
@ -69,7 +69,7 @@ const { title, optionalPreloads } = Astro.props;
|
||||||
<Header />
|
<Header />
|
||||||
<slot transition:animate={"fade"} />
|
<slot transition:animate={"fade"} />
|
||||||
<WelcomeLogging />
|
<WelcomeLogging />
|
||||||
<UVRegistrar />
|
<ProxyRegistrar />
|
||||||
<Footer />
|
<Footer />
|
||||||
<style is:global>
|
<style is:global>
|
||||||
:root {
|
:root {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
---
|
---
|
||||||
import Layout from "../../layouts/Layout.astro";
|
import Layout from "../../layouts/Layout.astro";
|
||||||
import games from "../../json/games.json";
|
import games from "../../json/games.json";
|
||||||
import GameItem from "../../components/GameItem.astro";
|
import GameItem from "@components/GameItem.astro";
|
||||||
|
|
||||||
import { STATIC_PATHS, getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { STATIC_PATHS, i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export function getStaticPaths() {
|
||||||
return STATIC_PATHS;
|
return STATIC_PATHS;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
---
|
---
|
||||||
import Layout from "../../layouts/Layout.astro";
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
|
||||||
import { STATIC_PATHS, getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { STATIC_PATHS, i18n } from "@i18n/utils";
|
||||||
import Link from "../../components/Link.astro";
|
import Link from "@components/UI/Link.astro";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export function getStaticPaths() {
|
||||||
return STATIC_PATHS;
|
return STATIC_PATHS;
|
||||||
|
|
@ -63,11 +62,11 @@ export function getStaticPaths() {
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import { TransportMgr } from "../../components/ts/TransportManager";
|
import { TransportMgr } from "@components/ts/TransportManager";
|
||||||
document.addEventListener("astro:after-swap", () => {
|
document.addEventListener("astro:after-swap", () => {
|
||||||
console.log("Updating transport...")
|
console.log("Updating transport...");
|
||||||
TransportMgr.updateTransport();
|
TransportMgr.updateTransport();
|
||||||
})
|
});
|
||||||
type Suggestion = {
|
type Suggestion = {
|
||||||
phrase: string;
|
phrase: string;
|
||||||
};
|
};
|
||||||
|
|
@ -79,7 +78,7 @@ export function getStaticPaths() {
|
||||||
let request = await fetch("/search?query=" + url);
|
let request = await fetch("/search?query=" + url);
|
||||||
let data = await request.json();
|
let data = await request.json();
|
||||||
searchSuggestions.innerHTML = "";
|
searchSuggestions.innerHTML = "";
|
||||||
data.map((suggestion: Suggestion) => {
|
data.map((suggestion: Suggestion) => {
|
||||||
let suggestionElement = document.createElement("div");
|
let 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";
|
||||||
|
|
@ -131,7 +130,7 @@ export function getStaticPaths() {
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
cb(...args);
|
cb(...args);
|
||||||
}, delay);
|
}, delay);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
urlInput.addEventListener("keyup", async () => {
|
urlInput.addEventListener("keyup", async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
---
|
---
|
||||||
import SettingsTablist from "../../components/SettingsTablist.astro";
|
import SettingsTablist from "@components/SettingsTablist.astro";
|
||||||
import Layout from "../../layouts/Layout.astro";
|
import Layout from "../../layouts/Layout.astro";
|
||||||
|
|
||||||
import { STATIC_PATHS, getLangFromUrl, useTranslations } from "../../i18n/utils";
|
import { STATIC_PATHS, i18n } from "@i18n/utils";
|
||||||
const lang = getLangFromUrl(Astro.url);
|
const t = i18n.inferLangUseTranslations(Astro.url);
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export function getStaticPaths() {
|
||||||
return STATIC_PATHS;
|
return STATIC_PATHS;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import { ViewTransitions } from "astro:transitions";
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<ViewTransitions />
|
<ViewTransitions />
|
||||||
<script>
|
<script>
|
||||||
if (localStorage.getItem("alu__selectedLanguage") === null) window.location.href = "/en/";
|
|
||||||
let currentLang = localStorage.getItem("alu__selectedLanguage");
|
let currentLang = localStorage.getItem("alu__selectedLanguage");
|
||||||
if (currentLang) {
|
if (currentLang) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -28,6 +27,14 @@ import { ViewTransitions } from "astro:transitions";
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (navigator.language.includes("ja")) {
|
||||||
|
localStorage.setItem("alu__selectedLanguage", JSON.stringify({ value: "jp" }));
|
||||||
|
window.location.href = "/jp/";
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("alu__selectedLanguage", JSON.stringify({ value: "en" }));
|
||||||
|
window.location.href = "/en/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"exclude": ["dist/**", "node_modules/**", "public/games/**", ".eslint.cjs"]
|
"exclude": ["dist/**", "node_modules/**", "public/games/**", ".eslint.cjs"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@components/*": ["src/components/*"],
|
||||||
|
"@i18n/*": ["src/i18n/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue