some reorginization

This commit is contained in:
MathMan05
2024-11-30 19:04:00 -06:00
parent e06b28742c
commit d94c20b275
17 changed files with 586 additions and 503 deletions

View File

@@ -0,0 +1,79 @@
class BinRead{
private i = 0;
private view:DataView;
constructor(buffer:ArrayBuffer){
this.view=new DataView(buffer, 0)
}
read16(){
const int = this.view.getUint16(this.i);
this.i += 2;
return int;
}
read8(){
const int = this.view.getUint8(this.i);
this.i += 1;
return int;
}
readString8(){
return this.readStringNo(this.read8());
}
readString16(){
return this.readStringNo(this.read16());
}
readStringNo(length: number){
const array = new Uint8Array(length);
for(let i = 0; i < length; i++){
array[i] = this.read8();
}
//console.log(array);
return new TextDecoder("utf8").decode(array.buffer as ArrayBuffer);
}
}
class BinWrite{
private view: DataView;
private buffer:ArrayBuffer;
private i=0;
constructor(maxSize:number=2**26){
this.buffer=new ArrayBuffer(maxSize);
this.view=new DataView(this.buffer, 0);
}
write16(numb:number){
this.view.setUint16(this.i,numb);
this.i+=2;
}
write8(numb:number){
this.view.setUint8(this.i,numb);
this.i+=1;
}
writeString8(str:string){
const encode=new TextEncoder().encode(str);
this.write8(encode.length);
for(const thing of encode){
this.write8(thing);
}
}
writeString16(str:string){
const encode=new TextEncoder().encode(str);
this.write16(encode.length);
for(const thing of encode){
this.write8(thing);
}
}
writeStringNo(str:string){
const encode=new TextEncoder().encode(str);
for(const thing of encode){
this.write8(thing);
}
}
getBuffer(){
const buf=new ArrayBuffer(this.i);
const ar1=new Uint8Array(buf);
const ar2=new Uint8Array(this.buffer);
for(let i in ar1){
ar1[+i]=ar2[+i];
}
return buf;
}
}
export {BinRead,BinWrite}

436
src/webpage/utils/utils.ts Normal file
View File

@@ -0,0 +1,436 @@
import { I18n } from "../i18n.js";
setTheme();
export function setTheme() {
let name = localStorage.getItem("theme");
if (!name) {
localStorage.setItem("theme", "Dark");
name = "Dark";
}
document.body.className = name + "-theme";
}
export function getBulkUsers() {
const json = getBulkInfo();
for (const thing in json.users) {
json.users[thing] = new Specialuser(json.users[thing]);
}
return json;
}
export function getBulkInfo() {
return JSON.parse(localStorage.getItem("userinfos") as string);
}
export function setDefaults() {
let userinfos = getBulkInfo();
if (!userinfos) {
localStorage.setItem(
"userinfos",
JSON.stringify({
currentuser: null,
users: {},
preferences: {
theme: "Dark",
notifications: false,
notisound: "three",
},
})
);
userinfos = getBulkInfo();
}
if (userinfos.users === undefined) {
userinfos.users = {};
}
if (userinfos.accent_color === undefined) {
userinfos.accent_color = "#3096f7";
}
document.documentElement.style.setProperty(
"--accent-color",
userinfos.accent_color
);
if (userinfos.preferences === undefined) {
userinfos.preferences = {
theme: "Dark",
notifications: false,
notisound: "three",
};
}
if (userinfos.preferences && userinfos.preferences.notisound === undefined) {
console.warn("uhoh");
userinfos.preferences.notisound = "three";
}
localStorage.setItem("userinfos", JSON.stringify(userinfos));
}
setDefaults();
export class Specialuser {
serverurls: {
api: string;
cdn: string;
gateway: string;
wellknown: string;
login: string;
};
email: string;
token: string;
loggedin;
json;
constructor(json: any) {
if (json instanceof Specialuser) {
console.error("specialuser can't construct from another specialuser");
}
this.serverurls = json.serverurls;
let apistring = new URL(json.serverurls.api).toString();
apistring = apistring.replace(/\/(v\d+\/?)?$/, "") + "/v9";
this.serverurls.api = apistring;
this.serverurls.cdn = new URL(json.serverurls.cdn)
.toString()
.replace(/\/$/, "");
this.serverurls.gateway = new URL(json.serverurls.gateway)
.toString()
.replace(/\/$/, "");
this.serverurls.wellknown = new URL(json.serverurls.wellknown)
.toString()
.replace(/\/$/, "");
this.serverurls.login = new URL(json.serverurls.login)
.toString()
.replace(/\/$/, "");
this.email = json.email;
this.token = json.token;
this.loggedin = json.loggedin;
this.json = json;
this.json.localuserStore ??= {};
if (!this.serverurls || !this.email || !this.token) {
console.error(
"There are fundamentally missing pieces of info missing from this user"
);
}
}
set pfpsrc(e) {
this.json.pfpsrc = e;
this.updateLocal();
}
get pfpsrc() {
return this.json.pfpsrc;
}
set username(e) {
this.json.username = e;
this.updateLocal();
}
get username() {
return this.json.username;
}
set localuserStore(e) {
this.json.localuserStore = e;
this.updateLocal();
}
get localuserStore() {
return this.json.localuserStore;
}
set id(e) {
this.json.id = e;
this.updateLocal();
}
get id() {
return this.json.id;
}
get uid() {
return this.email + this.serverurls.wellknown;
}
toJSON() {
return this.json;
}
updateLocal() {
const info = getBulkInfo();
info.users[this.uid] = this.toJSON();
localStorage.setItem("userinfos", JSON.stringify(info));
}
}
const mobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
const iOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
export{
mobile,
iOS,
}
let instances:
| {
name: string;
description?: string;
descriptionLong?: string;
image?: string;
url?: string;
display?: boolean;
online?: boolean;
uptime: { alltime: number; daytime: number; weektime: number };
urls: {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login?: string;
};
}[]
| null;
const datalist = document.getElementById("instances");
console.warn(datalist);
const instancefetch=fetch("/instances.json")
.then(res=>res.json())
.then(
(json: {
name: string;
description?: string;
descriptionLong?: string;
image?: string;
url?: string;
display?: boolean;
online?: boolean;
uptime: { alltime: number; daytime: number; weektime: number };
urls: {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login?: string;
}
}[]
)=>{
instances = json;
if(datalist){
console.warn(json);
const instancein = document.getElementById("instancein") as HTMLInputElement;
if(instancein && instancein.value === ""){
instancein.value = json[0].name;
}
for(const instance of json){
if(instance.display === false){
continue;
}
const option = document.createElement("option");
option.disabled = !instance.online;
option.value = instance.name;
if(instance.url){
stringURLMap.set(option.value, instance.url);
if(instance.urls){
stringURLsMap.set(instance.url, instance.urls);
}
}else if(instance.urls){
stringURLsMap.set(option.value, instance.urls);
}else{
option.disabled = true;
}
if(instance.description){
option.label = instance.description;
}else{
option.label = instance.name;
}
datalist.append(option);
}
checkInstance("");
}
}
);
const stringURLMap = new Map<string, string>();
const stringURLsMap = new Map<
string,
{
wellknown: string;
api: string;
cdn: string;
gateway: string;
login?: string;
}
>();
export async function getapiurls(str: string): Promise<
{
api: string;
cdn: string;
gateway: string;
wellknown: string;
login: string;
}
| false
>{
function appendApi(str:string){
return str.includes("api")?"" : (str.endsWith("/")? "api" : "/api");
}
if(!URL.canParse(str)){
const val = stringURLMap.get(str);
if(stringURLMap.size===0){
await new Promise<void>(res=>{
setInterval(()=>{
if(stringURLMap.size!==0){
res();
}
},100);
});
}
if(val){
str = val;
}else{
const val = stringURLsMap.get(str);
if(val){
const responce = await fetch(
val.api + (val.api.endsWith("/") ? "" : "/") + "ping"
);
if(responce.ok){
if(val.login){
return val as {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login: string;
};
}else{
val.login = val.api;
return val as {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login: string;
};
}
}
}
}
}
if(str.at(-1) !== "/"){
str += "/";
}
let api: string;
try{
const info = await fetch(`${str}.well-known/spacebar`).then(x=>x.json()
);
api = info.api;
}catch{
api=str;
}
if(!URL.canParse(api)){
return false;
}
const url = new URL(api);
try{
const info = await fetch(
`${api}${
url.pathname.includes("api") ? "" : "api"
}/policies/instance/domains`
).then(x=>x.json());
const apiurl = new URL(info.apiEndpoint);
return{
api: info.apiEndpoint+appendApi(apiurl.pathname),
gateway: info.gateway,
cdn: info.cdn,
wellknown: str,
login: info.apiEndpoint+appendApi(apiurl.pathname),
};
}catch{
const val = stringURLsMap.get(str);
if(val){
const responce = await fetch(
val.api + (val.api.endsWith("/") ? "" : "/") + "ping"
);
if(responce.ok){
if(val.login){
return val as {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login: string;
};
}else{
val.login = val.api;
return val as {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login: string;
};
}
}
}
return false;
}
}
export async function checkInstance(instance: string){
await instancefetch;
const verify = document.getElementById("verify");
try{
verify!.textContent = I18n.getTranslation("login.checking");
const instanceValue = instance;
const instanceinfo = (await getapiurls(instanceValue)) as {
wellknown: string;
api: string;
cdn: string;
gateway: string;
login: string;
value: string;
};
if(instanceinfo){
instanceinfo.value = instanceValue;
localStorage.setItem("instanceinfo", JSON.stringify(instanceinfo));
verify!.textContent = I18n.getTranslation("login.allGood");
// @ts-ignore
if(checkInstance.alt){
// @ts-ignore
checkInstance.alt();
}
setTimeout((_: any)=>{
console.log(verify!.textContent);
verify!.textContent = "";
}, 3000);
}else{
verify!.textContent = I18n.getTranslation("login.invalid");
}
}catch{
console.log("catch");
verify!.textContent = I18n.getTranslation("login.invalid");
}
}
export function getInstances(){
return instances;
}
export class SW{
static worker:undefined|ServiceWorker;
static setMode(mode:"false"|"offlineOnly"|"true"){
localStorage.setItem("SWMode",mode);
if(this.worker){
this.worker.postMessage({data:mode,code:"setMode"});
}
}
static checkUpdate(){
if(this.worker){
this.worker.postMessage({code:"CheckUpdate"});
}
}
static forceClear(){
if(this.worker){
this.worker.postMessage({code:"ForceClear"});
}
}
}
if ("serviceWorker" in navigator){
navigator.serviceWorker.register("/service.js", {
scope: "/",
}).then((registration) => {
let serviceWorker:ServiceWorker|undefined;
if (registration.installing) {
serviceWorker = registration.installing;
console.log("installing");
} else if (registration.waiting) {
serviceWorker = registration.waiting;
console.log("waiting");
} else if (registration.active) {
serviceWorker = registration.active;
console.log("active");
}
SW.worker=serviceWorker;
SW.setMode(localStorage.getItem("SWMode") as "false"|"offlineOnly"|"true");
if (serviceWorker) {
console.log(serviceWorker.state);
serviceWorker.addEventListener("statechange", (_) => {
console.log(serviceWorker.state);
});
}
})
}