Theme support!!!!!!
This commit is contained in:
parent
6953527d2a
commit
fc77fccc55
10 changed files with 191 additions and 45 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 19 KiB |
|
|
@ -27,3 +27,56 @@ const languageList = [
|
||||||
<Dropdown buttonNameDefault="English" dropdownList={languageList} id="dropdown__selected-language" />
|
<Dropdown buttonNameDefault="English" dropdownList={languageList} id="dropdown__selected-language" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import IDBManager, { type ExtensionMetadata } from "@components/ts/IDBManager";
|
||||||
|
|
||||||
|
// let idb = IDBManager.GetIDB();
|
||||||
|
|
||||||
|
// if (!(idb instanceof IDBDatabase)) {
|
||||||
|
// idb = await loadIndexedDB();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let store = IDBManager.GetStore("InstalledExtensions", "readonly");
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// async function loadIndexedDB(): Promise<IDBDatabase> {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// const load = IDBManager.loadIDB("AluDB", 1);
|
||||||
|
// load.onsuccess = () => {
|
||||||
|
// const db = load.result;
|
||||||
|
// IDBManager.SetIDB(db);
|
||||||
|
// resolve(idb);
|
||||||
|
// };
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function addThemeToDropdown(extension: ExtensionMetadata) {
|
||||||
|
// let dropdown = document.getElementById("dropdown__selected-theme-menu");
|
||||||
|
// if (dropdown) {
|
||||||
|
// let themeItem = document.createElement("li");
|
||||||
|
// themeItem.classList.add("dropdown-item");
|
||||||
|
// themeItem.dataset.setting = extension.themeName;
|
||||||
|
// themeItem.textContent = extension.title!;
|
||||||
|
// dropdown.appendChild(themeItem);
|
||||||
|
// themeItem.addEventListener("click", () => {
|
||||||
|
// localStorage.setItem("alu__selectedTheme", JSON.stringify({ name: extension.title, value: extension.themeName }));
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// addThemeToDropdown(extension);
|
||||||
|
// }, 1000);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function switchTheme() {
|
function switchTheme() {
|
||||||
let currentTheme = localStorage.getItem("alu__selectedTheme");
|
let currentTheme = localStorage.getItem("alu__selectedTheme");
|
||||||
|
|
||||||
|
|
@ -8,9 +9,43 @@
|
||||||
if (footer) {
|
if (footer) {
|
||||||
footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase();
|
footer.dataset.theme = JSON.parse(currentTheme).value.toLowerCase();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
localStorage.setItem("alu__selectedTheme", JSON.stringify({ name: "Alu", value: "alu" }));
|
||||||
|
switchTheme();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switchTheme();
|
switchTheme();
|
||||||
|
|
||||||
document.addEventListener("astro:after-swap", switchTheme);
|
document.addEventListener("astro:after-swap", switchTheme);
|
||||||
|
|
||||||
|
import IDBManager, { type ExtensionMetadata } from "@components/ts/IDBManager";
|
||||||
|
const idb = IDBManager.loadIDB("AluDB", 1);
|
||||||
|
|
||||||
|
idb.onsuccess = () => {
|
||||||
|
const db = idb.result;
|
||||||
|
IDBManager.SetIDB(db);
|
||||||
|
|
||||||
|
let store = IDBManager.GetStore("InstalledExtensions", "readonly");
|
||||||
|
store.getAll().onsuccess = (event) => {
|
||||||
|
const result = (event.target as IDBRequest).result;
|
||||||
|
if (result) {
|
||||||
|
result.forEach((extension: ExtensionMetadata) => {
|
||||||
|
if (extension.type === "theme" && extension.themeName) {
|
||||||
|
// Load theme CSS
|
||||||
|
window.loadedThemeAtob = atob(extension.scriptCopy!);
|
||||||
|
loadStyleFromAtob();
|
||||||
|
|
||||||
|
document.addEventListener("astro:after-swap", () => {
|
||||||
|
loadStyleFromAtob();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function loadStyleFromAtob() {
|
||||||
|
const style = document.createElement("style");
|
||||||
|
style.textContent = window.loadedThemeAtob;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const { buttonNameDefault, dropdownList, id, localStorageKey } = Astro.props;
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style is:global>
|
||||||
.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;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,19 @@
|
||||||
|
type VALID_EXT_TYPES = "serviceWorker" | "theme" | "page";
|
||||||
|
export interface ExtensionMetadata {
|
||||||
|
title: string;
|
||||||
|
// TODO: Add description to the manifest
|
||||||
|
// description: string;
|
||||||
|
|
||||||
|
// Versions should follow semantic versioning
|
||||||
|
version: string;
|
||||||
|
script: string;
|
||||||
|
entryNamespace?: string;
|
||||||
|
entryFunc?: string;
|
||||||
|
scriptCopy: string | null;
|
||||||
|
type: VALID_EXT_TYPES;
|
||||||
|
themeName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export let CurrentIDB: IDBDatabase;
|
export let CurrentIDB: IDBDatabase;
|
||||||
|
|
||||||
export function loadIDB(name: string, version: number) {
|
export function loadIDB(name: string, version: number) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ declare global {
|
||||||
};
|
};
|
||||||
loadFormContent: Function | null;
|
loadFormContent: Function | null;
|
||||||
loadSelectedTransport: Function | null;
|
loadSelectedTransport: Function | null;
|
||||||
|
loadedThemeAtob: string;
|
||||||
|
idb: IDBDatabase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,17 @@ import "notyf/notyf.min.css";
|
||||||
import { Notyf } from "notyf";
|
import { Notyf } from "notyf";
|
||||||
import marketplaceManifest from "../../json/marketplace.json";
|
import marketplaceManifest from "../../json/marketplace.json";
|
||||||
const installButtons = document.getElementsByClassName("btn-install");
|
const installButtons = document.getElementsByClassName("btn-install");
|
||||||
import IDBManager from "./IDBManager";
|
import IDBManager, { type ExtensionMetadata } from "./IDBManager";
|
||||||
|
|
||||||
|
|
||||||
type VALID_EXT_TYPES = "serviceWorker" | "theme" | "page";
|
|
||||||
|
|
||||||
// This just makes it shorter to type
|
// This just makes it shorter to type
|
||||||
interface HTMLButton extends HTMLButtonElement {}
|
interface HTMLButton extends HTMLButtonElement {}
|
||||||
|
|
||||||
interface ExtensionMetadata {
|
|
||||||
title: string;
|
|
||||||
// TODO: Add description to the manifest
|
|
||||||
// description: string;
|
|
||||||
|
|
||||||
// Versions should follow semantic versioning
|
|
||||||
version: string;
|
|
||||||
script: string;
|
|
||||||
entryNamespace?: string;
|
|
||||||
entryFunc?: string;
|
|
||||||
scriptCopy: string | null;
|
|
||||||
type: VALID_EXT_TYPES;
|
|
||||||
themeName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum EXT_RETURN {
|
enum EXT_RETURN {
|
||||||
INSTALL_SUCCESS = 0,
|
ACTION_SUCCESS = 0,
|
||||||
INSTALL_FAILED = -1,
|
INSTALL_FAILED = -1,
|
||||||
ALREADY_INSTALLED = 1,
|
ALREADY_INSTALLED = 1,
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +41,7 @@ Array.from(installButtons).forEach((btn) => {
|
||||||
let notifMessage: string;
|
let notifMessage: string;
|
||||||
let timeout = 2000;
|
let timeout = 2000;
|
||||||
switch (ret.code) {
|
switch (ret.code) {
|
||||||
case EXT_RETURN.INSTALL_SUCCESS:
|
case EXT_RETURN.ACTION_SUCCESS:
|
||||||
notifMessage = `Installed ${title} Successfully!`;
|
notifMessage = `Installed ${title} Successfully!`;
|
||||||
// Unregister the service worker if it's a service worker
|
// Unregister the service worker if it's a service worker
|
||||||
if (obj.type === "serviceWorker") {
|
if (obj.type === "serviceWorker") {
|
||||||
|
|
@ -82,8 +69,8 @@ Array.from(installButtons).forEach((btn) => {
|
||||||
notification.options.duration = 2000;
|
notification.options.duration = 2000;
|
||||||
notification.success(notifMessage);
|
notification.success(notifMessage);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
notification.success(`Please refresh the page to see the changes!`);
|
window.location.reload();
|
||||||
}, 200)
|
}, 1000)
|
||||||
notification.options.duration = 999999;
|
notification.options.duration = 999999;
|
||||||
let btn = document.querySelector(`button[data-slug="${ret.slug}"]`) as HTMLButton;
|
let btn = document.querySelector(`button[data-slug="${ret.slug}"]`) as HTMLButton;
|
||||||
setInstallBtnText(btn);
|
setInstallBtnText(btn);
|
||||||
|
|
@ -125,7 +112,7 @@ async function installExtension(ext: ExtensionMetadata, slug: string): Promise<I
|
||||||
reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug });
|
reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug });
|
||||||
};
|
};
|
||||||
addRequest.onsuccess = () => {
|
addRequest.onsuccess = () => {
|
||||||
resolve({ code: EXT_RETURN.INSTALL_SUCCESS, slug: slug });
|
resolve({ code: EXT_RETURN.ACTION_SUCCESS, slug: slug });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -145,7 +132,7 @@ document.querySelectorAll("button[data-uninstall-slug]").forEach((btn) => {
|
||||||
ripple: true,
|
ripple: true,
|
||||||
});
|
});
|
||||||
switch (uninst.code) {
|
switch (uninst.code) {
|
||||||
case EXT_RETURN.INSTALL_SUCCESS:
|
case EXT_RETURN.ACTION_SUCCESS:
|
||||||
notification.success(`Uninstalled ${uninst.title}!`);
|
notification.success(`Uninstalled ${uninst.title}!`);
|
||||||
let btn = document.querySelector(`button[data-slug="${uninst.slug}"]`) as HTMLButton;
|
let btn = document.querySelector(`button[data-slug="${uninst.slug}"]`) as HTMLButton;
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
|
|
@ -171,6 +158,21 @@ async function uninstallExtension(slug: string): Promise<InstallReturn> {
|
||||||
const request = IDBManager.GetIDB();
|
const request = IDBManager.GetIDB();
|
||||||
const transaction = request.transaction("InstalledExtensions", "readwrite");
|
const transaction = request.transaction("InstalledExtensions", "readwrite");
|
||||||
const store = transaction.objectStore("InstalledExtensions");
|
const store = transaction.objectStore("InstalledExtensions");
|
||||||
|
|
||||||
|
let ext = store.get(slug);
|
||||||
|
ext.onsuccess = async () => {
|
||||||
|
if (ext.result == null) {
|
||||||
|
reject({ code: EXT_RETURN.INSTALL_FAILED, slug: slug });
|
||||||
|
}
|
||||||
|
if (ext.result.type === "theme") {
|
||||||
|
let currTheme = localStorage.getItem("alu__selectedTheme");
|
||||||
|
if (currTheme) {
|
||||||
|
if (JSON.parse(currTheme!).value == ext.result.themeName) {
|
||||||
|
console.log("Reverting theme to default!")
|
||||||
|
localStorage.setItem("alu__selectedTheme", JSON.stringify({ name: "Alu", value: "alu" }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const deleteRequest = store.delete(slug);
|
const deleteRequest = store.delete(slug);
|
||||||
deleteRequest.onerror = () => {
|
deleteRequest.onerror = () => {
|
||||||
console.error(`Error uninstalling ${slug}!`);
|
console.error(`Error uninstalling ${slug}!`);
|
||||||
|
|
@ -184,7 +186,8 @@ async function uninstallExtension(slug: string): Promise<InstallReturn> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
resolve({ code: EXT_RETURN.INSTALL_SUCCESS, slug: slug, title: slug });
|
resolve({ code: EXT_RETURN.ACTION_SUCCESS, slug: slug, title: ext.result.title });
|
||||||
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"image": "/marketplace/oled-theme/theme.png",
|
"image": "/marketplace/oled-theme/theme.png",
|
||||||
"script": "/marketplace/oled-theme/theme.css",
|
"script": "/marketplace/oled-theme/theme.css",
|
||||||
"type": "style",
|
"type": "theme",
|
||||||
"themeName": "oled"
|
"themeName": "oled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@ const { title, optionalPreloads } = Astro.props;
|
||||||
<Footer />
|
<Footer />
|
||||||
<style is:global>
|
<style is:global>
|
||||||
:root {
|
:root {
|
||||||
|
--background-color: black;
|
||||||
|
}
|
||||||
|
[data-theme="alu"] {
|
||||||
--background-color: #211d29;
|
--background-color: #211d29;
|
||||||
--background-highlight: #35314a;
|
--background-highlight: #35314a;
|
||||||
--accent-color: #624978;
|
--accent-color: #624978;
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,15 @@ export function getStaticPaths() {
|
||||||
<div id="current-content"></div>
|
<div id="current-content"></div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
<script>
|
||||||
|
import IDBManager, { type ExtensionMetadata } from "@components/ts/IDBManager";
|
||||||
|
let load = IDBManager.loadIDB("AluDB", 1);
|
||||||
|
load.onsuccess = () => {
|
||||||
|
window.idb = IDBManager.GetIDB();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
window.loadedContentStorage = {};
|
loadedContentStorage = {};
|
||||||
window.currentlySelectedTab;
|
window.currentlySelectedTab;
|
||||||
function settingsLoad() {
|
function settingsLoad() {
|
||||||
document.addEventListener("astro:before-swap", () => {
|
document.addEventListener("astro:before-swap", () => {
|
||||||
|
|
@ -67,7 +74,7 @@ export function getStaticPaths() {
|
||||||
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;
|
loadedContentStorage[tab.id] = contentToLoad.innerHTML;
|
||||||
contentToLoad.remove();
|
contentToLoad.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +90,7 @@ export function getStaticPaths() {
|
||||||
if (currentContent) {
|
if (currentContent) {
|
||||||
currentContent.style.opacity = "0";
|
currentContent.style.opacity = "0";
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
currentContent.innerHTML = window.loadedContentStorage[tabID];
|
currentContent.innerHTML = loadedContentStorage[tabID];
|
||||||
currentContent.style.opacity = "1";
|
currentContent.style.opacity = "1";
|
||||||
document.dispatchEvent(new CustomEvent("setting-tabChange", { detail: tabID }));
|
document.dispatchEvent(new CustomEvent("setting-tabChange", { detail: tabID }));
|
||||||
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
|
document.dispatchEvent(new CustomEvent("setting-tabLoad", { detail: tabID }));
|
||||||
|
|
@ -193,17 +200,44 @@ export function getStaticPaths() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addThemeToDropdown(extension) {
|
||||||
|
let dropdown = document.getElementById("dropdown__selected-theme-menu");
|
||||||
|
if (dropdown) {
|
||||||
|
let themeItem = document.createElement("li");
|
||||||
|
themeItem.classList.add("dropdown-item");
|
||||||
|
themeItem.dataset.setting = extension.themeName;
|
||||||
|
themeItem.textContent = extension.title;
|
||||||
|
dropdown.appendChild(themeItem);
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
addThemeToDropdown(extension);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("setting-tabChange", determineListener);
|
document.addEventListener("setting-tabChange", determineListener);
|
||||||
|
|
||||||
loadContent("setting-tab-proxy");
|
loadContent("setting-tab-proxy");
|
||||||
|
|
||||||
function setupCustomizationSettings() {
|
function setupCustomizationSettings() {
|
||||||
|
let store = window.idb.transaction("InstalledExtensions", "readonly").objectStore("InstalledExtensions");
|
||||||
|
store.getAll().onsuccess = (event) => {
|
||||||
|
const result = event.target.result;
|
||||||
|
if (result) {
|
||||||
|
result.forEach((extension) => {
|
||||||
|
if (extension.type === "theme" && extension.themeName) {
|
||||||
|
// Create a dropdown item for the theme
|
||||||
|
addThemeToDropdown(extension);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
|
applySavedLocalStorage("alu__selectedTheme", "dropdown__selected-theme");
|
||||||
applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language");
|
applySavedLocalStorage("alu__selectedLanguage", "dropdown__selected-language");
|
||||||
let themeDropdown = document.getElementById("dropdown__selected-theme-menu");
|
let themeDropdown = document.getElementById("dropdown__selected-theme-menu");
|
||||||
let languageDropdown = document.getElementById("dropdown__selected-language-menu");
|
let languageDropdown = document.getElementById("dropdown__selected-language-menu");
|
||||||
applyDropdownEventListeners(themeDropdown, "dropdown__selected-theme", "alu__selectedTheme", changeTheme);
|
applyDropdownEventListeners(themeDropdown, "dropdown__selected-theme", "alu__selectedTheme", changeTheme);
|
||||||
applyDropdownEventListeners(languageDropdown, "dropdown__selected-language", "alu__selectedLanguage", navigateToNewLangaugePage);
|
applyDropdownEventListeners(languageDropdown, "dropdown__selected-language", "alu__selectedLanguage", navigateToNewLangaugePage);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupCloakingSettings() {
|
function setupCloakingSettings() {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue