mirror of
https://github.com/NebulaServices/Nebula.git
synced 2025-05-13 03:50:02 -04:00
Marketplace: change the way we deal with themes (no refresh)
This commit is contained in:
parent
6b227f241b
commit
c63662f602
17 changed files with 352 additions and 392 deletions
|
@ -1,19 +1,19 @@
|
|||
:root {
|
||||
--background-primary: rgba(0, 0, 0, 0) !important;
|
||||
--background-lighter: #000 !important;
|
||||
--navbar-color: #000 !important;
|
||||
--navbar-height: 60px !important;
|
||||
--navbar-text-color: greenyellow !important;
|
||||
--navbar-link-color: greenyellow !important;
|
||||
--navbar-link-hover-color: green !important;
|
||||
--navbar-font: "Roboto" !important;
|
||||
--input-text-color: greenyellow !important;
|
||||
--input-placeholder-color: white !important;
|
||||
--input-background-color: #000 !important;
|
||||
--input-border-color: greenyellow !important;
|
||||
--input-border-size: 1.3px !important;
|
||||
--navbar-logo-filter: none !important;
|
||||
--dropdown-option-hover-color: #312a49 !important;
|
||||
--tab-color: var(--black) !important;
|
||||
--border-color: greenyellow !important;
|
||||
--background-primary: rgba(0, 0, 0, 0) ;
|
||||
--background-lighter: #000 ;
|
||||
--navbar-color: #000 ;
|
||||
--navbar-height: 60px ;
|
||||
--navbar-text-color: greenyellow ;
|
||||
--navbar-link-color: greenyellow ;
|
||||
--navbar-link-hover-color: green ;
|
||||
--navbar-font: "Roboto" ;
|
||||
--input-text-color: greenyellow ;
|
||||
--input-placeholder-color: white ;
|
||||
--input-background-color: #000 ;
|
||||
--input-border-color: greenyellow ;
|
||||
--input-border-size: 1.3px ;
|
||||
--navbar-logo-filter: none ;
|
||||
--dropdown-option-hover-color: #312a49 ;
|
||||
--tab-color: var(--black) ;
|
||||
--border-color: greenyellow ;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"@mercuryworkshop/libcurl-transport": "^1.3.10",
|
||||
"@rubynetwork/rammerhead": "^1.3.5",
|
||||
"@rubynetwork/rammerhead-browser": "^1.0.9",
|
||||
"@svelte-drama/suspense": "0.5.1",
|
||||
"@titaniumnetwork-dev/ultraviolet": "3.1.2",
|
||||
"astro": "^4.15.11",
|
||||
"astro-icon": "^1.1.1",
|
||||
|
|
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
|
@ -44,6 +44,9 @@ importers:
|
|||
'@rubynetwork/rammerhead-browser':
|
||||
specifier: ^1.0.9
|
||||
version: 1.0.9
|
||||
'@svelte-drama/suspense':
|
||||
specifier: 0.5.1
|
||||
version: 0.5.1(svelte@4.2.19)
|
||||
'@titaniumnetwork-dev/ultraviolet':
|
||||
specifier: 3.1.2
|
||||
version: 3.1.2
|
||||
|
@ -829,6 +832,11 @@ packages:
|
|||
'@shikijs/vscode-textmate@9.3.0':
|
||||
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
|
||||
|
||||
'@svelte-drama/suspense@0.5.1':
|
||||
resolution: {integrity: sha512-fovSQHYDxb9fEnMVBHxBi4v39CR+Hrsp16lSYOHm+aPfm8FyBQtG8VsrIg9BszNWz8GCEFIVCaE/Iqty1ovB6Q==}
|
||||
peerDependencies:
|
||||
svelte: ^3.54.0 || ^4.0.0 || ^5.0.0
|
||||
|
||||
'@sveltejs/vite-plugin-svelte-inspector@2.1.0':
|
||||
resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==}
|
||||
engines: {node: ^18.0.0 || >=20}
|
||||
|
@ -4603,6 +4611,10 @@ snapshots:
|
|||
|
||||
'@shikijs/vscode-textmate@9.3.0': {}
|
||||
|
||||
'@svelte-drama/suspense@0.5.1(svelte@4.2.19)':
|
||||
dependencies:
|
||||
svelte: 4.2.19
|
||||
|
||||
'@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.8(@types/node@22.7.5)))(svelte@4.2.19)(vite@5.4.8(@types/node@22.7.5))':
|
||||
dependencies:
|
||||
'@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.8(@types/node@22.7.5))
|
||||
|
|
23
src/components/Loading.astro
Normal file
23
src/components/Loading.astro
Normal file
|
@ -0,0 +1,23 @@
|
|||
<div class="w-full h-full bg-primary text-navbar-text-color flex justify-center items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 400 400" width="400" height="400" fill="#5e17eb" class="animate-pulse-brighter w-48 h-48">
|
||||
<g id="svgg">
|
||||
<path id="path0" fill-rule="evenodd" class="s0" d="m213.6 84c1 0.3 3.4 0.7 5.1 1 1.8 0.2 4.1 0.7 5.2 1 13.2 4.1 20.3 6.8 24.5 9.1 0.6 0.3 2.3 1.2 3.8 2 2.8 1.4 13.1 8 14.4 9.2 0.5 0.3 2.3 1.9 4.2 3.5 6.7 5.5 15.5 14.9 19.2 20.4 1 1.4 2 2.7 2.2 2.8 0.3 0.1 0.5 0.5 0.5 0.8 0 0.3 1.2 2.2 2.5 4.3 2.3 3.4 7.8 14.3 9.8 19.3 0.8 2.1 0.9 2.2 10 4.9 5.6 1.6 11.1 3.4 11.7 3.8 0.3 0.2 2.4 1.1 4.7 1.9 11.1 4.1 23 12.5 27.3 19.4 5.5 8.7 3.6 20.5-4.5 28.5-3.1 3-7.5 6.4-8.4 6.4-0.3 0-0.7 0.2-0.8 0.5-1.1 2.3-23.3 11.2-35.9 14.3-3.2 0.9-3.5 1.2-5.7 6.8-7.5 19-25.5 40.6-42.3 51.1-1.6 1-3.1 2-3.3 2.2-0.1 0.2-0.9 0.7-1.7 1.2-0.8 0.4-2.2 1.2-2.9 1.6-0.8 0.4-1.6 1-1.8 1.1-0.5 0.5-4.1 2.2-8.1 3.9-1.8 0.8-3.8 1.6-4.5 2-0.7 0.3-3.1 1.1-5.2 1.8-8.3 2.6-9.8 3-21 4.9-6.4 1.1-25.3 1.3-30.5 0.3-1.9-0.3-5.8-1.1-8.6-1.6-6.8-1.3-12.7-3-20-5.7-3.3-1.2-18-8.8-19.7-10.1-0.9-0.7-4.1-3.1-7.1-5.2-5.7-4.1-17.9-15.9-20.7-20-0.9-1.2-2-2.7-2.5-3.2-3.2-3.3-13.7-21.7-13.7-24.1 0-0.6-0.2-1.2-0.6-1.4-0.3-0.2-0.8-1.2-1-2.3-0.4-1.9-1.7-2.7-6.5-3.8-23.2-5.6-43.1-17.2-48.6-28.5-7.1-14.4 4.5-31.3 27.3-39.7 1.8-0.7 4.1-1.6 5.2-2 3.7-1.5 8-2.9 19.5-6.2 1.6-0.5 2.8-1.2 2.8-1.7 0-2.4 9.8-21.6 13.1-25.7 0.2-0.4 1.4-1.8 2.5-3.2 13.8-18.1 30.2-30.6 50.6-38.8 4.3-1.7 6-2.3 14.3-4.5 5.5-1.6 11.2-2.4 18.4-2.9 7.9-0.5 24-0.2 26.8 0.6zm-29.7 17.3c-0.2 0.1-7.3 1.7-12.9 2.7-1.7 0.4-4.3 1.2-5.8 1.9-1.5 0.6-3.9 1.5-5.5 2-1.5 0.4-3.3 1.3-4 2-0.7 0.7-1.7 1.2-2.3 1.2-1.2 0-9.5 4.5-9.8 5.3-0.2 0.3-0.5 0.6-0.9 0.6-1.9 0-19.6 16-23.8 21.6-9.3 12.2-16.1 27.4-19.2 42.7-2 10.1-1.1 37.5 1.4 41.4 0 0.1 3.7 0.9 8.1 1.8 9.5 1.9 12.8 2.4 34.6 4.9 38.5 4.5 107.9 2.2 138.3-4.5 1.4-0.3 4.1-0.9 6.1-1.3 4.2-0.8 3.4 0.2 4.9-7.1 1.6-8.3 1.7-27 0.1-34.6-1.5-7.1-3.2-13.4-3.7-14.2-0.3-0.4-0.7-1.5-0.9-2.6-2.8-12.1-19.2-34.1-33-44.3-2.9-2.1-5.5-4-5.8-4.3-2.8-2.2-4.9-3.1-7.2-3.1-2.1 0-2.6-0.2-2.7-1.3-0.2-1.5-5.7-4.5-6.3-3.5-0.7 1.1-2.4 0.6-2.7-0.7-0.4-1.3-1.2-1.6-5.8-2.1-1.6-0.2-4-0.9-5.5-1.6-3.9-1.8-5.3-2.2-10.2-2.6-4.6-0.4-25.2-0.7-25.5-0.3zm74.3 42.2c7.4 9.8 4.8 23.5-4.6 24.9-6.9 1-20.9-5.8-21-10.2 0-0.2-0.3-0.8-0.8-1.3-6.4-6.8-5-20.8 2.4-24.1 6.7-2.9 17.2 1.8 24 10.7zm-176.4 36.4c-0.1-0.1-4.6 1.1-5.9 1.6-0.7 0.3-3 1.2-5.1 2-9.9 3.8-15.1 6.8-19.6 11.5-3.4 3.5-3.3 4.5 0.5 8.7 1 1 11.3 7.6 12 7.6 0.2 0 1.7 0.6 3.4 1.3 1.6 0.8 3.6 1.6 4.3 1.9 1.8 0.8 9.3 3.3 9.9 3.3 0.3 0 0.3-2 0-4.4-0.6-5.6-0.6-24.5 0.1-29.6 0.3-2.1 0.5-3.9 0.4-3.9zm229.3-0.3c-0.2 0 0 1 0.2 2.1 0.6 2.8 0.6 31.3 0 34-0.5 2.2-0.4 2.2 1.3 1.8 3.1-0.7 12.9-4.5 18.3-7 8.5-4 14.3-10.1 12.6-13.3-1.1-2.1-6.7-7.2-7.9-7.2-0.4 0-0.9-0.2-1-0.5-0.4-1.1-11.8-6.1-19.2-8.5-2.3-0.7-4.2-1.4-4.3-1.4zm-199.4 63.4l-3.1-0.4 1.8 3.2c0.9 1.8 1.9 3.4 2.2 3.5 0.3 0.1 0.5 0.6 0.5 1.1 0 0.4 0.6 1.5 1.3 2.3 0.7 0.9 1.5 1.9 1.8 2.2 0.3 0.4 0.8 1.2 1.1 1.7 6.2 10.7 35.6 33.5 43.3 33.5 0.2 0 1.3 0.4 2.5 0.9 2.5 1.2 10.6 3.4 15.3 4.2 9.5 1.8 11.6 2.1 17.4 2.1 6.6 0 16.4-1.3 22.9-3 2.2-0.5 5.2-1.3 6.8-1.7 1.6-0.3 3.2-0.9 3.5-1.2 0.4-0.3 1.1-0.6 1.6-0.6 2.3 0 22-10.6 24-12.9 0.2-0.2 2.2-1.9 4.5-3.7 5.7-4.5 11.8-11 17.1-18.4 1.6-2.3 3.2-4.5 3.6-4.9 0.4-0.4 0.7-1 0.7-1.2 0-0.2 0.8-1.9 1.9-3.6 1.1-1.7 1.9-3.2 1.9-3.4 0-0.2-3.8 0.4-11 1.6-31.7 5.4-85.1 6.7-126.9 3.1-9.6-0.8-23.1-2.3-27.8-3.2-2.2-0.4-5.3-0.9-6.9-1.2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<style>
|
||||
@keyframes pulse-brighter {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.animate-pulse-brighter {
|
||||
animation: pulse-brighter 2s infinite;
|
||||
height: 11rem;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,63 +1,46 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { Settings } from "@utils/settings";
|
||||
import { Suspense } from "@svelte-drama/suspense";
|
||||
export let page;
|
||||
let assetPromise = get_assets();
|
||||
async function get_assets() {
|
||||
async function getAssets() {
|
||||
const response = await fetch("/api/catalog-assets?page=" + page);
|
||||
const data = await response.json();
|
||||
return data.assets;
|
||||
}
|
||||
const assets = getAssets();
|
||||
</script>
|
||||
|
||||
<div class="text-3xl roboto font-bold text-text-color p-10">
|
||||
{#await assetPromise}
|
||||
Loading assets...
|
||||
{:then assets}
|
||||
{#if Object.keys(assets).length > 0}
|
||||
<div class="flex flex-row gap-6 flex-wrap justify-center">
|
||||
{#each Object.entries(assets) as [key, asset]}
|
||||
<a href={"/assets/" + key}>
|
||||
<div
|
||||
class="bg-navbar-color w-64 rounded-3xl shadow-lg overflow-hidden transition-transform duration-300 hover:scale-105"
|
||||
>
|
||||
<img
|
||||
src={"/images/" + asset.image}
|
||||
alt={asset.title}
|
||||
class="w-full h-40 object-cover"
|
||||
/>
|
||||
<div class="p-6 text-sm">
|
||||
<div class="font-semibold text-2xl mb-2">
|
||||
{asset.title}
|
||||
<Suspense let:suspend>
|
||||
<div slot="loading">
|
||||
<p class="text-4xl"> Loading... </p>
|
||||
</div>
|
||||
{#await suspend(assets) then data}
|
||||
{#if Object.keys(data).length > 0}
|
||||
<div class="flex flex-row gap-6 flex-wrap justify-center">
|
||||
{#each Object.entries(data) as [key, asset]}
|
||||
<a href={`/assets/${key}`}>
|
||||
<div class="bg-navbar-color w-64 rounded-3xl shadow-lg overflow-hidden transition-transform duration-300 hover:scale-105">
|
||||
<img src={`/images/${asset.image}`} alt={asset.title} class="w-full h-40 object-cover" />
|
||||
<div class="p-6 text-sm">
|
||||
<p class="font-semibold text-2xl mb-2"> {asset.title} </p>
|
||||
<p class="mb-4"> {asset.description} </p>
|
||||
<div class="flex flex-wrap gap-2 mb-4 w-full">
|
||||
{#each asset.tags as tag}
|
||||
<p class="bg-navbar-text-color text-navbar-color font-bold px-3 py-1 rounded-md text-center"> {tag} </p>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Version:</strong>
|
||||
{asset.version}
|
||||
</div>
|
||||
<div><strong>Type:</strong> {asset.type}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="mb-4">{asset.description}</div>
|
||||
<div class="flex flex-wrap gap-2 mb-4">
|
||||
{#each asset.tags as tag}
|
||||
<div
|
||||
class="bg-navbar-text-color text-navbar-color font-bold px-3 py-1 rounded-md text-center"
|
||||
>
|
||||
{tag}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Version:</strong>
|
||||
{asset.version}
|
||||
</div>
|
||||
<div><strong>Type:</strong> {asset.type}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-2xl text-center text-text-color mt-6 w-96">
|
||||
No assets available at the moment. The server host's database is empty.
|
||||
Please contact the maintainer of this site if you think this is an
|
||||
error.
|
||||
</div>
|
||||
{/if}
|
||||
{:catch someError}
|
||||
<div class="text-lg text-center text-red-500 mt-6">
|
||||
System error: {someError.message}.
|
||||
</div>
|
||||
{/await}
|
||||
{/if}
|
||||
{/await}
|
||||
</Suspense>
|
||||
</div>
|
||||
|
|
|
@ -1,144 +1,64 @@
|
|||
<script>
|
||||
let assetPromise = get_all_assets();
|
||||
async function logItem(item) {
|
||||
// hell
|
||||
try {
|
||||
const response = await fetch(`/api/packages/${item}`);
|
||||
const data = await response.json();
|
||||
|
||||
return {
|
||||
...data,
|
||||
package_name: item
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("error: failed to fetch", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function get_all_assets() {
|
||||
let items = JSON.parse(localStorage.getItem("installed_themes")) || [];
|
||||
const promises = items.map(logItem);
|
||||
const dataArray = await Promise.all(promises);
|
||||
|
||||
const accumulatedData = dataArray.filter((data) => data !== null);
|
||||
console.log(JSON.stringify(accumulatedData));
|
||||
return accumulatedData;
|
||||
}
|
||||
|
||||
function install(assets_json, package_name) {
|
||||
if (assets_json.background_video) {
|
||||
localStorage.setItem("background_video", assets_json.background_video);
|
||||
} else {
|
||||
localStorage.removeItem("video");
|
||||
}
|
||||
if (assets_json.background_image) {
|
||||
localStorage.setItem("background_image", assets_json.background_image);
|
||||
} else {
|
||||
localStorage.removeItem("background_image");
|
||||
}
|
||||
if (assets_json.type == "theme") {
|
||||
localStorage.setItem("stylesheet", "/styles/" + assets_json.payload);
|
||||
}
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function reset_theme() {
|
||||
localStorage.removeItem("background_video");
|
||||
localStorage.removeItem("background_image");
|
||||
localStorage.removeItem("stylesheet");
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function delete_theme(key) {
|
||||
let items = JSON.parse(localStorage.getItem("installed_themes")) || [];
|
||||
|
||||
const index = items.indexOf(key);
|
||||
|
||||
items.splice(index, 1);
|
||||
|
||||
localStorage.setItem("installed_themes", JSON.stringify(items));
|
||||
|
||||
reset_theme();
|
||||
}
|
||||
<script lang="ts">
|
||||
import { Suspense } from "@svelte-drama/suspense";
|
||||
import { Settings, marketPlaceSettings } from '@utils/settings';
|
||||
import Parent from "./Parent.svelte";
|
||||
async function getItem(item) {
|
||||
try {
|
||||
const response = await fetch(`/api/packages/${item}`);
|
||||
const data = await response.json();
|
||||
return {
|
||||
...data,
|
||||
package_name: item
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("error: failed to fetch", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async function getAssets() {
|
||||
const items = JSON.parse(localStorage.getItem(Settings.AppearanceSettings.themes)) || [];
|
||||
const promises = items.map(getItem);
|
||||
const dataArray = await Promise.all(promises);
|
||||
const accumulatedData = dataArray.filter((data) => data !== null);
|
||||
console.log(JSON.stringify(accumulatedData));
|
||||
return accumulatedData;
|
||||
}
|
||||
let assets = getAssets();
|
||||
let compRef = [];
|
||||
</script>
|
||||
|
||||
{#await assetPromise}
|
||||
Loading assets...
|
||||
{:then assets}
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
||||
{#each Object.entries(assets) as [key, asset]}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<Suspense let:suspend>
|
||||
<div class="rounded-3xl bg-navbar-color w-64 flex flex-col cursor-pointer">
|
||||
<div class="w-full" on:click={() => install(asset, key)}>
|
||||
<img
|
||||
src={"/images/" + asset.image}
|
||||
alt="Theme"
|
||||
class="aspect-[16/9] rounded-t-3xl"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="h-2/6 text-center content-center p-3 font-semibold items-center flex flex-col"
|
||||
>
|
||||
<div class="text-2xl">{asset.title}</div>
|
||||
<div class="flex flex-row">
|
||||
<div
|
||||
class="h-8 w-8 cursor-pointer"
|
||||
on:click={() => delete_theme(key)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 256 256"
|
||||
{...$$props}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<a
|
||||
class="h-8 w-8 cursor-pointer"
|
||||
href={"/assets/" + asset.package_name}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 256 256"
|
||||
{...$$props}
|
||||
>
|
||||
<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>
|
||||
</a>
|
||||
<div class="w-full" on:click={() => {marketPlaceSettings.changeTheme(true)}}>
|
||||
<img src='/classic_theme.png' alt="Classic Nebula" class="aspect-[16/9] rounded-t-3xl"/>
|
||||
</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>
|
||||
{/each}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class="rounded-3xl bg-navbar-color w-64 flex flex-col"
|
||||
on:click={() => reset_theme()}
|
||||
>
|
||||
<div class="w-full">
|
||||
<img
|
||||
src="/classic_theme.png"
|
||||
alt="Theme"
|
||||
class="aspect-[16/9] rounded-t-3xl"
|
||||
/>
|
||||
</div>
|
||||
<div class="h-2/6 text-center content-center p-3 font-semibold text-2xl">
|
||||
Classic Nebula
|
||||
</div>
|
||||
</div>
|
||||
{:catch someError}
|
||||
System error: {someError.message}.
|
||||
{/await}
|
||||
{#await suspend(assets) then data}
|
||||
{#each Object.entries(data) as [key, asset]}
|
||||
<Parent bind:this={compRef[key]}>
|
||||
<div class="rounded-3xl bg-navbar-color w-64 flex flex-col cursor-pointer">
|
||||
<div class="w-full" on:click={() => {marketPlaceSettings.changeTheme(false, asset.payload, asset.background_video, asset.background_image)}}>
|
||||
<img src={`/images/${asset.image}`} alt="theme" class="aspect-[16/9] rounded-t-3xl"/>
|
||||
</div>
|
||||
<div class="h-2/6 text-center content-center p-3 font-semibold items-center flex flex-col">
|
||||
<div class="text-2xl"> {asset.title} </div>
|
||||
<div class="flex flex-row">
|
||||
<div class="h-8 w-8 cursor-pointer" on:click={() => {marketPlaceSettings.uninstall("theme", asset.package_name); marketPlaceSettings.changeTheme(true); compRef[key].$destroy()}}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256" {...$$props}>
|
||||
<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>
|
||||
</div>
|
||||
<a class="h-8 w-8 cursor-pointer" href={"/assets/" + asset.package_name}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 256 256" {...$$props}>
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Parent>
|
||||
{/each}
|
||||
{/await}
|
||||
</Suspense>
|
||||
|
|
1
src/components/catalog/Parent.svelte
Normal file
1
src/components/catalog/Parent.svelte
Normal file
|
@ -0,0 +1 @@
|
|||
<slot />
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { tabSettings, proxySettings, Settings } from "@utils/settings.ts";
|
||||
import { tabSettings, proxySettings, marketPlaceSettings, Settings } from "@utils/settings.ts";
|
||||
// This loads the settings in a nice way
|
||||
tabSettings.cloakTab(localStorage.getItem(Settings.TabSettings.tabCloak) as string || "default");
|
||||
proxySettings.changeProxy(localStorage.getItem(Settings.ProxySettings.proxy) as string || "automatic");
|
||||
|
@ -7,7 +7,9 @@
|
|||
proxySettings.setSearchEngine(localStorage.getItem(Settings.ProxySettings.searchEngine) as string || "ddg");
|
||||
proxySettings.setWispURL(localStorage.getItem(Settings.ProxySettings.wispServerURL) as string || "default");
|
||||
proxySettings.setTransport(localStorage.getItem(Settings.ProxySettings.transport) as string || "epoxy");
|
||||
marketPlaceSettings.changeTheme(false, undefined, localStorage.getItem(Settings.AppearanceSettings.video) as string, localStorage.getItem(Settings.AppearanceSettings.image) as string);
|
||||
document.addEventListener("astro:after-swap", function() {
|
||||
tabSettings.cloakTab(localStorage.getItem(Settings.TabSettings.tabCloak) as string || "default");
|
||||
//marketPlaceSettings.changeTheme(false);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -77,30 +77,6 @@ const { title, noHeader } = Astro.props;
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
const stylesheet_link = localStorage.getItem("stylesheet");
|
||||
const stylesheet = document.getElementById(
|
||||
"stylesheet"
|
||||
)! as HTMLAnchorElement;
|
||||
|
||||
if (stylesheet_link) {
|
||||
stylesheet.href = stylesheet_link;
|
||||
}
|
||||
|
||||
const video_link = localStorage.getItem("background_video");
|
||||
|
||||
const image_link = localStorage.getItem("background_image");
|
||||
|
||||
const image_source = document.getElementById("nebulaImage")! as any;
|
||||
const source = document.getElementById("nebulaVideo")! as any;
|
||||
|
||||
if (video_link) {
|
||||
source.src = "/videos/" + video_link;
|
||||
}
|
||||
if (image_link) {
|
||||
image_source.style.display = "block";
|
||||
image_source.src = "/images/" + image_link;
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#mobileNavMenu {
|
||||
|
|
|
@ -8,32 +8,16 @@ import { Icon } from "astro-icon/components";
|
|||
---
|
||||
|
||||
<div class="flex flex-row">
|
||||
<div
|
||||
class="text-text-color mt-16 fixed inset-0 h-[calc(100%-4rem)] z-0 bg-primary flex-col flex md:flex-row"
|
||||
>
|
||||
<div
|
||||
class="items-center p-3 flex flex-row border-border-color gap-5 border-r-2 md:w-2/12 md:flex-col md:bg-navbar-color md:gap-0 md:p-0"
|
||||
>
|
||||
<SidebarButton
|
||||
title={t("settings.appearance")}
|
||||
route={`/${lang}/settings/appearance`}
|
||||
>
|
||||
<Icon
|
||||
name="ph:palette"
|
||||
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
|
||||
/>
|
||||
<div class="text-text-color mt-16 fixed inset-0 h-[calc(100%-4rem)] z-0 bg-primary flex-col flex md:flex-row">
|
||||
<div class="items-center p-3 flex flex-row border-border-color gap-5 border-r-2 md:w-2/12 md:flex-col md:bg-navbar-color md:gap-0 md:p-0">
|
||||
<SidebarButton title={t("settings.appearance")} route={`/${lang}/settings/appearance`}>
|
||||
<Icon name="ph:palette" class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
|
||||
</SidebarButton>
|
||||
<SidebarButton title={t("settings.proxy")} route={`/${lang}/settings/pr`}>
|
||||
<Icon
|
||||
name="ph:globe-hemisphere-east-fill"
|
||||
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
|
||||
/>
|
||||
<Icon name="ph:globe-hemisphere-east-fill" class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
|
||||
</SidebarButton>
|
||||
<SidebarButton title={t("settings.tab")} route={`/${lang}/settings/tab/`}>
|
||||
<Icon
|
||||
name="ph:laptop-fill"
|
||||
class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6"
|
||||
/>
|
||||
<Icon name="ph:laptop-fill" class="h-6 w-6 text-text-color transition duration-500 group-hover:text-text-hover-color md:h-6 md:w-6" />
|
||||
</SidebarButton>
|
||||
</div>
|
||||
<div class="p-8 md:w-10/12 overflow-y-auto">
|
||||
|
|
|
@ -19,7 +19,7 @@ export const prerender = true;
|
|||
if (iframe) {
|
||||
initSw().then(() => {
|
||||
setTransport(localStorage.getItem(Settings.ProxySettings.transport) as string).then(async () => {
|
||||
iframe.src = __uv$config!.prefix + __uv$config.encodeUrl("https://radon.games");
|
||||
iframe.src = __uv$config!.prefix + __uv$config.encodeUrl!("https://radon.games");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ const lang = getLangFromUrl(Astro.url);
|
|||
const t = useTranslations(lang);
|
||||
---
|
||||
|
||||
<Layout title="Welcome to Astro.">
|
||||
<Layout title="Nebula">
|
||||
<div
|
||||
class="flex flex-wrap mt-16 justify-center content-center w-full bg-primary fixed inset-0 h-[calc(100%-4rem)] z-0 flex-col items-center"
|
||||
>
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
---
|
||||
import InstalledThemes from "@components/catalog/InstalledThemes.svelte";
|
||||
import ThemeCard from "@components/settings/ThemeCard.astro";
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import SettingsLayout from "@layouts/SettingsLayout.astro";
|
||||
import SettingsSection from "@layouts/SettingsSection.astro";
|
||||
import { Icon } from "astro-icon/components";
|
||||
import ClassicNebula from "../../../assets/classic_theme.png";
|
||||
import fortnite from "../../../assets/fortnite.jpg";
|
||||
import { getLangFromUrl, useTranslations } from "../../../i18n/utils";
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const t = useTranslations(lang);
|
||||
|
@ -24,15 +21,15 @@ export const prerender = true;
|
|||
subtitle="Choose a theme so your eyes don't hate us.">
|
||||
<div class="flex flex-row flex-wrap gap-4 items-center roboto">
|
||||
<div class="justify-center flex flex-row gap-6 flex-wrap md:justify-normal">
|
||||
<InstalledThemes client:only="svelte" />
|
||||
<div class="rounded-3xl bg-navbar-color w-64 flex flex-col">
|
||||
<InstalledThemes client:only="svelte" />
|
||||
<a href="/catalog/1" class="rounded-3xl bg-navbar-color w-64 flex flex-col">
|
||||
<div class="w-full items-center justify-center flex aspect-[16/9]">
|
||||
<Icon name="ph:plus-bold" class="h-16 w-16" />
|
||||
</div>
|
||||
<div class="h-2/6 text-center content-center p-3 font-semibold">
|
||||
Get more themes in the <strong>Nebula Catalog!</strong>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-3xl roboto font-bold text-text-color"></div>
|
||||
</div>
|
||||
|
|
80
src/pages/assets/[...packageName].astro
Normal file
80
src/pages/assets/[...packageName].astro
Normal file
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
const { packageName } = Astro.params;
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
const response = await fetch(new URL("/api/packages/" + packageName, Astro.url));
|
||||
const assetsJson = await response.json();
|
||||
---
|
||||
|
||||
<Layout title={`Package: ${packageName}`}>
|
||||
<div class="flex flex-wrap mt-16 w-full fixed inset-0 h-full md:h-[calc(100%-4rem)] z-0 bg-primary flex-col items-center content-center justify-center md:pb-64 roboto max-md:p-4">
|
||||
{assetsJson.error && <h1 class="text-text-color text-3xl font-bold"> Unexpected error. Is the name right? </h1>}
|
||||
{!assetsJson.error &&
|
||||
<div class="flex flex-col md:flex-row items-center text-text-color bg-navbar-color rounded-2xl">
|
||||
{assetsJson.background_video &&
|
||||
<video src={`/videos/${assetsJson.background_video}`} controls class="w-[44rem] h-[25rem] object-cover rounded-xl">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
}
|
||||
{assetsJson.backgroundImage &&
|
||||
<div style={{backgroundImage: `url(/images/${assetsJson.backgroundImage})`}} class="w-[44rem] h-[25rem] bg-cover bg-center rounded-xl"/>
|
||||
}
|
||||
{!assetsJson.background_video && !assetsJson.backgroundImage && <img src={`/images/${assetsJson.image}`} alt={assetsJson .title} class="w-[44rem] h-[25rem] object-cover rounded-xl"/>}
|
||||
<div class="flex flex-col ml-7 p-16">
|
||||
<p class="text-xl">{assetsJson.type}</p>
|
||||
<h1 class="text-4xl roboto font-semibold">{assetsJson.title}</h1>
|
||||
<p class="text-xl"> By: <strong>{assetsJson.author}</strong></p>
|
||||
<p class="text-xl">{assetsJson.description}</p>
|
||||
<button class="bg-primary text-text-color border border-transparent rounded-lg px-6 py-3 hover:bg-navbar-color transition-colors duration-300 mt-9" id="install">
|
||||
Install
|
||||
</button>
|
||||
<button class="hidden bg-primary text-text-color border border-transparent rounded-lg px-6 py-3 hover:bg-navbar-color transition-colors duration-300 mt-9" id="uninstall">
|
||||
Uninstall
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<variable-define data-assets={JSON.stringify(assetsJson)} data-name={packageName} data-type={assetsJson.type} />
|
||||
</Layout>
|
||||
<script>
|
||||
import { Settings, type PackageType, marketPlaceSettings } from "@utils/settings";
|
||||
let packageName: string;
|
||||
let assetsJson: any;
|
||||
let packageType: string;
|
||||
//some weird trickery to get the variables.
|
||||
class VariableDefiner extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
assetsJson = this.dataset.assets;
|
||||
packageName = this.dataset.name as string;
|
||||
packageType = this.dataset.type as PackageType;
|
||||
}
|
||||
}
|
||||
customElements.define('variable-define', VariableDefiner);
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
try {
|
||||
const items = JSON.parse(localStorage.getItem(Settings.AppearanceSettings.themes) as string) || [];
|
||||
const itemExists = items.indexOf(packageName) !== -1;
|
||||
const installButton = document.getElementById("install") as HTMLButtonElement;
|
||||
const uninstallButton = document.getElementById("uninstall") as HTMLButtonElement;
|
||||
const payload = assetsJson ? JSON.parse(assetsJson) : undefined;
|
||||
if (itemExists) {
|
||||
uninstallButton.classList.remove("hidden");
|
||||
installButton.classList.add("hidden");
|
||||
}
|
||||
installButton.addEventListener("click", () => {
|
||||
marketPlaceSettings.install({theme: {payload: payload.payload, video: payload.background_video, bgImage: payload.background_image}}, packageName, payload.payload).then(() => {
|
||||
installButton.classList.add("hidden");
|
||||
uninstallButton.classList.remove("hidden");
|
||||
})
|
||||
});
|
||||
uninstallButton.addEventListener("click", () => {
|
||||
marketPlaceSettings.uninstall(packageType as PackageType, packageName).then(() => {
|
||||
uninstallButton.classList.add("hidden")
|
||||
installButton.classList.remove("hidden");
|
||||
});
|
||||
})
|
||||
}
|
||||
catch (err) { /* DEBUGGING ONLY: console.error(err) */ }
|
||||
});
|
||||
</script>
|
|
@ -1,103 +0,0 @@
|
|||
---
|
||||
const { package_name } = Astro.params;
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
const response = await fetch(new URL("/api/packages/" + package_name, Astro.url));
|
||||
const assetsJson = await response.json();
|
||||
---
|
||||
|
||||
<Layout title="Package">
|
||||
<div class="flex flex-wrap mt-16 w-full fixed inset-0 h-[calc(100%-4rem)] z-0 bg-primary flex-col items-center content-center justify-center pb-64 roboto">
|
||||
{assetsJson.error ? (
|
||||
<h1 class="text-text-color text-3xl"> Unexpected error. Are you sure you typed the name right? </h1>
|
||||
) : (
|
||||
<div class="flex flex-row items-center text-text-color bg-navbar-color rounded-2xl">
|
||||
{assetsJson.background_video ? (
|
||||
// Background video
|
||||
<video src={`/videos/${assetsJson.background_video}`} controls class="w-[44rem] h-[25rem] object-cover rounded-xl">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
) : assetsJson.backgroundImage ? (
|
||||
// Background image
|
||||
<div style={{backgroundImage: `url(/images/${assetsJson.backgroundImage})`}} class="w-[44rem] h-[25rem] bg-cover bg-center rounded-xl"/>
|
||||
) : (
|
||||
// Fallback to cover image
|
||||
<img src={`/images/${assetsJson.image}`} alt={assetsJson .title} class="w-[44rem] h-[25rem] object-cover rounded-xl"/>
|
||||
)}
|
||||
<div class="flex flex-col ml-7 p-16">
|
||||
<div class="text-xl">{assetsJson.type}</div>
|
||||
<div class="text-4xl roboto font-semibold">{assetsJson.title}</div>
|
||||
<div class="text-xl">
|
||||
By <strong>{assetsJson.author}</strong>
|
||||
</div>
|
||||
<div class="text-xl">{assetsJson.description}</div>
|
||||
<button class="bg-primary text-text-color border border-transparent rounded-lg px-6 py-3 hover:bg-navbar-color transition-colors duration-300 mt-9" id="install">
|
||||
Install
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<script is:inline define:vars={{ assetsJson, package_name }}>
|
||||
// determine if this is installed
|
||||
let items = JSON.parse(localStorage.getItem("installed_themes")) || [];
|
||||
|
||||
const packageExists = items.indexOf(package_name) !== -1;
|
||||
|
||||
if (packageExists) {
|
||||
document.getElementById("install").textContent = "Uninstall";
|
||||
}
|
||||
|
||||
document.getElementById("install").addEventListener("click", install);
|
||||
function install() {
|
||||
if (packageExists) {
|
||||
const index = items.indexOf(package_name);
|
||||
items.splice(index, 1);
|
||||
localStorage.setItem("installed_themes", JSON.stringify(items));
|
||||
|
||||
localStorage.removeItem("background_video");
|
||||
localStorage.removeItem("background_image");
|
||||
localStorage.removeItem("stylesheet");
|
||||
location.reload();
|
||||
} else {
|
||||
console.log("Package does not exist in the items array.");
|
||||
let installedThemes = localStorage.getItem("installed_themes");
|
||||
|
||||
if (installedThemes) {
|
||||
// If it exists, append it
|
||||
installedThemes = JSON.parse(installedThemes);
|
||||
installedThemes.push(package_name);
|
||||
} else {
|
||||
// If it doesn't exist, create a new array
|
||||
installedThemes = [package_name];
|
||||
}
|
||||
|
||||
localStorage.setItem(
|
||||
"installed_themes",
|
||||
JSON.stringify(installedThemes)
|
||||
);
|
||||
|
||||
if (assetsJson.background_video) {
|
||||
localStorage.setItem(
|
||||
"background_video",
|
||||
assetsJson.background_video
|
||||
);
|
||||
} else {
|
||||
localStorage.removeItem("video");
|
||||
}
|
||||
if (assetsJson.background_image) {
|
||||
localStorage.setItem(
|
||||
"background_image",
|
||||
assetsJson.background_image
|
||||
);
|
||||
} else {
|
||||
localStorage.removeItem("background_image");
|
||||
}
|
||||
if (assetsJson.type == "theme") {
|
||||
localStorage.setItem("stylesheet", "/styles/" + assetsJson.payload);
|
||||
}
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</Layout>
|
|
@ -1,31 +1,11 @@
|
|||
---
|
||||
import Layout from "@layouts/Layout.astro";
|
||||
import Loading from "@components/Loading.astro";
|
||||
---
|
||||
|
||||
<Layout title="Loading..." noHeader="true">
|
||||
<div class="w-full h-full bg-primary text-navbar-text-color flex justify-center items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 400 400" width="400" height="400" fill="#5e17eb" class="animate-pulse-brighter w-48 h-48">
|
||||
<g id="svgg">
|
||||
<path id="path0" fill-rule="evenodd" class="s0" d="m213.6 84c1 0.3 3.4 0.7 5.1 1 1.8 0.2 4.1 0.7 5.2 1 13.2 4.1 20.3 6.8 24.5 9.1 0.6 0.3 2.3 1.2 3.8 2 2.8 1.4 13.1 8 14.4 9.2 0.5 0.3 2.3 1.9 4.2 3.5 6.7 5.5 15.5 14.9 19.2 20.4 1 1.4 2 2.7 2.2 2.8 0.3 0.1 0.5 0.5 0.5 0.8 0 0.3 1.2 2.2 2.5 4.3 2.3 3.4 7.8 14.3 9.8 19.3 0.8 2.1 0.9 2.2 10 4.9 5.6 1.6 11.1 3.4 11.7 3.8 0.3 0.2 2.4 1.1 4.7 1.9 11.1 4.1 23 12.5 27.3 19.4 5.5 8.7 3.6 20.5-4.5 28.5-3.1 3-7.5 6.4-8.4 6.4-0.3 0-0.7 0.2-0.8 0.5-1.1 2.3-23.3 11.2-35.9 14.3-3.2 0.9-3.5 1.2-5.7 6.8-7.5 19-25.5 40.6-42.3 51.1-1.6 1-3.1 2-3.3 2.2-0.1 0.2-0.9 0.7-1.7 1.2-0.8 0.4-2.2 1.2-2.9 1.6-0.8 0.4-1.6 1-1.8 1.1-0.5 0.5-4.1 2.2-8.1 3.9-1.8 0.8-3.8 1.6-4.5 2-0.7 0.3-3.1 1.1-5.2 1.8-8.3 2.6-9.8 3-21 4.9-6.4 1.1-25.3 1.3-30.5 0.3-1.9-0.3-5.8-1.1-8.6-1.6-6.8-1.3-12.7-3-20-5.7-3.3-1.2-18-8.8-19.7-10.1-0.9-0.7-4.1-3.1-7.1-5.2-5.7-4.1-17.9-15.9-20.7-20-0.9-1.2-2-2.7-2.5-3.2-3.2-3.3-13.7-21.7-13.7-24.1 0-0.6-0.2-1.2-0.6-1.4-0.3-0.2-0.8-1.2-1-2.3-0.4-1.9-1.7-2.7-6.5-3.8-23.2-5.6-43.1-17.2-48.6-28.5-7.1-14.4 4.5-31.3 27.3-39.7 1.8-0.7 4.1-1.6 5.2-2 3.7-1.5 8-2.9 19.5-6.2 1.6-0.5 2.8-1.2 2.8-1.7 0-2.4 9.8-21.6 13.1-25.7 0.2-0.4 1.4-1.8 2.5-3.2 13.8-18.1 30.2-30.6 50.6-38.8 4.3-1.7 6-2.3 14.3-4.5 5.5-1.6 11.2-2.4 18.4-2.9 7.9-0.5 24-0.2 26.8 0.6zm-29.7 17.3c-0.2 0.1-7.3 1.7-12.9 2.7-1.7 0.4-4.3 1.2-5.8 1.9-1.5 0.6-3.9 1.5-5.5 2-1.5 0.4-3.3 1.3-4 2-0.7 0.7-1.7 1.2-2.3 1.2-1.2 0-9.5 4.5-9.8 5.3-0.2 0.3-0.5 0.6-0.9 0.6-1.9 0-19.6 16-23.8 21.6-9.3 12.2-16.1 27.4-19.2 42.7-2 10.1-1.1 37.5 1.4 41.4 0 0.1 3.7 0.9 8.1 1.8 9.5 1.9 12.8 2.4 34.6 4.9 38.5 4.5 107.9 2.2 138.3-4.5 1.4-0.3 4.1-0.9 6.1-1.3 4.2-0.8 3.4 0.2 4.9-7.1 1.6-8.3 1.7-27 0.1-34.6-1.5-7.1-3.2-13.4-3.7-14.2-0.3-0.4-0.7-1.5-0.9-2.6-2.8-12.1-19.2-34.1-33-44.3-2.9-2.1-5.5-4-5.8-4.3-2.8-2.2-4.9-3.1-7.2-3.1-2.1 0-2.6-0.2-2.7-1.3-0.2-1.5-5.7-4.5-6.3-3.5-0.7 1.1-2.4 0.6-2.7-0.7-0.4-1.3-1.2-1.6-5.8-2.1-1.6-0.2-4-0.9-5.5-1.6-3.9-1.8-5.3-2.2-10.2-2.6-4.6-0.4-25.2-0.7-25.5-0.3zm74.3 42.2c7.4 9.8 4.8 23.5-4.6 24.9-6.9 1-20.9-5.8-21-10.2 0-0.2-0.3-0.8-0.8-1.3-6.4-6.8-5-20.8 2.4-24.1 6.7-2.9 17.2 1.8 24 10.7zm-176.4 36.4c-0.1-0.1-4.6 1.1-5.9 1.6-0.7 0.3-3 1.2-5.1 2-9.9 3.8-15.1 6.8-19.6 11.5-3.4 3.5-3.3 4.5 0.5 8.7 1 1 11.3 7.6 12 7.6 0.2 0 1.7 0.6 3.4 1.3 1.6 0.8 3.6 1.6 4.3 1.9 1.8 0.8 9.3 3.3 9.9 3.3 0.3 0 0.3-2 0-4.4-0.6-5.6-0.6-24.5 0.1-29.6 0.3-2.1 0.5-3.9 0.4-3.9zm229.3-0.3c-0.2 0 0 1 0.2 2.1 0.6 2.8 0.6 31.3 0 34-0.5 2.2-0.4 2.2 1.3 1.8 3.1-0.7 12.9-4.5 18.3-7 8.5-4 14.3-10.1 12.6-13.3-1.1-2.1-6.7-7.2-7.9-7.2-0.4 0-0.9-0.2-1-0.5-0.4-1.1-11.8-6.1-19.2-8.5-2.3-0.7-4.2-1.4-4.3-1.4zm-199.4 63.4l-3.1-0.4 1.8 3.2c0.9 1.8 1.9 3.4 2.2 3.5 0.3 0.1 0.5 0.6 0.5 1.1 0 0.4 0.6 1.5 1.3 2.3 0.7 0.9 1.5 1.9 1.8 2.2 0.3 0.4 0.8 1.2 1.1 1.7 6.2 10.7 35.6 33.5 43.3 33.5 0.2 0 1.3 0.4 2.5 0.9 2.5 1.2 10.6 3.4 15.3 4.2 9.5 1.8 11.6 2.1 17.4 2.1 6.6 0 16.4-1.3 22.9-3 2.2-0.5 5.2-1.3 6.8-1.7 1.6-0.3 3.2-0.9 3.5-1.2 0.4-0.3 1.1-0.6 1.6-0.6 2.3 0 22-10.6 24-12.9 0.2-0.2 2.2-1.9 4.5-3.7 5.7-4.5 11.8-11 17.1-18.4 1.6-2.3 3.2-4.5 3.6-4.9 0.4-0.4 0.7-1 0.7-1.2 0-0.2 0.8-1.9 1.9-3.6 1.1-1.7 1.9-3.2 1.9-3.4 0-0.2-3.8 0.4-11 1.6-31.7 5.4-85.1 6.7-126.9 3.1-9.6-0.8-23.1-2.3-27.8-3.2-2.2-0.4-5.3-0.9-6.9-1.2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<Loading />
|
||||
</Layout>
|
||||
<style>
|
||||
@keyframes pulse-brighter {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.animate-pulse-brighter {
|
||||
animation: pulse-brighter 2s infinite;
|
||||
height: 11rem;
|
||||
}
|
||||
</style>
|
||||
<script is:inline>
|
||||
let currentLang = localStorage.getItem("selectedLanguage");
|
||||
const redirect = (loc) => (window.location.href = loc);
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
const wispUrl = (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/";
|
||||
const AppearanceSettings = {
|
||||
themes: "nebula||themes",
|
||||
stylePayload: "nebula||stylepayload",
|
||||
video: "nebula||video",
|
||||
image: "nebula||image"
|
||||
}
|
||||
const TabSettings = {
|
||||
tabCloak: "nebula||tabCloak",
|
||||
abblob: "nebula||abBlob"
|
||||
|
@ -11,6 +17,7 @@ const ProxySettings = {
|
|||
transport: "nebula||transport"
|
||||
};
|
||||
const Settings = {
|
||||
AppearanceSettings,
|
||||
TabSettings,
|
||||
ProxySettings
|
||||
};
|
||||
|
@ -19,7 +26,16 @@ type TabCloaks = "default" | "google" | "wikipedia" | "canvas" | "classroom" | "
|
|||
type AbCloaks = "a:b" | "blob";
|
||||
type OpenIn = "a:b" | "blob" | "direct" | "embed";
|
||||
type Proxy = "automatic" | "uv" | "rh";
|
||||
type Transport = "epoxy" | "libcurl";
|
||||
type Transport = "epoxy" | "libcurl";
|
||||
type PackageType = "theme" | "plugin"
|
||||
interface Package {
|
||||
theme?: {
|
||||
payload: string,
|
||||
video?: string
|
||||
bgImage?: string
|
||||
}
|
||||
plugin?: {}
|
||||
}
|
||||
const SearchEngines: Record<string, string> = {
|
||||
ddg: "https://duckduckgo.com/?q=%s",
|
||||
google: "https://google.com/search?q=%s",
|
||||
|
@ -125,4 +141,92 @@ const proxySettings = {
|
|||
}
|
||||
};
|
||||
|
||||
export { tabSettings, proxySettings, Settings, WispServerURLS, SearchEngines, cloak, type Proxy };
|
||||
const marketPlaceSettings = {
|
||||
install: function(p: Package, packageName: string, payload?: any) {
|
||||
return new Promise<void>((resolve) => {
|
||||
if (p.theme) {
|
||||
let themes = localStorage.getItem(Settings.AppearanceSettings.themes) as any;
|
||||
themes ? themes = JSON.parse(themes) : themes = [];
|
||||
if (!themes.find((theme: any) => theme === packageName)) {
|
||||
themes.push(packageName);
|
||||
localStorage.setItem(Settings.AppearanceSettings.themes, JSON.stringify(themes));
|
||||
this.changeTheme(false, payload, p.theme.video, p.theme.bgImage);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
uninstall: function(p: PackageType, packageName: string) {
|
||||
return new Promise<void>((resolve) => {
|
||||
if (p === "theme") {
|
||||
let items = localStorage.getItem(Settings.AppearanceSettings.themes) as any;
|
||||
items ? items = JSON.parse(items) : items = [];
|
||||
if (items.find((theme: any) => theme === packageName)) {
|
||||
const idx = items.indexOf(packageName);
|
||||
items.splice(idx, 1);
|
||||
localStorage.setItem(Settings.AppearanceSettings.themes, JSON.stringify(items));
|
||||
this.changeTheme(true);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
changeTheme: async function(reset: Boolean, payload?: any, videoSource?: string, bgSource?: string) {
|
||||
async function resetCSS() {
|
||||
const stylesheet = document.getElementById("stylesheet")! as HTMLLinkElement;
|
||||
localStorage.removeItem(Settings.AppearanceSettings.stylePayload);
|
||||
stylesheet.href = "/nebula.css";
|
||||
}
|
||||
function resetVideo() {
|
||||
localStorage.removeItem(Settings.AppearanceSettings.video);
|
||||
const source = document.getElementById('nebulaVideo')! as HTMLVideoElement;
|
||||
source.src = "";
|
||||
}
|
||||
function resetBGImage() {
|
||||
localStorage.removeItem(Settings.AppearanceSettings.image);
|
||||
const image = document.getElementById("nebulaImage")! as HTMLImageElement;
|
||||
image.style.display = "none";
|
||||
image.src = "";
|
||||
}
|
||||
if (reset === true) {
|
||||
await resetCSS();
|
||||
await resetCSS();
|
||||
resetBGImage();
|
||||
resetVideo();
|
||||
}
|
||||
if (videoSource || localStorage.getItem(Settings.AppearanceSettings.video)) {
|
||||
resetBGImage();
|
||||
resetVideo();
|
||||
const source = document.getElementById("nebulaVideo")! as HTMLVideoElement;
|
||||
if (!localStorage.getItem(Settings.AppearanceSettings.video)) {
|
||||
localStorage.setItem(Settings.AppearanceSettings.video, videoSource as string);
|
||||
}
|
||||
source.src = `/videos/${videoSource ? videoSource : localStorage.getItem(Settings.AppearanceSettings.video)}`
|
||||
}
|
||||
if (bgSource || localStorage.getItem(Settings.AppearanceSettings.image)) {
|
||||
resetVideo();
|
||||
resetBGImage();
|
||||
const image = document.getElementById("nebulaImage")! as HTMLImageElement;
|
||||
if (!localStorage.getItem(Settings.AppearanceSettings.image)) {
|
||||
localStorage.setItem(Settings.AppearanceSettings.image, bgSource as string);
|
||||
}
|
||||
image.style.display = "block";
|
||||
image.src = `/images/${bgSource ? bgSource : localStorage.getItem(Settings.AppearanceSettings.image)}`
|
||||
}
|
||||
if (payload) {
|
||||
const stylesheet = document.getElementById("stylesheet")! as HTMLLinkElement;
|
||||
if (localStorage.getItem(Settings.AppearanceSettings.stylePayload) !== payload) {
|
||||
localStorage.setItem(Settings.AppearanceSettings.stylePayload, payload);
|
||||
}
|
||||
stylesheet.href = `/styles/${localStorage.getItem(Settings.AppearanceSettings.stylePayload)}`;
|
||||
}
|
||||
else {
|
||||
if (localStorage.getItem(Settings.AppearanceSettings.stylePayload)) {
|
||||
const stylesheet = document.getElementById("stylesheet")! as HTMLLinkElement;
|
||||
stylesheet.href = `/styles/${localStorage.getItem(Settings.AppearanceSettings.stylePayload)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { tabSettings, proxySettings, marketPlaceSettings, Settings, WispServerURLS, SearchEngines, cloak, type Proxy, type PackageType };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue