Rename mocha and macchiato i18n key to just catppuccin, only add eng translation. Move settings code to settings.ts, and fix links in credits page.

This commit is contained in:
wearrrrr 2024-08-04 01:46:43 -05:00
parent e0a8eb0dd4
commit 26797b6ee6
13 changed files with 383 additions and 365 deletions

View file

@ -1,39 +1,38 @@
---
import Card from "@components/UI/Card.astro";
import Link from "@components/UI/Link.astro";
import { i18n } from "@i18n/utils";
const t = i18n.inferLangUseTranslations(Astro.url);
---
<div class="settings-container">
<div class="credits-container">
<Card title={t("ultraviolet")}>
<Link href="https://titaniumnetwork.org/" newTab>Titanium Network</Link>
<Card title={t("ultraviolet")} href="https://titaniumnetwork.org">
Titanium Network
</Card>
<Card title={t("settings.credits.esTranslations")}>
<Link href="https://github.com/builtbyvys/" newTab>vys</Link>
<Card title={t("settings.credits.esTranslations")} href="https://github.com/builtbyvys/">
vys
</Card>
<Card title={t("settings.credits.frTranslations")}>
<Link href="https://github.com/notboeing747">notboeing747</Link>
<Card title={t("settings.credits.frTranslations")} href="https://github.com/notboeing747">
notboeing747
</Card>
<Card title={t("settings.credits.jpTranslations")}>
<Link href="https://wearr.dev" newTab>wearr</Link>
<Card title={t("settings.credits.jpTranslations")} href="https://wearr.dev">
wearr
</Card>
<Card title={t("settings.credits.ptTranslations")}> kersosina_ </Card>
<Card title={t("settings.credits.ruTranslations")}>
<Link href="https://3kh0.net" newTab>Echo</Link>
<Card title={t("settings.credits.ruTranslations")} href="https://3kh0.net">
Echo
</Card>
<Card title={t("settings.credits.zhTranslations")}>
<Link href="https://3kh0.net" newTab>Echo</Link>
<Card title={t("settings.credits.zhTranslations")} href="https://3kh0.net">
Echo
</Card>
<Card title={t("settings.credits.mochaandmacchiatothemes")}>
<Link href="https://github.com/catppuccin/catppuccin" newTab>Catppuccin</Link>
<Card title={t("settings.credits.catppuccin")} href="https://github.com/catppuccin/catppuccin">
Catppuccin
</Card>
<Card title="Wisp Server">
<Link href="https://github.com/MercuryWorkshop/wisp-server-node" newTab>Wisp Server</Link>
<Card title="Wisp Server" href="https://github.com/MercuryWorkshop/wisp-server-node">
Mercury Workshop
</Card>
<Card title="Rosé Pine Theme">
<Link href="https://rosepinetheme.com/" newTab>Rosé Pine</Link>
<Card title="Rosé Pine Theme" href="https://rosepinetheme.com/">
Rosé Pine
</Card>
</div>
</div>

View file

@ -1,15 +1,31 @@
---
const { title } = Astro.props;
import Link from './Link.astro';
const { title, href } = Astro.props;
interface Props {
title: string;
href?: string;
}
const ID = title.toLowerCase().replaceAll(" ", "-");
---
<div class="card" id=`card-${title.toLowerCase()}`>
<h2 class="card-title">{title}</h2>
<slot />
</div>
{href ? (
<Link href={href} newTab>
<div class="card card-link" id={"card-" + ID}>
<h2 class="card-title">{title}</h2>
<slot />
</div>
</Link>
) : (
<div class="card" id={"card-" + ID}>
<h2 class="card-title">{title}</h2>
<slot />
</div>
)}
<style>
.card {
@ -21,10 +37,12 @@ interface Props {
background-color: var(--background-highlight);
border-radius: 10px;
padding-bottom: 1rem;
transition: 250ms ease-in-out;
cursor: pointer;
}
.card:hover {
.card-link {
cursor: pointer;
transition: 250ms ease-in-out;
}
.card-link:hover {
filter: brightness(0.8);
}
.card-title {

View file

@ -10,11 +10,12 @@ const target = newTab ? "_blank" : "_self";
const rel = newTab ? "noopener noreferrer" : "";
---
<a href={href} target={target} rel={rel}><slot /></a>
<a href={href} target={target} rel={rel}>
<slot />
</a>
<style>
a {
color: var(--text-color);
width: fit-content;
}
</style>

View file

@ -1,7 +1,7 @@
const KEYSTORE: Alu.DefaultKeys = {
proxy: {
name: "Ultraviolet",
value: "ultraviolet",
name: "Auto",
value: "auto",
},
search: {
name: "Google",
@ -36,33 +36,33 @@ if (localStorage.getItem("AluStore") === null) {
}
class AluStore {
private store: Alu.DefaultKeys;
#store: Alu.DefaultKeys;
constructor() {
const localstore = localStorage.getItem("AluStore");
if (!localstore) {
localStorage.setItem("AluStore", JSON.stringify(KEYSTORE));
}
this.store = JSON.parse(localStorage.getItem("AluStore") || "{}");
this.#store = JSON.parse(localStorage.getItem("AluStore") || "{}");
}
public getStore(): Alu.DefaultKeys {
return this.store;
return this.#store;
}
public get(key: Alu.ValidStoreKeys): Alu.Key {
return this.store[key];
return this.#store[key];
}
public set(key: Alu.ValidStoreKeys, value: Alu.Key): void {
this.store[key] = value;
this.#store[key] = value;
this.save();
}
public reset(key: Alu.ValidStoreKeys) {
this.set(key, KEYSTORE[key]);
}
public remove(key: Alu.ValidStoreKeys) {
delete this.store[key];
delete this.#store[key];
this.save();
}
private save(): void {
localStorage.setItem("AluStore", JSON.stringify(this.store));
localStorage.setItem("AluStore", JSON.stringify(this.#store));
}
}

View file

@ -0,0 +1,324 @@
window.loadedContentStorage = {};
window.currentlySelectedTab;
document.addEventListener("astro:before-swap", () => {
window.currentlySelectedTab = "";
});
function settingsLoad() {
Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
const contentToLoad = document.getElementById("content-" + tab.id);
if (contentToLoad) {
window.loadedContentStorage[tab.id] = contentToLoad.innerHTML;
contentToLoad.remove();
}
tab.addEventListener("click", (event: Event) => {
const target = event.target as HTMLElement;
loadContent(target.id);
});
});
}
function loadContent(tabID: string) {
if (window.currentlySelectedTab == tabID) return;
else window.currentlySelectedTab = tabID;
const currentContent = document.getElementById("current-content");
if (currentContent) {
currentContent.style.opacity = "0";
setTimeout(() => {
currentContent.innerHTML = window.loadedContentStorage[tabID];
currentContent.style.opacity = "1";
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
}, 250);
}
}
function addDropdownListener() {
const dropdown_toggles = document.getElementsByClassName("dropdown-toggle") as HTMLCollectionOf<HTMLElement>;
Array.from(dropdown_toggles).forEach((toggle) => {
toggle.onclick = function () {
closeOtherDropdowns(toggle.id);
toggleDropdown(toggle);
};
});
}
function toggleDropdown(toggle: HTMLElement) {
const dropdown = document.getElementById(toggle.id + "-menu")!;
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 closeOtherDropdowns(dropdownIDToExclude: string) {
const dropdowns = document.getElementsByClassName("dropdown-menu") as HTMLCollectionOf<HTMLElement>;
Array.from(dropdowns).forEach((dropdown) => {
dropdown.style.maxHeight = "0px";
setTimeout(() => {
if (dropdown.id != dropdownIDToExclude + "-menu") {
const dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", ""))!;
dropdown_toggle.style.borderRadius = "10px";
}
}, 300);
});
}
function closeDropdown(dropdownID: string) {
const dropdown = document.getElementById(dropdownID);
if (dropdown) {
dropdown.style.maxHeight = "0px";
setTimeout(() => {
const dropdown_toggle = document.getElementById(dropdownID.replace("-menu", ""))!;
dropdown_toggle.style.borderRadius = "10px";
}, 300);
}
}
function getLocalStorageValue(localStorageItem: Alu.ValidStoreKeys, dropdownID: string) {
// I was kinda dumb for not doing this earlier.
const dropdown = document.getElementById(dropdownID);
const dropdownMenu = document.getElementById(dropdownID + "-menu") as HTMLElement;
if (dropdown && dropdownMenu) {
// Now we find the child that matches localStorageItem.value.
const dropdownItem = Array.from(dropdownMenu.children).find((item) => {
const itemEl = item as HTMLElement;
return Alu.store.get(localStorageItem).value == itemEl.dataset.setting;
}) as HTMLElement;
// Now set the inner text to the name in the dropdownItem.
return dropdownItem.innerText;
}
}
function applySavedLocalStorage(localStorageItem: Alu.ValidStoreKeys, dropdownID: string) {
if (Alu.store.get(localStorageItem)) {
const dropdown_toggle = document.getElementById(dropdownID) as HTMLElement;
if (dropdown_toggle) {
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID)!;
}
}
}
function applyDropdownEventListeners(dropdown: HTMLElement, optionalCallback?: () => void) {
const dropdownSibling = document.getElementById(dropdown.id + "-menu")!;
const localStorageItem = dropdown.dataset.localStorageKey as Alu.ValidStoreKeys;
Array.from(dropdownSibling.children).forEach((child) => {
const childEl = child as HTMLElement;
childEl.onclick = () => {
const localStorageItemContent: Alu.Key = {
name: childEl.innerText,
value: childEl.dataset.setting!,
};
Alu.store.set(localStorageItem, localStorageItemContent);
applySavedLocalStorage(localStorageItem, dropdown.id);
closeDropdown(dropdownSibling.id);
if (typeof optionalCallback === "function") {
optionalCallback();
}
};
});
}
function applyInputListeners(input: HTMLInputElement, localStorageItem: Alu.ValidStoreKeys) {
input.addEventListener("input", () => {
Alu.store.set(localStorageItem, { value: input.value });
});
}
function addThemeToDropdown(extension: ExtensionMetadata) {
const dropdown = document.getElementById("dropdown__selected-theme-menu");
if (dropdown) {
// TODO: Figure out why addThemeToDropdown is being called 6 times
// This when you go from another page and back to settings->customization.
const duplicateItem = Array.from(dropdown.children).find((item) => {
const itemEl = item as HTMLElement;
return itemEl.dataset.setting == extension.themeName;
});
if (duplicateItem) return;
const themeItem = document.createElement("li");
themeItem.classList.add("dropdown-item");
themeItem.dataset.setting = extension.themeName;
themeItem.textContent = extension.title;
dropdown.appendChild(themeItem);
}
}
loadContent("setting-tab-proxy");
function setupProxySettings() {
applySavedLocalStorage("proxy", "dropdown__selected-proxy");
applySavedLocalStorage("search", "dropdown__search-engine");
applySavedLocalStorage("openpage", "dropdown__open-with");
applySavedLocalStorage("wisp", "dropdown__wisp-url");
applySavedLocalStorage("transport", "dropdown__transport");
// Dropdowns
const selectedProxyDropdown = document.getElementById("dropdown__selected-proxy");
const searchEngineDropdown = document.getElementById("dropdown__search-engine");
const openWithDropdown = document.getElementById("dropdown__open-with");
const currentTransportDropdown = document.getElementById("dropdown__transport");
const wispURLDropdown = document.getElementById("dropdown__wisp-url");
// Inputs
const searxngUrlInput = document.getElementById("searxng-url-input") as HTMLInputElement;
const bareURLInput = document.getElementById("bare-url-input") as HTMLInputElement;
bareURLInput.value = Alu.store.get("bareUrl").value.toString();
// Proxy settings
[selectedProxyDropdown, openWithDropdown, currentTransportDropdown, wispURLDropdown].forEach((dropdown) => {
applyDropdownEventListeners(dropdown!);
});
applyDropdownEventListeners(searchEngineDropdown!, checkSearxng);
checkSearxng();
applyInputListeners(searxngUrlInput, "searxng");
applyInputListeners(bareURLInput, "bareUrl");
}
function setupCustomizationSettings() {
const store = window.idb.transaction("InstalledExtensions", "readonly").objectStore("InstalledExtensions");
store.getAll().onsuccess = (event) => {
const result = (event.target as IDBRequest).result;
if (result) {
result.forEach((extension: ExtensionMetadata) => {
if (extension.type === "theme" && extension.themeName) {
// Create a dropdown item for the theme
addThemeToDropdown(extension);
}
});
}
applySavedLocalStorage("theme", "dropdown__selected-theme");
applySavedLocalStorage("lang", "dropdown__selected-language");
const themeDropdown = document.getElementById("dropdown__selected-theme");
const languageDropdown = document.getElementById("dropdown__selected-language");
applyDropdownEventListeners(themeDropdown!, changeTheme);
applyDropdownEventListeners(languageDropdown!, navigateToNewLangaugePage);
};
}
function setupCloakingSettings() {
Array.from(document.getElementById("cloak-list")!.children).forEach((cloak) => {
cloak.addEventListener("click", () => {
const cloakEl = cloak as HTMLElement;
let cloakName = cloakEl.dataset.cloakName;
let cloakIcon = cloakEl.dataset.cloakIcon;
const cloakItem = {
name: cloakName,
value: {
name: cloakName,
icon: cloakIcon,
isCustom: false,
},
// eeyikes, make this better later.
} as unknown as Alu.Key;
Alu.store.set("cloak", cloakItem);
if (cloakName == "None") {
Alu.store.remove("cloak");
cloakName = "Settings | Alu";
cloakIcon = "/favicon.svg";
}
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
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");
}
});
});
const customNameInput = document.getElementById("cloak-custom-name-input") as HTMLInputElement;
const customFaviconInput = document.getElementById("cloak-custom-favicon-input") as HTMLInputElement;
const cloak = Alu.store.get("cloak") as Alu.Key;
if (cloak && typeof cloak.value == "object") {
if (cloak.value.isCustom) {
customNameInput.value = cloak.value.name;
customFaviconInput.value = cloak.value.icon;
}
}
document.getElementById("cloak-custom-button")!.addEventListener("click", () => {
const cloakCustomName = document.getElementById("cloak-custom-name-input") as HTMLInputElement;
const cloakCustomFavicon = document.getElementById("cloak-custom-favicon-input") as HTMLInputElement;
let cloakName = cloakCustomName.value;
let cloakIcon = cloakCustomFavicon.value;
const cloakItem = {
name: cloakName,
icon: cloakIcon,
isCustom: true,
};
// @ts-expect-error - Need to make cloak typing more standardized.
Alu.store.set("cloak", cloakItem);
if (cloakName == "None") {
Alu.store.remove("cloak");
cloakName = "Settings | Alu";
cloakIcon = "/favicon.svg";
}
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
if (!link) {
link = document.createElement("link");
link.rel = "icon";
document.head.appendChild(link);
}
link.href = cloakIcon;
document.title = cloakName;
});
}
function changeTheme() {
const theme = Alu.store.get("theme").value;
document.documentElement.setAttribute("data-theme", theme.toString());
}
function setupSettings(event: CustomEvent) {
addDropdownListener();
if (event.detail == "setting-tab-proxy") {
setupProxySettings();
} else if (event.detail == "setting-tab-customization") {
setupCustomizationSettings();
} else if (event.detail == "setting-tab-cloaking") {
setupCloakingSettings();
}
}
function checkSearxng() {
// Callback for search engine dropdown
const searchEngine = Alu.store.get("search");
const searxInput = document.getElementsByClassName("setting__searxng-url")[0] as HTMLElement;
if (searchEngine.value == "searx") {
searxInput.style.opacity = "1";
} else {
searxInput.style.opacity = "0";
}
}
document.addEventListener("setting-tabLoad", (event) => {
// I hate doing this :/
setupSettings(event as CustomEvent);
});
function navigateToNewLangaugePage() {
const value = Alu.store.get("lang").value;
const currentLanguage = window.location.pathname.split("/")[1];
if (value == currentLanguage) return;
window.location.href = `/${value}/settings`;
}
document.addEventListener("astro:after-swap", () => {
settingsLoad();
loadContent("setting-tab-proxy");
});
settingsLoad();

View file

@ -60,7 +60,7 @@
"settings.cloaking.updateCloak": "Update Cloak",
"settings.credits": "Credits",
"settings.credits.mochaandmacchiatothemes": "Mocha & Macchiato Themes",
"settings.credits.catppuccin": "Catppuccin",
"settings.credits.esTranslations": "Spanish Translations",
"settings.credits.frTranslations": "French Translations",
"settings.credits.jpTranslations": "Japanese Translations",

View file

@ -60,7 +60,7 @@
"settings.cloaking.updateCloak": "Capa de actualización",
"settings.credits": "Créditos",
"settings.credits.mochaandmacchiatothemes": "Temas de Mocha y Macchiato",
"settings.credits.catppuccin": "Temas de Mocha y Macchiato",
"settings.credits.esTranslations": "Traducciones al español",
"settings.credits.frTranslations": "Traducciones al francés",
"settings.credits.jpTranslations": "Traducciones al japonés",

View file

@ -59,7 +59,6 @@
"settings.cloaking.subtext": "Changez l'apparence de votre fenêtre",
"settings.cloaking.updateCloak": "Mettre à jour le déguise",
"settings.credits": "Crédits",
"settings.credits.mochaandmacchiatothemes": "Thème Moka & Macchiato",
"settings.credits.esTranslations": "Traductions Espagnoles",
"settings.credits.frTranslations": "Traductions Françaises",
"settings.credits.jpTranslations": "Traductions Japonais",

View file

@ -60,7 +60,6 @@
"settings.cloaking.updateCloak": "クロークを更新",
"settings.credits": "クレジット",
"settings.credits.mochaandmacchiatothemes": "モカとマキアートテーマ",
"settings.credits.esTranslations": "スペイン語翻訳",
"settings.credits.frTranslations": "フランス語翻訳",
"settings.credits.jpTranslations": "日本語翻訳",

View file

@ -60,7 +60,6 @@
"settings.cloaking.updateCloak": "Alterar camuflagem",
"settings.credits": "Créditos",
"settings.credits.mochaandmacchiatothemes": "Temas Mocha & Macchiato",
"settings.credits.esTranslations": "Traduções espanholas",
"settings.credits.frTranslations": "Traduções francesas",
"settings.credits.jpTranslations": "Traduções japonesas",

View file

@ -60,7 +60,6 @@
"settings.cloaking.updateCloak": "Обновить плащ",
"settings.credits": "Кредиты",
"settings.credits.mochaandmacchiatothemes": "Mocha и Macchiato Темы",
"settings.credits.esTranslations": "Испанские переводы",
"settings.credits.frTranslations": "Французские переводы",
"settings.credits.jpTranslations": "Японские переводы",

View file

@ -60,7 +60,6 @@
"settings.cloaking.updateCloak": "更新斗篷",
"settings.credits": "致谢",
"settings.credits.mochaandmacchiatothemes": "Mocha 和 Macchiato 主题",
"settings.credits.esTranslations": "西班牙语翻译",
"settings.credits.frTranslations": "法语翻译",
"settings.credits.jpTranslations": "日语翻译",

View file

@ -55,326 +55,7 @@ export function getStaticPaths() {
<div id="current-content"></div>
</div>
</main>
<script>
window.loadedContentStorage = {};
window.currentlySelectedTab;
document.addEventListener("astro:before-swap", () => {
window.currentlySelectedTab = "";
});
function settingsLoad() {
Array.from(document.getElementsByClassName("setting-tab")).forEach((tab) => {
const contentToLoad = document.getElementById("content-" + tab.id);
if (contentToLoad) {
window.loadedContentStorage[tab.id] = contentToLoad.innerHTML;
contentToLoad.remove();
}
tab.addEventListener("click", (event: Event) => {
const target = event.target as HTMLElement;
loadContent(target.id);
});
});
}
function loadContent(tabID: string) {
if (window.currentlySelectedTab == tabID) return;
else window.currentlySelectedTab = tabID;
const currentContent = document.getElementById("current-content");
if (currentContent) {
currentContent.style.opacity = "0";
setTimeout(() => {
currentContent.innerHTML = window.loadedContentStorage[tabID];
currentContent.style.opacity = "1";
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
}, 250);
}
}
function addDropdownListener() {
const dropdown_toggles = document.getElementsByClassName("dropdown-toggle") as HTMLCollectionOf<HTMLElement>;
Array.from(dropdown_toggles).forEach((toggle) => {
toggle.onclick = function () {
closeOtherDropdowns(toggle.id);
toggleDropdown(toggle);
};
});
}
function toggleDropdown(toggle: HTMLElement) {
const dropdown = document.getElementById(toggle.id + "-menu")!;
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 closeOtherDropdowns(dropdownIDToExclude: string) {
const dropdowns = document.getElementsByClassName("dropdown-menu") as HTMLCollectionOf<HTMLElement>;
Array.from(dropdowns).forEach((dropdown) => {
dropdown.style.maxHeight = "0px";
setTimeout(() => {
if (dropdown.id != dropdownIDToExclude + "-menu") {
const dropdown_toggle = document.getElementById(dropdown.id.replace("-menu", ""))!;
dropdown_toggle.style.borderRadius = "10px";
}
}, 300);
});
}
function closeDropdown(dropdownID: string) {
const dropdown = document.getElementById(dropdownID);
if (dropdown) {
dropdown.style.maxHeight = "0px";
setTimeout(() => {
const dropdown_toggle = document.getElementById(dropdownID.replace("-menu", ""))!;
dropdown_toggle.style.borderRadius = "10px";
}, 300);
}
}
function getLocalStorageValue(localStorageItem: Alu.ValidStoreKeys, dropdownID: string) {
// I was kinda dumb for not doing this earlier.
const dropdown = document.getElementById(dropdownID);
const dropdownMenu = document.getElementById(dropdownID + "-menu") as HTMLElement;
if (dropdown && dropdownMenu) {
// Now we find the child that matches localStorageItem.value.
const dropdownItem = Array.from(dropdownMenu.children).find((item) => {
const itemEl = item as HTMLElement;
return Alu.store.get(localStorageItem).value == itemEl.dataset.setting;
}) as HTMLElement;
// Now set the inner text to the name in the dropdownItem.
return dropdownItem.innerText;
}
}
function applySavedLocalStorage(localStorageItem: Alu.ValidStoreKeys, dropdownID: string) {
if (Alu.store.get(localStorageItem)) {
const dropdown_toggle = document.getElementById(dropdownID) as HTMLElement;
if (dropdown_toggle) {
dropdown_toggle.innerText = getLocalStorageValue(localStorageItem, dropdownID)!;
}
}
}
function applyDropdownEventListeners(dropdown: HTMLElement, optionalCallback?: Function) {
const dropdownSibling = document.getElementById(dropdown.id + "-menu")!;
const localStorageItem = dropdown.dataset.localStorageKey as Alu.ValidStoreKeys;
Array.from(dropdownSibling.children).forEach((child) => {
const childEl = child as HTMLElement;
childEl.onclick = () => {
const localStorageItemContent: Alu.Key = {
name: childEl.innerText,
value: childEl.dataset.setting!,
};
Alu.store.set(localStorageItem, localStorageItemContent);
applySavedLocalStorage(localStorageItem, dropdown.id);
closeDropdown(dropdownSibling.id);
if (typeof optionalCallback === "function") {
optionalCallback();
}
};
});
}
function applyInputListeners(input: HTMLInputElement, localStorageItem: Alu.ValidStoreKeys) {
input.addEventListener("input", () => {
Alu.store.set(localStorageItem, { value: input.value });
});
}
function addThemeToDropdown(extension: ExtensionMetadata) {
const dropdown = document.getElementById("dropdown__selected-theme-menu");
if (dropdown) {
// TODO: Figure out why addThemeToDropdown is being called 6 times
// This when you go from another page and back to settings->customization.
const duplicateItem = Array.from(dropdown.children).find((item) => {
const itemEl = item as HTMLElement;
return itemEl.dataset.setting == extension.themeName;
});
if (duplicateItem) return;
const themeItem = document.createElement("li");
themeItem.classList.add("dropdown-item");
themeItem.dataset.setting = extension.themeName;
themeItem.textContent = extension.title;
dropdown.appendChild(themeItem);
}
}
document.addEventListener("setting-tabLoad", addDropdownListener);
loadContent("setting-tab-proxy");
function setupCustomizationSettings() {
const store = window.idb.transaction("InstalledExtensions", "readonly").objectStore("InstalledExtensions");
store.getAll().onsuccess = (event) => {
const result = (event.target as IDBRequest).result;
if (result) {
result.forEach((extension: ExtensionMetadata) => {
if (extension.type === "theme" && extension.themeName) {
// Create a dropdown item for the theme
addThemeToDropdown(extension);
}
});
}
applySavedLocalStorage("theme", "dropdown__selected-theme");
applySavedLocalStorage("lang", "dropdown__selected-language");
const themeDropdown = document.getElementById("dropdown__selected-theme");
const languageDropdown = document.getElementById("dropdown__selected-language");
applyDropdownEventListeners(themeDropdown!, changeTheme);
applyDropdownEventListeners(languageDropdown!, navigateToNewLangaugePage);
};
}
function setupCloakingSettings() {
Array.from(document.getElementById("cloak-list")!.children).forEach((cloak) => {
cloak.addEventListener("click", () => {
const cloakEl = cloak as HTMLElement;
let cloakName = cloakEl.dataset.cloakName;
let cloakIcon = cloakEl.dataset.cloakIcon;
const cloakItem = {
name: cloakName,
value: {
name: cloakName,
icon: cloakIcon,
isCustom: false,
},
// eeyikes, make this better later.
} as unknown as Alu.Key;
Alu.store.set("cloak", cloakItem);
if (cloakName == "None") {
Alu.store.remove("cloak");
cloakName = "Settings | Alu";
cloakIcon = "/favicon.svg";
}
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
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");
}
});
});
const customNameInput = document.getElementById("cloak-custom-name-input") as HTMLInputElement;
const customFaviconInput = document.getElementById("cloak-custom-favicon-input") as HTMLInputElement;
const cloak = Alu.store.get("cloak") as Alu.Key;
if (cloak && typeof cloak.value == "object") {
if (cloak.value.isCustom) {
customNameInput.value = cloak.value.name;
customFaviconInput.value = cloak.value.icon;
}
}
document.getElementById("cloak-custom-button")!.addEventListener("click", () => {
const cloakCustomName = document.getElementById("cloak-custom-name-input") as HTMLInputElement;
const cloakCustomFavicon = document.getElementById("cloak-custom-favicon-input") as HTMLInputElement;
let cloakName = cloakCustomName.value;
let cloakIcon = cloakCustomFavicon.value;
const cloakItem = {
name: cloakName,
icon: cloakIcon,
isCustom: true,
};
// @ts-expect-error - Need to make cloak typing more standardized.
Alu.store.set("cloak", cloakItem);
if (cloakName == "None") {
Alu.store.remove("cloak");
cloakName = "Settings | Alu";
cloakIcon = "/favicon.svg";
}
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement;
if (!link) {
link = document.createElement("link");
link.rel = "icon";
document.head.appendChild(link);
}
link.href = cloakIcon;
document.title = cloakName;
});
}
function changeTheme() {
const theme = Alu.store.get("theme").value;
document.documentElement.setAttribute("data-theme", theme.toString());
}
function setupSettings(event: any) {
if (event.detail == "setting-tab-proxy") {
applySavedLocalStorage("proxy", "dropdown__selected-proxy");
applySavedLocalStorage("search", "dropdown__search-engine");
applySavedLocalStorage("openpage", "dropdown__open-with");
applySavedLocalStorage("wisp", "dropdown__wisp-url");
applySavedLocalStorage("transport", "dropdown__transport");
// Dropdowns
const selectedProxyDropdown = document.getElementById("dropdown__selected-proxy");
const searchEngineDropdown = document.getElementById("dropdown__search-engine");
const openWithDropdown = document.getElementById("dropdown__open-with");
const currentTransportDropdown = document.getElementById("dropdown__transport");
const wispURLDropdown = document.getElementById("dropdown__wisp-url");
// Inputs
const searxngUrlInput = document.getElementById("searxng-url-input") as HTMLInputElement;
const bareURLInput = document.getElementById("bare-url-input") as HTMLInputElement;
bareURLInput.value = Alu.store.get("bareUrl").value.toString();
// Proxy settings
[selectedProxyDropdown, openWithDropdown, currentTransportDropdown, wispURLDropdown].forEach((dropdown) => {
applyDropdownEventListeners(dropdown!);
});
applyDropdownEventListeners(searchEngineDropdown!, checkSearxng);
checkSearxng();
applyInputListeners(searxngUrlInput, "searxng");
applyInputListeners(bareURLInput, "bareUrl");
} else if (event.detail == "setting-tab-customization") {
setupCustomizationSettings();
} else if (event.detail == "setting-tab-cloaking") {
setupCloakingSettings();
}
}
function checkSearxng() {
// Callback for search engine dropdown
const searchEngine = Alu.store.get("search");
const searxInput = document.getElementsByClassName("setting__searxng-url")[0] as HTMLElement;
if (searchEngine.value == "searx") {
searxInput.style.opacity = "1";
} else {
searxInput.style.opacity = "0";
}
}
document.addEventListener("setting-tabLoad", setupSettings);
function navigateToNewLangaugePage() {
const value = Alu.store.get("lang").value;
const currentLanguage = window.location.pathname.split("/")[1];
if (value == currentLanguage) return;
window.location.href = `/${value}/settings`;
}
document.addEventListener("astro:after-swap", () => {
settingsLoad();
loadContent("setting-tab-proxy");
});
settingsLoad();
</script>
<script src="@components/ts/settings.ts"></script>
<style is:global>
.content-hidden {
display: none;