138 lines
5.9 KiB
Text
138 lines
5.9 KiB
Text
<div id="parent" class="flex flex-row flex-wrap gap-4 items-center font-roboto justify-center">
|
|
<div id="main-theme" class="rounded-3xl bg-navbar-color w-64 flex flex-col cursor-pointer">
|
|
<div class="w-full">
|
|
<img src="/classic_theme.png" alt="Classic nebula" class="aspect-[16/9] rounded-t-3xl" loading="eager" />
|
|
</div>
|
|
<div class="h-2/6 text-center content-center p-3 font-semibold items-center flex flex-col text-2xl">
|
|
Classic Nebula
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="w-0 h-0 visibility-none hidden">
|
|
<asset-loader />
|
|
</div>
|
|
|
|
<script>
|
|
import { Elements } from "@utils/index";
|
|
import { Marketplace } from "@utils/marketplace";
|
|
import { SettingsVals } from "@utils/values";
|
|
|
|
type Item = {
|
|
description: string,
|
|
image: string,
|
|
package_name: string,
|
|
payload: string,
|
|
tags: [],
|
|
background_video: string,
|
|
background_image: string,
|
|
title: string,
|
|
type: string,
|
|
version: string
|
|
}
|
|
|
|
const getItem = async (item: any) => {
|
|
try {
|
|
const res = await fetch(new URL(`/api/packages/${item}`, window.location.origin));
|
|
const data = await res.json();
|
|
return { ...data, package_name: item }
|
|
}
|
|
catch (err: any) {
|
|
console.log(`Err in themes: ${err}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const constructElements = async (item: Item, mainTheme: HTMLDivElement, parent: HTMLDivElement, marketplace: Marketplace) => {
|
|
const main = document.createElement("div");
|
|
main.classList.add("rounded-3xl", "bg-navbar-color", "w-64", "flex", "flex-col", "cursor-pointer", "border-text-color");
|
|
main.dataset.name = item.package_name
|
|
|
|
const click = document.createElement("div");
|
|
click.classList.add("w-full");
|
|
|
|
const img = document.createElement("img");
|
|
img.classList.add("aspect-[16/9]", "rounded-t-3xl");
|
|
img.src = `/packages/${item.package_name}/${item.image}`;
|
|
img.alt = `${item.type}-${item.package_name}`;
|
|
img.loading = "lazy";
|
|
|
|
const info = document.createElement("div");
|
|
info.classList.add("h-2/6", "text-center", "content-center", "p-3", "font-semibold", "items-center", "flex", "flex-col");
|
|
|
|
const infoTitle = document.createElement("p");
|
|
infoTitle.classList.add("text-2xl");
|
|
infoTitle.innerHTML = item.title;
|
|
|
|
const infoInner = document.createElement("div");
|
|
infoInner.classList.add("flex", "flex-row");
|
|
|
|
const infoInnerDelete = document.createElement("div");
|
|
infoInnerDelete.classList.add("h-8", "w-8", "cursor-pointer");
|
|
// This is cursed yes. SVG's SUUUCK
|
|
infoInnerDelete.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M216 48h-40v-8a24 24 0 0 0-24-24h-48a24 24 0 0 0-24 24v8H40a8 8 0 0 0 0 16h8v144a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16V64h8a8 8 0 0 0 0-16M112 168a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm48 0a8 8 0 0 1-16 0v-64a8 8 0 0 1 16 0Zm0-120H96v-8a8 8 0 0 1 8-8h48a8 8 0 0 1 8 8Z" /></svg>`;
|
|
|
|
const infoInnerOpen = document.createElement("a");
|
|
infoInnerOpen.classList.add("h-8", "w-8", "cursor-pointer");
|
|
infoInnerOpen.href = `../catalog/package/${item.package_name}`;
|
|
infoInnerOpen.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256"><path fill="currentColor" d="M192 136v72a16 16 0 0 1-16 16H48a16 16 0 0 1-16-16V80a16 16 0 0 1 16-16h72a8 8 0 0 1 0 16H48v128h128v-72a8 8 0 0 1 16 0m32-96a8 8 0 0 0-8-8h-64a8 8 0 0 0-5.66 13.66L172.69 72l-42.35 42.34a8 8 0 0 0 11.32 11.32L184 83.31l26.34 26.35A8 8 0 0 0 224 104Z" /></svg>`;
|
|
|
|
click.appendChild(img);
|
|
infoInner.appendChild(infoInnerDelete);
|
|
infoInner.appendChild(infoInnerOpen);
|
|
info.appendChild(infoTitle);
|
|
info.appendChild(infoInner);
|
|
main.appendChild(click);
|
|
main.appendChild(info);
|
|
parent.appendChild(main);
|
|
|
|
|
|
Elements.attachEvent(mainTheme, "click", () => {
|
|
marketplace.theme({ type: 'remove' });
|
|
});
|
|
|
|
Elements.attachEvent(click, "click", async () => {
|
|
await marketplace.theme(
|
|
{
|
|
type: 'normal',
|
|
payload: item.payload,
|
|
sources: {
|
|
video: item.background_video,
|
|
bg: item.background_image
|
|
},
|
|
name: item.package_name
|
|
}
|
|
);
|
|
});
|
|
|
|
Elements.attachEvent(infoInnerDelete, "click", async () => {
|
|
await marketplace.uninstallTheme({ name: item.package_name });
|
|
parent.removeChild(main);
|
|
await marketplace.theme({ type: 'remove' });
|
|
});
|
|
}
|
|
|
|
const init = async () => {
|
|
await Marketplace.ready();
|
|
const mp = Marketplace.getInstances().next().value!;
|
|
const els = Elements.select([
|
|
{ type: 'id', val: 'main-theme' },
|
|
{ type: 'id', val: 'parent' }
|
|
]);
|
|
const itemsJSON = JSON.parse(await mp.getValueFromStore(SettingsVals.marketPlace.themes)) || [];
|
|
const itemPromises = itemsJSON.map(getItem);
|
|
const itemsArray = await Promise.all(itemPromises);
|
|
return {
|
|
items: itemsArray.filter((data) => data !== null),
|
|
elements: els,
|
|
marketplace: mp
|
|
}
|
|
}
|
|
|
|
Elements.createCustomElement("asset-loader", async () => {
|
|
const { items, elements, marketplace } = await init();
|
|
const mainTheme = Elements.exists<HTMLDivElement>(await elements.next());
|
|
const parentElem = Elements.exists<HTMLDivElement>(await elements.next());
|
|
const promises = items.map(item => constructElements(item, mainTheme, parentElem, marketplace));
|
|
await Promise.all(promises);
|
|
});
|
|
</script>
|