Add astro linting, and make some css changes.

This commit is contained in:
wearrrrr 2024-02-06 12:22:35 -06:00
parent 39fc988bce
commit 6af2cd3428
25 changed files with 1840 additions and 1309 deletions

47
package-lock.json generated
View file

@ -26,7 +26,8 @@
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"devDependencies": { "devDependencies": {
"prettier": "3.2.5" "prettier": "3.2.5",
"prettier-plugin-astro": "^0.13.0"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@ -8393,6 +8394,26 @@
"url": "https://github.com/prettier/prettier?sponsor=1" "url": "https://github.com/prettier/prettier?sponsor=1"
} }
}, },
"node_modules/prettier-plugin-astro": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.13.0.tgz",
"integrity": "sha512-5HrJNnPmZqTUNoA97zn4gNQv9BgVhv+et03314WpQ9H9N8m2L9OSV798olwmG2YLXPl1iSstlJCR1zB3x5xG4g==",
"devOptional": true,
"dependencies": {
"@astrojs/compiler": "^1.5.5",
"prettier": "^3.0.0",
"sass-formatter": "^0.7.6"
},
"engines": {
"node": "^14.15.0 || >=16.0.0"
}
},
"node_modules/prettier-plugin-astro/node_modules/@astrojs/compiler": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-1.8.2.tgz",
"integrity": "sha512-o/ObKgtMzl8SlpIdzaxFnt7SATKPxu4oIP/1NL+HDJRzxfJcAkOTAb/ZKMRyULbz4q+1t2/DAebs2Z1QairkZw==",
"devOptional": true
},
"node_modules/prismjs": { "node_modules/prismjs": {
"version": "1.29.0", "version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
@ -9182,6 +9203,12 @@
"queue-microtask": "^1.2.2" "queue-microtask": "^1.2.2"
} }
}, },
"node_modules/s.color": {
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/s.color/-/s.color-0.0.15.tgz",
"integrity": "sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==",
"devOptional": true
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -9206,6 +9233,15 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"node_modules/sass-formatter": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/sass-formatter/-/sass-formatter-0.7.9.tgz",
"integrity": "sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==",
"devOptional": true,
"dependencies": {
"suf-log": "^2.5.3"
}
},
"node_modules/sax": { "node_modules/sax": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
@ -9665,6 +9701,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/suf-log": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/suf-log/-/suf-log-2.5.3.tgz",
"integrity": "sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==",
"devOptional": true,
"dependencies": {
"s.color": "0.0.15"
}
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",

View file

@ -27,6 +27,7 @@
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"devDependencies": { "devDependencies": {
"prettier": "3.2.5" "prettier": "3.2.5",
"prettier-plugin-astro": "^0.13.0"
} }
} }

View file

@ -5,6 +5,7 @@ const config = {
bracketSpacing: true, bracketSpacing: true,
bracketSameLine: true, bracketSameLine: true,
arrowParens: "always", arrowParens: "always",
plugins: ["prettier-plugin-astro"],
}; };
export default config; export default config;

View file

@ -1,32 +1,34 @@
<script> <script>
function loadCloak() { function loadCloak() {
let localStorageCloak = localStorage.getItem('alu__selectedCloak'); let localStorageCloak = localStorage.getItem("alu__selectedCloak");
if (localStorageCloak) { if (localStorageCloak) {
let parsedCloak = JSON.parse(localStorageCloak); let parsedCloak = JSON.parse(localStorageCloak);
if (parsedCloak) { if (parsedCloak) {
if (parsedCloak.name != "None") { if (parsedCloak.name != "None") {
document.title = parsedCloak.name document.title = parsedCloak.name;
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement; let link = document.querySelector(
if (!link) { "link[rel~='icon']"
link = document.createElement('link'); ) as HTMLLinkElement;
link.rel = 'icon'; if (!link) {
} link = document.createElement("link");
link.href = parsedCloak.icon; link.rel = "icon";
document.getElementsByTagName('head')[0].appendChild(link); }
} link.href = parsedCloak.icon;
} document.getElementsByTagName("head")[0].appendChild(link);
} else {
// Load default cloak
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
if (!link) {
link = document.createElement('link');
link.rel = 'icon';
}
link.href = "/favicon.png";
document.getElementsByTagName('head')[0].appendChild(link);
} }
}
} else {
// Load default cloak
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
if (!link) {
link = document.createElement("link");
link.rel = "icon";
}
link.href = "/favicon.png";
document.getElementsByTagName("head")[0].appendChild(link);
} }
}
loadCloak(); loadCloak();
document.addEventListener("astro:after-swap", loadCloak); document.addEventListener("astro:after-swap", loadCloak);
</script> </script>

View file

@ -1,61 +1,65 @@
--- ---
const { buttonNameDefault, dropdownList, id } = Astro.props; const { buttonNameDefault, dropdownList, id } = Astro.props;
--- ---
<div class="dropdown"> <div class="dropdown">
<button id={id} class="dropdown-toggle" type="button" data-toggle="dropdown"> <button id={id} class="dropdown-toggle" type="button" data-toggle="dropdown">
{buttonNameDefault} {buttonNameDefault}
<span class="caret"></span></button> <span class="caret"></span></button
<ul class="dropdown-menu" id={id + "-menu"}> >
<ul class="dropdown-menu" id={id + "-menu"}>
{ {
dropdownList.map((item: any) => { dropdownList.map((item: any) => {
return <li class="dropdown-item" data-setting={item.value}>{item.name}</li> return (
}) <li class="dropdown-item" data-setting={item.value}>
{item.name}
</li>
);
})
} }
</ul> </ul>
</div> </div>
<style> <style>
.dropdown { .dropdown {
box-shadow: 4px 6px 15px 0px var(--background-color); box-shadow: 4px 6px 15px 0px var(--background-color);
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
position: relative; position: relative;
} }
.dropdown-toggle { .dropdown-toggle {
background-color: var(--accent-color); background-color: var(--accent-color);
border: none; border: none;
color: var(--text-color); color: var(--text-color);
padding: 12px 16px; padding: 12px 16px;
font-size: 16px; font-size: 16px;
cursor: pointer; cursor: pointer;
font-family: 'Varela Round', sans-serif; font-family: "Varela Round", sans-serif;
width: 100%; width: 100%;
border-radius: 10px; border-radius: 10px;
min-width: 140px; min-width: 140px;
height: 50px; height: 50px;
} }
.dropdown-menu { .dropdown-menu {
margin: 0; margin: 0;
list-style: none; list-style: none;
padding: 0; padding: 0;
text-align: center; text-align: center;
max-height: 0px; /* Set max-height to 0 instead of height */ max-height: 0px; /* Set max-height to 0 instead of height */
overflow: hidden; overflow: hidden;
transition: max-height 350ms ease-in-out; /* Use max-height in the transition property */ transition: max-height 350ms ease-in-out; /* Use max-height in the transition property */
border-bottom-left-radius: 10px; border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px; border-bottom-right-radius: 10px;
background-color: var(--dropdown-background-color); background-color: var(--dropdown-background-color);
position: absolute; position: absolute;
width: 100%; width: 100%;
} }
.dropdown-item { .dropdown-item {
border-bottom: 1px solid var(--text-color-accent); border-bottom: 1px solid var(--text-color-accent);
padding: 10px; padding: 10px;
color: var(--text-color); color: var(--text-color);
cursor: pointer; cursor: pointer;
} }
.dropdown-item:nth-last-child(1) { .dropdown-item:nth-last-child(1) {
border-bottom: none; border-bottom: none;
} }
</style> </style>

View file

@ -1,38 +1,36 @@
--- ---
import { getLangFromUrl, useTranslations } from "../i18n/utils";
import { getLangFromUrl, useTranslations } from "../i18n/utils"
import WaveSVG from "./WaveSVG.astro"; import WaveSVG from "./WaveSVG.astro";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
--- ---
<div class="footer"> <div class="footer">
<div class="wave-svg-container"> <div class="wave-svg-container">
<WaveSVG /> <WaveSVG />
</div>
<div class="footer-top">
<div class="footer-title">
<h2>{t("footer.brand")}</h2>
</div> </div>
<div class="footer-top">
<div class="footer-title"> <div class="footer-madeby">
<h2>{t("footer.brand")}</h2> <a href="https://wearr.dev">{t("footer.madeWithLove")}</a>
</div>
<div class="footer-madeby">
<a href="https://wearr.dev">{t("footer.madeWithLove")}</a>
</div>
</div> </div>
<div class="footer-bottom"> </div>
<div class="footer-links"> <div class="footer-bottom">
<a href="https://titaniumnetwork.org">Titanium Network</a> <div class="footer-links">
</div> <a href="https://titaniumnetwork.org">Titanium Network</a>
<div class="footer-copyright">
<p>&copy; {t("footer.aluProject")} 2024</p>
</div>
</div> </div>
<div class="footer-copyright">
<p>&copy; {t("footer.aluProject")} 2024</p>
</div>
</div>
</div> </div>
<style> <style>
.wave-svg-container { .wave-svg-container {
bottom: 0; bottom: 0;
left: 0; left: 0;
position: absolute; position: absolute;
@ -40,9 +38,10 @@ const t = useTranslations(lang);
z-index: -1; z-index: -1;
overflow: hidden; overflow: hidden;
height: 300px; height: 300px;
} filter: brightness(1.5);
}
.footer { .footer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: space-around;
@ -50,18 +49,18 @@ const t = useTranslations(lang);
position: relative; position: relative;
padding-top: 100px; padding-top: 100px;
gap: 50px; gap: 50px;
} }
.footer-top, .footer-bottom { .footer-top,
.footer-bottom {
width: 90%; width: 90%;
margin: 0 auto; margin: 0 auto;
} }
.footer-title { .footer-title {
font-size: 20px; font-size: 20px;
} }
a { a {
color: var(--text-color); color: var(--text-color);
} }
</style>
</style>

View file

@ -3,27 +3,30 @@ const { name, image, slugName } = Astro.props;
--- ---
<div class="game"> <div class="game">
<a href=`/games/${slugName || name}`><img class="game-img" src=`${image}` alt=""></a> <a href=`/games/${slugName || name}`
<p class="game-title">{name}</p> ><img class="game-img" src=`${image}` alt="" /></a
>
<p class="game-title">{name}</p>
</div> </div>
<style> <style>
.game { .game {
border: 2px solid #D8DEE9; border: 2px solid var(--text-color);
padding: 1rem; padding: 1rem;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
} border-radius: 15px;
.game-img { }
.game-img {
width: 128px; width: 128px;
height: 128px; height: 128px;
} }
.game-title { .game-title {
color: var(--text-color); color: var(--text-color);
text-align: center; text-align: center;
max-width: 125px; max-width: 125px;
} }
</style> </style>

View file

@ -1,29 +1,29 @@
--- ---
import { getLangFromUrl, useTranslations } from "../i18n/utils" import { getLangFromUrl, useTranslations } from "../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
--- ---
<div class="top-header"> <div class="top-header">
<div id="title-background" class="title-background"> <div id="title-background" class="title-background">
<div class="left"> <div class="left">
<a href={`/${lang}/`} class="header-item">{t("nav.brand")}</a> <a href={`/${lang}/`} class="header-item">{t("nav.brand")}</a>
</div>
<div class="right">
<a href={`/${lang}/games/`} class="header-item">{t("nav.games")}</a>
<a href={`/${lang}/settings/`} class="header-item">{t("nav.settings")}</a>
</div>
</div> </div>
<div class="right">
<a href={`/${lang}/games/`} class="header-item">{t("nav.games")}</a>
<a href={`/${lang}/settings/`} class="header-item">{t("nav.settings")}</a>
</div>
</div>
</div> </div>
<style> <style>
.top-header { .top-header {
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
transition: 250ms ease-in; transition: 250ms ease-in;
} }
.title-background { .title-background {
background-color: var(--accent-color); background-color: var(--accent-color);
display: flex; display: flex;
align-items: center; align-items: center;
@ -37,28 +37,29 @@
z-index: 10; z-index: 10;
border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
} }
.left, .right { .left,
.right {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 20px; gap: 20px;
} }
.header-item { .header-item {
color: var(--text-color); color: var(--text-color);
text-decoration: none; text-decoration: none;
font-size: 22px; font-size: 22px;
transition: 250ms ease-in-out; transition: 250ms ease-in-out;
} }
.header-item:hover { .header-item:hover {
color: var(--text-color-accent); color: var(--text-color-accent);
} }
@media only screen and (max-width: 1003px) { @media only screen and (max-width: 1003px) {
.title-background { .title-background {
width: 500%; width: 500%;
} }
} }
</style> </style>

View file

@ -1,31 +1,34 @@
--- ---
const { type, inputName, defaultTextContent, height, placeholder } = Astro.props; const { inputName, defaultTextContent, height, placeholder } = Astro.props;
// typescript brainrot
type HTMLInputTypeAttribute = "button" | "checkbox" | "color" | "date" | "datetime-local" | "email" | "file" | "hidden" | "image" | "month" | "number" | "password" | "radio" | "range" | "reset" | "search" | "submit" | "tel" | "text" | "time" | "url" | "week";
interface Props { interface Props {
type?: HTMLInputTypeAttribute; inputName: string;
inputName: string; defaultTextContent?: string;
defaultTextContent?: string; height: string;
height: string; placeholder?: string;
placeholder?: string;
} }
--- ---
<input style={`height: ${height}`} id={inputName + "-input"} placeholder={placeholder || ""} value={defaultTextContent || ""} type={type} /> <input
style={`height: ${height}`}
id={inputName + "-input"}
placeholder={placeholder || ""}
value={defaultTextContent || ""}
type="text"
/>
<style> <style>
input { input {
width: 100%; width: 100%;
border: 2px solid var(--accent-color-brighter); border: 2px solid var(--background-highlight);
border-radius: 10px; border-radius: 10px;
background-color: #1b1b1b; background-color: var(--accent-color);
color: var(--text-color); color: var(--text-color);
transition: .1s ease-in-out; transition: 0.1s ease-in-out;
} }
input:focus { input:focus {
outline: none; outline: none;
border: 2px solid var(--text-color); border: 2px solid var(--text-color);
} }
</style> </style>

View file

@ -1,91 +1,133 @@
--- ---
import Input from "../Input.astro" import Input from "../Input.astro";
const presetCloaks = [
{"cloakTitle": "None", "favicon": "/favicon.png"},
{"cloakTitle": "Google", "favicon": "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://google.com&size=128"},
{"cloakTitle": "Instructure", "favicon": "https://du11hjcvx0uqb.cloudfront.net/dist/images/favicon-e10d657a73.ico"},
{"cloakTitle": "Google Classroom", "favicon": "https://ssl.gstatic.com/classroom/ic_product_classroom_144.png"},
{"cloakTitle": "Classlink", "favicon": "https://cdn.classlink.com/production/launchpad/resources/images/favicon/favicon-32x32.png"},
{"cloakTitle": "Google Drive", "favicon": "https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png"},
{"cloakTitle": "Schoology", "favicon": "https://asset-cdn.schoology.com/sites/all/themes/schoology_theme/favicon.ico"}
]
const presetCloaks = [
{ cloakTitle: "None", favicon: "/favicon.png" },
{
cloakTitle: "Google",
favicon:
"https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://google.com&size=128",
},
{
cloakTitle: "Instructure",
favicon:
"https://du11hjcvx0uqb.cloudfront.net/dist/images/favicon-e10d657a73.ico",
},
{
cloakTitle: "Google Classroom",
favicon: "https://ssl.gstatic.com/classroom/ic_product_classroom_144.png",
},
{
cloakTitle: "Classlink",
favicon:
"https://cdn.classlink.com/production/launchpad/resources/images/favicon/favicon-32x32.png",
},
{
cloakTitle: "Google Drive",
favicon:
"https://ssl.gstatic.com/docs/doclist/images/drive_2022q3_32dp.png",
},
{
cloakTitle: "Schoology",
favicon:
"https://asset-cdn.schoology.com/sites/all/themes/schoology_theme/favicon.ico",
},
];
--- ---
<div class="settings-container"> <div class="settings-container">
<div class="cloak-container"> <div class="cloak-container">
<div id="cloak-list"> <div id="cloak-list">
{presetCloaks.map((cloak: any) => { {
return <div class="cloak-item" data-cloak-name={cloak.cloakTitle} data-cloak-icon={cloak.favicon}><img class="cloak-image" src={cloak.favicon} alt={cloak.cloakTitle}/></div> presetCloaks.map((cloak: any) => {
})} return (
</div> <div
<div class="cloak-custom-override"> class="cloak-item"
<Input inputName="cloak-custom-name" placeholder="Custom Name" height="30px" /> data-cloak-name={cloak.cloakTitle}
<Input inputName="cloak-custom-favicon" placeholder="Custom Favicon" height="30px" /> data-cloak-icon={cloak.favicon}>
<button id="cloak-custom-button">Update Cloak</button> <img
</div> class="cloak-image"
src={cloak.favicon}
alt={cloak.cloakTitle}
/>
</div>
);
})
}
</div> </div>
<div class="cloak-custom-override">
<Input
inputName="cloak-custom-name"
placeholder="Custom Name"
height="30px"
/>
<Input
inputName="cloak-custom-favicon"
placeholder="Custom Favicon"
height="30px"
/>
<button id="cloak-custom-button">Update Cloak</button>
</div>
</div>
</div> </div>
<style> <style>
.cloak-container { .cloak-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
} }
#cloak-list { #cloak-list {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
gap: 15px; gap: 15px;
} }
.cloak-item { .cloak-item {
width: 75px; width: 75px;
height: 75px; height: 75px;
border-radius: 50%; border-radius: 50%;
padding: 15px; padding: 15px;
background-color: var(--dropdown-background-color); background-color: var(--dropdown-background-color);
border: 3px solid var(--accent-color); border: 3px solid var(--accent-color);
cursor: pointer; cursor: pointer;
transition: 250ms ease-in-out; transition: 250ms ease-in-out;
} }
.cloak-item.selected { .cloak-item.selected {
/* Make border color brighter */ /* Make border color brighter */
border: 3px solid var(--accent-color-brighter) border: 3px solid var(--accent-color-brighter);
} }
.cloak-image { .cloak-image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.cloak-custom-override { .cloak-custom-override {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
width: 50%; width: 50%;
} }
#cloak-custom-button { #cloak-custom-button {
margin-top: 6px; margin-top: 6px;
height: 25px; height: 25px;
border-radius: 10px; border-radius: 10px;
background-color: var(--accent-color-brighter); background-color: var(--accent-color-brighter);
border: 0; border: 0;
color: var(--text-color); color: var(--text-color);
cursor: pointer; cursor: pointer;
} }
.cloak-custom-input { .cloak-custom-input {
height: 40px; height: 40px;
width: 100%; width: 100%;
border: 2px solid var(--accent-color-brighter); border: 2px solid var(--accent-color-brighter);
border-radius: 10px; border-radius: 10px;
background-color: #1b1b1b; background-color: #1b1b1b;
color: var(--text-color); color: var(--text-color);
transition: .1s ease-in-out; transition: 0.1s ease-in-out;
} }
.cloak-custom-input:focus { .cloak-custom-input:focus {
outline: none; outline: none;
border: 2px solid var(--text-color); border: 2px solid var(--text-color);
} }
</style> </style>

View file

@ -1,27 +1,35 @@
--- ---
import { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
--- ---
<div class="settings-container"> <div class="settings-container">
<div class="credits-container">
<div class="credits-container"> <p class="credit-item">
<p class="credit-item">{t("ultraviolet")} - <a href="https://titaniumnetwork.org/">Titanium Network</a></p> {t("ultraviolet")} - <a href="https://titaniumnetwork.org/"
<p class="credit-item">{t("settings.credits.japaneseTranslations")} - <a href="https://wearr.dev">wearr</a></p> >Titanium Network</a
<p class="credit-item">{t("settings.credits.mochaandmacchiatothemes")} - <a href="">Catppuccin</a></p> >
</div> </p>
<p class="credit-item">
{t("settings.credits.japaneseTranslations")} - <a href="https://wearr.dev"
>wearr</a
>
</p>
<p class="credit-item">
{t("settings.credits.mochaandmacchiatothemes")} - <a href="">Catppuccin</a
>
</p>
</div>
</div> </div>
<style> <style>
.credit-item { .credit-item {
color: var(--text-color); color: var(--text-color);
font-size: 18px; font-size: 18px;
} }
.credit-item > a { .credit-item > a {
color: var(--text-color); color: var(--text-color);
font-weight: bold; font-weight: bold;
} }
</style> </style>

View file

@ -1,30 +1,40 @@
--- ---
import Dropdown from "../Dropdown.astro" import Dropdown from "../Dropdown.astro";
import { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
const themeList = [ const themeList = [
{"name": t("settings.customization.theme.Alu"), "value": "alu"}, { name: t("settings.customization.theme.Alu"), value: "alu" },
{"name": t("settings.customization.theme.Macchiato"), "value": "macchiato"}, { name: t("settings.customization.theme.Macchiato"), value: "macchiato" },
{"name": t("settings.customization.theme.Mocha"), "value": "mocha"}, { name: t("settings.customization.theme.Mocha"), value: "mocha" },
{"name": "Rosé Pine", "value": "rose_pine"} { name: "Rosé Pine", value: "rose_pine" },
] ];
const languageList = [ const languageList = [
{"name": "English", "value": "en"}, { name: "English", value: "en" },
{"name": "日本語", "value": "jp"} { name: "日本語", value: "jp" },
] ];
--- ---
<div class="settings-container"> <div class="settings-container">
<div class="setting__theme"> <div class="setting__theme">
<label class="setting-label">{t("settings.customization.theme")}</label> <label class="setting-label">{t("settings.customization.theme")}</label>
<Dropdown buttonNameDefault="Alu" dropdownList={themeList}, id="dropdown__selected-theme" /> <Dropdown
</div> buttonNameDefault="Alu"
<div class="setting__language"> dropdownList={themeList}
<label class="setting-label">{t("settings.customization.language")}</label> ,
<Dropdown buttonNameDefault="English" dropdownList={languageList}, id="dropdown__selected-language" /> id="dropdown__selected-theme"
</div> />
</div> </div>
<div class="setting__language">
<label class="setting-label">{t("settings.customization.language")}</label>
<Dropdown
buttonNameDefault="English"
dropdownList={languageList}
,
id="dropdown__selected-language"
/>
</div>
</div>

View file

@ -1,51 +1,74 @@
--- ---
import Input from "../Input.astro" import Input from "../Input.astro";
import Dropdown from "../Dropdown.astro" import Dropdown from "../Dropdown.astro";
import { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
const proxyList = [ const proxyList = [
{ "name": t("settings.proxy.auto"), "value": "auto" }, { name: t("settings.proxy.auto"), value: "auto" },
{ "name": t("ultraviolet"), "value": "ultraviolet" }, { name: t("ultraviolet"), value: "ultraviolet" },
{ "name": "Rammerhead", "value": "rammerhead" }, { name: "Rammerhead", value: "rammerhead" },
{ "name": "Dynamic", "value": "dynamic" } { name: "Dynamic", value: "dynamic" },
] ];
const searchEngineList = [ const searchEngineList = [
{ "name": "Google", "value": "google" }, { name: "Google", value: "google" },
{ "name": "Bing", "value": "bing" }, { name: "Bing", value: "bing" },
{ "name": "Brave", "value": "brave" }, { name: "Brave", value: "brave" },
{ "name": "Searx", "value": "searx" } { name: "Searx", value: "searx" },
] ];
const openPageWith = [ const openPageWith = [
{ "name": t("settings.proxy.openPageWith.embed"), "value": "embed" }, { name: t("settings.proxy.openPageWith.embed"), value: "embed" },
{ "name": "About:Blank", "value": "about:blank" }, { name: "About:Blank", value: "about:blank" },
{ "name": t("settings.proxy.openPageWith.newTab"), "value": "newTab" }, { name: t("settings.proxy.openPageWith.newTab"), value: "newTab" },
] ];
--- ---
<div class="settings-container"> <div class="settings-container">
<div class="setting__selected-proxy"> <div class="setting__selected-proxy">
<label class="setting-label">{t("settings.proxy.selectedProxy")}</label> <label class="setting-label">{t("settings.proxy.selectedProxy")}</label>
<Dropdown buttonNameDefault="Ultraviolet" dropdownList={proxyList}, id="dropdown__selected-proxy" /> <Dropdown
</div> buttonNameDefault="Ultraviolet"
<div class="setting__search-engine"> dropdownList={proxyList}
<label class="setting-label">{t("settings.proxy.searchEngine")}</label> ,
<Dropdown buttonNameDefault="Google" dropdownList={searchEngineList}, id="dropdown__search-engine" /> id="dropdown__selected-proxy"
</div> />
<div class="setting__open_with"> </div>
<label class="setting-label">{t("settings.proxy.openPageWith")}</label> <div class="setting__search-engine">
<Dropdown buttonNameDefault={t("settings.proxy.openPageWith.embed")} dropdownList={openPageWith}, id="dropdown__open-with" /> <label class="setting-label">{t("settings.proxy.searchEngine")}</label>
</div> <Dropdown
<div class="setting__bare-url"> buttonNameDefault="Google"
<label class="setting-label" for="bare-url-input">{t("settings.proxy.bareURL")}</label> dropdownList={searchEngineList}
<Input inputName="bare-url" height="50px" /> ,
</div> id="dropdown__search-engine"
/>
</div>
<div class="setting__open_with">
<label class="setting-label">{t("settings.proxy.openPageWith")}</label>
<Dropdown
buttonNameDefault={t("settings.proxy.openPageWith.embed")}
dropdownList={openPageWith}
,
id="dropdown__open-with"
/>
</div>
<div class="setting__bare-url">
<label class="setting-label" for="bare-url-input"
>{t("settings.proxy.bareURL")}</label
>
<Input inputName="bare-url" height="50px" />
</div>
</div> </div>
<div class="setting__searxng-url"> <div class="setting__searxng-url">
<label for="searxng-url-input" class="setting-label">{t("settings.proxy.searxngURL")}</label> <label for="searxng-url-input" class="setting-label"
<Input height="50px" inputName="searxng-url" defaultTextContent="https://searxng.site/" /> >{t("settings.proxy.searxngURL")}</label
</div> >
<Input
height="50px"
inputName="searxng-url"
defaultTextContent="https://searxng.site/"
/>
</div>

View file

@ -2,7 +2,7 @@
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 { 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 lang = getLangFromUrl(Astro.url);
@ -10,446 +10,562 @@ const t = useTranslations(lang);
--- ---
<div class="content-hidden"> <div class="content-hidden">
<div id="content-setting-tab-proxy"> <div id="content-setting-tab-proxy">
<h1 class="content-setting-header">{t("settings.proxy")}</h1> <h1 class="content-setting-header">{t("settings.proxy")}</h1>
<ProxyTab /> <ProxyTab />
</div>
</div> <div id="content-setting-tab-customization">
<div id="content-setting-tab-customization"> <h1 class="content-setting-header">{t("settings.customization")}</h1>
<h1 class="content-setting-header">{t("settings.customization")}</h1> <CustomizationTab />
<CustomizationTab /> </div>
</div> <div id="content-setting-tab-cloaking">
<div id="content-setting-tab-cloaking"> <h1 class="content-setting-header">{t("settings.cloaking")}</h1>
<h1 class="content-setting-header">{t("settings.cloaking")}</h1> <p class="content-setting-subtext">{t("settings.cloaking.subtext")}</p>
<p class="content-setting-subtext">{t("settings.cloaking.subtext")}</p> <CloakingTab />
<CloakingTab /> </div>
</div> <div id="content-setting-tab-credits">
<div id="content-setting-tab-credits"> <h1 class="content-setting-header">{t("settings.credits")}</h1>
<h1 class="content-setting-header">{t("settings.credits")}</h1> <CreditsTab />
<CreditsTab /> </div>
</div>
</div> </div>
<div class="popup"> <div class="popup">
<div class="tabs"> <div class="tabs">
<input type="radio" id="setting-tab-proxy" class="setting-tab" name="tab" checked="true"> <input
<label for="setting-tab-proxy">Proxy</label> type="radio"
<input type="radio" id="setting-tab-customization" class="setting-tab" name="tab"> id="setting-tab-proxy"
<label for="setting-tab-customization">Customization</label> class="setting-tab"
<input type="radio" id="setting-tab-cloaking" class="setting-tab" name="tab"> name="tab"
<label for="setting-tab-cloaking">Cloaking</label> checked="true"
<input type="radio" id="setting-tab-credits" class="setting-tab" name="tab"> />
<label for="setting-tab-credits">Credits</label> <label for="setting-tab-proxy">Proxy</label>
<div class="marker"> <input
<div id="top"></div> type="radio"
<div id="bottom"></div> id="setting-tab-customization"
</div> class="setting-tab"
</div> name="tab"
<div id="current-content"> />
<label for="setting-tab-customization">Customization</label>
<input
type="radio"
id="setting-tab-cloaking"
class="setting-tab"
name="tab"
/>
<label for="setting-tab-cloaking">Cloaking</label>
<input
type="radio"
id="setting-tab-credits"
class="setting-tab"
name="tab"
/>
<label for="setting-tab-credits">Credits</label>
<div class="marker">
<div id="top"></div>
<div id="bottom"></div>
</div> </div>
</div> </div>
<script is:inline> <div id="current-content"></div>
document.addEventListener("astro:before-swap", () => { </div>
window.currentlySelectedTab = "" <script is:inline>
document.removeEventListener('setting-tabChange', determineListener) document.addEventListener("astro:before-swap", () => {
}) window.currentlySelectedTab = "";
window.currentlySelectedTab; document.removeEventListener("setting-tabChange", determineListener);
window.loadedContentStorage = {} });
window.currentlySelectedTab;
window.loadedContentStorage = {};
Array.from(document.getElementsByClassName('setting-tab')).forEach((tab)=>{ Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
let contentToLoad = document.getElementById('content-' + tab.id) let 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();
} }
tab.addEventListener('click', (event) => { tab.addEventListener("click", (event) => {
loadContent(event.target.id) loadContent(event.target.id);
}) });
}) });
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') let currentContent = document.getElementById("current-content");
if (currentContent) { if (currentContent) {
currentContent.style.opacity = '0' currentContent.style.opacity = "0";
setTimeout(() => { setTimeout(() => {
currentContent.innerHTML = window.loadedContentStorage[tabID] currentContent.innerHTML = window.loadedContentStorage[tabID];
currentContent.style.opacity = '1' currentContent.style.opacity = "1";
document.dispatchEvent(new CustomEvent('setting-tabChange', {detail: tabID })) document.dispatchEvent(
document.dispatchEvent(new CustomEvent('setting-tabLoad', {detail: tabID })) new CustomEvent("setting-tabChange", { detail: tabID })
}, 250); );
document.dispatchEvent(
new CustomEvent("setting-tabLoad", { detail: tabID })
);
}, 250);
}
}
function addDropdownListener() {
let dropdown_toggles = document.getElementsByClassName("dropdown-toggle");
Array.from(dropdown_toggles).forEach((toggle) => {
toggle.addEventListener("click", () => {
let dropdown = document.getElementById(toggle.id + "-menu");
if (dropdown) {
if (
dropdown.style.maxHeight == "0px" ||
dropdown.style.maxHeight == ""
) {
dropdown.style.maxHeight = dropdown.scrollHeight + "px";
toggle.style.borderRadius = "10px 10px 0 0";
} else {
dropdown.style.maxHeight = "0px";
setTimeout(() => {
toggle.style.borderRadius = "10px";
}, 300);
}
} }
} });
});
}
function addDropdownListener() { function determineListener(event) {
let dropdown_toggles = document.getElementsByClassName('dropdown-toggle') if (event.detail == "setting-tab-proxy") {
Array.from(dropdown_toggles).forEach((toggle) => { addDropdownListener();
toggle.addEventListener('click', () => { } else if (event.detail == "setting-tab-customization") {
let dropdown = document.getElementById(toggle.id + "-menu") addDropdownListener();
if (dropdown) {
if (dropdown.style.maxHeight == '0px' || dropdown.style.maxHeight == '') {
dropdown.style.maxHeight = dropdown.scrollHeight + 'px';
toggle.style.borderRadius = '10px 10px 0 0';
} else {
dropdown.style.maxHeight = '0px';
setTimeout(() => {
toggle.style.borderRadius = '10px';
}, 300);
}
}
})
})
} }
}
function determineListener(event) { function closeDropdown(dropdownID) {
if (event.detail == "setting-tab-proxy") { let dropdown = document.getElementById(dropdownID);
addDropdownListener() if (dropdown) {
} else if (event.detail == "setting-tab-customization") { dropdown.style.maxHeight = "0px";
addDropdownListener() setTimeout(() => {
let dropdown_toggle = document.getElementById(
dropdownID.replace("-menu", "")
);
dropdown_toggle.style.borderRadius = "10px";
}, 300);
}
}
function getLocalStorageValue(localStorageItem, dropdownID) {
// I was kinda dumb for not doing this earlier.
let dropdown = document.getElementById(dropdownID);
let dropdownMenu = document.getElementById(dropdownID + "-menu");
if (dropdown && dropdownMenu) {
// Now we find the child that matches localStorageItem.value.
let dropdownItem = Array.from(dropdownMenu.children).find((item) => {
return (
JSON.parse(localStorage.getItem(localStorageItem)).value ==
item.dataset.setting
);
});
// Now set the inner text to the name in the dropdownItem.
return dropdownItem.innerText;
}
}
function applySavedLocalStorage(localStorageItem, dropdownID) {
if (localStorage.getItem(localStorageItem)) {
let dropdown_toggle = document.getElementById(dropdownID);
if (dropdown_toggle) {
dropdown_toggle.innerText = getLocalStorageValue(
localStorageItem,
dropdownID
);
} }
} }
}
function closeDropdown(dropdownID) { function applyDropdownEventListeners(
let dropdown = document.getElementById(dropdownID) item,
if (dropdown) { dropdownID,
dropdown.style.maxHeight = '0px'; localStorageItem,
setTimeout(() => { optionalCallback
let dropdown_toggle = document.getElementById(dropdownID.replace('-menu', '')); ) {
dropdown_toggle.style.borderRadius = '10px'; Array.from(item.children).forEach((item) => {
}, 300); item.addEventListener("click", () => {
} let localStorageItemContent = {
} name: item.innerText,
value: item.dataset.setting,
function getLocalStorageValue(localStorageItem, dropdownID) { };
// I was kinda dumb for not doing this earlier. localStorage.setItem(
let dropdown = document.getElementById(dropdownID); localStorageItem,
let dropdownMenu = document.getElementById(dropdownID + "-menu"); JSON.stringify(localStorageItemContent)
);
if (dropdown && dropdownMenu) { applySavedLocalStorage(localStorageItem, dropdownID);
// Now we find the child that matches localStorageItem.value. closeDropdown(item.parentElement.id);
let dropdownItem = Array.from(dropdownMenu.children).find((item) => { if (typeof optionalCallback == "function") {
return JSON.parse(localStorage.getItem(localStorageItem)).value == item.dataset.setting optionalCallback();
})
// Now set the inner text to the name in the dropdownItem.
return dropdownItem.innerText
}
}
function applySavedLocalStorage(localStorageItem, dropdownID) {
if (localStorage.getItem(localStorageItem)) {
let dropdown_toggle = document.getElementById(dropdownID);
if (dropdown_toggle) {
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID)
} }
} });
} });
// Array.from(item.children).forEach((item) => {
// item.addEventListener('click', () => {
// localStorage.setItem(localStorageItem, item.dataset.setting)
// applySavedLocalStorage(localStorageItem, dropdownID)
// closeDropdown(item.parentElement.id);
function applyDropdownEventListeners(item, dropdownID, localStorageItem, optionalCallback) { // if (typeof optionalCallback == "function") {
Array.from(item.children).forEach((item) => { // optionalCallback();
item.addEventListener('click', () => { // }
let localStorageItemContent = { // })
"name": item.innerText, // })
"value": item.dataset.setting, }
}
localStorage.setItem(localStorageItem, JSON.stringify(localStorageItemContent))
applySavedLocalStorage(localStorageItem, dropdownID)
closeDropdown(item.parentElement.id);
if (typeof optionalCallback == "function") {
optionalCallback();
}
})
})
// Array.from(item.children).forEach((item) => {
// item.addEventListener('click', () => {
// localStorage.setItem(localStorageItem, item.dataset.setting)
// applySavedLocalStorage(localStorageItem, dropdownID)
// closeDropdown(item.parentElement.id);
// if (typeof optionalCallback == "function") { function applyInputListeners(item, localStorageItem) {
// optionalCallback(); item.addEventListener("input", () => {
// } localStorage.setItem(localStorageItem, item.value);
// }) });
// }) }
}
function applyInputListeners(item, localStorageItem) { document.addEventListener("setting-tabChange", determineListener);
item.addEventListener('input', () => {
localStorage.setItem(localStorageItem, item.value)
})
}
document.addEventListener('setting-tabChange', determineListener) loadContent("setting-tab-proxy");
loadContent('setting-tab-proxy') function setupCustomizationSettings() {
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
applySavedLocalStorage(
"alu__selectedLanguage",
"dropdown__selected-language"
);
let themeDropdown = document.getElementById(
"dropdown__selected-theme-menu"
);
let languageDropdown = document.getElementById(
"dropdown__selected-language-menu"
);
applyDropdownEventListeners(
themeDropdown,
"dropdown__selected-theme",
"alu__selectedTheme",
changeTheme
);
applyDropdownEventListeners(
languageDropdown,
"dropdown__selected-language",
"alu__selectedLanguage",
navigateToNewLangaugePage
);
}
function setupCustomizationSettings() { function setupCloakingSettings() {
applySavedLocalStorage('alu__selectedTheme', 'dropdown__selected-theme'); Array.from(document.getElementById("cloak-list").children).forEach(
applySavedLocalStorage('alu__selectedLanguage', 'dropdown__selected-language'); (cloak) => {
let themeDropdown = document.getElementById('dropdown__selected-theme-menu') cloak.addEventListener("click", () => {
let languageDropdown = document.getElementById('dropdown__selected-language-menu') let cloakName = cloak.dataset.cloakName;
applyDropdownEventListeners(themeDropdown, 'dropdown__selected-theme', 'alu__selectedTheme', changeTheme); let cloakIcon = cloak.dataset.cloakIcon;
applyDropdownEventListeners(languageDropdown, 'dropdown__selected-language', 'alu__selectedLanguage', navigateToNewLangaugePage);
}
function setupCloakingSettings() {
Array.from(document.getElementById('cloak-list').children).forEach((cloak) => {
cloak.addEventListener('click', () => {
let cloakName = cloak.dataset.cloakName
let cloakIcon = cloak.dataset.cloakIcon
let localStorageItem = { let localStorageItem = {
"name": cloakName, name: cloakName,
"icon": cloakIcon, icon: cloakIcon,
"isCustom": false, isCustom: false,
} };
localStorage.setItem('alu__selectedCloak', JSON.stringify(localStorageItem)) localStorage.setItem(
"alu__selectedCloak",
JSON.stringify(localStorageItem)
);
if (cloakName == "None") { if (cloakName == "None") {
localStorage.removeItem('alu__selectedCloak') localStorage.removeItem("alu__selectedCloak");
cloakName = "Settings | Alu" cloakName = "Settings | Alu";
cloakIcon = "/favicon.png" cloakIcon = "/favicon.png";
} }
let link = document.querySelector("link[rel~='icon']"); let link = document.querySelector("link[rel~='icon']");
if (!link) { if (!link) {
link = document.createElement('link'); link = document.createElement("link");
link.rel = 'icon'; link.rel = "icon";
document.head.appendChild(link); document.head.appendChild(link);
} }
link.href = cloakIcon; link.href = cloakIcon;
document.title = cloakName; document.title = cloakName;
if (!cloak.classList.contains("selected")) { if (!cloak.classList.contains("selected")) {
Array.from(document.getElementById('cloak-list').children).forEach((cloak2) => { Array.from(document.getElementById("cloak-list").children).forEach(
cloak2.classList.remove('selected') (cloak2) => {
}) cloak2.classList.remove("selected");
cloak.classList.add('selected') }
} );
}) cloak.classList.add("selected");
}) }
});
let customNameInput = document.getElementById('cloak-custom-name-input')
let customFaviconInput = document.getElementById('cloak-custom-favicon-input')
if (localStorage.getItem('alu__selectedCloak')) {
let selectedCloak = JSON.parse(localStorage.getItem('alu__selectedCloak'))
if (selectedCloak.isCustom) {
customNameInput.value = selectedCloak.name
customFaviconInput.value = selectedCloak.icon
}
} }
);
document.getElementById('cloak-custom-button').addEventListener("click", () => { let customNameInput = document.getElementById("cloak-custom-name-input");
let cloakName = document.getElementById('cloak-custom-name-input').value let customFaviconInput = document.getElementById(
let cloakIcon = document.getElementById('cloak-custom-favicon-input').value "cloak-custom-favicon-input"
);
if (localStorage.getItem("alu__selectedCloak")) {
let selectedCloak = JSON.parse(
localStorage.getItem("alu__selectedCloak")
);
if (selectedCloak.isCustom) {
customNameInput.value = selectedCloak.name;
customFaviconInput.value = selectedCloak.icon;
}
}
document
.getElementById("cloak-custom-button")
.addEventListener("click", () => {
let cloakName = document.getElementById(
"cloak-custom-name-input"
).value;
let cloakIcon = document.getElementById(
"cloak-custom-favicon-input"
).value;
let localStorageItem = { let localStorageItem = {
"name": cloakName, name: cloakName,
"icon": cloakIcon, icon: cloakIcon,
"isCustom": true, isCustom: true,
} };
localStorage.setItem('alu__selectedCloak', JSON.stringify(localStorageItem)) localStorage.setItem(
"alu__selectedCloak",
JSON.stringify(localStorageItem)
);
if (cloakName == "None") { if (cloakName == "None") {
localStorage.removeItem('alu__selectedCloak') localStorage.removeItem("alu__selectedCloak");
cloakName = "Settings | Alu" cloakName = "Settings | Alu";
cloakIcon = "/favicon.png" cloakIcon = "/favicon.png";
} }
let link = document.querySelector("link[rel~='icon']"); let link = document.querySelector("link[rel~='icon']");
if (!link) { if (!link) {
link = document.createElement('link'); link = document.createElement("link");
link.rel = 'icon'; link.rel = "icon";
document.head.appendChild(link); document.head.appendChild(link);
} }
link.href = cloakIcon; link.href = cloakIcon;
document.title = cloakName; document.title = cloakName;
}) });
} }
function changeTheme() { function changeTheme() {
let theme = JSON.parse(localStorage.getItem('alu__selectedTheme')).value let 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'); let footer = document.getElementById("footer");
if (footer) { if (footer) {
footer.dataset.theme = theme.toLowerCase(); footer.dataset.theme = theme.toLowerCase();
}
} }
} }
}
function setupSettings(event) { function setupSettings(event) {
if (event.detail == "setting-tab-proxy") { if (event.detail == "setting-tab-proxy") {
applySavedLocalStorage('alu__selectedProxy', 'dropdown__selected-proxy'); applySavedLocalStorage("alu__selectedProxy", "dropdown__selected-proxy");
applySavedLocalStorage('alu__search_engine', 'dropdown__search-engine'); applySavedLocalStorage("alu__search_engine", "dropdown__search-engine");
applySavedLocalStorage("alu__selectedOpenWith", 'dropdown__open-with'); applySavedLocalStorage("alu__selectedOpenWith", "dropdown__open-with");
let selectedProxyDropdown = document.getElementById('dropdown__selected-proxy-menu') let selectedProxyDropdown = document.getElementById(
let searchEngineDropdown = document.getElementById('dropdown__search-engine-menu') "dropdown__selected-proxy-menu"
let openWithDropdown = document.getElementById('dropdown__open-with-menu') );
let bareUrlInput = document.getElementById('bare-url-input') let searchEngineDropdown = document.getElementById(
let searxngUrlInput = document.getElementById('searxng-url-input') "dropdown__search-engine-menu"
let savedSearxngUrl = localStorage.getItem("alu__searxngUrl") );
if (savedSearxngUrl != undefined) { let openWithDropdown = document.getElementById(
if (savedSearxngUrl == "") localStorage.setItem("alu__searxngUrl", "https://searxng.site/") "dropdown__open-with-menu"
searxngUrlInput.value = localStorage.getItem("alu__searxngUrl") );
} let bareUrlInput = document.getElementById("bare-url-input");
// Proxy settings let searxngUrlInput = document.getElementById("searxng-url-input");
applyInputListeners(bareUrlInput, 'alu__bareUrl') let savedSearxngUrl = localStorage.getItem("alu__searxngUrl");
applyInputListeners(searxngUrlInput, 'alu__searxngUrl') if (savedSearxngUrl != undefined) {
applyDropdownEventListeners(searchEngineDropdown, 'dropdown__search-engine', 'alu__search_engine', checkSearxng); if (savedSearxngUrl == "")
applyDropdownEventListeners(selectedProxyDropdown, 'dropdown__selected-proxy', 'alu__selectedProxy'); localStorage.setItem("alu__searxngUrl", "https://searxng.site/");
applyDropdownEventListeners(openWithDropdown, 'dropdown__open-with', 'alu__selectedOpenWith'); searxngUrlInput.value = localStorage.getItem("alu__searxngUrl");
if (localStorage.getItem('bareUrl')) { }
bareUrlInput.value = localStorage.getItem('bareUrl') // Proxy settings
} else { applyInputListeners(bareUrlInput, "alu__bareUrl");
bareUrlInput.value = '/bare/' applyInputListeners(searxngUrlInput, "alu__searxngUrl");
} applyDropdownEventListeners(
checkSearxng(); searchEngineDropdown,
} else if (event.detail == "setting-tab-customization") { "dropdown__search-engine",
setupCustomizationSettings(); "alu__search_engine",
} else if (event.detail == "setting-tab-cloaking") { checkSearxng
setupCloakingSettings(); );
} applyDropdownEventListeners(
selectedProxyDropdown,
"dropdown__selected-proxy",
"alu__selectedProxy"
);
applyDropdownEventListeners(
openWithDropdown,
"dropdown__open-with",
"alu__selectedOpenWith"
);
if (localStorage.getItem("bareUrl")) {
bareUrlInput.value = localStorage.getItem("bareUrl");
} else {
bareUrlInput.value = "/bare/";
}
checkSearxng();
} else if (event.detail == "setting-tab-customization") {
setupCustomizationSettings();
} else if (event.detail == "setting-tab-cloaking") {
setupCloakingSettings();
} }
}
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.
if (localStorage.getItem("alu__search_engine")) { if (localStorage.getItem("alu__search_engine")) {
if (JSON.parse(localStorage.getItem("alu__search_engine")).value.toLowerCase() == "searx") { if (
document.getElementsByClassName('setting__searxng-url')[0].style.opacity = '1' JSON.parse(
} else { localStorage.getItem("alu__search_engine")
document.getElementsByClassName('setting__searxng-url')[0].style.opacity = '0' ).value.toLowerCase() == "searx"
} ) {
document.getElementsByClassName(
"setting__searxng-url"
)[0].style.opacity = "1";
} else {
document.getElementsByClassName(
"setting__searxng-url"
)[0].style.opacity = "0";
} }
} }
}
document.addEventListener('setting-tabLoad', setupSettings) document.addEventListener("setting-tabLoad", setupSettings);
function navigateToNewLangaugePage() { function navigateToNewLangaugePage() {
let value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value let value = JSON.parse(localStorage.getItem("alu__selectedLanguage")).value;
let currentLanguage = window.location.pathname.split("/")[1] let 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;
switch (value) { switch (value) {
case "en": case "en":
window.location.href = "/en/settings/" window.location.href = "/en/settings/";
break; break;
case "jp": case "jp":
window.location.href = "/jp/settings/" window.location.href = "/jp/settings/";
break; break;
}
} }
}
</script> </script>
<style is:global> <style is:global>
.content-hidden { .content-hidden {
display: none; display: none;
} }
#current-content { #current-content {
transition: opacity 250ms ease-in-out; transition: opacity 250ms ease-in-out;
margin-left: 20px; margin-left: 20px;
} }
.settings-container { .settings-container {
display: flex; display: flex;
gap: 20px; gap: 20px;
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
.content-setting-header { .content-setting-header {
color: var(--text-color); color: var(--text-color);
font-weight: 400; font-weight: 400;
} }
.content-setting-subtext { .content-setting-subtext {
font-size: 20px; font-size: 20px;
color: var(--text-color-accent); color: var(--text-color-accent);
} }
.setting-label { .setting-label {
color: var(--text-color); color: var(--text-color);
font-size: 18px; font-size: 18px;
font-weight: 400; font-weight: 400;
/* annoying stuff with label elements. */ /* annoying stuff with label elements. */
display: block; display: block;
opacity: 1.0; opacity: 1;
margin-block: 1em; margin-block: 1em;
margin-inline: 0; margin-inline: 0;
user-select: none; user-select: none;
width: 100%; width: 100%;
cursor: auto; cursor: auto;
} }
.setting__searxng-url { .setting__searxng-url {
margin-top: 10px; margin-top: 10px;
opacity: 0; opacity: 0;
transition: opacity 250ms ease-in-out; transition: opacity 250ms ease-in-out;
} }
label { label {
font-size: 24px; font-size: 24px;
font-weight: 700; font-weight: 700;
cursor: pointer; cursor: pointer;
color: #d8d8d8; color: #d8d8d8;
opacity: .6; opacity: 0.6;
transition: opacity .4s ease-in-out; transition: opacity 0.4s ease-in-out;
display: block; display: block;
width: calc(100% - 48px) ; width: calc(100% - 48px);
text-align: right; text-align: right;
z-index: 100; z-index: 100;
user-select: none; user-select: none;
text-align: start; text-align: start;
margin-left: 20px; margin-left: 20px;
} }
input[type="radio"]{ input[type="radio"] {
display: none; display: none;
width: 0; width: 0;
} }
label:hover, input[type="radio"]:checked+label { label:hover,
opacity: 1; input[type="radio"]:checked + label {
} opacity: 1;
.popup{ }
width: 98%; .popup {
height: 80%; width: 98%;
margin: 0 auto; height: 80%;
min-height: 400px; margin: 0 auto;
max-height: 400px; min-height: 400px;
border-radius: 48px; max-height: 400px;
box-sizing: border-box; border-radius: 48px;
background-color: var(--background-color); box-sizing: border-box;
overflow: hidden; background-color: var(--background-color);
display: flex; overflow: hidden;
align-self: center; display: flex;
} align-self: center;
.tabs{ }
width: 100%; .tabs {
max-width: 240px; width: 100%;
height: 100%; max-width: 240px;
display: flex; height: 100%;
flex-direction: column; display: flex;
justify-content: space-around; flex-direction: column;
position: relative; justify-content: space-around;
gap: 25px position: relative;
} gap: 25px;
.marker{ }
position: absolute; .marker {
width: 100%; position: absolute;
height: 200%; width: 100%;
display: flex; height: 200%;
flex-direction: column; display: flex;
top: calc(-100% ); flex-direction: column;
left: 0; top: calc(-100%);
transition: transform .2s ease-in-out; left: 0;
background-color: var(--accent-color); transition: transform 0.2s ease-in-out;
} background-color: var(--accent-color);
.marker #bottom, .marker #top{ }
background-color: var(--background-highlight); .marker #bottom,
} .marker #top {
.marker #top{ background-color: var(--background-highlight);
height: calc(50%); }
margin-bottom: auto; .marker #top {
border-radius: 0 0 32px 0; height: calc(50%);
} margin-bottom: auto;
.marker #bottom{ border-radius: 0 0 32px 0;
height: calc(50% - 72px); }
border-radius: 0 32px 0 0; .marker #bottom {
} height: calc(50% - 72px);
#setting-tab-proxy:checked ~ .marker{transform: translateY(0%)} border-radius: 0 32px 0 0;
#setting-tab-customization:checked ~ .marker{transform: translateY(13.5%)} }
#setting-tab-cloaking:checked ~ .marker{transform: translateY(27%)} #setting-tab-proxy:checked ~ .marker {
#setting-tab-credits:checked ~ .marker{transform: translateY(41%)} transform: translateY(0%);
</style> }
#setting-tab-customization:checked ~ .marker {
transform: translateY(13.5%);
}
#setting-tab-cloaking:checked ~ .marker {
transform: translateY(27%);
}
#setting-tab-credits:checked ~ .marker {
transform: translateY(41%);
}
</style>

View file

@ -3,159 +3,193 @@ const { inputID } = Astro.props;
--- ---
<label class="switch"> <label class="switch">
<input id={inputID} checked="" type="checkbox"> <input id={inputID} checked="" type="checkbox" />
<div class="slider"> <div class="slider">
<div class="circle"> <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"> <svg
<g> class="cross"
<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> xml:space="preserve"
</g> style="enable-background:new 0 0 512 512"
</svg> viewBox="0 0 365.696 365.696"
<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"> y="0"
<g> x="0"
<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> height="6"
</g> width="6"
</svg> xmlns:xlink="http://www.w3.org/1999/xlink"
</div> 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>
</div>
</label> </label>
<style> <style>
.switch { .switch {
--switch-width: 46px; --switch-width: 46px;
--switch-height: 24px; --switch-height: 24px;
--switch-bg: rgb(131, 131, 131); --switch-bg: rgb(131, 131, 131);
--switch-checked-bg: rgb(0, 218, 80); --switch-checked-bg: rgb(0, 218, 80);
--switch-offset: calc((var(--switch-height) - var(--circle-diameter)) / 2); --switch-offset: calc((var(--switch-height) - var(--circle-diameter)) / 2);
--switch-transition: all .2s cubic-bezier(0.27, 0.2, 0.25, 1.51); --switch-transition: all 0.2s cubic-bezier(0.27, 0.2, 0.25, 1.51);
--circle-diameter: 18px; --circle-diameter: 18px;
--circle-bg: #fff; --circle-bg: #fff;
--circle-shadow: 1px 1px 2px rgba(146, 146, 146, 0.45); --circle-shadow: 1px 1px 2px rgba(146, 146, 146, 0.45);
--circle-checked-shadow: -1px 1px 2px rgba(163, 163, 163, 0.45); --circle-checked-shadow: -1px 1px 2px rgba(163, 163, 163, 0.45);
--circle-transition: var(--switch-transition); --circle-transition: var(--switch-transition);
--icon-transition: all .2s cubic-bezier(0.27, 0.2, 0.25, 1.51); --icon-transition: all 0.2s cubic-bezier(0.27, 0.2, 0.25, 1.51);
--icon-cross-color: var(--switch-bg); --icon-cross-color: var(--switch-bg);
--icon-cross-size: 6px; --icon-cross-size: 6px;
--icon-checkmark-color: var(--switch-checked-bg); --icon-checkmark-color: var(--switch-checked-bg);
--icon-checkmark-size: 10px; --icon-checkmark-size: 10px;
--effect-width: calc(var(--circle-diameter) / 2); --effect-width: calc(var(--circle-diameter) / 2);
--effect-height: calc(var(--effect-width) / 2 - 1px); --effect-height: calc(var(--effect-width) / 2 - 1px);
--effect-bg: var(--circle-bg); --effect-bg: var(--circle-bg);
--effect-border-radius: 1px; --effect-border-radius: 1px;
--effect-transition: all .2s ease-in-out; --effect-transition: all 0.2s ease-in-out;
} }
.switch input { .switch input {
display: none; display: none;
} }
.switch { .switch {
display: inline-block; display: inline-block;
} }
.switch svg { .switch svg {
-webkit-transition: var(--icon-transition); -webkit-transition: var(--icon-transition);
-o-transition: var(--icon-transition); -o-transition: var(--icon-transition);
transition: var(--icon-transition); transition: var(--icon-transition);
position: absolute; position: absolute;
height: auto; height: auto;
} }
.switch .checkmark { .switch .checkmark {
width: var(--icon-checkmark-size); width: var(--icon-checkmark-size);
color: var(--icon-checkmark-color); color: var(--icon-checkmark-color);
-webkit-transform: scale(0); -webkit-transform: scale(0);
-ms-transform: scale(0); -ms-transform: scale(0);
transform: scale(0); transform: scale(0);
} }
.switch .cross { .switch .cross {
width: var(--icon-cross-size); width: var(--icon-cross-size);
color: var(--icon-cross-color); color: var(--icon-cross-color);
} }
.slider { .slider {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
width: var(--switch-width); width: var(--switch-width);
height: var(--switch-height); height: var(--switch-height);
background: var(--switch-bg); background: var(--switch-bg);
border-radius: 999px; border-radius: 999px;
display: -webkit-box; display: -webkit-box;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-box-align: center; -webkit-box-align: center;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
position: relative; position: relative;
-webkit-transition: var(--switch-transition); -webkit-transition: var(--switch-transition);
-o-transition: var(--switch-transition); -o-transition: var(--switch-transition);
transition: var(--switch-transition); transition: var(--switch-transition);
cursor: pointer; cursor: pointer;
} }
.circle { .circle {
width: var(--circle-diameter); width: var(--circle-diameter);
height: var(--circle-diameter); height: var(--circle-diameter);
background: var(--circle-bg); background: var(--circle-bg);
border-radius: inherit; border-radius: inherit;
-webkit-box-shadow: var(--circle-shadow); -webkit-box-shadow: var(--circle-shadow);
box-shadow: var(--circle-shadow); box-shadow: var(--circle-shadow);
display: -webkit-box; display: -webkit-box;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-webkit-box-align: center; -webkit-box-align: center;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
-webkit-box-pack: center; -webkit-box-pack: center;
-ms-flex-pack: center; -ms-flex-pack: center;
justify-content: center; justify-content: center;
-webkit-transition: var(--circle-transition); -webkit-transition: var(--circle-transition);
-o-transition: var(--circle-transition); -o-transition: var(--circle-transition);
transition: var(--circle-transition); transition: var(--circle-transition);
z-index: 1; z-index: 1;
position: absolute; position: absolute;
left: var(--switch-offset); left: var(--switch-offset);
} }
.slider::before { .slider::before {
content: ""; content: "";
position: absolute; position: absolute;
width: var(--effect-width); width: var(--effect-width);
height: var(--effect-height); height: var(--effect-height);
left: calc(var(--switch-offset) + (var(--effect-width) / 2)); left: calc(var(--switch-offset) + (var(--effect-width) / 2));
background: var(--effect-bg); background: var(--effect-bg);
border-radius: var(--effect-border-radius); border-radius: var(--effect-border-radius);
-webkit-transition: var(--effect-transition); -webkit-transition: var(--effect-transition);
-o-transition: var(--effect-transition); -o-transition: var(--effect-transition);
transition: var(--effect-transition); transition: var(--effect-transition);
} }
/* actions */ /* actions */
.switch input:checked+.slider { .switch input:checked + .slider {
background: var(--switch-checked-bg); background: var(--switch-checked-bg);
} }
.switch input:checked+.slider .checkmark { .switch input:checked + .slider .checkmark {
-webkit-transform: scale(1); -webkit-transform: scale(1);
-ms-transform: scale(1); -ms-transform: scale(1);
transform: scale(1); transform: scale(1);
} }
.switch input:checked+.slider .cross { .switch input:checked + .slider .cross {
-webkit-transform: scale(0); -webkit-transform: scale(0);
-ms-transform: scale(0); -ms-transform: scale(0);
transform: scale(0); transform: scale(0);
} }
.switch input:checked+.slider::before { .switch input:checked + .slider::before {
left: calc(100% - var(--effect-width) - (var(--effect-width) / 2) - var(--switch-offset)); left: calc(
} 100% - var(--effect-width) - (var(--effect-width) / 2) -
var(--switch-offset)
);
}
.switch input:checked+.slider .circle { .switch input:checked + .slider .circle {
left: calc(100% - var(--circle-diameter) - var(--switch-offset)); left: calc(100% - var(--circle-diameter) - var(--switch-offset));
-webkit-box-shadow: var(--circle-checked-shadow); -webkit-box-shadow: var(--circle-checked-shadow);
box-shadow: var(--circle-checked-shadow); box-shadow: var(--circle-checked-shadow);
} }
</style> </style>

View file

@ -1,18 +1,19 @@
<script> <script>
function switchTheme() { function switchTheme() {
let currentTheme = localStorage.getItem("alu__selectedTheme") let currentTheme = localStorage.getItem("alu__selectedTheme");
if (currentTheme) { if (currentTheme) {
document.documentElement.setAttribute("data-theme", JSON.parse(currentTheme).value.toLowerCase()); document.documentElement.setAttribute(
let footer = document.getElementById('footer'); "data-theme",
if (footer) { JSON.parse(currentTheme).value.toLowerCase()
footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase(); );
} let footer = document.getElementById("footer");
} if (footer) {
footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase();
}
} }
switchTheme() }
switchTheme();
document.addEventListener("astro:after-swap", switchTheme);
</script>
document.addEventListener('astro:after-swap', switchTheme)
</script>

View file

@ -3,80 +3,93 @@
<script transition:persist defer> <script transition:persist defer>
// This is a hack to make sure window.__uv$config is defined, because this means everything has been. // This is a hack to make sure window.__uv$config is defined, because this means everything has been.
if (window.__uv$config == undefined) window.location.reload(); if (window.__uv$config == undefined) window.location.reload();
var form = document.querySelector('form'); var form = document.querySelector("form");
var input = document.querySelector('input'); var input = document.querySelector("input");
window.navigator.serviceWorker.register('/sw.js', { window.navigator.serviceWorker.register("/sw.js", {
scope: window.__uv$config.prefix scope: window.__uv$config.prefix,
})
form.addEventListener('submit', (event) => {
event.preventDefault();
let loadingContent = document.getElementById('loading-content');
loadingContent.style.opacity = 1;
let url = input.value.trim();
if (!isUrl(url)) url = getSearchEngine() + url;
else if (!(url.startsWith('https://') || url.startsWith('http://'))) url = 'http://' + url;
let iframe = document.getElementById('proxy-frame');
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
iframe.style.pointerEvents = "auto";
iframe.classList.add("proxy-frame");
document.body.appendChild(iframe);
iframe.addEventListener('load', () => {
let topBar = document.getElementById('top-bar');
loadingContent.style.opacity = 0;
topBar.innerHTML = "";
topBar.classList.add("top-bar");
let closeButton = document.createElement('button');
closeButton.classList.add("close-button")
closeButton.innerText = "Close";
closeButton.addEventListener('click', () => {
iframe.style.opacity = 0;
topBar.style.opacity = 0;
iframe.style.pointerEvents = "none";
topBar.style.pointerEvents = "none";
});
let urlText = document.createElement('p');
urlText.classList.add("url-text");
urlText.innerText = window.__uv$config.decodeUrl(iframe.src.split(__uv$config.prefix)[1]);
iframe.style.opacity = 1;
topBar.style.opacity = 1;
topBar.style.pointerEvents = "auto";
topBar.appendChild(closeButton);
topBar.appendChild(urlText);
document.body.appendChild(topBar);
})
}); });
function isUrl(val = ''){ form.addEventListener("submit", (event) => {
if (/^http(s?):\/\//.test(val) || val.includes('.') && val.substr(0, 1) !== ' ') return true; event.preventDefault();
return false; let loadingContent = document.getElementById("loading-content");
}; loadingContent.style.opacity = 1;
let url = input.value.trim();
if (!isUrl(url)) url = getSearchEngine() + url;
else if (!(url.startsWith("https://") || url.startsWith("http://")))
url = "http://" + url;
let iframe = document.getElementById("proxy-frame");
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
iframe.style.pointerEvents = "auto";
iframe.classList.add("proxy-frame");
document.body.appendChild(iframe);
iframe.addEventListener("load", () => {
let topBar = document.getElementById("top-bar");
loadingContent.style.opacity = 0;
topBar.innerHTML = "";
topBar.classList.add("top-bar");
let closeButton = document.createElement("button");
closeButton.classList.add("close-button");
closeButton.innerText = "Close";
closeButton.addEventListener("click", () => {
iframe.style.opacity = 0;
topBar.style.opacity = 0;
iframe.style.pointerEvents = "none";
topBar.style.pointerEvents = "none";
});
let urlText = document.createElement("p");
urlText.classList.add("url-text");
urlText.innerText = window.__uv$config.decodeUrl(
iframe.src.split(__uv$config.prefix)[1]
);
iframe.style.opacity = 1;
topBar.style.opacity = 1;
topBar.style.pointerEvents = "auto";
topBar.appendChild(closeButton);
topBar.appendChild(urlText);
document.body.appendChild(topBar);
});
});
function isUrl(val = "") {
if (
/^http(s?):\/\//.test(val) ||
(val.includes(".") && val.substr(0, 1) !== " ")
)
return true;
return false;
}
function getSearchEngine() { function getSearchEngine() {
switch (JSON.parse(localStorage.getItem("alu__search_engine")).value.toLowerCase()) { let localStorageSearchEngine = localStorage.getItem("alu__search_engine");
case "google": { if (!localStorageSearchEngine) {
return "https://google.com/search?q="; return "https://google.com/search?q=";
} }
case "bing": { switch (
return "https://bing.com/search?q=d"; JSON.parse(localStorage.getItem("alu__search_engine")).value.toLowerCase()
} ) {
case "brave": { case "google": {
return "https://search.brave.com/search?q="; return "https://google.com/search?q=";
} }
case "searx": { case "bing": {
let localStorageURL = localStorage.getItem("alu__searxngUrl"); return "https://bing.com/search?q=d";
if (localStorageURL) { }
if (localStorageURL == "") return "https://searxng.site/search?q="; case "brave": {
// Ugly hack to remove the trailing slash :) return "https://search.brave.com/search?q=";
if (localStorageURL.endsWith("/")) localStorageURL = localStorageURL.slice(0, -1); }
return localStorageURL + "/search?q="; case "searx": {
} let localStorageURL = localStorage.getItem("alu__searxngUrl");
else return "https://searxng.site/search?q="; if (localStorageURL) {
} if (localStorageURL == "") return "https://searxng.site/search?q=";
default: { // Ugly hack to remove the trailing slash :)
return "https://google.com/search?q=" if (localStorageURL.endsWith("/"))
} localStorageURL = localStorageURL.slice(0, -1);
return localStorageURL + "/search?q=";
} else return "https://searxng.site/search?q=";
}
default: {
return "https://google.com/search?q=";
}
} }
} }
</script> </script>

View file

@ -1,27 +1,45 @@
<svg width="100%" height="100%" preserveAspectRatio="none" id="svg" viewBox="0 0 1440 390" xmlns="http://www.w3.org/2000/svg" class="transition duration-300 ease-in-out delay-150"> <svg
width="100%"
height="100%"
preserveAspectRatio="none"
id="svg"
viewBox="0 0 1440 390"
xmlns="http://www.w3.org/2000/svg"
class="transition duration-300 ease-in-out delay-150">
<style> <style>
.path-0{ .path-0 {
animation:pathAnim-0 15s; animation: pathAnim-0 15s;
animation-timing-function: linear; animation-timing-function: linear;
animation-iteration-count: infinite; animation-iteration-count: infinite;
} }
@keyframes pathAnim-0{ @keyframes pathAnim-0 {
0%{ 0% {
d: path("M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z"); d: path(
} "M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z"
25%{ );
d: path("M 0,400 L 0,100 C 171.19999999999993,71.6 342.39999999999986,43.2 497,54 C 651.6000000000001,64.8 789.6000000000001,114.80000000000001 944,129 C 1098.3999999999999,143.2 1269.1999999999998,121.6 1440,100 L 1440,400 L 0,400 Z"); }
} 25% {
50%{ d: path(
d: path("M 0,400 L 0,100 C 186.66666666666669,82.13333333333333 373.33333333333337,64.26666666666667 540,54 C 706.6666666666666,43.733333333333334 853.3333333333333,41.06666666666666 1000,50 C 1146.6666666666667,58.93333333333334 1293.3333333333335,79.46666666666667 1440,100 L 1440,400 L 0,400 Z"); "M 0,400 L 0,100 C 171.19999999999993,71.6 342.39999999999986,43.2 497,54 C 651.6000000000001,64.8 789.6000000000001,114.80000000000001 944,129 C 1098.3999999999999,143.2 1269.1999999999998,121.6 1440,100 L 1440,400 L 0,400 Z"
} );
75%{ }
d: path("M 0,400 L 0,100 C 110.13333333333333,74.53333333333333 220.26666666666665,49.06666666666666 393,58 C 565.7333333333333,66.93333333333334 801.0666666666666,110.26666666666668 986,123 C 1170.9333333333334,135.73333333333332 1305.4666666666667,117.86666666666666 1440,100 L 1440,400 L 0,400 Z"); 50% {
} d: path(
100%{ "M 0,400 L 0,100 C 186.66666666666669,82.13333333333333 373.33333333333337,64.26666666666667 540,54 C 706.6666666666666,43.733333333333334 853.3333333333333,41.06666666666666 1000,50 C 1146.6666666666667,58.93333333333334 1293.3333333333335,79.46666666666667 1440,100 L 1440,400 L 0,400 Z"
d: path("M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z"); );
} }
}</style> 75% {
d: path(
"M 0,400 L 0,100 C 110.13333333333333,74.53333333333333 220.26666666666665,49.06666666666666 393,58 C 565.7333333333333,66.93333333333334 801.0666666666666,110.26666666666668 986,123 C 1170.9333333333334,135.73333333333332 1305.4666666666667,117.86666666666666 1440,100 L 1440,400 L 0,400 Z"
);
}
100% {
d: path(
"M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z"
);
}
}
</style>
<style media="screen"></style> <style media="screen"></style>
<defs> <defs>
<linearGradient id="gradient" x1="0%" y1="53%" x2="100%" y2="47%"> <linearGradient id="gradient" x1="0%" y1="53%" x2="100%" y2="47%">
@ -29,30 +47,47 @@
<stop offset="95%" stop-color="var(--accent-color-brighter)"></stop> <stop offset="95%" stop-color="var(--accent-color-brighter)"></stop>
</linearGradient> </linearGradient>
</defs> </defs>
<path d="M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z" stroke="none" stroke-width="0" fill="url(#gradient)" fill-opacity="0.53" class="transition-all duration-300 ease-in-out delay-150 path-0"></path> <path
d="M 0,400 L 0,100 C 124.53333333333336,122.66666666666667 249.06666666666672,145.33333333333334 415,143 C 580.9333333333333,140.66666666666666 788.2666666666667,113.33333333333333 966,102 C 1143.7333333333333,90.66666666666667 1291.8666666666668,95.33333333333334 1440,100 L 1440,400 L 0,400 Z"
stroke="none"
stroke-width="0"
fill="url(#gradient)"
fill-opacity="0.53"
class="transition-all duration-300 ease-in-out delay-150 path-0"></path>
<style> <style>
.path-1{ .path-1 {
animation:pathAnim-1 15s; animation: pathAnim-1 15s;
animation-timing-function: linear; animation-timing-function: linear;
animation-iteration-count: infinite; animation-iteration-count: infinite;
} }
@keyframes pathAnim-1{ @keyframes pathAnim-1 {
0%{ 0% {
d: path("M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z"); d: path(
} "M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z"
25%{ );
d: path("M 0,400 L 0,233 C 202,220.46666666666667 404,207.93333333333334 539,220 C 674,232.06666666666666 742.0000000000001,268.7333333333333 881,275 C 1019.9999999999999,281.2666666666667 1230,257.1333333333333 1440,233 L 1440,400 L 0,400 Z"); }
} 25% {
50%{ d: path(
d: path("M 0,400 L 0,233 C 181.33333333333337,210.86666666666667 362.66666666666674,188.73333333333332 512,188 C 661.3333333333333,187.26666666666668 778.6666666666665,207.93333333333334 928,219 C 1077.3333333333335,230.06666666666666 1258.6666666666667,231.53333333333333 1440,233 L 1440,400 L 0,400 Z"); "M 0,400 L 0,233 C 202,220.46666666666667 404,207.93333333333334 539,220 C 674,232.06666666666666 742.0000000000001,268.7333333333333 881,275 C 1019.9999999999999,281.2666666666667 1230,257.1333333333333 1440,233 L 1440,400 L 0,400 Z"
} );
75%{ }
d: path("M 0,400 L 0,233 C 195.06666666666666,222.86666666666667 390.1333333333333,212.73333333333332 559,216 C 727.8666666666667,219.26666666666668 870.5333333333333,235.93333333333334 1013,241 C 1155.4666666666667,246.06666666666666 1297.7333333333333,239.53333333333333 1440,233 L 1440,400 L 0,400 Z"); 50% {
} d: path(
100%{ "M 0,400 L 0,233 C 181.33333333333337,210.86666666666667 362.66666666666674,188.73333333333332 512,188 C 661.3333333333333,187.26666666666668 778.6666666666665,207.93333333333334 928,219 C 1077.3333333333335,230.06666666666666 1258.6666666666667,231.53333333333333 1440,233 L 1440,400 L 0,400 Z"
d: path("M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z"); );
} }
}</style> 75% {
d: path(
"M 0,400 L 0,233 C 195.06666666666666,222.86666666666667 390.1333333333333,212.73333333333332 559,216 C 727.8666666666667,219.26666666666668 870.5333333333333,235.93333333333334 1013,241 C 1155.4666666666667,246.06666666666666 1297.7333333333333,239.53333333333333 1440,233 L 1440,400 L 0,400 Z"
);
}
100% {
d: path(
"M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z"
);
}
}
</style>
<style media="screen"></style> <style media="screen"></style>
<defs> <defs>
<linearGradient id="gradient" x1="0%" y1="53%" x2="100%" y2="47%"> <linearGradient id="gradient" x1="0%" y1="53%" x2="100%" y2="47%">
@ -60,5 +95,11 @@
<stop offset="95%" stop-color="#3d097d"></stop> <stop offset="95%" stop-color="#3d097d"></stop>
</linearGradient> </linearGradient>
</defs> </defs>
<path d="M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z" stroke="none" stroke-width="0" fill="url(#gradient)" fill-opacity="1" class="transition-all duration-300 ease-in-out delay-150 path-1"></path> <path
</svg> d="M 0,400 L 0,233 C 170.53333333333336,233.66666666666666 341.0666666666667,234.33333333333331 507,236 C 672.9333333333333,237.66666666666669 834.2666666666667,240.33333333333334 989,240 C 1143.7333333333333,239.66666666666666 1291.8666666666668,236.33333333333331 1440,233 L 1440,400 L 0,400 Z"
stroke="none"
stroke-width="0"
fill="url(#gradient)"
fill-opacity="1"
class="transition-all duration-300 ease-in-out delay-150 path-1"></path>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -1,11 +1,36 @@
<script is:inline> <script is:inline>
console.log("%cWelcome to Alu", "color: #0251d9; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 0 #033c9e;"); console.log(
"%cWelcome to Alu",
"color: #0251d9; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 0 #033c9e;"
);
console.log("%cSystem Information: ", "color: #025bf5; font-size: 1rem; font-weight: bold;"); console.log(
console.log("%cOS: %c" + navigator.platform, "color: #025bf5; font-size: 0.75rem; font-weight: bold;", "color: #025bf5; font-size: 0.75rem;"); "%cSystem Information: ",
console.log("%cBrowser: %c" + navigator.userAgent, "color: #025bf5; font-size: 0.75rem; font-weight: bold;", "color: #025bf5; font-size: 0.75rem;"); "color: #025bf5; font-size: 1rem; font-weight: bold;"
console.log("%cCPU Cores: %c" + navigator.hardwareConcurrency, "color: #025bf5; font-size: 0.75rem; font-weight: bold;", "color: #025bf5; font-size: 0.75rem;"); );
// Cmon firefox, do we really not support this?? Basic stuff here from the "indie browser". console.log(
console.log("%cMemory: %c" + navigator.deviceMemory + "GB", "color: #025bf5; font-size: 0.75rem; font-weight: bold;", "color: #025bf5; font-size: 0.75rem;"); "%cOS: %c" + navigator.platform,
console.log("%cPlease include this information in a bug report!", "color: #025bf5; font-size: 0.75rem; font-weight: bold;"); "color: #025bf5; font-size: 0.75rem; font-weight: bold;",
</script> "color: #025bf5; font-size: 0.75rem;"
);
console.log(
"%cBrowser: %c" + navigator.userAgent,
"color: #025bf5; font-size: 0.75rem; font-weight: bold;",
"color: #025bf5; font-size: 0.75rem;"
);
console.log(
"%cCPU Cores: %c" + navigator.hardwareConcurrency,
"color: #025bf5; font-size: 0.75rem; font-weight: bold;",
"color: #025bf5; font-size: 0.75rem;"
);
// Cmon firefox, do we really not support this?? Basic stuff here from the "indie browser".
console.log(
"%cMemory: %c" + navigator.deviceMemory + "GB",
"color: #025bf5; font-size: 0.75rem; font-weight: bold;",
"color: #025bf5; font-size: 0.75rem;"
);
console.log(
"%cPlease include this information in a bug report!",
"color: #025bf5; font-size: 0.75rem; font-weight: bold;"
);
</script>

View file

@ -1,183 +1,189 @@
--- ---
import { ViewTransitions } from 'astro:transitions'; import { ViewTransitions } from "astro:transitions";
import Header from '../components/Header.astro'; import Header from "../components/Header.astro";
import Footer from '../components/Footer.astro'; import Footer from "../components/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";
type Preload = { type Preload = {
"href": string href: string;
"as": string as: string;
} };
interface Props { interface Props {
title: string; title: string;
optionalPreloads?: Preload[]; optionalPreloads?: Preload[];
} }
const { title, optionalPreloads } = Astro.props; const { title, optionalPreloads } = Astro.props;
--- ---
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<ThemeLoader /> <ThemeLoader />
<CloakLoader transition:persist /> <CloakLoader transition:persist />
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="description" content="Astro description" /> <meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap" rel="stylesheet" as="style"> <link
{optionalPreloads?.map((item) => { href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap"
return <link rel="preload" href={item.href} as={item.as} /> rel="stylesheet"
})} as="style"
<meta name="generator" content={Astro.generator} /> />
<title>{title}</title> {
optionalPreloads?.map((item) => {
return <link rel="preload" href={item.href} as={item.as} />;
})
}
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<ViewTransitions /> <ViewTransitions />
</head> </head>
<body> <body>
<Header></Header> <Header />
<slot transition:animate={"fade"} /> <slot transition:animate={"fade"} />
<WelcomeLogging /> <WelcomeLogging />
<Footer></Footer> <Footer />
</body> <style is:global>
* {
box-sizing: border-box;
}
body {
opacity: 0;
animation: fadeIn ease 0.2s forwards;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
:root {
--background-color: #080808;
--background-highlight: #252525;
--accent-color: #6b00c9;
--accent-color-brighter: #7e00e0;
--text-color: #fff;
--text-color-accent: #c7c7c7;
--dropdown-background-color: #1e1e1e;
}
[data-theme="mocha"] {
/* Catppucin Mocha theme */
--background-color: #1e1e2e;
--background-highlight: #45475a;
--accent-color: #181825;
--accent-color-brighter: #242539;
--text-color: #cdd6f4;
--text-color-accent: #bac2de;
--dropdown-background-color: #32324e;
}
[data-theme="macchiato"] {
/* Catppuccin Macchiato Theme */
--background-color: #24273a;
--background-highlight: #494d64;
--accent-color: #1e2030;
--accent-color-brighter: #2a2d42;
--text-color: #cad3f5;
--text-color-accent: #b8c0e0;
--dropdown-background-color: #323550;
}
[data-theme="rose_pine"] {
/* Rosé Pine Theme */
--background-color: #191724;
--background-highlight: #1f1d2e;
--accent-color: #26233a;
--accent-color-brighter: #2e2b4a;
--text-color: #e0def4;
--text-color-accent: #c7c5e0;
--dropdown-background-color: #1f1d2e;
}
body,
html {
margin: 0;
padding: 0;
height: 100%;
font-family: "Varela Round", sans-serif;
}
body {
background-color: var(--background-color);
max-width: 100vw;
margin: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
body > * {
opacity: 1;
}
.title-text {
color: var(--text-color);
text-align: center;
font-weight: 400;
}
::-webkit-scrollbar {
display: none;
}
.main-content {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 60vh;
}
#proxy-frame {
display: block;
position: absolute;
z-index: 1000;
width: 100vw;
height: 95vh;
top: 5vh;
border: none;
background-color: var(--background-color);
transition: opacity 250ms ease-in-out;
pointer-events: none;
}
#proxy-frame {
opacity: 0;
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1rem;
height: 5vh;
background-color: var(--accent-color);
color: var(--text-color);
position: fixed;
top: 0;
left: 0;
width: 100vw;
z-index: 100;
transition: opacity 350ms ease-in-out;
pointer-events: none;
}
.close-button {
padding: 5px;
padding-inline: 40px;
border: none;
background-color: var(--background-highlight);
color: var(--text-color-accent);
border-radius: 15px;
cursor: pointer;
}
</style>
</body>
</html> </html>
<style is:global>
* {
box-sizing: border-box;
}
body {
opacity: 0;
animation: fadeIn ease 0.2s forwards;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
:root {
--background-color: #080808;
--background-highlight: #252525;
--accent-color: #6b00c9;
--accent-color-brighter: #7e00e0;
--text-color: #fff;
--text-color-accent: #c7c7c7;
--dropdown-background-color: #1e1e1e;
}
[data-theme="mocha"] {
/* Catppucin Mocha theme */
--background-color: #1e1e2e;
--background-highlight: #45475a;
--accent-color: #181825;
--accent-color-brighter: #242539;
--text-color: #cdd6f4;
--text-color-accent: #bac2de;
--dropdown-background-color: #32324e;
}
[data-theme="macchiato"] {
/* Catppuccin Macchiato Theme */
--background-color: #24273a;
--background-highlight: #494d64;
--accent-color: #1e2030;
--accent-color-brighter: #2a2d42;
--text-color: #cad3f5;
--text-color-accent: #b8c0e0;
--dropdown-background-color: #323550;
}
[data-theme="rose_pine"] {
/* Rosé Pine Theme */
--background-color: #191724;
--background-highlight: #1f1d2e;
--accent-color: #26233a;
--accent-color-brighter: #2e2b4a;
--text-color: #e0def4;
--text-color-accent: #c7c5e0;
--dropdown-background-color: #1f1d2e;
}
body, html {
margin: 0;
padding: 0;
height: 100%;
font-family: 'Varela Round', sans-serif;
}
body {
background-color: var(--background-color);
max-width: 100vw;
margin: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
body > * {
opacity: 1;
}
.title-text {
color: var(--text-color);
text-align: center;
font-weight: 400;
}
::-webkit-scrollbar {
display: none;
}
.main-content {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 60vh;
}
#proxy-frame {
display: block;
position: absolute;
z-index: 1000;
width: 100vw;
height: 95vh;
top: 5vh;
border: none;
background-color: var(--background-color);
transition: opacity 250ms ease-in-out;
pointer-events: none;
}
#proxy-frame {
opacity: 0;
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1rem;
height: 5vh;
background-color: var(--accent-color);
color: var(--text-color);
position: fixed;
top: 0;
left: 0;
width: 100vw;
z-index: 100;
transition: opacity 350ms ease-in-out;
pointer-events: none;
}
.close-button {
padding: 5px;
padding-inline: 40px;
border: none;
background-color: var(--background-highlight);
color: var(--text-color-accent);
border-radius: 15px;
cursor: pointer;
}
</style>

