push current translation support progress
This commit is contained in:
parent
602b16a0ef
commit
a0d870c1b3
14 changed files with 243 additions and 195 deletions
|
@ -6,6 +6,7 @@ import { User } from "./user.js";
|
|||
import {guildjson} from "./jsontypes.js";
|
||||
import { PermissionToggle } from "./role.js";
|
||||
import { Permissions } from "./permissions.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
class Bot{
|
||||
readonly owner:Localuser;
|
||||
readonly token:string;
|
||||
|
@ -27,7 +28,7 @@ class Bot{
|
|||
};
|
||||
}
|
||||
settings(){
|
||||
const settings = new Settings("Bot Settings");
|
||||
const settings = new Settings(I18n.getTranslation("botSettings"));
|
||||
const botOptions = settings.addButton("Profile",{ltr:true});
|
||||
const bot=new User(this.json,this.localuser);
|
||||
{
|
||||
|
@ -50,7 +51,7 @@ class Bot{
|
|||
settingsRight.addHTMLArea(hypotheticalProfile);
|
||||
|
||||
const finput = settingsLeft.addFileInput(
|
||||
"Upload pfp:",
|
||||
I18n.getTranslation("uploadPfp"),
|
||||
_=>{
|
||||
if(file){
|
||||
this.updatepfp(file);
|
||||
|
@ -76,7 +77,7 @@ class Bot{
|
|||
});
|
||||
let bfile: undefined | File | null;
|
||||
const binput = settingsLeft.addFileInput(
|
||||
"Upload banner:",
|
||||
I18n.getTranslation("uploadBanner"),
|
||||
_=>{
|
||||
if(bfile !== undefined){
|
||||
this.updatebanner(bfile);
|
||||
|
@ -102,7 +103,7 @@ class Bot{
|
|||
});
|
||||
let changed = false;
|
||||
const pronounbox = settingsLeft.addTextInput(
|
||||
"Pronouns",
|
||||
I18n.getTranslation("pronouns"),
|
||||
_=>{
|
||||
if(newpronouns || newbio || changed){
|
||||
this.updateProfile({
|
||||
|
@ -119,7 +120,7 @@ class Bot{
|
|||
newpronouns = _;
|
||||
regen();
|
||||
});
|
||||
const bioBox = settingsLeft.addMDInput("Bio:", _=>{}, {
|
||||
const bioBox = settingsLeft.addMDInput(I18n.getTranslation("bio"), _=>{}, {
|
||||
initText: bot.bio.rawString,
|
||||
});
|
||||
bioBox.watchForChange(_=>{
|
||||
|
@ -134,7 +135,7 @@ class Bot{
|
|||
color = "transparent";
|
||||
}
|
||||
const colorPicker = settingsLeft.addColorInput(
|
||||
"Profile color",
|
||||
I18n.getTranslation("profileColor"),
|
||||
_=>{},
|
||||
{ initColor: color }
|
||||
);
|
||||
|
@ -148,7 +149,7 @@ class Bot{
|
|||
}
|
||||
{
|
||||
const guildsettings=settings.addButton("Guilds");
|
||||
guildsettings.addTitle("Guilds bot is in:");
|
||||
guildsettings.addTitle(I18n.getTranslation("botGuilds"));
|
||||
fetch(this.info.api+"/users/@me/guilds/",{
|
||||
headers:this.headers
|
||||
}).then(_=>_.json()).then((json:(guildjson["properties"])[])=>{
|
||||
|
@ -187,8 +188,8 @@ class Bot{
|
|||
content.onclick=()=>{
|
||||
const guildsetting=guildsettings.addSubOptions(guild.name);
|
||||
guildsetting.addHTMLArea(content);
|
||||
guildsetting.addButtonInput("","Leave Guild",()=>{
|
||||
if(confirm(`Are you sure you want to leave ${guild.name}?`)){
|
||||
guildsetting.addButtonInput("",I18n.getTranslation("leaveGuild"),()=>{
|
||||
if(confirm(I18n.getTranslation("confirmGuildLeave",guild.name))){
|
||||
fetch(this.info.api+"/users/@me/guilds/"+guild.id,{
|
||||
method:"DELETE",
|
||||
headers:this.headers
|
||||
|
@ -250,7 +251,7 @@ class Bot{
|
|||
});
|
||||
}
|
||||
static InviteMaker(id:string,container:Form,info:Localuser["info"]){
|
||||
const gen=container.addSubOptions("URL generator",{
|
||||
const gen=container.addSubOptions(I18n.getTranslation("UrlGen"),{
|
||||
noSubmit:true
|
||||
});
|
||||
const params = new URLSearchParams("");
|
||||
|
|
|
@ -15,6 +15,7 @@ import{ MarkDown }from"./markdown.js";
|
|||
import{ Member }from"./member.js";
|
||||
import { Voice } from "./voice.js";
|
||||
import { User } from "./user.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
|
||||
declare global {
|
||||
interface NotificationOptions {
|
||||
|
@ -53,20 +54,20 @@ class Channel extends SnowFlake{
|
|||
voice?:Voice;
|
||||
bitrate:number=128000;
|
||||
static setupcontextmenu(){
|
||||
this.contextmenu.addbutton("Copy channel id", function(this: Channel){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("channel.copyId"), function(this: Channel){
|
||||
navigator.clipboard.writeText(this.id);
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton("Mark as read", function(this: Channel){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("channel.markRead"), function(this: Channel){
|
||||
this.readbottom();
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton("Settings", function(this: Channel){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("channel.settings"), function(this: Channel){
|
||||
this.generateSettings();
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
"Delete channel",
|
||||
()=>I18n.getTranslation("channel.delete"),
|
||||
function(this: Channel){
|
||||
this.deleteChannel();
|
||||
},
|
||||
|
@ -77,7 +78,7 @@ class Channel extends SnowFlake{
|
|||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
"Make invite",
|
||||
()=>I18n.getTranslation("channel.makeInvite"),
|
||||
function(this: Channel){
|
||||
this.createInvite();
|
||||
},
|
||||
|
@ -86,24 +87,6 @@ class Channel extends SnowFlake{
|
|||
return this.hasPermission("CREATE_INSTANT_INVITE") && this.type !== 4;
|
||||
}
|
||||
);
|
||||
/*
|
||||
this.contextmenu.addbutton("Test button",function(){
|
||||
this.localuser.ws.send(JSON.stringify({
|
||||
"op": 14,
|
||||
"d": {
|
||||
"guild_id": this.guild.id,
|
||||
"channels": {
|
||||
[this.id]: [
|
||||
[
|
||||
0,
|
||||
99
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}))
|
||||
},null);
|
||||
/**/
|
||||
}
|
||||
createInvite(){
|
||||
const div = document.createElement("div");
|
||||
|
@ -148,20 +131,20 @@ class Channel extends SnowFlake{
|
|||
update();
|
||||
new Dialog([
|
||||
"vdiv",
|
||||
["title", "Invite people"],
|
||||
["title", I18n.getTranslation("inviteOptions.title")],
|
||||
["text", `to #${this.name} in ${this.guild.properties.name}`],
|
||||
[
|
||||
"select",
|
||||
"Expire after:",
|
||||
[
|
||||
"30 Minutes",
|
||||
"1 Hour",
|
||||
"6 Hours",
|
||||
"12 Hours",
|
||||
"1 Day",
|
||||
"7 Days",
|
||||
"30 Days",
|
||||
"Never",
|
||||
I18n.getTranslation("inviteOptions.30m"),
|
||||
I18n.getTranslation("inviteOptions.1h"),
|
||||
I18n.getTranslation("inviteOptions.6h"),
|
||||
I18n.getTranslation("inviteOptions.12h"),
|
||||
I18n.getTranslation("inviteOptions.1d"),
|
||||
I18n.getTranslation("inviteOptions.7d"),
|
||||
I18n.getTranslation("inviteOptions.30d"),
|
||||
I18n.getTranslation("inviteOptions.never"),
|
||||
],
|
||||
function(e: Event){
|
||||
expires = [1800, 3600, 21600, 43200, 86400, 604800, 2592000, 0,][(e.srcElement as HTMLSelectElement).selectedIndex];
|
||||
|
@ -174,13 +157,13 @@ class Channel extends SnowFlake{
|
|||
"select",
|
||||
"Max uses:",
|
||||
[
|
||||
"No limit",
|
||||
"1 use",
|
||||
"5 uses",
|
||||
"10 uses",
|
||||
"25 uses",
|
||||
"50 uses",
|
||||
"100 uses",
|
||||
I18n.getTranslation("inviteOptions.noLimit"),
|
||||
I18n.getTranslation("inviteOptions.limit","1"),
|
||||
I18n.getTranslation("inviteOptions.limit","5"),
|
||||
I18n.getTranslation("inviteOptions.limit","10"),
|
||||
I18n.getTranslation("inviteOptions.limit","25"),
|
||||
I18n.getTranslation("inviteOptions.limit","50"),
|
||||
I18n.getTranslation("inviteOptions.limit","100"),
|
||||
],
|
||||
function(e: Event){
|
||||
uses = [0, 1, 5, 10, 25, 50, 100][(e.srcElement as HTMLSelectElement).selectedIndex];
|
||||
|
@ -193,7 +176,7 @@ class Channel extends SnowFlake{
|
|||
}
|
||||
generateSettings(){
|
||||
this.sortPerms();
|
||||
const settings = new Settings("Settings for " + this.name);
|
||||
const settings = new Settings(I18n.getTranslation("channel.settingsFor",this.name));
|
||||
{
|
||||
const gensettings=settings.addButton("Settings");
|
||||
const form=gensettings.addForm("",()=>{},{
|
||||
|
@ -201,18 +184,19 @@ class Channel extends SnowFlake{
|
|||
method: "PATCH",
|
||||
headers: this.headers,
|
||||
});
|
||||
form.addTextInput("Name:","name",{initText:this.name});
|
||||
form.addMDInput("Topic:","topic",{initText:this.topic});
|
||||
form.addCheckboxInput("NSFW:","nsfw",{initState:this.nsfw});
|
||||
form.addTextInput(I18n.getTranslation("channel.name:"),"name",{initText:this.name});
|
||||
form.addMDInput(I18n.getTranslation("channel.topic:"),"topic",{initText:this.topic});
|
||||
form.addCheckboxInput(I18n.getTranslation("channel.nsfw:"),"nsfw",{initState:this.nsfw});
|
||||
if(this.type!==4){
|
||||
const options=["voice", "text", "announcement"];
|
||||
form.addSelect("Type:","type",options,{
|
||||
form.addSelect("Type:","type",options.map(e=>I18n.getTranslation("channel."+e)),{
|
||||
defaultIndex:options.indexOf({0:"text", 2:"voice", 5:"announcement", 4:"category" }[this.type] as string)
|
||||
},options);
|
||||
form.addPreprocessor((obj:any)=>{
|
||||
obj.type={text: 0, voice: 2, announcement: 5, category: 4 }[obj.type as string]
|
||||
})
|
||||
}
|
||||
form.addPreprocessor((obj:any)=>{
|
||||
obj.type={text: 0, voice: 2, announcement: 5, category: 4 }[obj.type as string]
|
||||
})
|
||||
|
||||
}
|
||||
const s1 = settings.addButton("Permissions");
|
||||
s1.options.push(
|
||||
|
@ -308,10 +292,7 @@ class Channel extends SnowFlake{
|
|||
this.permission_overwrites = new Map();
|
||||
this.permission_overwritesar = [];
|
||||
for(const thing of json.permission_overwrites){
|
||||
if(
|
||||
thing.id === "1182819038095799904" ||
|
||||
thing.id === "1182820803700625444"
|
||||
){
|
||||
if(thing.id === "1182819038095799904" ||thing.id === "1182820803700625444"){
|
||||
continue;
|
||||
}
|
||||
if(!this.permission_overwrites.has(thing.id)){
|
||||
|
@ -376,10 +357,10 @@ class Channel extends SnowFlake{
|
|||
}
|
||||
return(
|
||||
Boolean(this.lastmessageid) &&
|
||||
(!this.lastreadmessageid ||
|
||||
SnowFlake.stringToUnixTime(this.lastmessageid as string) >
|
||||
SnowFlake.stringToUnixTime(this.lastreadmessageid)) &&
|
||||
this.type !== 4
|
||||
(!this.lastreadmessageid ||
|
||||
SnowFlake.stringToUnixTime(this.lastmessageid as string) >
|
||||
SnowFlake.stringToUnixTime(this.lastreadmessageid)) &&
|
||||
this.type !== 4
|
||||
);
|
||||
}
|
||||
hasPermission(name: string, member = this.guild.member): boolean{
|
||||
|
@ -406,10 +387,7 @@ class Channel extends SnowFlake{
|
|||
return false;
|
||||
}
|
||||
get canMessage(): boolean{
|
||||
if(
|
||||
this.permission_overwritesar.length === 0 &&
|
||||
this.hasPermission("MANAGE_CHANNELS")
|
||||
){
|
||||
if(this.permission_overwritesar.length === 0 &&this.hasPermission("MANAGE_CHANNELS")){
|
||||
const role = this.guild.roles.find(_=>_.name === "@everyone");
|
||||
if(role){
|
||||
this.addRoleToPerms(role);
|
||||
|
@ -435,16 +413,17 @@ class Channel extends SnowFlake{
|
|||
calculateReorder(){
|
||||
let position = -1;
|
||||
const build: {
|
||||
id: string;
|
||||
position: number | undefined;
|
||||
parent_id: string | undefined;
|
||||
}[] = [];
|
||||
id: string;
|
||||
position: number | undefined;
|
||||
parent_id: string | undefined;
|
||||
}[] = [];
|
||||
for(const thing of this.children){
|
||||
const thisthing: {
|
||||
id: string;
|
||||
position: number | undefined;
|
||||
parent_id: string | undefined;
|
||||
} = { id: thing.id, position: undefined, parent_id: undefined };
|
||||
id: string;
|
||||
position: number | undefined;
|
||||
parent_id: string | undefined;
|
||||
} = { id: thing.id, position: undefined, parent_id: undefined };
|
||||
|
||||
if(thing.position < position){
|
||||
thing.position = thisthing.position = position + 1;
|
||||
}
|
||||
|
@ -652,12 +631,7 @@ class Channel extends SnowFlake{
|
|||
return;
|
||||
}
|
||||
fetch(
|
||||
this.info.api +
|
||||
"/channels/" +
|
||||
this.id +
|
||||
"/messages/" +
|
||||
this.lastmessageid +
|
||||
"/ack",
|
||||
this.info.api +"/channels/" + this.id + "/messages/" + this.lastmessageid + "/ack",
|
||||
{
|
||||
method: "POST",
|
||||
headers: this.headers,
|
||||
|
@ -768,7 +742,7 @@ class Channel extends SnowFlake{
|
|||
if(this.replyingto){
|
||||
replybox.innerHTML = "";
|
||||
const span = document.createElement("span");
|
||||
span.textContent = "Replying to " + this.replyingto.author.username;
|
||||
span.textContent = I18n.getTranslation("replyingTo", this.replyingto.author.username);
|
||||
const X = document.createElement("button");
|
||||
X.onclick = _=>{
|
||||
if(this.replyingto?.div){
|
||||
|
@ -827,9 +801,7 @@ class Channel extends SnowFlake{
|
|||
history.pushState(null, "", "/channels/" + this.guild_id + "/" + this.id);
|
||||
|
||||
this.localuser.pageTitle("#" + this.name);
|
||||
const channelTopic = document.getElementById(
|
||||
"channelTopic"
|
||||
) as HTMLSpanElement;
|
||||
const channelTopic = document.getElementById("channelTopic") as HTMLSpanElement;
|
||||
if(this.topic){
|
||||
channelTopic.innerHTML = new MarkDown(
|
||||
this.topic,
|
||||
|
@ -855,8 +827,7 @@ class Channel extends SnowFlake{
|
|||
|
||||
await this.buildmessages();
|
||||
//loading.classList.remove("loading");
|
||||
(document.getElementById("typebox") as HTMLDivElement).contentEditable =
|
||||
"" + this.canMessage;
|
||||
(document.getElementById("typebox") as HTMLDivElement).contentEditable =""+this.canMessage;
|
||||
}
|
||||
typingmap: Map<Member, number> = new Map();
|
||||
async typingStart(typing: startTypingjson): Promise<void>{
|
||||
|
@ -893,11 +864,7 @@ class Channel extends SnowFlake{
|
|||
this.typingmap.delete(thing);
|
||||
}
|
||||
}
|
||||
if(i > 1){
|
||||
build += " are typing";
|
||||
}else{
|
||||
build += " is typing";
|
||||
}
|
||||
build=I18n.getTranslation("typing",i+"",build);
|
||||
if(this.localuser.channelfocus === this){
|
||||
if(showing){
|
||||
typingtext.classList.remove("hidden");
|
||||
|
@ -1013,12 +980,7 @@ class Channel extends SnowFlake{
|
|||
}
|
||||
|
||||
await fetch(
|
||||
this.info.api +
|
||||
"/channels/" +
|
||||
this.id +
|
||||
"/messages?before=" +
|
||||
id +
|
||||
"&limit=100",
|
||||
this.info.api + "/channels/" + this.id +"/messages?before=" + id + "&limit=100",
|
||||
{
|
||||
headers: this.headers,
|
||||
}
|
||||
|
@ -1059,10 +1021,10 @@ class Channel extends SnowFlake{
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Please dont use this, its not implemented.
|
||||
* @deprecated
|
||||
* @todo
|
||||
**/
|
||||
* Please dont use this, its not implemented.
|
||||
* @deprecated
|
||||
* @todo
|
||||
**/
|
||||
async grabArround(/* id: string */){
|
||||
//currently unused and no plans to use it yet
|
||||
throw new Error("please don't call this, no one has implemented it :P");
|
||||
|
@ -1099,8 +1061,7 @@ class Channel extends SnowFlake{
|
|||
if(!removetitle){
|
||||
const title = document.createElement("h2");
|
||||
title.id = "removetitle";
|
||||
title.textContent =
|
||||
"No messages appear to be here, be the first to say something!";
|
||||
title.textContent = I18n.getTranslation("noMessages");
|
||||
title.classList.add("titlespace");
|
||||
messages.append(title);
|
||||
}
|
||||
|
@ -1353,7 +1314,7 @@ class Channel extends SnowFlake{
|
|||
noticontent ||= message.embeds[0]?.json.title;
|
||||
noticontent ||= message.content.textContent;
|
||||
}
|
||||
noticontent ||= "Blank Message";
|
||||
noticontent ||= I18n.getTranslation("blankMessage");
|
||||
let imgurl: null | string = null;
|
||||
const images = message.getimages();
|
||||
if(images.length){
|
||||
|
|
|
@ -12,6 +12,7 @@ import{
|
|||
import{ Permissions }from"./permissions.js";
|
||||
import{ SnowFlake }from"./snowflake.js";
|
||||
import{ Contextmenu }from"./contextmenu.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
|
||||
class Direct extends Guild{
|
||||
declare channelids: { [key: string]: Group };
|
||||
|
@ -99,24 +100,24 @@ dmPermissions.setPermission("SPEAK", 1);
|
|||
dmPermissions.setPermission("STREAM", 1);
|
||||
dmPermissions.setPermission("USE_VAD", 1);
|
||||
|
||||
// @ts-ignore
|
||||
// @ts-ignore I need to look into this lol
|
||||
class Group extends Channel{
|
||||
user: User;
|
||||
static contextmenu = new Contextmenu<Group, undefined>("channel menu");
|
||||
static setupcontextmenu(){
|
||||
this.contextmenu.addbutton("Copy DM id", function(this: Group){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("DMs.copyId"), function(this: Group){
|
||||
navigator.clipboard.writeText(this.id);
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton("Mark as read", function(this: Group){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("DMs.markRead"), function(this: Group){
|
||||
this.readbottom();
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton("Close DM", function(this: Group){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("DMs.close"), function(this: Group){
|
||||
this.deleteChannel();
|
||||
});
|
||||
|
||||
this.contextmenu.addbutton("Copy user ID", function(){
|
||||
this.contextmenu.addbutton(()=>I18n.getTranslation("user.copyId"), function(){
|
||||
navigator.clipboard.writeText(this.user.id);
|
||||
});
|
||||
}
|
||||
|
@ -179,10 +180,7 @@ class Group extends Channel{
|
|||
const prom = this.infinite.delete();
|
||||
history.pushState(null, "", "/channels/" + this.guild_id + "/" + this.id);
|
||||
this.localuser.pageTitle("@" + this.name);
|
||||
(document.getElementById("channelTopic") as HTMLElement).setAttribute(
|
||||
"hidden",
|
||||
""
|
||||
);
|
||||
(document.getElementById("channelTopic") as HTMLElement).setAttribute("hidden","");
|
||||
|
||||
const loading = document.getElementById("loadingdiv") as HTMLDivElement;
|
||||
Channel.regenLoadingMessages();
|
||||
|
@ -306,4 +304,5 @@ class Group extends Channel{
|
|||
}
|
||||
}
|
||||
export{ Direct, Group };
|
||||
Group.setupcontextmenu();
|
||||
|
||||
Group.setupcontextmenu()
|
||||
|
|
|
@ -4,6 +4,7 @@ import{ MarkDown }from"./markdown.js";
|
|||
import{ embedjson, invitejson }from"./jsontypes.js";
|
||||
import{ getapiurls, getInstances }from"./login.js";
|
||||
import{ Guild }from"./guild.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
|
||||
class Embed{
|
||||
type: string;
|
||||
|
@ -296,8 +297,7 @@ guild as invitejson["guild"] & { info: { cdn: string } }
|
|||
guildinfo.append(name);
|
||||
|
||||
const members = document.createElement("span");
|
||||
members.innerText =
|
||||
"#" + json.channel.name + " • Members: " + guild.member_count;
|
||||
members.innerText = "#" + json.channel.name + " • Members: " + guild.member_count;
|
||||
guildinfo.append(members);
|
||||
members.classList.add("subtext");
|
||||
iconrow.append(guildinfo);
|
||||
|
@ -305,12 +305,12 @@ guild as invitejson["guild"] & { info: { cdn: string } }
|
|||
|
||||
div.append(iconrow);
|
||||
const h2 = document.createElement("h2");
|
||||
h2.textContent = `You've been invited by ${json.inviter.username}`;
|
||||
h2.textContent = I18n.getTranslation("invite.invitedBy",json.inviter.username);
|
||||
div.append(h2);
|
||||
const button = document.createElement("button");
|
||||
button.textContent = "Accept";
|
||||
button.textContent = I18n.getTranslation("invite.accept");
|
||||
if(this.localuser.info.api.startsWith(info.api) && this.localuser.guildids.has(guild.id)){
|
||||
button.textContent = "Already joined";
|
||||
button.textContent = I18n.getTranslation("invite.alreadyJoined");
|
||||
button.disabled = true;
|
||||
}
|
||||
button.classList.add("acceptinvbutton");
|
||||
|
|
|
@ -2,6 +2,7 @@ import{ Contextmenu }from"./contextmenu.js";
|
|||
import{ Guild }from"./guild.js";
|
||||
import{ Localuser }from"./localuser.js";
|
||||
|
||||
//I need to recompile the emoji format for translation
|
||||
class Emoji{
|
||||
static emojis: {
|
||||
name: string;
|
||||
|
@ -158,13 +159,7 @@ class Emoji{
|
|||
const img = document.createElement("img");
|
||||
img.classList.add("pfp", "servericon", "emoji-server");
|
||||
img.crossOrigin = "anonymous";
|
||||
img.src =
|
||||
localuser.info.cdn +
|
||||
"/icons/" +
|
||||
guild.properties.id +
|
||||
"/" +
|
||||
guild.properties.icon +
|
||||
".png?size=48";
|
||||
img.src = localuser.info.cdn+"/icons/"+guild.properties.id+"/"+guild.properties.icon+".png?size=48";
|
||||
img.alt = "Server: " + guild.properties.name;
|
||||
select.appendChild(img);
|
||||
}else{
|
||||
|
|
|
@ -145,9 +145,7 @@ class File{
|
|||
static filesizehuman(fsize: number){
|
||||
const i = fsize == 0 ? 0 : Math.floor(Math.log(fsize) / Math.log(1024));
|
||||
return(
|
||||
Number((fsize / Math.pow(1024, i)).toFixed(2)) * 1 +
|
||||
" " +
|
||||
["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "Terabytes"][i]
|
||||
Number((fsize / Math.pow(1024, i)).toFixed(2)) * 1 + " " + ["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "Terabytes"][i] // I don't think this changes across languages, correct me if I'm wrong
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import{
|
|||
rolesjson,
|
||||
}from"./jsontypes.js";
|
||||
import{ User }from"./user.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
|
||||
class Guild extends SnowFlake{
|
||||
owner!: Localuser;
|
||||
|
@ -38,20 +39,20 @@ class Guild extends SnowFlake{
|
|||
members=new Set<Member>();
|
||||
static contextmenu = new Contextmenu<Guild, undefined>("guild menu");
|
||||
static setupcontextmenu(){
|
||||
Guild.contextmenu.addbutton("Copy Guild id", function(this: Guild){
|
||||
Guild.contextmenu.addbutton(()=>I18n.getTranslation("guild.copyId"), function(this: Guild){
|
||||
navigator.clipboard.writeText(this.id);
|
||||
});
|
||||
|
||||
Guild.contextmenu.addbutton("Mark as read", function(this: Guild){
|
||||
Guild.contextmenu.addbutton(()=>I18n.getTranslation("guild.markRead"), function(this: Guild){
|
||||
this.markAsRead();
|
||||
});
|
||||
|
||||
Guild.contextmenu.addbutton("Notifications", function(this: Guild){
|
||||
Guild.contextmenu.addbutton(()=>I18n.getTranslation("guild.notifications"), function(this: Guild){
|
||||
this.setnotifcation();
|
||||
});
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
"Leave guild",
|
||||
()=>I18n.getTranslation("guild.leave"),
|
||||
function(this: Guild){
|
||||
this.confirmleave();
|
||||
},
|
||||
|
@ -62,7 +63,7 @@ class Guild extends SnowFlake{
|
|||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
"Delete guild",
|
||||
()=>I18n.getTranslation("guild.delete"),
|
||||
function(this: Guild){
|
||||
this.confirmDelete();
|
||||
},
|
||||
|
@ -73,13 +74,13 @@ class Guild extends SnowFlake{
|
|||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
"Create invite",
|
||||
()=>I18n.getTranslation("guild.makeInvite"),
|
||||
function(this: Guild){},
|
||||
null,
|
||||
_=>true,
|
||||
_=>false
|
||||
);
|
||||
Guild.contextmenu.addbutton("Settings", function(this: Guild){
|
||||
Guild.contextmenu.addbutton(()=>I18n.getTranslation("guild.settings"), function(this: Guild){
|
||||
this.generateSettings();
|
||||
});
|
||||
/* -----things left for later-----
|
||||
|
@ -94,28 +95,28 @@ class Guild extends SnowFlake{
|
|||
*/
|
||||
}
|
||||
generateSettings(){
|
||||
const settings = new Settings("Settings for " + this.properties.name);
|
||||
const settings = new Settings(I18n.getTranslation("guild.settingsFor",this.properties.name));
|
||||
{
|
||||
const overview = settings.addButton("Overview");
|
||||
const overview = settings.addButton(I18n.getTranslation("guild.overview"));
|
||||
const form = overview.addForm("", _=>{}, {
|
||||
headers: this.headers,
|
||||
traditionalSubmit: true,
|
||||
fetchURL: this.info.api + "/guilds/" + this.id,
|
||||
method: "PATCH",
|
||||
});
|
||||
form.addTextInput("Name:", "name", { initText: this.properties.name });
|
||||
form.addTextInput(I18n.getTranslation("guild.name:"), "name", { initText: this.properties.name });
|
||||
form.addMDInput("Description:", "description", {
|
||||
initText: this.properties.description,
|
||||
});
|
||||
form.addFileInput("Banner:", "banner", { clear: true });
|
||||
form.addFileInput("Icon:", "icon", { clear: true });
|
||||
form.addFileInput(I18n.getTranslation("guild.banner:"), "banner", { clear: true });
|
||||
form.addFileInput(I18n.getTranslation("guild.icon:"), "icon", { clear: true });
|
||||
let region = this.properties.region;
|
||||
if(!region){
|
||||
region = "";
|
||||
}
|
||||
form.addTextInput("Region:", "region", { initText: region });
|
||||
form.addTextInput(I18n.getTranslation("guild.region:"), "region", { initText: region });
|
||||
}
|
||||
const s1 = settings.addButton("Roles");
|
||||
const s1 = settings.addButton(I18n.getTranslation("guild.roles"));
|
||||
const permlist: [Role, Permissions][] = [];
|
||||
for(const thing of this.roles){
|
||||
permlist.push([thing, thing.permissions]);
|
||||
|
@ -261,14 +262,15 @@ class Guild extends SnowFlake{
|
|||
}
|
||||
setnotifcation(){
|
||||
let noti = this.message_notifications;
|
||||
const options=["all", "onlyMentions", "none"].map(e=>I18n.getTranslation("guild."+e))
|
||||
const notiselect = new Dialog([
|
||||
"vdiv",
|
||||
[
|
||||
"radio",
|
||||
"select notifications type",
|
||||
["all", "only mentions", "none"],
|
||||
function(e: string /* "all" | "only mentions" | "none" */){
|
||||
noti = ["all", "only mentions", "none"].indexOf(e);
|
||||
I18n.getTranslation("guild.selectnoti"),
|
||||
options,
|
||||
function(e: string){
|
||||
noti = options.indexOf(e);
|
||||
},
|
||||
noti,
|
||||
],
|
||||
|
@ -294,13 +296,13 @@ class Guild extends SnowFlake{
|
|||
confirmleave(){
|
||||
const full = new Dialog([
|
||||
"vdiv",
|
||||
["title", "Are you sure you want to leave?"],
|
||||
["title", I18n.getTranslation("guild.confirmLeave")],
|
||||
[
|
||||
"hdiv",
|
||||
[
|
||||
"button",
|
||||
"",
|
||||
"Yes, I'm sure",
|
||||
I18n.getTranslation("yesLeave"),
|
||||
(_: any)=>{
|
||||
this.leave().then(_=>{
|
||||
full.hide();
|
||||
|
@ -310,7 +312,7 @@ class Guild extends SnowFlake{
|
|||
[
|
||||
"button",
|
||||
"",
|
||||
"Nevermind",
|
||||
I18n.getTranslation("noLeave"),
|
||||
(_: any)=>{
|
||||
full.hide();
|
||||
},
|
||||
|
@ -467,11 +469,11 @@ class Guild extends SnowFlake{
|
|||
"vdiv",
|
||||
[
|
||||
"title",
|
||||
"Are you sure you want to delete " + this.properties.name + "?",
|
||||
I18n.getTranslation("guild.confirmDelete",this.properties.name)
|
||||
],
|
||||
[
|
||||
"textbox",
|
||||
"Name of server:",
|
||||
I18n.getTranslation("serverName"),
|
||||
"",
|
||||
function(this: HTMLInputElement){
|
||||
confirmname = this.value;
|
||||
|
@ -482,7 +484,7 @@ class Guild extends SnowFlake{
|
|||
[
|
||||
"button",
|
||||
"",
|
||||
"Yes, I'm sure",
|
||||
I18n.getTranslation("yesDelete"),
|
||||
(_: any)=>{
|
||||
console.log(confirmname);
|
||||
if(confirmname !== this.properties.name){
|
||||
|
@ -496,7 +498,7 @@ class Guild extends SnowFlake{
|
|||
[
|
||||
"button",
|
||||
"",
|
||||
"Nevermind",
|
||||
I18n.getTranslation("noDelete"),
|
||||
(_: any)=>{
|
||||
full.hide();
|
||||
},
|
||||
|
@ -638,22 +640,23 @@ class Guild extends SnowFlake{
|
|||
createchannels(func = this.createChannel){
|
||||
let name = "";
|
||||
let category = 0;
|
||||
const options=["voice", "text", "announcement"].map(e=>I18n.getTranslation("channel."+e));
|
||||
const numbers=[2,0,5]
|
||||
const channelselect = new Dialog([
|
||||
"vdiv",
|
||||
[
|
||||
"radio",
|
||||
"select channel type",
|
||||
["voice", "text", "announcement"],
|
||||
I18n.getTranslation("channel.selectType"),
|
||||
options,
|
||||
function(radio: string){
|
||||
console.log(radio);
|
||||
category =
|
||||
{ text: 0, voice: 2, announcement: 5, category: 4 }[radio] || 0;
|
||||
category = numbers[options.indexOf(radio)] || 0;
|
||||
},
|
||||
1,
|
||||
],
|
||||
[
|
||||
"textbox",
|
||||
"Name of channel",
|
||||
I18n.getTranslation("channel.selectName"),
|
||||
"",
|
||||
function(this: HTMLInputElement){
|
||||
name = this.value;
|
||||
|
@ -662,7 +665,7 @@ class Guild extends SnowFlake{
|
|||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
I18n.getTranslation("submit"),
|
||||
()=>{
|
||||
console.log(name, category);
|
||||
func.bind(this)(name, category);
|
||||
|
@ -679,7 +682,7 @@ class Guild extends SnowFlake{
|
|||
"vdiv",
|
||||
[
|
||||
"textbox",
|
||||
"Name of category",
|
||||
I18n.getTranslation("channel.selectCatName"),
|
||||
"",
|
||||
function(this: HTMLInputElement){
|
||||
name = this.value;
|
||||
|
@ -688,7 +691,7 @@ class Guild extends SnowFlake{
|
|||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
I18n.getTranslation("submit"),
|
||||
function(this:Guild){
|
||||
console.log(name, category);
|
||||
this.createChannel(name, category);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { I18n } from "./i18n.js";
|
||||
import{ mobile }from"./login.js";
|
||||
console.log(mobile);
|
||||
const serverbox = document.getElementById("instancebox") as HTMLDivElement;
|
||||
|
@ -5,7 +6,7 @@ const serverbox = document.getElementById("instancebox") as HTMLDivElement;
|
|||
fetch("/instances.json")
|
||||
.then(_=>_.json())
|
||||
.then(
|
||||
(
|
||||
async (
|
||||
json: {
|
||||
name: string;
|
||||
description?: string;
|
||||
|
@ -24,6 +25,7 @@ fetch("/instances.json")
|
|||
};
|
||||
}[]
|
||||
)=>{
|
||||
await I18n.done;
|
||||
console.warn(json);
|
||||
for(const instance of json){
|
||||
if(instance.display === false){
|
||||
|
@ -66,11 +68,11 @@ fetch("/instances.json")
|
|||
const stats = document.createElement("div");
|
||||
stats.classList.add("flexltr");
|
||||
const span = document.createElement("span");
|
||||
span.innerText = `Uptime: All time: ${Math.round(
|
||||
span.innerText = I18n.getTranslation("home.uptimeStats",Math.round(
|
||||
instance.uptime.alltime * 100
|
||||
)}% This week: ${Math.round(
|
||||
)+"",Math.round(
|
||||
instance.uptime.weektime * 100
|
||||
)}% Today: ${Math.round(instance.uptime.daytime * 100)}%`;
|
||||
)+"",Math.round(instance.uptime.daytime * 100)+"")
|
||||
stats.append(span);
|
||||
statbox.append(stats);
|
||||
}
|
||||
|
@ -79,7 +81,7 @@ fetch("/instances.json")
|
|||
if(instance.online){
|
||||
window.location.href = "/register.html?instance=" + encodeURI(instance.name);
|
||||
}else{
|
||||
alert("Instance is offline, can't connect");
|
||||
alert(I18n.getTranslation("home.warnOffiline"));
|
||||
}
|
||||
};
|
||||
serverbox.append(div);
|
||||
|
|
|
@ -105,4 +105,5 @@ class I18n{
|
|||
}
|
||||
}
|
||||
}
|
||||
I18n.create("/translations/en.json","en")
|
||||
export{I18n};
|
||||
|
|
|
@ -4,6 +4,7 @@ import{ mobile, getBulkUsers, setTheme, Specialuser }from"./login.js";
|
|||
import{ MarkDown }from"./markdown.js";
|
||||
import{ Message }from"./message.js";
|
||||
import{ File }from"./file.js";
|
||||
import { I18n } from "./i18n.js";
|
||||
|
||||
(async ()=>{
|
||||
async function waitForLoad(): Promise<void>{
|
||||
|
@ -13,7 +14,7 @@ import{ File }from"./file.js";
|
|||
}
|
||||
|
||||
await waitForLoad();
|
||||
|
||||
await I18n.done
|
||||
const users = getBulkUsers();
|
||||
if(!users.currentuser){
|
||||
window.location.href = "/login.html";
|
||||
|
@ -74,7 +75,7 @@ import{ File }from"./file.js";
|
|||
|
||||
const switchAccountDiv = document.createElement("div");
|
||||
switchAccountDiv.classList.add("switchtable");
|
||||
switchAccountDiv.textContent = "Switch accounts ⇌";
|
||||
switchAccountDiv.textContent = I18n.getTranslation("switchAccounts");
|
||||
switchAccountDiv.addEventListener("click", ()=>{
|
||||
window.location.href = "/login.html";
|
||||
});
|
||||
|
@ -93,9 +94,7 @@ import{ File }from"./file.js";
|
|||
showAccountSwitcher();
|
||||
});
|
||||
|
||||
const switchAccountsElement = document.getElementById(
|
||||
"switchaccounts"
|
||||
) as HTMLDivElement;
|
||||
const switchAccountsElement = document.getElementById("switchaccounts") as HTMLDivElement;
|
||||
switchAccountsElement.addEventListener("click", event=>{
|
||||
event.stopImmediatePropagation();
|
||||
showAccountSwitcher();
|
||||
|
@ -115,14 +114,13 @@ import{ File }from"./file.js";
|
|||
});
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
(document.getElementById("load-desc") as HTMLSpanElement).textContent =
|
||||
"Account unable to start";
|
||||
(document.getElementById("load-desc") as HTMLSpanElement).textContent = I18n.getTranslation("accountNotStart");
|
||||
thisUser = new Localuser(-1);
|
||||
}
|
||||
|
||||
const menu = new Contextmenu("create rightclick");
|
||||
const menu = new Contextmenu<void,void>("create rightclick");
|
||||
menu.addbutton(
|
||||
"Create channel",
|
||||
I18n.getTranslation("channel.createChannel"),
|
||||
()=>{
|
||||
if(thisUser.lookingguild){
|
||||
thisUser.lookingguild.createchannels();
|
||||
|
@ -133,7 +131,7 @@ import{ File }from"./file.js";
|
|||
);
|
||||
|
||||
menu.addbutton(
|
||||
"Create category",
|
||||
I18n.getTranslation("channel.createCatagory"),
|
||||
()=>{
|
||||
if(thisUser.lookingguild){
|
||||
thisUser.lookingguild.createcategory();
|
||||
|
@ -143,15 +141,9 @@ import{ File }from"./file.js";
|
|||
()=>thisUser.isAdmin()
|
||||
);
|
||||
|
||||
menu.bindContextmenu(
|
||||
document.getElementById("channels") as HTMLDivElement,
|
||||
0,
|
||||
0
|
||||
);
|
||||
menu.bindContextmenu(document.getElementById("channels") as HTMLDivElement);
|
||||
|
||||
const pasteImageElement = document.getElementById(
|
||||
"pasteimage"
|
||||
) as HTMLDivElement;
|
||||
const pasteImageElement = document.getElementById("pasteimage") as HTMLDivElement;
|
||||
let replyingTo: Message | null = null;
|
||||
|
||||
async function handleEnter(event: KeyboardEvent): Promise<void>{
|
||||
|
|
|
@ -65,7 +65,6 @@ class Localuser{
|
|||
"Content-type": "application/json; charset=UTF-8",
|
||||
Authorization: this.userinfo.token,
|
||||
};
|
||||
I18n.create("/translations/en.json","en")
|
||||
}
|
||||
async gottenReady(ready: readyjson): Promise<void>{
|
||||
await I18n.done;
|
||||
|
|
|
@ -56,13 +56,13 @@ class Message extends SnowFlake{
|
|||
Message.setupcmenu();
|
||||
}
|
||||
static setupcmenu(){
|
||||
Message.contextmenu.addbutton(I18n.getTranslation.bind(I18n,"copyrawtext"), function(this: Message){
|
||||
Message.contextmenu.addbutton(()=>I18n.getTranslation("copyrawtext"), function(this: Message){
|
||||
navigator.clipboard.writeText(this.content.rawString);
|
||||
});
|
||||
Message.contextmenu.addbutton(I18n.getTranslation.bind(I18n,"reply"), function(this: Message){
|
||||
Message.contextmenu.addbutton(()=>I18n.getTranslation("reply"), function(this: Message){
|
||||
this.channel.setReplying(this);
|
||||
});
|
||||
Message.contextmenu.addbutton(I18n.getTranslation.bind(I18n,"copymessageid"), function(this: Message){
|
||||
Message.contextmenu.addbutton(()=>I18n.getTranslation("copymessageid"), function(this: Message){
|
||||
navigator.clipboard.writeText(this.id);
|
||||
});
|
||||
Message.contextmenu.addsubmenu(
|
||||
|
|
|
@ -938,15 +938,18 @@ class Form implements OptionsElement<object>{
|
|||
(this.button.deref() as HTMLElement).hidden=false;
|
||||
}
|
||||
}
|
||||
selectMap=new WeakMap<SelectInput,string[]>();
|
||||
addSelect(
|
||||
label: string,
|
||||
formName: string,
|
||||
selections: string[],
|
||||
{ defaultIndex = 0, required = false } = {}
|
||||
{ defaultIndex = 0, required = false}={},
|
||||
correct:string[]=selections
|
||||
){
|
||||
const select = this.options.addSelect(label, _=>{}, selections, {
|
||||
defaultIndex,
|
||||
});
|
||||
this.selectMap.set(select,correct);
|
||||
this.names.set(formName, select);
|
||||
if(required){
|
||||
this.required.add(select);
|
||||
|
@ -1110,7 +1113,7 @@ class Form implements OptionsElement<object>{
|
|||
if(thing === "")continue;
|
||||
const input = this.names.get(thing) as OptionsElement<any>;
|
||||
if(input instanceof SelectInput){
|
||||
(build as any)[thing] = input.options[input.value];
|
||||
(build as any)[thing] = (this.selectMap.get(input) as string[])[input.value];
|
||||
continue;
|
||||
}else if(input instanceof FileInput){
|
||||
const options = this.fileOptions.get(input);
|
||||
|
|
|
@ -122,7 +122,101 @@
|
|||
"no":"No",
|
||||
"todayAt":"Today at $1",
|
||||
"yesterdayAt":"Yesterday at $1",
|
||||
"otherAt":"$1 at $2"
|
||||
"otherAt":"$1 at $2",
|
||||
"botSettings":"Bot Settings",
|
||||
"uploadPfp":"Upload pfp:",
|
||||
"uploadBanner":"Upload banner:",
|
||||
"pronouns":"Pronouns:",
|
||||
"bio":"Bio:",
|
||||
"profileColor":"Profile color",
|
||||
"botGuilds":"Guilds bot is in:",
|
||||
"leaveGuild":"Leave Guild",
|
||||
"confirmGuildLeave":"Are you sure you want to leave $1",
|
||||
"UrlGen":"URL generator",
|
||||
"typing":"$2 {{PLURAL:$1|are|is}} typing",
|
||||
"noMessages":"No messages appear to be here, be the first to say something!",
|
||||
"blankMessage":"Blank Message",
|
||||
"channel":{
|
||||
"copyId":"Copy channel id",
|
||||
"markRead":"Mark as read",
|
||||
"settings":"Settings",
|
||||
"delete":"Delete channel",
|
||||
"makeInvite":"Make invite",
|
||||
"settingsFor":"Settings for $1",
|
||||
"voice":"Voice",
|
||||
"text":"Text",
|
||||
"announcement":"Announcements",
|
||||
"name:":"Name:",
|
||||
"topic:":"Topic:",
|
||||
"nsfw:":"NSFW:",
|
||||
"selectType":"Select channel type",
|
||||
"selectName":"Name of channel",
|
||||
"selectCatName":"Name of channel",
|
||||
"createChannel":"Create channel",
|
||||
"createCatagory":"Create category"
|
||||
},
|
||||
"switchAccounts":"Switch accounts ⇌",
|
||||
"accountNotStart":"Account unable to start",
|
||||
"home":{
|
||||
"uptimeStats":"Uptime: \n All time: $1\nThis week: $2\nToday: $3",
|
||||
"warnOffiline":"Instance is offline, can't connect"
|
||||
},
|
||||
"submit":"submit",
|
||||
"guild":{
|
||||
"copyId":"Copy guild id",
|
||||
"markRead":"Mark as read",
|
||||
"notifications":"Notifications",
|
||||
"leave":"Leave guild",
|
||||
"settings":"Settings",
|
||||
"delete":"Delete guild",
|
||||
"makeInvite":"Make invite",
|
||||
"settingsFor":"Settings for $1",
|
||||
"name:":"Name:",
|
||||
"topic:":"Topic:",
|
||||
"icon:":"Icon:",
|
||||
"overview":"Overview",
|
||||
"banner:":"Banner:",
|
||||
"region:":"Region:",
|
||||
"roles":"Roles",
|
||||
"selectnoti":"Select notifications type",
|
||||
"all":"all",
|
||||
"onlyMentions":"only mentions",
|
||||
"none":"node",
|
||||
"confirmLeave":"Are you sure you want to leave?",
|
||||
"yesLeave":"Yes, I'm sure",
|
||||
"noLeave":"Nevermind",
|
||||
"confirmDelete":"Are you sure you want to delete $1?",
|
||||
"serverName":"Name of server:",
|
||||
"yesDelete":"Yes, I'm sure",
|
||||
"noDelete":"Nevermind"
|
||||
},
|
||||
"inviteOptions":{
|
||||
"title":"Invite People",
|
||||
"30m":"30 Minutes",
|
||||
"1h":"1 Hour",
|
||||
"6h":"6 Hours",
|
||||
"12h":"12 Hours",
|
||||
"1d":"1 Day",
|
||||
"7d":"7 Days",
|
||||
"30d":"30 Days",
|
||||
"never":"Never",
|
||||
"limit":"$1 {{PLURAL:$1|use|uses}}",
|
||||
"noLimit":"No limit"
|
||||
},
|
||||
"invite":{
|
||||
"invitedBy":"You've been invited by $1",
|
||||
"alreadyJoined":"Already joined",
|
||||
"accept":"Accept"
|
||||
},
|
||||
"replyingTo":"Replying to $1",
|
||||
"DMs":{
|
||||
"copyId":"Copy DM id",
|
||||
"markRead":"Mark as read",
|
||||
"close":"Close DM"
|
||||
},
|
||||
"user":{
|
||||
"copyId":"Copy user ID"
|
||||
}
|
||||
},
|
||||
"ru": "./ru.json"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue