Index page is almost back : D

This commit is contained in:
MotorTruck1221 2025-01-06 05:58:22 -07:00
parent ef0f7055a0
commit 84f8605269
No known key found for this signature in database
GPG key ID: 08F417E2B8B61EA4
8 changed files with 215 additions and 186 deletions

View file

@ -36,10 +36,10 @@
const info = "Hello developer or curious individual & welcome to the console! \nThere isn't a whole lot here for you unless you have run into an error.";
const sysInfo = `In which case please include the info below when opening the issue: \n\nOS: ${navigator.platform} \nBrowser: ${navigator.userAgent} \nService workers: ${"serviceWorker" in navigator ? "Yes" : "No"}`
const init = async () => {
log("normal", { bg: false, prefix: false }, titleText);
log("normal", { bg: true, prefix: false }, info);
log("normal", { bg: true, prefix: false }, sysInfo);
log("info", { bg: true, prefix: true }, "General init...");
log({ type: 'normal', bg: false, prefix: false }, titleText);
log({ type: 'normal', bg: true, prefix: false }, info);
log({ type: 'normal', bg: true, prefix: false }, sysInfo);
log({ type: 'info', bg: true, prefix: true }, "General init...");
for (const script of createProxyScripts()) {
document.body.appendChild(script);
}
@ -48,18 +48,20 @@
await setTransport(conn, "libcurl");
window.sw = new SW(conn);
const { serviceWorker, bareMuxConn, sj } = await window.sw.getSWInfo();
log("info", { bg: true, prefix: true }, `General init completed! \n\nInit info: \nServiceWorker: ${serviceWorker.active?.state} \nBareMux Transport: ${await bareMuxConn.getTransport()} \nScramjetController: ${sj ? 'Active' : 'Not active'}`);
log({ type: 'info', bg: true, prefix: true }, `General init completed! \n\nServiceWorker: ${serviceWorker.active?.state} \nBareMuxConn: ${bareMuxConn ? 'Active': 'Not active'} \nScramjetController: ${sj ? 'Active' : 'Not active'}`);
}
const initSettings = async () => {
log({ type: 'info', bg: true, prefix: true }, "Initializing settings...");
log({ type: 'info', bg: true, prefix: true }, "Initialized Settings!");
}
log("info", { bg: true, prefix: true }, "Initializing settings...");
log("info", { bg: true, prefix: true }, "Initialized Settings!");
const eventHandler = new EventHandler({
events: {
"DOMContentLoaded": (async () => {
await init();
await initSettings();
}),
"astro:page-load": (async () => {
"astro:after-swap": (async () => {
})
},
logging: true

18
src/env.d.ts vendored
View file

@ -21,15 +21,15 @@ interface SJOptions {
sync: string;
};
flags?: {
serviceworkers: boolean;
syncxhr: boolean;
naiiveRewriter: boolean;
strictRewrites: boolean;
rewriterLogs: boolean;
captureErrors: boolean;
cleanErrors: boolean;
scramitize: boolean;
sourcemaps: boolean;
serviceworkers?: boolean;
syncxhr?: boolean;
naiiveRewriter?: boolean;
strictRewrites?: boolean;
rewriterLogs?: boolean;
captureErrors?: boolean;
cleanErrors?: boolean;
scramitize?: boolean;
sourcemaps?: boolean;
};
siteFlags?: {};
codec?: {

View file

@ -8,19 +8,13 @@ import { VERSION } from "astro:env/client";
---
<Layout title="Home">
<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"
>
<div
class="w-full flex flex-col justify-center items-center content-center h-2/4"
>
<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">
<div class="w-full flex flex-col justify-center items-center content-center h-2/4">
<div class="flex flex-row items-center mb-8">
<div class="h-32 w-32 fill-navbar-text-color">
<Logo />
</div>
<h1
class="font-roboto whitespace-nowrap text-navbar-text-color sm:visible text-5xl sm:text-7xl roboto"
>
<h1 class="font-roboto whitespace-nowrap text-navbar-text-color sm:visible text-5xl sm:text-7xl roboto">
nebula.
</h1>
</div>
@ -49,140 +43,68 @@ import { VERSION } from "astro:env/client";
</div>
</Layout>
<script>
import { setTransport, getSWStuff } from "@utils/registerSW"; //../../utils/registerSW.ts
import { pageLoad } from "@utils/events";
import { SupportedSites } from "@utils/siteSupport";
import {
SearchEngines,
Settings,
cloak,
settings,
} from "@utils/settings/index";
import { search } from "@utils/search"; //../../utils/search.ts
import { EventHandler } from "@utils/events";
import { SupportedSites, SearchEngines, SettingsVals } from "@utils/values";
import { search, Elements } from "@utils/index";
import { BareClient } from "@mercuryworkshop/bare-mux";
import { defaultStore } from "@utils/storage";
type Suggestion = {
phrase: string;
};
function proxy(term: string, scram: typeof ScramjetController, pr: "uv" | "sj"): string {
const searchEngine = localStorage.getItem(Settings.ProxySettings.searchEngine);
const openIn = localStorage.getItem(Settings.ProxySettings.openIn);
return pr === "uv" ? `${__uv$config!.prefix}${__uv$config.encodeUrl!(search(term, searchEngine ? SearchEngines[searchEngine] : SearchEngines.ddg))}` : scram.encodeUrl(search(term, searchEngine ? SearchEngines[searchEngine] : SearchEngines.ddg ))
}
async function uv(iframe: HTMLIFrameElement, term: string) {
const { sw, conn, sj } = getSWStuff();
await setTransport(
conn,
localStorage.getItem(Settings.ProxySettings.transport) as string
);
await settings.marketPlaceSettings.handlePlugins(sw);
iframe.classList.remove("hidden");
const url = proxy(term, sj, "uv");
if (url) {
iframe.src = url;
}
}
async function sj(iframe: HTMLIFrameElement, term: string) {
const { sw, conn, sj } = getSWStuff();
await setTransport(conn, localStorage.getItem(Settings.ProxySettings.transport) as string);
iframe.classList.remove("hidden");
const url = proxy(term, sj, "sj");
if (url) {
iframe.src = url;
}
}
//we need to rerun this on every page load
pageLoad(async () => {
const input = document.getElementById("nebula-input") as HTMLInputElement;
const iframe = document.getElementById("neb-iframe") as HTMLIFrameElement;
const omnibox = document.getElementById("omnibox") as HTMLDivElement;
const copyright = document.getElementById("version") as HTMLDivElement;
const client = new BareClient();
input?.addEventListener("keypress", async function (event: any) {
const init = async (): Promise<void> => {
const bc = new BareClient();
const se = Elements.select([
{ type: 'id', val: 'nebula-input' },
{ type: 'id', val: 'omnibox' },
{ type: 'id', val: 'version' },
{ type: 'id', val: 'neb-iframe' }
]);
const input = Elements.exists<HTMLInputElement>(await se.next());
const omnibox = Elements.exists<HTMLDivElement>(await se.next());
const copyright = Elements.exists<HTMLDivElement>(await se.next());
const iframe = Elements.exists<HTMLIFrameElement>(await se.next());
input.addEventListener("keypress", async (event: any) => {
if (event.key === "Enter") {
copyright.classList.add("hidden");
if (localStorage.getItem(Settings.ProxySettings.proxy) === "automatic") {
const key = SupportedSites[input?.value];
switch (key) {
if (defaultStore.getVal(SettingsVals.proxy.proxy.key) === SettingsVals.proxy.proxy.available.automatic) {
switch(SupportedSites[input.value]) {
case "uv":
uv(iframe, input?.value);
iframe.classList.remove("hidden");
iframe.src = `${__uv$config.prefix}${__uv$config.encodeUrl!(
search(
input.value,
defaultStore.getVal(SettingsVals.proxy.searchEngine)
? SearchEngines[defaultStore.getVal(SettingsVals.proxy.searchEngine)]
: SearchEngines.ddg
))}
`
break;
default:
uv(iframe, input?.value);
case "sj":
const { sj } = await window.sw.getSWInfo();
iframe.classList.remove("hidden");
iframe.src = sj.encodeUrl(
search(
input.value,
defaultStore.getVal(SettingsVals.proxy.searchEngine) ? SearchEngines[defaultStore.getVal(SettingsVals.proxy.searchEngine)]: SearchEngines.ddg
)
);
break;
}
}
else if (localStorage.getItem(Settings.ProxySettings.proxy) === "uv") {
uv(iframe, input?.value);
}
else if (localStorage.getItem(Settings.ProxySettings.proxy) === "sj") {
sj(iframe, input?.value);
}
}
});
input?.addEventListener("input", async function () {
omnibox.innerHTML = "";
const value = input?.value;
input.classList.remove("rounded-b-2xl");
omnibox.classList.remove("hidden");
if (value.length === 0) {
input.classList.add("rounded-b-2xl");
omnibox.classList.add("hidden");
}
if (value.length >= 3) {
const data = await client.fetch(`https://api.duckduckgo.com/ac?q=${encodeURIComponent(value)}&format=json`);
const dataRes = await data.json();
const filteredData = dataRes.slice(0, 8); //Trim to only about 8 results. Any more and our omnibox dies
if (filteredData) {
omnibox.innerHTML = "";
filteredData.map((results: Suggestion) => {
let span = document.createElement("span");
let pTag = document.createElement("p");
span.classList.add(
"cursor-pointer",
"font-roboto",
"border-b",
"border-input-border-color",
"last:rounded-b-xl",
"last:border-none",
"text-ellipsis",
"whitespace-nowrap",
"w-full",
"text-input-text",
"h-9",
"text-xl",
"text-align-center",
"overflow-hidden",
"flex",
"items-center",
"justify-center",
"hover:bg-lighter",
"active:bg-primary"
);
span.addEventListener("click", function () {
//When the box is clicked, we want to fill the omnibox and hit enter. This allows us to re-use the existing event listener on the input.
const event = new KeyboardEvent("keypress", {
key: "Enter",
code: "Enter",
which: 13,
keyCode: 13,
});
input.value = results.phrase;
input.dispatchEvent(event);
});
pTag.classList.add(
"cursor-pointer",
"text-ellipsis",
"text-center",
"w-full",
"overflow-hidden",
"whitespace-nowrap"
);
pTag.innerText = results.phrase;
span.appendChild(pTag);
omnibox.appendChild(span);
});
new EventHandler({
events: {
"astro:page-load": async () => {
await init()
}
}
});
}, true);
},
logging: true
})
.bind();
</script>

View file

@ -9,15 +9,15 @@ import Layout from "@layouts/Layout.astro";
<script>
import { EventHandler } from "@utils/events";
import { defaultStore } from "@utils/storage";
import { SettingsVals } from "@utils/values";
import { navigate } from "astro:transitions/client";
const eHandler = new EventHandler({
events: {
"astro:page-load": () => {
let currentLang = localStorage.getItem("selectedLanguage");
let currentLang = defaultStore.getVal(SettingsVals.i18n.lang);
if (currentLang) {
try {
let parsed = JSON.parse(currentLang).value;
switch (parsed) {
switch (currentLang) {
case "en_US":
navigate("/en_US/");
break;
@ -35,11 +35,11 @@ import Layout from "@layouts/Layout.astro";
}
else {
if (navigator.language.includes("ja")) {
defaultStore.setVal("selectedLanguage", JSON.stringify({ value: "jp" }));
defaultStore.setVal("selectedLanguage", SettingsVals.i18n.languages.jp);
navigate("/jp/");
}
else {
defaultStore.setVal("selectedLanguage", JSON.stringify({ value: "en_US" }));
defaultStore.setVal("selectedLanguage", SettingsVals.i18n.languages.en);
navigate("/en_US/");
}
}

View file

@ -35,6 +35,43 @@ function toast(query: string) {
element.click();
}
type Items = {
type: "id" | "class" | "generic",
val: string
}
class Elements {
/**
* An async generator function to get your objects quickly and easily.
*
* @example
* const items = selectElements(items: [{ type: "id", val: "iframe" }]);
* for await (const item of items) {
* console.log(item) // Perform some action on this item (OR pause and continue when needed!)
* }
*/
static async *select(items: Items[]) {
for (const item in items) {
switch (items[item].type) {
case "id":
yield document.getElementById(items[item].val) as HTMLElement;
break;
case "class":
yield document.getElementsByClassName(items[item].val);
break;
case "generic":
yield document.getElementsByName(items[item].val);
break;
}
}
};
static exists<RetType>(elem: any): RetType {
if (elem.value) return elem.value as RetType;
throw new Error(`Something is WRONG. The element doesn't exist!`);
}
}
/**
* Allows use to turn a basic phrase into a full URL. Mainly used when ther user enters something in for use in UV/SJ
*
@ -53,7 +90,7 @@ function search(input: string, template: string) {
return template.replace("%s", encodeURIComponent(input));
}
type LogTypes = "normal" | "info" | "error" | "warn";
type LogOpts = { type: "normal" | "warn" | "info", bg: boolean, prefix: boolean } | { type: "error", bg: boolean, prefix: boolean, throw: boolean }
/**
* Custom built log function with styles applied.
*
@ -61,7 +98,7 @@ type LogTypes = "normal" | "info" | "error" | "warn";
* import { log } from "@utils/index";
* log("info", opts: { bg: true, prefix: false }, message: "This is an example"); // BG can be true or false when BG is false, most of the time it reverts back to normal styling (except for the "normal" mode). When prefix is true, this adds a prefix of the type of message used.
*/
const log = (type: LogTypes, opts: { bg: boolean, prefix: boolean }, message: string) => {
const log = (type: LogOpts, message: string): void => {
const styles = {
warn: {
bg: {
@ -92,18 +129,19 @@ const log = (type: LogTypes, opts: { bg: boolean, prefix: boolean }, message: st
normal: "#7967dd"
}
}
switch(type) {
switch(type.type) {
case "info":
console.info(`%c${opts.prefix ? `Info: ${message}` : message}`, `${opts.bg ? `color: ${styles.info.bg.color}; background-color: ${styles.info.bg.bg}; padding: 2px 10px; font-weight: bold;` : `color: ${styles.info.normal}; font-weight: bold;`}`);
console.info(`%c${type.prefix ? `Info: ${message}` : message}`, `${type.bg ? `color: ${styles.info.bg.color}; background-color: ${styles.info.bg.bg}; padding: 2px 10px; font-weight: bold;` : `color: ${styles.info.normal}; font-weight: bold;`}`);
break;
case "error":
console.error(`%c${opts.prefix ? `Error: ${message}` : message }`, `${opts.bg ? `color: ${styles.error.bg.color}; background-color: ${styles.error.bg.bg}; padding: 2px 10px;` : `color: ${styles.error.normal};`}`);
if (type.throw) throw new Error(message);
console.error(`%c${type.prefix ? `Error: ${message}` : message }`, `${type.bg ? `color: ${styles.error.bg.color}; background-color: ${styles.error.bg.bg}; padding: 2px 10px;` : `color: ${styles.error.normal};`}`);
break;
case "warn":
console.warn(`%c${opts.prefix ? `Warning: ${message}` : message}`, `${opts.bg ? `color: ${styles.warn.bg.color}; background-color: ${styles.warn.bg.bg}; padding: 2px 10px;` : `color: ${styles.warn.normal};`}`);
console.warn(`%c${type.prefix ? `Warning: ${message}` : message}`, `${type.bg ? `color: ${styles.warn.bg.color}; background-color: ${styles.warn.bg.bg}; padding: 2px 10px;` : `color: ${styles.warn.normal};`}`);
break;
case "normal":
console.log(`%c${message}`, `${opts.bg ? `color: ${styles.normal.bg.color}; background-color: ${styles.normal.bg.bg}; padding: 2px 10px; font-weight: bold;` : `color: ${styles.normal.normal}; font-weight: bold;`}`);
console.log(`%c${message}`, `${type.bg ? `color: ${styles.normal.bg.color}; background-color: ${styles.normal.bg.bg}; padding: 2px 10px; font-weight: bold;` : `color: ${styles.normal.normal}; font-weight: bold;`}`);
break;
}
};
@ -115,5 +153,6 @@ export {
type Props,
toast,
search,
log
log,
Elements
};

View file

@ -109,11 +109,15 @@ class SW {
client: "/scram/scramjet.client.js",
shared: "/scram/scramjet.shared.js",
sync: "/scram/scramjet.sync.js"
},
flags: {
rewriterLogs: false
}
});
return sj;
}
if ("serviceWorker" in navigator) {
(async () => { await navigator.serviceWorker.getRegistrations() })();
const scram = sj();
(async () => await scram.init())();
navigator.serviceWorker.ready.then(async (reg) => {

View file

@ -1,3 +1,4 @@
import { log } from "./index";
/**
* This class will create a new StoreManager with an appended prefix to it. The generic is there to tell you what that prefix ***is***
*
@ -15,16 +16,18 @@
* </code>
*/
class StoreManager<Prefix extends string /* This is here so I know what prefix is appended. It's inferred from the constructor */> {
prefix: Prefix;
#prefix: Prefix;
constructor(pref: Prefix) {
this.prefix = pref;
this.#prefix = pref;
}
getVal(key: string): string {
return localStorage.getItem(`${this.prefix}||${key}`) as string;
log({ type: 'info', bg: true, prefix: true }, `Getting key: ${key} \nFull key: ${this.#prefix}||${key}`);
return localStorage.getItem(`${this.#prefix}||${key}`) as string;
}
setVal(key: string, val: string): void {
localStorage.setItem(key, val);
localStorage.setItem(`${this.#prefix}||${key}`, val);
}
}
//this is done so I can see the prefix used.

View file

@ -22,18 +22,77 @@ const SupportedSites: Record<string, "uv" | "sj"> = {
"spotify.com": "sj",
"spotify.link": "sj",
"youtube.com": "uv",
"youtu.be": "uv"
"youtu.be": "uv",
"google.com": "uv"
};
interface SettingsVals {
i18n: {
lang: "selectedLanguage",
languages: {
en: string,
jp: string
}
},
proxy: {
wispServer: string,
proxy: {
key: string,
available: {
uv: string;
sj: string;
automatic: string
}
},
searchEngine: string,
transport: {
key: string,
available: {
epoxy: string;
libcurl: string;
}
},
},
tab: {
cloak: string
},
marketPlace: {
appearance: {
video: string;
image: string;
themeName: string;
}
}
}
/**
* This object allows us to access things such as the wisp server url and other things that aren't just one offs
*/
const SettingsVals = {
const SettingsVals: SettingsVals = {
i18n: {
lang: "selectedLanguage",
languages: {
en: "en_US",
jp: "jp"
}
},
proxy: {
wispServer: "wispServerUrl",
proxy: "proxy",
proxy: {
key: "proxy",
available: {
sj: "sj",
uv: "uv",
automatic: "automatic"
}
},
searchEngine: "searchEngine",
transport: "transport"
transport: {
key: "transport",
available: {
epoxy: "epoxy",
libcurl: "libcurl"
}
}
},
tab: {
cloak: "cloak"