View file

@ -3,14 +3,14 @@ import Layout from "../layouts/Layout.astro";
--- ---
<Layout title="404 | Alu"> <Layout title="404 | Alu">
<div class="main-content error-page"> <div class="main-content error-page">
<h1>404!</h1> <h1>404!</h1>
<p>The content you have requested could not be found!</p> <p>The content you have requested could not be found!</p>
</div> </div>
</Layout> </Layout>
<style> <style>
.error-page { .error-page {
color: white color: white;
} }
</style> </style>

View file

@ -2,79 +2,239 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
import GameItem from "../../components/GameItem.astro"; import GameItem from "../../components/GameItem.astro";
import { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
export function getStaticPaths () { export function getStaticPaths() {
return [ return [{ params: { lang: "en" } }, { params: { lang: "jp" } }];
{params: {lang: 'en'}},
{params: {lang: 'jp'}},
];
} }
--- ---
<Layout title={t("pages.games")}> <Layout title={t("pages.games")}>
<h1 class="title-text">{t("games.title")}</h1> <h1 class="title-text">{t("games.title")}</h1>
<div class="grid"> <div class="grid">
<GameItem name="1v1.lol" image="/games/1v1.lol/logo.png"></GameItem> <GameItem name="1v1.lol" image="/games/1v1.lol/logo.png" />
<GameItem name="2048" image="/games/2048/logo.png"></GameItem> <GameItem name="2048" image="/games/2048/logo.png" />
<GameItem name="The Backrooms" image="/games/backrooms/logo.png" slugName="backrooms"></GameItem> <GameItem
<GameItem name="Baldi's Basics" image="/games/baldi/logo.png" slugName="baldi"></GameItem> name="The Backrooms"
<GameItem name="Cannon Basketball 4" image="/games/cannon-basketball-4/logo.png" slugName="cannon-basketball-4"></GameItem> image="/games/backrooms/logo.png"
<GameItem name="Cell Machine" image="/games/cell-machine/logo.png" slugName="cell-machine"></GameItem> slugName="backrooms"
<GameItem name="Chrome Dino" image="/games/chrome-dino/logo.png" slugName="chrome-dino"></GameItem> />
<GameItem name="Cookie Clicker" image="/games/cookie-clicker/logo.png" slugName="cookie-clicker"></GameItem> <GameItem
<GameItem name="CSGO Clicker" image="/games/csgo-clicker/logo.png" slugName="csgo-clicker"></GameItem> name="Baldi's Basics"
<GameItem name="Cut The Rope" image="/games/ctr/logo.png" slugName="ctr"></GameItem> image="/games/baldi/logo.png"
<GameItem name="Cut The Rope - Holiday" image="/games/ctr-holiday/logo.png" slugName="ctr-holiday"></GameItem> slugName="baldi"
<GameItem name="Cut The Rope - Time Travel" image="/games/ctr-tr/logo.png" slugName="ctr-tr"></GameItem> />
<GameItem name="Death Run 3D" image="/games/death-run-3d/logo.png" slugName="death-run-3d"></GameItem> <GameItem
<GameItem name="Doge Miner" image="/games/doge-miner/logo.png" slugName="doge-miner"></GameItem> name="Cannon Basketball 4"
<GameItem name="Doodle Jump" image="/games/doodle-jump/logo.png" slugName="doodle-jump"></GameItem> image="/games/cannon-basketball-4/logo.png"
<GameItem name="Doom" image="/games/doom/logo.png" slugName="doom"></GameItem> slugName="cannon-basketball-4"
<GameItem name="Draw The Hill" image="/games/draw-the-hill/logo.png" slugName="draw-the-hill"></GameItem> />
<GameItem name="Evil Glitch" image="/games/evil-glitch/logo.png" slugName="evil-glitch"></GameItem> <GameItem
<GameItem name="Fall Boys" image="/games/fall-boys/logo.png" slugName="fall-boys"></GameItem> name="Cell Machine"
<GameItem name="Fireboy and Watergirl" image="/games/firewater/logo.png" slugName="firewater"></GameItem> image="/games/cell-machine/logo.png"
<GameItem name="Fireboy and Watergirl 2" image="/games/firewater2/logo.png" slugName="firewater2"></GameItem> slugName="cell-machine"
<GameItem name="Five Nights at Freddy's" image="/games/fnaf/logo.png" slugName="fnaf"></GameItem> />
<GameItem name="Five Nights at Freddy's 2" image="/games/fnaf2/logo.png" slugName="fnaf2"></GameItem> <GameItem
<GameItem name="Five Nights at Freddy's 3" image="/games/fnaf3/logo.png" slugName="fnaf3"></GameItem> name="Chrome Dino"
<GameItem name="Five Nights at Freddy's 4" image="/games/fnaf4/logo.png" slugName="fnaf4"></GameItem> image="/games/chrome-dino/logo.png"
<GameItem name="Game Inside" image="/games/game-inside/logo.png" slugName="game-inside"></GameItem> slugName="chrome-dino"
<GameItem name="Google Snake" image="/games/google-snake/logo.png" slugName="google-snake"></GameItem> />
<GameItem name="Grindcraft" image="/games/grindcraft/logo.png" slugName="grindcraft"></GameItem> <GameItem
<GameItem name="Idle Breakout" image="/games/idle-breakout/logo.png" slugName="idle-breakout"></GameItem> name="Cookie Clicker"
<GameItem name="Just One Boss" image="/games/just-one-boss/logo.png" slugName="just-one-boss"></GameItem> image="/games/cookie-clicker/logo.png"
<GameItem name="Line Rider" image="/games/line-rider/logo.png" slugName="line-rider"></GameItem> slugName="cookie-clicker"
<GameItem name="Minecraft Classic" image="/games/minecraft-classic/logo.png" slugName="minecraft-classic"></GameItem> />
<GameItem name="Minesweeper" image="/games/minesweeper/logo.png" slugName="minesweeper"></GameItem> <GameItem
<GameItem name="Moto X3M" image="/games/moto-x3m/logo.png" slugName="moto-x3m"></GameItem> name="CSGO Clicker"
<GameItem name="Moto X3M Pool Party" image="/games/moto-x3m-pool/logo.png" slugName="moto-x3m-pool"></GameItem> image="/games/csgo-clicker/logo.png"
<GameItem name="Moto X3M Spooky Land" image="/games/moto-x3m-spooky/logo.png" slugName="moto-x3m-spooky"></GameItem> slugName="csgo-clicker"
<GameItem name="Moto X3M Winter" image="/games/moto-x3m-winter/logo.png" slugName="moto-x3m-winter"></GameItem> />
<GameItem name="osu!" image="/games/osu/logo.png" slugName="osu"></GameItem> <GameItem name="Cut The Rope" image="/games/ctr/logo.png" slugName="ctr" />
<GameItem name="Retro Bowl" image="/games/retro-bowl/logo.png" slugName="retro-bowl"></GameItem> <GameItem
<GameItem name="Slope" image="/games/slope/logo.png" slugName="slope"></GameItem> name="Cut The Rope - Holiday"
<GameItem name="Super Mario 64" image="/games/sm64/logo.png" slugName="sm64"></GameItem> image="/games/ctr-holiday/logo.png"
<GameItem name="Solitaire" image="/games/solitaire/logo.png" slugName="solitaire"></GameItem> slugName="ctr-holiday"
<GameItem name="Superhot" image="/games/superhot/logo.png" slugName="superhot"></GameItem> />
<GameItem name="There is No Game" image="/games/there-is-no-game/logo.png" slugName="there-is-no-game"></GameItem> <GameItem
<GameItem name="Ultima 6" image="/games/ul6/logo.png" slugName="ul6"></GameItem> name="Cut The Rope - Time Travel"
<GameItem name="Vex 3" image="/games/vex3/logo.png" slugName="vex3"></GameItem> image="/games/ctr-tr/logo.png"
<GameItem name="Vex 4" image="/games/vex4/logo.png" slugName="vex4"></GameItem> slugName="ctr-tr"
<GameItem name="Vex 5" image="/games/vex5/logo.png" slugName="vex5"></GameItem> />
<GameItem name="Vex 6" image="/games/vex6/logo.png" slugName="vex6"></GameItem> <GameItem
<GameItem name="World's Hardest Game" image="/games/worlds-hardest-game/logo.png" slugName="worlds-hardest-game"></GameItem> name="Death Run 3D"
<GameItem name="World's Hardest Game 2" image="/games/worlds-hardest-game-2/logo.png" slugName="worlds-hardest-game-2"></GameItem> image="/games/death-run-3d/logo.png"
<GameItem name="You are Bezos" image="/games/you-are-bezos/logo.png" slugName="you-are-bezos"></GameItem> slugName="death-run-3d"
</div> />
<GameItem
name="Doge Miner"
image="/games/doge-miner/logo.png"
slugName="doge-miner"
/>
<GameItem
name="Doodle Jump"
image="/games/doodle-jump/logo.png"
slugName="doodle-jump"
/>
<GameItem name="Doom" image="/games/doom/logo.png" slugName="doom" />
<GameItem
name="Draw The Hill"
image="/games/draw-the-hill/logo.png"
slugName="draw-the-hill"
/>
<GameItem
name="Evil Glitch"
image="/games/evil-glitch/logo.png"
slugName="evil-glitch"
/>
<GameItem
name="Fall Boys"
image="/games/fall-boys/logo.png"
slugName="fall-boys"
/>
<GameItem
name="Fireboy and Watergirl"
image="/games/firewater/logo.png"
slugName="firewater"
/>
<GameItem
name="Fireboy and Watergirl 2"
image="/games/firewater2/logo.png"
slugName="firewater2"
/>
<GameItem
name="Five Nights at Freddy's"
image="/games/fnaf/logo.png"
slugName="fnaf"
/>
<GameItem
name="Five Nights at Freddy's 2"
image="/games/fnaf2/logo.png"
slugName="fnaf2"
/>
<GameItem
name="Five Nights at Freddy's 3"
image="/games/fnaf3/logo.png"
slugName="fnaf3"
/>
<GameItem
name="Five Nights at Freddy's 4"
image="/games/fnaf4/logo.png"
slugName="fnaf4"
/>
<GameItem
name="Game Inside"
image="/games/game-inside/logo.png"
slugName="game-inside"
/>
<GameItem
name="Google Snake"
image="/games/google-snake/logo.png"
slugName="google-snake"
/>
<GameItem
name="Grindcraft"
image="/games/grindcraft/logo.png"
slugName="grindcraft"
/>
<GameItem
name="Idle Breakout"
image="/games/idle-breakout/logo.png"
slugName="idle-breakout"
/>
<GameItem
name="Just One Boss"
image="/games/just-one-boss/logo.png"
slugName="just-one-boss"
/>
<GameItem
name="Line Rider"
image="/games/line-rider/logo.png"
slugName="line-rider"
/>
<GameItem
name="Minecraft Classic"
image="/games/minecraft-classic/logo.png"
slugName="minecraft-classic"
/>
<GameItem
name="Minesweeper"
image="/games/minesweeper/logo.png"
slugName="minesweeper"
/>
<GameItem
name="Moto X3M"
image="/games/moto-x3m/logo.png"
slugName="moto-x3m"
/>
<GameItem
name="Moto X3M Pool Party"
image="/games/moto-x3m-pool/logo.png"
slugName="moto-x3m-pool"
/>
<GameItem
name="Moto X3M Spooky Land"
image="/games/moto-x3m-spooky/logo.png"
slugName="moto-x3m-spooky"
/>
<GameItem
name="Moto X3M Winter"
image="/games/moto-x3m-winter/logo.png"
slugName="moto-x3m-winter"
/>
<GameItem name="osu!" image="/games/osu/logo.png" slugName="osu" />
<GameItem
name="Retro Bowl"
image="/games/retro-bowl/logo.png"
slugName="retro-bowl"
/>
<GameItem name="Slope" image="/games/slope/logo.png" slugName="slope" />
<GameItem
name="Super Mario 64"
image="/games/sm64/logo.png"
slugName="sm64"
/>
<GameItem
name="Solitaire"
image="/games/solitaire/logo.png"
slugName="solitaire"
/>
<GameItem
name="Superhot"
image="/games/superhot/logo.png"
slugName="superhot"
/>
<GameItem
name="There is No Game"
image="/games/there-is-no-game/logo.png"
slugName="there-is-no-game"
/>
<GameItem name="Ultima 6" image="/games/ul6/logo.png" slugName="ul6" />
<GameItem name="Vex 3" image="/games/vex3/logo.png" slugName="vex3" />
<GameItem name="Vex 4" image="/games/vex4/logo.png" slugName="vex4" />
<GameItem name="Vex 5" image="/games/vex5/logo.png" slugName="vex5" />
<GameItem name="Vex 6" image="/games/vex6/logo.png" slugName="vex6" />
<GameItem
name="World's Hardest Game"
image="/games/worlds-hardest-game/logo.png"
slugName="worlds-hardest-game"
/>
<GameItem
name="World's Hardest Game 2"
image="/games/worlds-hardest-game-2/logo.png"
slugName="worlds-hardest-game-2"
/>
<GameItem
name="You are Bezos"
image="/games/you-are-bezos/logo.png"
slugName="you-are-bezos"
/>
</div>
</Layout> </Layout>
<style> <style>
.grid {
.grid {
color: var(--text-color); color: var(--text-color);
margin-top: -10px; margin-top: -10px;
height: max-content; height: max-content;
@ -86,18 +246,18 @@ export function getStaticPaths () {
justify-content: center; justify-content: center;
gap: 1rem; gap: 1rem;
margin-left: 20px; margin-left: 20px;
} }
@media only screen and (max-width: 973px) {
.grid {
grid-template-columns: repeat(3, 1fr);
padding: 0;
}
}
@media only screen and (max-width: 467px) { @media only screen and (max-width: 973px) {
.grid { .grid {
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(3, 1fr);
padding: 0;
} }
} }
</style>
@media only screen and (max-width: 467px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>

View file

@ -2,74 +2,71 @@
import Layout from "../../layouts/Layout.astro"; import Layout from "../../layouts/Layout.astro";
import UVRegistrar from "../../components/UVRegistrar.astro"; import UVRegistrar from "../../components/UVRegistrar.astro";
import { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
export function getStaticPaths () { export function getStaticPaths() {
return [ return [{ params: { lang: "en" } }, { params: { lang: "jp" } }];
{params: {lang: 'en'}},
{params: {lang: 'jp'}},
];
} }
--- ---
<Layout title={t("pages.home")}> <Layout title={t("pages.home")}>
<div class="main-content"> <div class="main-content">
<h1 class="title-text">{t("menu.welcome")}</h1> <h1 class="title-text">{t("menu.welcome")}</h1>
<form class="url-input-form" id="url-input-form"> <form class="url-input-form" id="url-input-form">
<input class="url-input" type="text" placeholder={t("menu.search")}> <input class="url-input" type="text" placeholder={t("menu.search")} />
<div id="loading-content">Loading...</div> <div id="loading-content">Loading...</div>
<div id="top-bar"></div> <div id="top-bar"></div>
<iframe title="proxy-iframe" id="proxy-frame"></iframe> <iframe title="proxy-iframe" id="proxy-frame"></iframe>
</form> </form>
</div> </div>
<UVRegistrar></UVRegistrar> <UVRegistrar />
</Layout> </Layout>
<style> <style>
form { form {
width: 30%; width: 30%;
} }
.title-text { .title-text {
font-size: 38px; font-size: 38px;
} }
.url-input-form { .url-input-form {
border: none; border: none;
padding: 0; padding: 0;
} }
.url-input { .url-input {
display: block; display: block;
background: transparent url("/img/search.svg") no-repeat 13px center; background: transparent url("/img/search.svg") no-repeat 13px center;
} }
.url-input { .url-input {
background-color: #080808; background-color: var(--dropdown-background-color);
color: #D8DEE9; color: var(--text-color);
border: 3px solid white; border: 3px solid var(--text-color);
border-radius: 30px; border-radius: 30px;
padding: 15px; padding: 15px;
width: 100%; width: 100%;
text-align: center; text-align: center;
transition: 400ms ease-out; transition: 400ms ease-out;
outline: none; outline: none;
font-family: 'Varela Round', sans-serif; font-family: "Varela Round", sans-serif;
font-size: 16px; font-size: 16px;
} }
.url-input::placeholder { .url-input::placeholder {
color: #D8DEE9; color: var(--text-color);
} }
#loading-content { #loading-content {
color: white; color: var(--text-color);
padding: 8px; padding: 8px;
position: relative; position: relative;
opacity: 0; opacity: 0;
transition: 250ms ease-in-out; transition: 250ms ease-in-out;
text-align: center; text-align: center;
} }
</style> </style>

View file

@ -2,25 +2,22 @@
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 { getLangFromUrl, useTranslations } from "../../i18n/utils" import { getLangFromUrl, useTranslations } from "../../i18n/utils";
const lang = getLangFromUrl(Astro.url); const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang); const t = useTranslations(lang);
export function getStaticPaths () { export function getStaticPaths() {
return [ return [{ params: { lang: "en" } }, { params: { lang: "jp" } }];
{params: {lang: 'en'}},
{params: {lang: 'jp'}},
];
} }
--- ---
<Layout title={t("pages.settings")}> <Layout title={t("pages.settings")}>
<h1 class="title-text">Settings</h1> <h1 class="title-text">Settings</h1>
<SettingsTablist /> <SettingsTablist />
</Layout> </Layout>
<style> <style>
h1 { h1 {
font-size: 40px; font-size: 40px;
} }
</style> </style>

View file

@ -1,6 +1,5 @@
--- ---
import { ViewTransitions } from "astro:transitions"; import { ViewTransitions } from "astro:transitions";
--- ---
<!doctype html> <!doctype html>
@ -9,28 +8,28 @@ 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/"; 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 {
let parsed = JSON.parse(currentLang).value let parsed = JSON.parse(currentLang).value;
switch (parsed) { switch (parsed) {
case "en": case "en":
window.location.href = "/en/"; window.location.href = "/en/";
break; break;
case "jp": case "jp":
window.location.href = "/jp/"; window.location.href = "/jp/";
break; break;
default: default:
window.location.href = "/en/"; window.location.href = "/en/";
break; break;
} }
} catch { } catch {
localStorage.clear(); localStorage.clear();
window.location.reload(); window.location.reload();
} }
} }
</script> </script>
</head> </head>
<body></body> <body></body>