Cloaking now fully works 🎉🎉
This commit is contained in:
parent
04f912536a
commit
7f41219948
8 changed files with 190 additions and 25 deletions
32
src/components/CloakLoader.astro
Normal file
32
src/components/CloakLoader.astro
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
function loadCloak() {
|
||||||
|
let localStorageCloak = localStorage.getItem('alu__selectedCloak');
|
||||||
|
if (localStorageCloak) {
|
||||||
|
let parsedCloak = JSON.parse(localStorageCloak);
|
||||||
|
if (parsedCloak) {
|
||||||
|
if (parsedCloak.name != "None") {
|
||||||
|
document.title = parsedCloak.name
|
||||||
|
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
|
||||||
|
if (!link) {
|
||||||
|
link = document.createElement('link');
|
||||||
|
link.rel = 'icon';
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCloak();
|
||||||
|
document.addEventListener("astro:after-swap", loadCloak);
|
||||||
|
</script>
|
||||||
|
|
@ -41,7 +41,7 @@ const t = useTranslations(lang);
|
||||||
--footer-svg-url: url("/img/macchiatowaves.svg");
|
--footer-svg-url: url("/img/macchiatowaves.svg");
|
||||||
}
|
}
|
||||||
#footer {
|
#footer {
|
||||||
padding-top: 20vh;
|
padding-top: 22vh;
|
||||||
background-image: var(--footer-svg-url);
|
background-image: var(--footer-svg-url);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100vw auto;
|
background-size: 100vw auto;
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,31 @@
|
||||||
---
|
---
|
||||||
const { type, inputName, defaultTextContent } = Astro.props;
|
const { type, inputName, defaultTextContent, height, placeholder } = Astro.props;
|
||||||
// as any should not be necessary here... but it is womp womp.
|
|
||||||
|
// 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?: string;
|
type?: HTMLInputTypeAttribute;
|
||||||
inputName: string;
|
inputName: string;
|
||||||
defaultTextContent?: string;
|
defaultTextContent?: string;
|
||||||
|
height: string;
|
||||||
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="input-container">
|
<input style={`height: ${height}`} id={inputName + "-input"} placeholder={placeholder || ""} value={defaultTextContent || ""} type={type} />
|
||||||
<input id={inputName + "-input"} value={defaultTextContent || ""} type={type as any} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
input {
|
input {
|
||||||
height: 50px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 4px solid #E0E0E0;
|
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: 100ms ease-in-out;
|
transition: .1s ease-in-out;
|
||||||
}
|
}
|
||||||
input:focus {
|
input:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border: 4px solid #7900e1;
|
border: 2px solid var(--text-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
---
|
---
|
||||||
|
import Input from "../Input.astro"
|
||||||
|
|
||||||
|
|
||||||
const presetCloaks = [
|
const presetCloaks = [
|
||||||
{"cloakTitle": "Alu", "favicon": "/favicon.png"},
|
{"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": "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": "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": "Google Classroom", "favicon": "https://ssl.gstatic.com/classroom/ic_product_classroom_144.png"},
|
||||||
|
|
@ -13,14 +15,28 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="settings-container">
|
<div class="settings-container">
|
||||||
|
<div class="cloak-container">
|
||||||
<div id="cloak-list">
|
<div id="cloak-list">
|
||||||
{presetCloaks.map((cloak: any) => {
|
{presetCloaks.map((cloak: any) => {
|
||||||
return <div class="cloak-item"><img class="cloak-image" src={cloak.favicon} alt={cloak.cloakTitle}/></div>
|
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>
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cloak-custom-override">
|
||||||
|
<!-- <input type="text" id="cloak-custom-name" class="cloak-custom-input" placeholder="Custom Name"/>
|
||||||
|
<input type="text" id="cloak-custom-favicon" class="cloak-custom-input" placeholder="Custom Favicon URL"/> -->
|
||||||
|
<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 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
#cloak-list {
|
#cloak-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
@ -35,9 +51,43 @@
|
||||||
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;
|
||||||
|
}
|
||||||
|
.cloak-item.selected {
|
||||||
|
/* Make border color brighter */
|
||||||
|
border: 3px solid var(--accent-color-brighter)
|
||||||
}
|
}
|
||||||
.cloak-image {
|
.cloak-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cloak-custom-override {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
#cloak-custom-button {
|
||||||
|
margin-top: 6px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: var(--accent-color-brighter);
|
||||||
|
border: 0;
|
||||||
|
color: var(--text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.cloak-custom-input {
|
||||||
|
height: 40px;
|
||||||
|
width: 100%;
|
||||||
|
border: 2px solid var(--accent-color-brighter);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #1b1b1b;
|
||||||
|
color: var(--text-color);
|
||||||
|
transition: .1s ease-in-out;
|
||||||
|
}
|
||||||
|
.cloak-custom-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid var(--text-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -42,10 +42,10 @@ const openPageWith = [
|
||||||
</div>
|
</div>
|
||||||
<div class="setting__bare-url">
|
<div class="setting__bare-url">
|
||||||
<label class="setting-label" for="bare-url-input">{t("settings.proxy.bareURL")}</label>
|
<label class="setting-label" for="bare-url-input">{t("settings.proxy.bareURL")}</label>
|
||||||
<Input inputName="bare-url" />
|
<Input inputName="bare-url" height="50px" />
|
||||||
</div>
|
</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">{t("settings.proxy.searxngURL")}</label>
|
||||||
<Input inputName="searxng-url" defaultTextContent="https://searxng.site/" />
|
<Input height="50px" inputName="searxng-url" defaultTextContent="https://searxng.site/" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -193,6 +193,78 @@ const t = useTranslations(lang);
|
||||||
applyDropdownEventListeners(languageDropdown, 'dropdown__selected-language', 'alu__selectedLanguage', navigateToNewLangaugePage);
|
applyDropdownEventListeners(languageDropdown, 'dropdown__selected-language', 'alu__selectedLanguage', navigateToNewLangaugePage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupCloakingSettings() {
|
||||||
|
Array.from(document.getElementById('cloak-list').children).forEach((cloak) => {
|
||||||
|
cloak.addEventListener('click', () => {
|
||||||
|
console.log("Here!")
|
||||||
|
let cloakName = cloak.dataset.cloakName
|
||||||
|
let cloakIcon = cloak.dataset.cloakIcon
|
||||||
|
|
||||||
|
let localStorageItem = {
|
||||||
|
"name": cloakName,
|
||||||
|
"icon": cloakIcon,
|
||||||
|
"isCustom": false,
|
||||||
|
}
|
||||||
|
localStorage.setItem('alu__selectedCloak', JSON.stringify(localStorageItem))
|
||||||
|
|
||||||
|
if (cloakName == "None") {
|
||||||
|
localStorage.removeItem('alu__selectedCloak')
|
||||||
|
cloakName = "Settings | Alu"
|
||||||
|
cloakIcon = "/favicon.png"
|
||||||
|
}
|
||||||
|
let link = document.querySelector("link[rel~='icon']");
|
||||||
|
if (!link) {
|
||||||
|
link = document.createElement('link');
|
||||||
|
link.rel = 'icon';
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
link.href = cloakIcon;
|
||||||
|
document.title = cloakName;
|
||||||
|
|
||||||
|
if (!cloak.classList.contains("selected")) {
|
||||||
|
Array.from(document.getElementById('cloak-list').children).forEach((cloak2) => {
|
||||||
|
cloak2.classList.remove('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 cloakName = document.getElementById('cloak-custom-name-input').value
|
||||||
|
let cloakIcon = document.getElementById('cloak-custom-favicon-input').value
|
||||||
|
let localStorageItem = {
|
||||||
|
"name": cloakName,
|
||||||
|
"icon": cloakIcon,
|
||||||
|
"isCustom": true,
|
||||||
|
}
|
||||||
|
localStorage.setItem('alu__selectedCloak', JSON.stringify(localStorageItem))
|
||||||
|
if (cloakName == "None") {
|
||||||
|
localStorage.removeItem('alu__selectedCloak')
|
||||||
|
cloakName = "Settings | Alu"
|
||||||
|
cloakIcon = "/favicon.png"
|
||||||
|
}
|
||||||
|
let link = document.querySelector("link[rel~='icon']");
|
||||||
|
if (!link) {
|
||||||
|
link = document.createElement('link');
|
||||||
|
link.rel = 'icon';
|
||||||
|
document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
link.href = cloakIcon;
|
||||||
|
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) {
|
||||||
|
|
@ -233,6 +305,8 @@ const t = useTranslations(lang);
|
||||||
checkSearxng();
|
checkSearxng();
|
||||||
} else if (event.detail == "setting-tab-customization") {
|
} else if (event.detail == "setting-tab-customization") {
|
||||||
setupCustomizationSettings();
|
setupCustomizationSettings();
|
||||||
|
} else if (event.detail == "setting-tab-cloaking") {
|
||||||
|
setupCloakingSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,19 @@ 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';
|
||||||
|
|
||||||
|
type Preload = {
|
||||||
|
"href": string
|
||||||
|
"as": string
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
optionalPreloads?: string[];
|
optionalPreloads?: Preload[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, optionalPreloads } = Astro.props;
|
const { title, optionalPreloads } = Astro.props;
|
||||||
|
|
||||||
import i18next from 'i18next';
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,17 +25,17 @@ import i18next from 'i18next';
|
||||||
<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="icon" type="image/svg+xml" href="/favicon.png" />
|
|
||||||
<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 href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap" rel="stylesheet" as="style">
|
||||||
{optionalPreloads?.map((item) => {
|
{optionalPreloads?.map((item) => {
|
||||||
return <link rel="preload" href={item} />
|
return <link rel="preload" href={item.href} as={item.as} />
|
||||||
})}
|
})}
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<ViewTransitions />
|
<ViewTransitions />
|
||||||
<ThemeLoader />
|
<ThemeLoader />
|
||||||
|
<CloakLoader transition:persist />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<Header></Header>
|
<Header></Header>
|
||||||
|
|
@ -60,7 +64,8 @@ body {
|
||||||
:root {
|
:root {
|
||||||
--background-color: #080808;
|
--background-color: #080808;
|
||||||
--background-highlight: #252525;
|
--background-highlight: #252525;
|
||||||
--accent-color: #7900e1;
|
--accent-color: #6b00c9;
|
||||||
|
--accent-color-brighter: #8800ff;
|
||||||
--text-color: #fff;
|
--text-color: #fff;
|
||||||
--text-color-accent: #c7c7c7;
|
--text-color-accent: #c7c7c7;
|
||||||
--dropdown-background-color: #1e1e1e;
|
--dropdown-background-color: #1e1e1e;
|
||||||
|
|
@ -71,6 +76,7 @@ body {
|
||||||
--background-color: #1e1e2e;
|
--background-color: #1e1e2e;
|
||||||
--background-highlight: #45475a;
|
--background-highlight: #45475a;
|
||||||
--accent-color: #181825;
|
--accent-color: #181825;
|
||||||
|
--accent-color-brighter: #242539;
|
||||||
--text-color: #cdd6f4;
|
--text-color: #cdd6f4;
|
||||||
--text-color-accent: #bac2de;
|
--text-color-accent: #bac2de;
|
||||||
--dropdown-background-color: #32324e;
|
--dropdown-background-color: #32324e;
|
||||||
|
|
@ -81,6 +87,7 @@ body {
|
||||||
--background-color: #24273a;
|
--background-color: #24273a;
|
||||||
--background-highlight: #494d64;
|
--background-highlight: #494d64;
|
||||||
--accent-color: #1e2030;
|
--accent-color: #1e2030;
|
||||||
|
--accent-color-brighter: #525571;
|
||||||
--text-color: #cad3f5;
|
--text-color: #cad3f5;
|
||||||
--text-color-accent: #b8c0e0;
|
--text-color-accent: #b8c0e0;
|
||||||
--dropdown-background-color: #323550;
|
--dropdown-background-color: #323550;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export function getStaticPaths () {
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={t("pages.settings")} optionalPreloads={["/img/aluwaves.svg", "/img/macchiatowaves.svg", "/img/mochawaves.svg"]}>
|
<Layout title={t("pages.settings")}>
|
||||||
<h1 class="title-text">Settings</h1>
|
<h1 class="title-text">Settings</h1>
|
||||||
<SettingsTablist />
|
<SettingsTablist />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue