some reorginization
This commit is contained in:
parent
e06b28742c
commit
d94c20b275
17 changed files with 586 additions and 503 deletions
|
@ -1,5 +1,3 @@
|
||||||
import{ getBulkInfo }from"./login.js";
|
|
||||||
|
|
||||||
class AVoice{
|
class AVoice{
|
||||||
audioCtx: AudioContext;
|
audioCtx: AudioContext;
|
||||||
info: { wave: string | Function; freq: number };
|
info: { wave: string | Function; freq: number };
|
||||||
|
@ -72,10 +70,6 @@ class AVoice{
|
||||||
return(_t: number, _freq: number)=>{
|
return(_t: number, _freq: number)=>{
|
||||||
return Math.random() * 2 - 1;
|
return Math.random() * 2 - 1;
|
||||||
};
|
};
|
||||||
case"noise":
|
|
||||||
return(_t: number, _freq: number)=>{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return new Function();
|
return new Function();
|
||||||
}
|
}
|
||||||
|
@ -183,14 +177,5 @@ class AVoice{
|
||||||
static get sounds(){
|
static get sounds(){
|
||||||
return["three", "zip", "square", "beep"];
|
return["three", "zip", "square", "beep"];
|
||||||
}
|
}
|
||||||
static setNotificationSound(sound: string){
|
|
||||||
const userinfos = getBulkInfo();
|
|
||||||
userinfos.preferences.notisound = sound;
|
|
||||||
localStorage.setItem("userinfos", JSON.stringify(userinfos));
|
|
||||||
}
|
|
||||||
static getNotificationSound(){
|
|
||||||
const userinfos = getBulkInfo();
|
|
||||||
return userinfos.preferences.notisound;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
export{ AVoice as AVoice };
|
export{ AVoice as AVoice };
|
22
src/webpage/audio/index.html
Normal file
22
src/webpage/audio/index.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Jank Audio</title>
|
||||||
|
<meta content="Jank Sound" property="og:title">
|
||||||
|
<meta content="A sound editor for jank clients sound format .jasf" property="og:description">
|
||||||
|
<meta content="/logo.webp" property="og:image">
|
||||||
|
<meta content="#4b458c" data-react-helmet="true" name="theme-color">
|
||||||
|
<link href="/style.css" rel="stylesheet">
|
||||||
|
<link href="/themes.css" rel="stylesheet" id="lightcss">
|
||||||
|
<style>body.no-theme{background:#16191b;}@media(prefers-color-scheme:light){body.no-theme{background:#9397bd;}}</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="no-theme" style="overflow-y: scroll;">
|
||||||
|
<h1>Place holder text</h1>
|
||||||
|
</body>
|
||||||
|
<script src="/page.js" type="module"></script>
|
||||||
|
|
||||||
|
</html>
|
0
src/webpage/audio/page.ts
Normal file
0
src/webpage/audio/page.ts
Normal file
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
import{ Message }from"./message.js";
|
import{ Message }from"./message.js";
|
||||||
import{ AVoice }from"./audio.js";
|
import{ AVoice }from"./audio/audio.js";
|
||||||
import{ Contextmenu }from"./contextmenu.js";
|
import{ Contextmenu }from"./contextmenu.js";
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
|
@ -1403,7 +1403,7 @@ class Channel extends SnowFlake{
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
notify(message: Message, deep = 0){
|
notify(message: Message, deep = 0){
|
||||||
AVoice.noises(AVoice.getNotificationSound());
|
AVoice.noises(this.localuser.getNotificationSound());
|
||||||
if(!("Notification" in window)){
|
if(!("Notification" in window)){
|
||||||
}else if(Notification.permission === "granted"){
|
}else if(Notification.permission === "granted"){
|
||||||
let noticontent: string | undefined | null = message.content.textContent;
|
let noticontent: string | undefined | null = message.content.textContent;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import{ iOS }from"./login.js";
|
import{ iOS }from"./utils/utils.js";
|
||||||
class Contextmenu<x, y>{
|
class Contextmenu<x, y>{
|
||||||
static currentmenu: HTMLElement | "";
|
static currentmenu: HTMLElement | "";
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import{ Message }from"./message.js";
|
import{ Message }from"./message.js";
|
||||||
import{ MarkDown }from"./markdown.js";
|
import{ MarkDown }from"./markdown.js";
|
||||||
import{ embedjson, invitejson }from"./jsontypes.js";
|
import{ embedjson, invitejson }from"./jsontypes.js";
|
||||||
import{ getapiurls, getInstances }from"./login.js";
|
import{ getapiurls, getInstances }from"./utils/utils.js";
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import { ImagesDisplay } from "./disimg.js";
|
import { ImagesDisplay } from "./disimg.js";
|
||||||
|
|
|
@ -2,6 +2,7 @@ import{ Contextmenu }from"./contextmenu.js";
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import { emojijson } from "./jsontypes.js";
|
import { emojijson } from "./jsontypes.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
|
import { BinRead } from "./utils/binaryUtils.js";
|
||||||
|
|
||||||
//I need to recompile the emoji format for translation
|
//I need to recompile the emoji format for translation
|
||||||
class Emoji{
|
class Emoji{
|
||||||
|
@ -64,51 +65,24 @@ class Emoji{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static decodeEmojiList(buffer: ArrayBuffer){
|
static decodeEmojiList(buffer: ArrayBuffer){
|
||||||
const view = new DataView(buffer, 0);
|
const reader=new BinRead(buffer)
|
||||||
let i = 0;
|
const build: { name: string; emojis: { name: string; emoji: string }[] }[] = [];
|
||||||
function read16(){
|
let cats = reader.read16();
|
||||||
const int = view.getUint16(i);
|
|
||||||
i += 2;
|
|
||||||
return int;
|
|
||||||
}
|
|
||||||
function read8(){
|
|
||||||
const int = view.getUint8(i);
|
|
||||||
i += 1;
|
|
||||||
return int;
|
|
||||||
}
|
|
||||||
function readString8(){
|
|
||||||
return readStringNo(read8());
|
|
||||||
}
|
|
||||||
function readString16(){
|
|
||||||
return readStringNo(read16());
|
|
||||||
}
|
|
||||||
function readStringNo(length: number){
|
|
||||||
const array = new Uint8Array(length);
|
|
||||||
|
|
||||||
for(let i = 0; i < length; i++){
|
|
||||||
array[i] = read8();
|
|
||||||
}
|
|
||||||
//console.log(array);
|
|
||||||
return new TextDecoder("utf8").decode(array.buffer as ArrayBuffer);
|
|
||||||
}
|
|
||||||
const build: { name: string; emojis: { name: string; emoji: string }[] }[] =
|
|
||||||
[];
|
|
||||||
let cats = read16();
|
|
||||||
|
|
||||||
for(; cats !== 0; cats--){
|
for(; cats !== 0; cats--){
|
||||||
const name = readString16();
|
const name = reader.readString16();
|
||||||
const emojis: {
|
const emojis: {
|
||||||
name: string;
|
name: string;
|
||||||
skin_tone_support: boolean;
|
skin_tone_support: boolean;
|
||||||
emoji: string;
|
emoji: string;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
let emojinumber = read16();
|
let emojinumber = reader.read16();
|
||||||
for(; emojinumber !== 0; emojinumber--){
|
for(; emojinumber !== 0; emojinumber--){
|
||||||
//console.log(emojis);
|
//console.log(emojis);
|
||||||
const name = readString8();
|
const name = reader.readString8();
|
||||||
const len = read8();
|
const len = reader.read8();
|
||||||
const skin_tone_support = len > 127;
|
const skin_tone_support = len > 127;
|
||||||
const emoji = readStringNo(len - Number(skin_tone_support) * 128);
|
const emoji = reader.readStringNo(len - Number(skin_tone_support) * 128);
|
||||||
emojis.push({
|
emojis.push({
|
||||||
name,
|
name,
|
||||||
skin_tone_support,
|
skin_tone_support,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import{ mobile }from"./login.js";
|
import{ mobile }from"./utils/utils.js";
|
||||||
console.log(mobile);
|
console.log(mobile);
|
||||||
const serverbox = document.getElementById("instancebox") as HTMLDivElement;
|
const serverbox = document.getElementById("instancebox") as HTMLDivElement;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
import{ Contextmenu }from"./contextmenu.js";
|
import{ Contextmenu }from"./contextmenu.js";
|
||||||
import{ mobile, getBulkUsers, setTheme, Specialuser }from"./login.js";
|
import{ mobile }from"./utils/utils.js";
|
||||||
|
import { getBulkUsers, setTheme, Specialuser } from "./utils/utils.js";
|
||||||
import{ MarkDown }from"./markdown.js";
|
import{ MarkDown }from"./markdown.js";
|
||||||
import{ Message }from"./message.js";
|
import{ Message }from"./message.js";
|
||||||
import{File}from"./file.js";
|
import{File}from"./file.js";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import{ getBulkUsers, Specialuser, getapiurls }from"./login.js";
|
import{ getapiurls }from"./utils/utils.js";
|
||||||
|
import { getBulkUsers, Specialuser } from "./utils/utils.js";
|
||||||
|
|
||||||
(async ()=>{
|
(async ()=>{
|
||||||
const users = getBulkUsers();
|
const users = getBulkUsers();
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import{ Channel }from"./channel.js";
|
import{ Channel }from"./channel.js";
|
||||||
import{ Direct }from"./direct.js";
|
import{ Direct }from"./direct.js";
|
||||||
import{ AVoice }from"./audio.js";
|
import{ AVoice }from"./audio/audio.js";
|
||||||
import{ User }from"./user.js";
|
import{ User }from"./user.js";
|
||||||
import{ getapiurls, getBulkInfo, setTheme, Specialuser, SW }from"./login.js";
|
import{ getapiurls, SW }from"./utils/utils.js";
|
||||||
|
import { getBulkInfo, setTheme, Specialuser } from "./utils/utils.js";
|
||||||
import{channeljson,guildjson,mainuserjson,memberjson,memberlistupdatejson,messageCreateJson,presencejson,readyjson,startTypingjson,wsjson,}from"./jsontypes.js";
|
import{channeljson,guildjson,mainuserjson,memberjson,memberlistupdatejson,messageCreateJson,presencejson,readyjson,startTypingjson,wsjson,}from"./jsontypes.js";
|
||||||
import{ Member }from"./member.js";
|
import{ Member }from"./member.js";
|
||||||
import{ Dialog, Form, FormError, Options, Settings }from"./settings.js";
|
import{ Dialog, Form, FormError, Options, Settings }from"./settings.js";
|
||||||
|
@ -1237,10 +1238,10 @@ class Localuser{
|
||||||
.addSelect(
|
.addSelect(
|
||||||
I18n.getTranslation("localuser.notisound"),
|
I18n.getTranslation("localuser.notisound"),
|
||||||
_=>{
|
_=>{
|
||||||
AVoice.setNotificationSound(sounds[_]);
|
this.setNotificationSound(sounds[_]);
|
||||||
},
|
},
|
||||||
sounds,
|
sounds,
|
||||||
{ defaultIndex: sounds.indexOf(AVoice.getNotificationSound()) }
|
{ defaultIndex: sounds.indexOf(this.getNotificationSound()) }
|
||||||
)
|
)
|
||||||
.watchForChange(_=>{
|
.watchForChange(_=>{
|
||||||
AVoice.noises(sounds[_]);
|
AVoice.noises(sounds[_]);
|
||||||
|
@ -2121,5 +2122,14 @@ class Localuser{
|
||||||
dialog.options.addText(I18n.getTranslation("instanceStats.members",json.counts.members));
|
dialog.options.addText(I18n.getTranslation("instanceStats.members",json.counts.members));
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
setNotificationSound(sound: string){
|
||||||
|
const userinfos = getBulkInfo();
|
||||||
|
userinfos.preferences.notisound = sound;
|
||||||
|
localStorage.setItem("userinfos", JSON.stringify(userinfos));
|
||||||
|
}
|
||||||
|
getNotificationSound(){
|
||||||
|
const userinfos = getBulkInfo();
|
||||||
|
return userinfos.preferences.notisound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export{ Localuser };
|
export{ Localuser };
|
||||||
|
|
|
@ -1,95 +1,12 @@
|
||||||
|
import { getBulkInfo, Specialuser } from "./utils/utils.js";
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import { Dialog, FormError } from "./settings.js";
|
import { Dialog, FormError } from "./settings.js";
|
||||||
|
import { checkInstance } from "./utils/utils.js";
|
||||||
|
|
||||||
const mobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|
||||||
const iOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
||||||
|
|
||||||
let instances:
|
|
||||||
| {
|
await I18n.done;
|
||||||
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);
|
|
||||||
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("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
setTheme();
|
|
||||||
await I18n.done
|
|
||||||
function setTheme(){
|
|
||||||
let name = localStorage.getItem("theme");
|
|
||||||
if(!name){
|
|
||||||
localStorage.setItem("theme", "Dark");
|
|
||||||
name = "Dark";
|
|
||||||
}
|
|
||||||
document.body.className = name + "-theme";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
(async ()=>{
|
(async ()=>{
|
||||||
|
@ -108,13 +25,7 @@ function setTheme(){
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
function getBulkUsers(){
|
|
||||||
const json = getBulkInfo();
|
|
||||||
for(const thing in json.users){
|
|
||||||
json.users[thing] = new Specialuser(json.users[thing]);
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
function trimswitcher(){
|
function trimswitcher(){
|
||||||
const json = getBulkInfo();
|
const json = getBulkInfo();
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
|
@ -148,133 +59,8 @@ function trimswitcher(){
|
||||||
console.log(json);
|
console.log(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBulkInfo(){
|
|
||||||
return JSON.parse(localStorage.getItem("userinfos") as string);
|
|
||||||
}
|
|
||||||
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();
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function adduser(user: typeof Specialuser.prototype.json){
|
function adduser(user: typeof Specialuser.prototype.json){
|
||||||
user = new Specialuser(user);
|
user = new Specialuser(user);
|
||||||
const info = getBulkInfo();
|
const info = getBulkInfo();
|
||||||
|
@ -286,167 +72,8 @@ function adduser(user: typeof Specialuser.prototype.json){
|
||||||
const instancein = document.getElementById("instancein") as HTMLInputElement;
|
const instancein = document.getElementById("instancein") as HTMLInputElement;
|
||||||
let timeout: ReturnType<typeof setTimeout> | string | number | undefined | null = null;
|
let timeout: ReturnType<typeof setTimeout> | string | number | undefined | null = null;
|
||||||
// let instanceinfo;
|
// let instanceinfo;
|
||||||
const stringURLMap = new Map<string, string>();
|
|
||||||
|
|
||||||
const stringURLsMap = new Map<
|
|
||||||
string,
|
|
||||||
{
|
|
||||||
wellknown: string;
|
|
||||||
api: string;
|
|
||||||
cdn: string;
|
|
||||||
gateway: string;
|
|
||||||
login?: string;
|
|
||||||
}
|
|
||||||
>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function checkInstance(instance?: string){
|
|
||||||
await instancefetch;
|
|
||||||
const verify = document.getElementById("verify");
|
|
||||||
try{
|
|
||||||
verify!.textContent = I18n.getTranslation("login.checking");
|
|
||||||
const instanceValue = instance || (instancein as HTMLInputElement).value;
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(instancein){
|
if(instancein){
|
||||||
console.log(instancein);
|
console.log(instancein);
|
||||||
|
@ -456,7 +83,7 @@ if(instancein){
|
||||||
if(timeout !== null && typeof timeout !== "string"){
|
if(timeout !== null && typeof timeout !== "string"){
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
}
|
}
|
||||||
timeout = setTimeout(()=>checkInstance(), 1000);
|
timeout = setTimeout(()=>checkInstance((instancein as HTMLInputElement).value), 1000);
|
||||||
});
|
});
|
||||||
if(localStorage.getItem("instanceinfo")){
|
if(localStorage.getItem("instanceinfo")){
|
||||||
const json = JSON.parse(localStorage.getItem("instanceinfo")!);
|
const json = JSON.parse(localStorage.getItem("instanceinfo")!);
|
||||||
|
@ -597,51 +224,6 @@ if(document.getElementById("form")){
|
||||||
if(!localStorage.getItem("SWMode")){
|
if(!localStorage.getItem("SWMode")){
|
||||||
localStorage.setItem("SWMode","true");
|
localStorage.setItem("SWMode","true");
|
||||||
}
|
}
|
||||||
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"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export {SW};
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchurl = document.getElementById("switch") as HTMLAreaElement;
|
const switchurl = document.getElementById("switch") as HTMLAreaElement;
|
||||||
if(switchurl){
|
if(switchurl){
|
||||||
|
@ -653,22 +235,13 @@ if(switchurl){
|
||||||
checkInstance("");
|
checkInstance("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export{ checkInstance };
|
|
||||||
trimswitcher();
|
trimswitcher();
|
||||||
|
|
||||||
export{
|
export{
|
||||||
mobile,
|
|
||||||
iOS,
|
|
||||||
getBulkUsers,
|
|
||||||
getBulkInfo,
|
|
||||||
setTheme,
|
|
||||||
Specialuser,
|
|
||||||
getapiurls,
|
|
||||||
adduser,
|
adduser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export function getInstances(){
|
|
||||||
return instances;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import{ File }from"./file.js";
|
||||||
import{ SnowFlake }from"./snowflake.js";
|
import{ SnowFlake }from"./snowflake.js";
|
||||||
import{ memberjson, messagejson }from"./jsontypes.js";
|
import{ memberjson, messagejson }from"./jsontypes.js";
|
||||||
import{ Emoji }from"./emoji.js";
|
import{ Emoji }from"./emoji.js";
|
||||||
import{ mobile }from"./login.js";
|
import{ mobile }from"./utils/utils.js";
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import { Hover } from "./hover.js";
|
import { Hover } from "./hover.js";
|
||||||
import { Dialog } from "./settings.js";
|
import { Dialog } from "./settings.js";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { I18n } from "../i18n.js";
|
import { I18n } from "../i18n.js";
|
||||||
import{ getBulkUsers, Specialuser, getapiurls }from"../login.js";
|
import{ getapiurls }from"../utils/utils.js";
|
||||||
|
import { getBulkUsers, Specialuser } from "../utils/utils.js";
|
||||||
import { Permissions } from "../permissions.js";
|
import { Permissions } from "../permissions.js";
|
||||||
type botjsonfetch={
|
type botjsonfetch={
|
||||||
guilds:{
|
guilds:{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import{ checkInstance, adduser }from"./login.js";
|
import{ checkInstance }from"./utils/utils.js";
|
||||||
|
import {adduser} from"./login.js";
|
||||||
import { MarkDown } from "./markdown.js";
|
import { MarkDown } from "./markdown.js";
|
||||||
await I18n.done
|
await I18n.done
|
||||||
const registerElement = document.getElementById("register");
|
const registerElement = document.getElementById("register");
|
||||||
|
|
79
src/webpage/utils/binaryUtils.ts
Normal file
79
src/webpage/utils/binaryUtils.ts
Normal 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
436
src/webpage/utils/utils.ts
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue