get rid of the dialog class/improved notifications
This commit is contained in:
parent
258fba7b8c
commit
d4d5da9da4
15 changed files with 500 additions and 785 deletions
|
@ -2,11 +2,10 @@
|
||||||
import{ Message }from"./message.js";
|
import{ Message }from"./message.js";
|
||||||
import{ AVoice }from"./audio.js";
|
import{ AVoice }from"./audio.js";
|
||||||
import{ Contextmenu }from"./contextmenu.js";
|
import{ Contextmenu }from"./contextmenu.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
import{ Permissions }from"./permissions.js";
|
import{ Permissions }from"./permissions.js";
|
||||||
import{ Settings }from"./settings.js";
|
import{ BDialog, Settings }from"./settings.js";
|
||||||
import{ Role, RoleList }from"./role.js";
|
import{ Role, RoleList }from"./role.js";
|
||||||
import{ InfiniteScroller }from"./infiniteScroller.js";
|
import{ InfiniteScroller }from"./infiniteScroller.js";
|
||||||
import{ SnowFlake }from"./snowflake.js";
|
import{ SnowFlake }from"./snowflake.js";
|
||||||
|
@ -43,7 +42,7 @@ class Channel extends SnowFlake{
|
||||||
lastpin!: string;
|
lastpin!: string;
|
||||||
move_id?: string;
|
move_id?: string;
|
||||||
typing!: number;
|
typing!: number;
|
||||||
message_notifications!: number;
|
message_notifications:number=3;
|
||||||
allthewayup!: boolean;
|
allthewayup!: boolean;
|
||||||
static contextmenu = new Contextmenu<Channel, undefined>("channel menu");
|
static contextmenu = new Contextmenu<Channel, undefined>("channel menu");
|
||||||
replyingto!: Message | null;
|
replyingto!: Message | null;
|
||||||
|
@ -53,6 +52,14 @@ class Channel extends SnowFlake{
|
||||||
messages: Map<string, Message> = new Map();
|
messages: Map<string, Message> = new Map();
|
||||||
voice?:Voice;
|
voice?:Voice;
|
||||||
bitrate:number=128000;
|
bitrate:number=128000;
|
||||||
|
|
||||||
|
muted:boolean=false;
|
||||||
|
mute_config= {selected_time_window: -1,end_time: 0}
|
||||||
|
handleUserOverrides(settings:{message_notifications: number,muted: boolean,mute_config: {selected_time_window: number,end_time: number},channel_id: string}){
|
||||||
|
this.message_notifications=settings.message_notifications;
|
||||||
|
this.muted=settings.muted;
|
||||||
|
this.mute_config=settings.mute_config;
|
||||||
|
}
|
||||||
static setupcontextmenu(){
|
static setupcontextmenu(){
|
||||||
this.contextmenu.addbutton(()=>I18n.getTranslation("channel.copyId"), function(this: Channel){
|
this.contextmenu.addbutton(()=>I18n.getTranslation("channel.copyId"), function(this: Channel){
|
||||||
navigator.clipboard.writeText(this.id);
|
navigator.clipboard.writeText(this.id);
|
||||||
|
@ -76,6 +83,12 @@ class Channel extends SnowFlake{
|
||||||
return this.isAdmin();
|
return this.isAdmin();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
this.contextmenu.addbutton(
|
||||||
|
()=>I18n.getTranslation("guild.notifications"),
|
||||||
|
function(){
|
||||||
|
this.setnotifcation();
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
this.contextmenu.addbutton(
|
this.contextmenu.addbutton(
|
||||||
()=>I18n.getTranslation("channel.makeInvite"),
|
()=>I18n.getTranslation("channel.makeInvite"),
|
||||||
|
@ -129,50 +142,21 @@ class Channel extends SnowFlake{
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
update();
|
update();
|
||||||
new Dialog([
|
const inviteOptions=new BDialog("",{noSubmit:true});
|
||||||
"vdiv",
|
inviteOptions.options.addTitle(I18n.getTranslation("inviteOptions.title"));
|
||||||
["title", I18n.getTranslation("inviteOptions.title")],
|
inviteOptions.options.addText(I18n.getTranslation("invite.subtext",this.name,this.guild.properties.name));
|
||||||
["text", `to #${this.name} in ${this.guild.properties.name}`],
|
|
||||||
[
|
|
||||||
"select",
|
|
||||||
"Expire after:",
|
|
||||||
[
|
|
||||||
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];
|
|
||||||
|
|
||||||
update();
|
inviteOptions.options.addSelect(I18n.getTranslation("invite.expireAfter"),()=>{},
|
||||||
},
|
["30m","1h","6h","12h","1d","7d","30d","never"].map((e)=>I18n.getTranslation("inviteOptions."+e))
|
||||||
0,
|
).onchange=(e)=>{expires=[1800, 3600, 21600, 43200, 86400, 604800, 2592000, 0][e];update()};
|
||||||
],
|
|
||||||
[
|
const timeOptions=["1","5","10","25","50","100"].map((e)=>I18n.getTranslation("inviteOptions.limit",e))
|
||||||
"select",
|
timeOptions.unshift(I18n.getTranslation("inviteOptions.noLimit"))
|
||||||
"Max uses:",
|
inviteOptions.options.addSelect(I18n.getTranslation("invite.expireAfter"),()=>{},timeOptions)
|
||||||
[
|
.onchange=(e)=>{uses=[0, 1, 5, 10, 25, 50, 100][e];update()};
|
||||||
I18n.getTranslation("inviteOptions.noLimit"),
|
|
||||||
I18n.getTranslation("inviteOptions.limit","1"),
|
inviteOptions.options.addHTMLArea(div);
|
||||||
I18n.getTranslation("inviteOptions.limit","5"),
|
inviteOptions.show();
|
||||||
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];
|
|
||||||
update();
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
],
|
|
||||||
["html", div],
|
|
||||||
]).show();
|
|
||||||
}
|
}
|
||||||
generateSettings(){
|
generateSettings(){
|
||||||
this.sortPerms();
|
this.sortPerms();
|
||||||
|
@ -938,6 +922,81 @@ class Channel extends SnowFlake{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastmessage: Message | undefined;
|
lastmessage: Message | undefined;
|
||||||
|
setnotifcation(){
|
||||||
|
const defualt=I18n.getTranslation("guild."+["all", "onlyMentions", "none","default"][this.guild.message_notifications])
|
||||||
|
const options=["all", "onlyMentions", "none","default"].map(e=>I18n.getTranslation("guild."+e,defualt));
|
||||||
|
const notiselect=new BDialog("");
|
||||||
|
const form=notiselect.options.addForm("",(_,sent:any)=>{
|
||||||
|
notiselect.hide();
|
||||||
|
console.log(sent);
|
||||||
|
this.message_notifications = sent.channel_overrides[this.id].message_notifications;
|
||||||
|
},{
|
||||||
|
fetchURL:`${this.info.api}/users/@me/guilds/${this.guild.id}/settings/`,
|
||||||
|
method:"PATCH",
|
||||||
|
headers:this.headers
|
||||||
|
});
|
||||||
|
form.addSelect(I18n.getTranslation("guild.selectnoti"),"message_notifications",options,{
|
||||||
|
radio:true,
|
||||||
|
defaultIndex:this.message_notifications
|
||||||
|
},[0,1,2,3]);
|
||||||
|
|
||||||
|
form.addPreprocessor((e:any)=>{
|
||||||
|
const message_notifications=e.message_notifications;
|
||||||
|
delete e.message_notifications;
|
||||||
|
e.channel_overrides={
|
||||||
|
[this.id]:{
|
||||||
|
message_notifications,
|
||||||
|
muted:this.muted,
|
||||||
|
mute_config:this.mute_config,
|
||||||
|
channel_id:this.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/*
|
||||||
|
let noti = this.message_notifications;
|
||||||
|
const defualt=I18n.getTranslation("guild."+["all", "onlyMentions", "none","default"][this.guild.message_notifications])
|
||||||
|
const options=["all", "onlyMentions", "none","default"].map(e=>I18n.getTranslation("guild."+e,defualt))
|
||||||
|
const notiselect = new Dialog([
|
||||||
|
"vdiv",
|
||||||
|
[
|
||||||
|
"radio",
|
||||||
|
I18n.getTranslation("guild.selectnoti"),
|
||||||
|
options,
|
||||||
|
function(e: string){
|
||||||
|
noti = options.indexOf(e);
|
||||||
|
},
|
||||||
|
noti,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"button",
|
||||||
|
"",
|
||||||
|
"submit",
|
||||||
|
(_: any)=>{
|
||||||
|
//
|
||||||
|
fetch(this.info.api + `/users/@me/guilds/${this.guild.id}/settings/`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: this.headers,
|
||||||
|
body: JSON.stringify({
|
||||||
|
channel_overrides:{
|
||||||
|
[this.id]:{
|
||||||
|
message_notifications: noti,
|
||||||
|
muted:false,
|
||||||
|
mute_config:{
|
||||||
|
selected_time_window:0,
|
||||||
|
end_time:0
|
||||||
|
},
|
||||||
|
channel_id:this.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}).then(()=>notiselect.hide());
|
||||||
|
this.message_notifications = noti;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
notiselect.show();
|
||||||
|
}
|
||||||
async putmessages(){
|
async putmessages(){
|
||||||
//TODO swap out with the WS op code
|
//TODO swap out with the WS op code
|
||||||
if(this.allthewayup){
|
if(this.allthewayup){
|
||||||
|
@ -1229,6 +1288,7 @@ class Channel extends SnowFlake{
|
||||||
notinumber = null;
|
notinumber = null;
|
||||||
}
|
}
|
||||||
notinumber ??= this.guild.message_notifications;
|
notinumber ??= this.guild.message_notifications;
|
||||||
|
console.warn("info:",notinumber);
|
||||||
switch(Number(notinumber)){
|
switch(Number(notinumber)){
|
||||||
case 0:
|
case 0:
|
||||||
return"all";
|
return"all";
|
||||||
|
|
|
@ -1,273 +0,0 @@
|
||||||
type dialogjson =
|
|
||||||
| ["hdiv", ...dialogjson[]]
|
|
||||||
| ["vdiv", ...dialogjson[]]
|
|
||||||
| ["img", string, [number, number] | undefined | ["fit"]]
|
|
||||||
| ["checkbox", string, boolean, (this: HTMLInputElement, e: Event) => unknown]
|
|
||||||
| ["button", string, string, (this: HTMLButtonElement, e: Event) => unknown]
|
|
||||||
| ["mdbox", string, string, (this: HTMLTextAreaElement, e: Event) => unknown]
|
|
||||||
| ["textbox", string, string, (this: HTMLInputElement, e: Event) => unknown]
|
|
||||||
| ["fileupload", string, (this: HTMLInputElement, e: Event) => unknown]
|
|
||||||
| ["text", string]
|
|
||||||
| ["title", string]
|
|
||||||
| ["radio", string, string[], (this: unknown, e: string) => unknown, number]
|
|
||||||
| ["html", HTMLElement]
|
|
||||||
| ["select", string, string[], (this: HTMLSelectElement, e: Event) => unknown, number]
|
|
||||||
| ["tabs", [string, dialogjson][]];
|
|
||||||
class Dialog{
|
|
||||||
layout: dialogjson;
|
|
||||||
onclose: Function;
|
|
||||||
onopen: Function;
|
|
||||||
html: HTMLDivElement;
|
|
||||||
background!: HTMLDivElement;
|
|
||||||
constructor(
|
|
||||||
layout: dialogjson,
|
|
||||||
onclose = (_: any)=>{},
|
|
||||||
onopen = (_: any)=>{}
|
|
||||||
){
|
|
||||||
this.layout = layout;
|
|
||||||
this.onclose = onclose;
|
|
||||||
this.onopen = onopen;
|
|
||||||
const div = document.createElement("div");
|
|
||||||
div.appendChild(this.tohtml(layout));
|
|
||||||
this.html = div;
|
|
||||||
this.html.classList.add("centeritem");
|
|
||||||
if(!(layout[0] === "img")){
|
|
||||||
this.html.classList.add("nonimagecenter");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tohtml(array: dialogjson): HTMLElement{
|
|
||||||
switch(array[0]){
|
|
||||||
case"img":
|
|
||||||
const img = document.createElement("img");
|
|
||||||
img.src = array[1];
|
|
||||||
if(array[2] != undefined){
|
|
||||||
if(array[2].length === 2){
|
|
||||||
img.width = array[2][0];
|
|
||||||
img.height = array[2][1];
|
|
||||||
}else if(array[2][0] === "fit"){
|
|
||||||
img.classList.add("imgfit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return img;
|
|
||||||
case"hdiv":
|
|
||||||
const hdiv = document.createElement("div");
|
|
||||||
hdiv.classList.add("flexltr");
|
|
||||||
|
|
||||||
for(const thing of array){
|
|
||||||
if(thing === "hdiv"){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hdiv.appendChild(this.tohtml(thing));
|
|
||||||
}
|
|
||||||
return hdiv;
|
|
||||||
case"vdiv":
|
|
||||||
const vdiv = document.createElement("div");
|
|
||||||
vdiv.classList.add("flexttb");
|
|
||||||
for(const thing of array){
|
|
||||||
if(thing === "vdiv"){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vdiv.appendChild(this.tohtml(thing));
|
|
||||||
}
|
|
||||||
return vdiv;
|
|
||||||
case"checkbox": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const checkbox = document.createElement("input");
|
|
||||||
div.appendChild(checkbox);
|
|
||||||
const label = document.createElement("span");
|
|
||||||
checkbox.checked = array[2];
|
|
||||||
label.textContent = array[1];
|
|
||||||
div.appendChild(label);
|
|
||||||
checkbox.addEventListener("change", array[3]);
|
|
||||||
checkbox.type = "checkbox";
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"button": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const input = document.createElement("button");
|
|
||||||
|
|
||||||
const label = document.createElement("span");
|
|
||||||
input.textContent = array[2];
|
|
||||||
label.textContent = array[1];
|
|
||||||
div.appendChild(label);
|
|
||||||
div.appendChild(input);
|
|
||||||
input.addEventListener("click", array[3]);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"mdbox": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const input = document.createElement("textarea");
|
|
||||||
input.value = array[2];
|
|
||||||
const label = document.createElement("span");
|
|
||||||
label.textContent = array[1];
|
|
||||||
input.addEventListener("input", array[3]);
|
|
||||||
div.appendChild(label);
|
|
||||||
div.appendChild(document.createElement("br"));
|
|
||||||
div.appendChild(input);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"textbox": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const input = document.createElement("input");
|
|
||||||
input.value = array[2];
|
|
||||||
input.type = "text";
|
|
||||||
const label = document.createElement("span");
|
|
||||||
label.textContent = array[1];
|
|
||||||
console.log(array[3]);
|
|
||||||
input.addEventListener("input", array[3]);
|
|
||||||
div.appendChild(label);
|
|
||||||
div.appendChild(input);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"fileupload": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const input = document.createElement("input");
|
|
||||||
input.type = "file";
|
|
||||||
const label = document.createElement("span");
|
|
||||||
label.textContent = array[1];
|
|
||||||
div.appendChild(label);
|
|
||||||
div.appendChild(input);
|
|
||||||
input.addEventListener("change", array[2]);
|
|
||||||
console.log(array);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"text": {
|
|
||||||
const span = document.createElement("span");
|
|
||||||
span.textContent = array[1];
|
|
||||||
return span;
|
|
||||||
}
|
|
||||||
case"title": {
|
|
||||||
const span = document.createElement("span");
|
|
||||||
span.classList.add("title");
|
|
||||||
span.textContent = array[1];
|
|
||||||
return span;
|
|
||||||
}
|
|
||||||
case"radio": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const fieldset = document.createElement("fieldset");
|
|
||||||
fieldset.addEventListener("change", ()=>{
|
|
||||||
let i = -1;
|
|
||||||
for(const thing of Array.from(fieldset.children)){
|
|
||||||
i++;
|
|
||||||
if(i === 0){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const checkbox = thing.children[0].children[0] as HTMLInputElement;
|
|
||||||
if(checkbox.checked){
|
|
||||||
array[3](checkbox.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const legend = document.createElement("legend");
|
|
||||||
legend.textContent = array[1];
|
|
||||||
fieldset.appendChild(legend);
|
|
||||||
let i = 0;
|
|
||||||
for(const thing of array[2]){
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const input = document.createElement("input");
|
|
||||||
input.classList.add("radio");
|
|
||||||
input.type = "radio";
|
|
||||||
input.name = array[1];
|
|
||||||
input.value = thing;
|
|
||||||
if(i === array[4]){
|
|
||||||
input.checked = true;
|
|
||||||
}
|
|
||||||
const label = document.createElement("label");
|
|
||||||
|
|
||||||
label.appendChild(input);
|
|
||||||
const span = document.createElement("span");
|
|
||||||
span.textContent = thing;
|
|
||||||
label.appendChild(span);
|
|
||||||
div.appendChild(label);
|
|
||||||
fieldset.appendChild(div);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
div.appendChild(fieldset);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"html":
|
|
||||||
return array[1];
|
|
||||||
|
|
||||||
case"select": {
|
|
||||||
const div = document.createElement("div");
|
|
||||||
const label = document.createElement("label");
|
|
||||||
const selectSpan = document.createElement("span");
|
|
||||||
selectSpan.classList.add("selectspan");
|
|
||||||
const select = document.createElement("select");
|
|
||||||
const selectArrow = document.createElement("span");
|
|
||||||
selectArrow.classList.add("svgicon","svg-category","selectarrow");
|
|
||||||
|
|
||||||
label.textContent = array[1];
|
|
||||||
selectSpan.append(select);
|
|
||||||
selectSpan.append(selectArrow);
|
|
||||||
div.append(label);
|
|
||||||
div.appendChild(selectSpan);
|
|
||||||
for(const thing of array[2]){
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.textContent = thing;
|
|
||||||
select.appendChild(option);
|
|
||||||
}
|
|
||||||
select.selectedIndex = array[4];
|
|
||||||
select.addEventListener("change", array[3]);
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
case"tabs": {
|
|
||||||
const table = document.createElement("div");
|
|
||||||
table.classList.add("flexttb");
|
|
||||||
const tabs = document.createElement("div");
|
|
||||||
tabs.classList.add("flexltr");
|
|
||||||
tabs.classList.add("tabbed-head");
|
|
||||||
table.appendChild(tabs);
|
|
||||||
const content = document.createElement("div");
|
|
||||||
content.classList.add("tabbed-content");
|
|
||||||
table.appendChild(content);
|
|
||||||
|
|
||||||
let shown: HTMLElement | undefined;
|
|
||||||
for(const thing of array[1]){
|
|
||||||
const button = document.createElement("button");
|
|
||||||
button.textContent = thing[0];
|
|
||||||
tabs.appendChild(button);
|
|
||||||
|
|
||||||
const html = this.tohtml(thing[1]);
|
|
||||||
content.append(html);
|
|
||||||
if(!shown){
|
|
||||||
shown = html;
|
|
||||||
}else{
|
|
||||||
html.style.display = "none";
|
|
||||||
}
|
|
||||||
button.addEventListener("click", _=>{
|
|
||||||
if(shown){
|
|
||||||
shown.style.display = "none";
|
|
||||||
}
|
|
||||||
html.style.display = "";
|
|
||||||
shown = html;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
console.error(
|
|
||||||
"can't find element:" + array[0],
|
|
||||||
" full element:",
|
|
||||||
array
|
|
||||||
);
|
|
||||||
return document.createElement("span");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
show(){
|
|
||||||
this.onopen();
|
|
||||||
console.log("fullscreen");
|
|
||||||
this.background = document.createElement("div");
|
|
||||||
this.background.classList.add("background");
|
|
||||||
document.body.appendChild(this.background);
|
|
||||||
document.body.appendChild(this.html);
|
|
||||||
this.background.onclick = _=>{
|
|
||||||
this.hide();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
hide(){
|
|
||||||
document.body.removeChild(this.background);
|
|
||||||
document.body.removeChild(this.html);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export{ Dialog };
|
|
37
src/webpage/disimg.ts
Normal file
37
src/webpage/disimg.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
class ImagesDisplay{
|
||||||
|
images:string[];
|
||||||
|
index=0;
|
||||||
|
constructor(srcs:string[],index=0){
|
||||||
|
this.images=srcs;
|
||||||
|
this.index=index;
|
||||||
|
}
|
||||||
|
weakbg=new WeakRef<HTMLElement>(document.createElement("div"));
|
||||||
|
get background():HTMLElement|undefined{
|
||||||
|
return this.weakbg.deref();
|
||||||
|
}
|
||||||
|
set background(e:HTMLElement){
|
||||||
|
this.weakbg=new WeakRef(e);
|
||||||
|
}
|
||||||
|
makeHTML():HTMLElement{
|
||||||
|
//TODO this should be able to display more than one image at a time lol
|
||||||
|
const image= document.createElement("img");
|
||||||
|
image.src=this.images[this.index];
|
||||||
|
image.classList.add("imgfit","centeritem");
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
show(){
|
||||||
|
this.background = document.createElement("div");
|
||||||
|
this.background.classList.add("background");
|
||||||
|
this.background.appendChild(this.makeHTML());
|
||||||
|
this.background.onclick = _=>{
|
||||||
|
this.hide();
|
||||||
|
};
|
||||||
|
document.body.append(this.background);
|
||||||
|
}
|
||||||
|
hide(){
|
||||||
|
if(this.background){
|
||||||
|
this.background.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export{ImagesDisplay}
|
|
@ -1,10 +1,10 @@
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
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"./login.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";
|
||||||
|
|
||||||
class Embed{
|
class Embed{
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -178,7 +178,7 @@ Url.pathname.split("/")[Url.pathname.split("/").length - 1];
|
||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
img.classList.add("messageimg");
|
img.classList.add("messageimg");
|
||||||
img.onclick = function(){
|
img.onclick = function(){
|
||||||
const full = new Dialog(["img", img.src, ["fit"]]);
|
const full = new ImagesDisplay([img.src]);
|
||||||
full.show();
|
full.show();
|
||||||
};
|
};
|
||||||
img.src = this.json.thumbnail.proxy_url;
|
img.src = this.json.thumbnail.proxy_url;
|
||||||
|
@ -214,7 +214,7 @@ Url.pathname.split("/")[Url.pathname.split("/").length - 1];
|
||||||
if(this.json.thumbnail){
|
if(this.json.thumbnail){
|
||||||
img.classList.add("embedimg");
|
img.classList.add("embedimg");
|
||||||
img.onclick = function(){
|
img.onclick = function(){
|
||||||
const full = new Dialog(["img", img.src, ["fit"]]);
|
const full = new ImagesDisplay([img.src]);
|
||||||
full.show();
|
full.show();
|
||||||
};
|
};
|
||||||
img.src = this.json.thumbnail.proxy_url;
|
img.src = this.json.thumbnail.proxy_url;
|
||||||
|
@ -392,7 +392,7 @@ guild as invitejson["guild"] & { info: { cdn: string } }
|
||||||
};
|
};
|
||||||
}else{
|
}else{
|
||||||
img.onclick = async ()=>{
|
img.onclick = async ()=>{
|
||||||
const full = new Dialog(["img", img.src, ["fit"]]);
|
const full = new ImagesDisplay([img.src]);
|
||||||
full.show();
|
full.show();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import{ Message }from"./message.js";
|
import{ Message }from"./message.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import{ filejson }from"./jsontypes.js";
|
import{ filejson }from"./jsontypes.js";
|
||||||
|
import { ImagesDisplay } from "./disimg.js";
|
||||||
|
|
||||||
class File{
|
class File{
|
||||||
owner: Message | null;
|
owner: Message | null;
|
||||||
|
@ -40,7 +40,7 @@ class File{
|
||||||
img.classList.add("messageimg");
|
img.classList.add("messageimg");
|
||||||
div.classList.add("messageimgdiv");
|
div.classList.add("messageimgdiv");
|
||||||
img.onclick = function(){
|
img.onclick = function(){
|
||||||
const full = new Dialog(["img", img.src, ["fit"]]);
|
const full = new ImagesDisplay([img.src]);
|
||||||
full.show();
|
full.show();
|
||||||
};
|
};
|
||||||
img.src = src;
|
img.src = src;
|
||||||
|
|
|
@ -2,9 +2,8 @@ import{ Channel }from"./channel.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
import{ Contextmenu }from"./contextmenu.js";
|
import{ Contextmenu }from"./contextmenu.js";
|
||||||
import{ Role, RoleList }from"./role.js";
|
import{ Role, RoleList }from"./role.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import{ Member }from"./member.js";
|
import{ Member }from"./member.js";
|
||||||
import{ Settings }from"./settings.js";
|
import{ BDialog, Settings }from"./settings.js";
|
||||||
import{ Permissions }from"./permissions.js";
|
import{ Permissions }from"./permissions.js";
|
||||||
import{ SnowFlake }from"./snowflake.js";
|
import{ SnowFlake }from"./snowflake.js";
|
||||||
import{channeljson,guildjson,emojijson,memberjson,invitejson,rolesjson,}from"./jsontypes.js";
|
import{channeljson,guildjson,emojijson,memberjson,invitejson,rolesjson,}from"./jsontypes.js";
|
||||||
|
@ -238,7 +237,7 @@ class Guild extends SnowFlake{
|
||||||
this.localuser.perminfo.guilds[this.id] = e;
|
this.localuser.perminfo.guilds[this.id] = e;
|
||||||
}
|
}
|
||||||
notisetting(settings: {
|
notisetting(settings: {
|
||||||
channel_overrides?: unknown[];
|
channel_overrides: {message_notifications: number,muted: boolean,mute_config: {selected_time_window: number,end_time: number},channel_id: string}[];
|
||||||
message_notifications: any;
|
message_notifications: any;
|
||||||
flags?: number;
|
flags?: number;
|
||||||
hide_muted_channels?: boolean;
|
hide_muted_channels?: boolean;
|
||||||
|
@ -253,66 +252,42 @@ class Guild extends SnowFlake{
|
||||||
guild_id?: string;
|
guild_id?: string;
|
||||||
}){
|
}){
|
||||||
this.message_notifications = settings.message_notifications;
|
this.message_notifications = settings.message_notifications;
|
||||||
|
for(const override of settings.channel_overrides){
|
||||||
|
const channel=this.localuser.channelids.get(override.channel_id);
|
||||||
|
if(!channel) continue;
|
||||||
|
channel.handleUserOverrides(override);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setnotifcation(){
|
setnotifcation(){
|
||||||
let noti = this.message_notifications;
|
|
||||||
const options=["all", "onlyMentions", "none"].map(e=>I18n.getTranslation("guild."+e))
|
const options=["all", "onlyMentions", "none"].map(e=>I18n.getTranslation("guild."+e));
|
||||||
const notiselect = new Dialog([
|
const notiselect=new BDialog("");
|
||||||
"vdiv",
|
const form=notiselect.options.addForm("",(_,sent:any)=>{
|
||||||
[
|
notiselect.hide();
|
||||||
"radio",
|
this.message_notifications = sent.message_notifications;
|
||||||
I18n.getTranslation("guild.selectnoti"),
|
},{
|
||||||
options,
|
fetchURL:`${this.info.api}/users/@me/guilds/${this.id}/settings/`,
|
||||||
function(e: string){
|
|
||||||
noti = options.indexOf(e);
|
|
||||||
},
|
|
||||||
noti,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
"submit",
|
|
||||||
(_: any)=>{
|
|
||||||
//
|
|
||||||
fetch(this.info.api + `/users/@me/guilds/${this.id}/settings/`, {
|
|
||||||
method:"PATCH",
|
method:"PATCH",
|
||||||
headers: this.headers,
|
headers:this.headers
|
||||||
body: JSON.stringify({
|
|
||||||
message_notifications: noti,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
this.message_notifications = noti;
|
form.addSelect(I18n.getTranslation("guild.selectnoti"),"message_notifications",options,{
|
||||||
},
|
radio:true,
|
||||||
],
|
defaultIndex:this.message_notifications
|
||||||
]);
|
},[0,1,2]);
|
||||||
notiselect.show();
|
notiselect.show();
|
||||||
}
|
}
|
||||||
confirmleave(){
|
confirmleave(){
|
||||||
const full = new Dialog([
|
const full = new BDialog("");
|
||||||
"vdiv",
|
full.options.addTitle(I18n.getTranslation("guild.confirmLeave"))
|
||||||
["title", I18n.getTranslation("guild.confirmLeave")],
|
const options=full.options.addOptions("",{ltr:true});
|
||||||
[
|
options.addButtonInput("",I18n.getTranslation("guild.yesLeave"),()=>{
|
||||||
"hdiv",
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("guild.yesLeave"),
|
|
||||||
(_: any)=>{
|
|
||||||
this.leave().then(_=>{
|
this.leave().then(_=>{
|
||||||
full.hide();
|
full.hide();
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
],
|
options.addButtonInput("",I18n.getTranslation("guild.noLeave"),()=>{
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("guild.noLeave"),
|
|
||||||
(_: any)=>{
|
|
||||||
full.hide();
|
full.hide();
|
||||||
},
|
});
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
full.show();
|
full.show();
|
||||||
}
|
}
|
||||||
async leave(){
|
async leave(){
|
||||||
|
@ -458,46 +433,26 @@ class Guild extends SnowFlake{
|
||||||
}
|
}
|
||||||
confirmDelete(){
|
confirmDelete(){
|
||||||
let confirmname = "";
|
let confirmname = "";
|
||||||
const full = new Dialog([
|
|
||||||
"vdiv",
|
const full = new BDialog("");
|
||||||
[
|
full.options.addTitle(I18n.getTranslation("guild.confirmDelete",this.properties.name));
|
||||||
"title",
|
full.options.addTextInput(I18n.getTranslation("guild.serverName"),()=>{}).onchange=(e)=>confirmname=e;
|
||||||
I18n.getTranslation("guild.confirmDelete",this.properties.name)
|
|
||||||
],
|
const options=full.options.addOptions("",{ltr:true});
|
||||||
[
|
options.addButtonInput("",I18n.getTranslation("guild.yesDelete"),()=>{
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("guild.serverName"),
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement){
|
|
||||||
confirmname = this.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"hdiv",
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("guild.yesDelete"),
|
|
||||||
(_: any)=>{
|
|
||||||
console.log(confirmname);
|
|
||||||
if(confirmname !== this.properties.name){
|
if(confirmname !== this.properties.name){
|
||||||
|
//TODO maybe some sort of form error? idk
|
||||||
|
alert("names don't match");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.delete().then(_=>{
|
this.delete().then(_=>{
|
||||||
full.hide();
|
full.hide();
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
],
|
|
||||||
[
|
options.addButtonInput("",I18n.getTranslation("guild.noDelete"),()=>{
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("guild.noDelete"),
|
|
||||||
(_: any)=>{
|
|
||||||
full.hide();
|
full.hide();
|
||||||
},
|
});
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
full.show();
|
full.show();
|
||||||
}
|
}
|
||||||
async delete(){
|
async delete(){
|
||||||
|
@ -677,67 +632,27 @@ class Guild extends SnowFlake{
|
||||||
return thischannel;
|
return thischannel;
|
||||||
}
|
}
|
||||||
createchannels(func = this.createChannel){
|
createchannels(func = this.createChannel){
|
||||||
let name = "";
|
const options=["text", "announcement","voice"].map(e=>I18n.getTranslation("channel."+e));
|
||||||
let category = 0;
|
|
||||||
const options=["voice", "text", "announcement"].map(e=>I18n.getTranslation("channel."+e));
|
const channelselect=new BDialog("");
|
||||||
const numbers=[2,0,5]
|
const form=channelselect.options.addForm("",(e:any)=>{
|
||||||
const channelselect = new Dialog([
|
func(e.name,e.type);
|
||||||
"vdiv",
|
|
||||||
[
|
|
||||||
"radio",
|
|
||||||
I18n.getTranslation("channel.selectType"),
|
|
||||||
options,
|
|
||||||
function(radio: string){
|
|
||||||
console.log(radio);
|
|
||||||
category = numbers[options.indexOf(radio)] || 0;
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("channel.selectName"),
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement){
|
|
||||||
name = this.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
()=>{
|
|
||||||
console.log(name, category);
|
|
||||||
func.bind(this)(name, category);
|
|
||||||
channelselect.hide();
|
channelselect.hide();
|
||||||
},
|
});
|
||||||
],
|
|
||||||
]);
|
form.addSelect(I18n.getTranslation("channel.selectType"),"type",options,{radio:true},[0,5,2]);
|
||||||
|
form.addTextInput(I18n.getTranslation("channel.selectName"),"name");
|
||||||
channelselect.show();
|
channelselect.show();
|
||||||
}
|
}
|
||||||
createcategory(){
|
createcategory(){
|
||||||
let name = "";
|
|
||||||
const category = 4;
|
const category = 4;
|
||||||
const channelselect = new Dialog([
|
const channelselect=new BDialog("");
|
||||||
"vdiv",
|
const options=channelselect.options;
|
||||||
[
|
const form=options.addForm("",(e:any)=>{
|
||||||
"textbox",
|
this.createChannel(e.name, category);
|
||||||
I18n.getTranslation("channel.selectCatName"),
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement){
|
|
||||||
name = this.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
function(this:Guild){
|
|
||||||
console.log(name, category);
|
|
||||||
this.createChannel(name, category);
|
|
||||||
channelselect.hide();
|
channelselect.hide();
|
||||||
}.bind(this),
|
});
|
||||||
],
|
form.addTextInput(I18n.getTranslation("channel.selectCatName"),"name");
|
||||||
]);
|
|
||||||
channelselect.show();
|
channelselect.show();
|
||||||
}
|
}
|
||||||
delChannel(json: channeljson){
|
delChannel(json: channeljson){
|
||||||
|
|
|
@ -63,7 +63,7 @@ type readyjson = {
|
||||||
};
|
};
|
||||||
user_guild_settings: {
|
user_guild_settings: {
|
||||||
entries: {
|
entries: {
|
||||||
channel_overrides: unknown[]; //will have to find example
|
channel_overrides: {message_notifications: number,muted: boolean,mute_config: {selected_time_window: number,end_time: number},channel_id: string}[];
|
||||||
message_notifications: number;
|
message_notifications: number;
|
||||||
flags: number;
|
flags: number;
|
||||||
hide_muted_channels: boolean;
|
hide_muted_channels: boolean;
|
||||||
|
@ -523,6 +523,11 @@ roleCreate | {
|
||||||
nickname: null
|
nickname: null
|
||||||
},
|
},
|
||||||
s: number
|
s: number
|
||||||
|
}|{
|
||||||
|
op: 0,
|
||||||
|
t: "PRESENCE_UPDATE",
|
||||||
|
d: presencejson,
|
||||||
|
s:number
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,10 @@ import{ Channel }from"./channel.js";
|
||||||
import{ Direct }from"./direct.js";
|
import{ Direct }from"./direct.js";
|
||||||
import{ AVoice }from"./audio.js";
|
import{ AVoice }from"./audio.js";
|
||||||
import{ User }from"./user.js";
|
import{ User }from"./user.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import{ getapiurls, getBulkInfo, setTheme, Specialuser, SW }from"./login.js";
|
import{ getapiurls, getBulkInfo, setTheme, Specialuser, SW }from"./login.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{ Form, FormError, Options, Settings }from"./settings.js";
|
import{ BDialog, Form, FormError, Options, Settings }from"./settings.js";
|
||||||
import{ getTextNodeAtPosition, MarkDown }from"./markdown.js";
|
import{ getTextNodeAtPosition, MarkDown }from"./markdown.js";
|
||||||
import { Bot } from "./bot.js";
|
import { Bot } from "./bot.js";
|
||||||
import { Role } from "./role.js";
|
import { Role } from "./role.js";
|
||||||
|
@ -26,8 +25,6 @@ class Localuser{
|
||||||
initialized!: boolean;
|
initialized!: boolean;
|
||||||
info!: Specialuser["serverurls"];
|
info!: Specialuser["serverurls"];
|
||||||
headers!: { "Content-type": string; Authorization: string };
|
headers!: { "Content-type": string; Authorization: string };
|
||||||
userConnections!: Dialog;
|
|
||||||
devPortal!: Dialog;
|
|
||||||
ready!: readyjson;
|
ready!: readyjson;
|
||||||
guilds!: Guild[];
|
guilds!: Guild[];
|
||||||
guildids: Map<string, Guild> = new Map();
|
guildids: Map<string, Guild> = new Map();
|
||||||
|
@ -559,6 +556,12 @@ class Localuser{
|
||||||
this.relationshipsUpdate();
|
this.relationshipsUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "PRESENCE_UPDATE":{
|
||||||
|
if(temp.d.user){
|
||||||
|
this.presences.set(temp.d.user.id, temp.d);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default :{
|
default :{
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
console.warn("Unhandled case "+temp.t,temp);
|
console.warn("Unhandled case "+temp.t,temp);
|
||||||
|
@ -888,86 +891,32 @@ class Localuser{
|
||||||
this.unreads();
|
this.unreads();
|
||||||
}
|
}
|
||||||
createGuild(){
|
createGuild(){
|
||||||
let inviteurl = "";
|
|
||||||
const error = document.createElement("span");
|
const full=new BDialog("");
|
||||||
const fields: { name: string; icon: string | null } = {
|
const buttons=full.options.addButtons("",{top:true});
|
||||||
name: "",
|
const viacode=buttons.add(I18n.getTranslation("invite.joinUsing"));
|
||||||
icon: null,
|
{
|
||||||
};
|
const form=viacode.addForm("",async (e: any)=>{
|
||||||
const full = new Dialog([
|
|
||||||
"tabs",
|
|
||||||
[
|
|
||||||
[
|
|
||||||
I18n.getTranslation("invite.joinUsing"),
|
|
||||||
[
|
|
||||||
"vdiv",
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("invite.inviteLinkCode"),
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement){
|
|
||||||
inviteurl = this.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
["html", error],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
(_: any)=>{
|
|
||||||
let parsed = "";
|
let parsed = "";
|
||||||
if(inviteurl.includes("/")){
|
if(e.code.includes("/")){
|
||||||
parsed =
|
parsed = e.code.split("/")[e.code.split("/").length - 1];
|
||||||
inviteurl.split("/")[inviteurl.split("/").length - 1];
|
|
||||||
}else{
|
}else{
|
||||||
parsed = inviteurl;
|
parsed = e.code;
|
||||||
}
|
}
|
||||||
fetch(this.info.api + "/invites/" + parsed, {
|
const json=await (await fetch(this.info.api + "/invites/" + parsed, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
})
|
})).json()
|
||||||
.then(r=>r.json())
|
if(json.message){
|
||||||
.then(_=>{
|
throw new FormError(text,json.message);
|
||||||
if(_.message){
|
|
||||||
error.textContent = _.message;
|
|
||||||
}
|
}
|
||||||
|
full.hide();
|
||||||
});
|
});
|
||||||
},
|
const text=form.addTextInput(I18n.getTranslation("invite.inviteLinkCode"),"code");
|
||||||
],
|
}
|
||||||
],
|
const guildcreate=buttons.add(I18n.getTranslation("guild.create"));
|
||||||
],
|
{
|
||||||
[
|
const form=guildcreate.addForm("",(fields:any)=>{
|
||||||
I18n.getTranslation("guild.create"),
|
|
||||||
[
|
|
||||||
"vdiv",
|
|
||||||
["title", I18n.getTranslation("guild.create")],
|
|
||||||
[
|
|
||||||
"fileupload",
|
|
||||||
I18n.getTranslation("guild.icon:"),
|
|
||||||
function(event: Event){
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
if(!target.files)return;
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.readAsDataURL(target.files[0]);
|
|
||||||
reader.onload = ()=>{
|
|
||||||
fields.icon = reader.result as string;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("guild.name:"),
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement, event: Event){
|
|
||||||
const target = event.target as HTMLInputElement;
|
|
||||||
fields.name = target.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
()=>{
|
|
||||||
this.makeGuild(fields).then(_=>{
|
this.makeGuild(fields).then(_=>{
|
||||||
if(_.message){
|
if(_.message){
|
||||||
alert(_.errors.name._errors[0].message);
|
alert(_.errors.name._errors[0].message);
|
||||||
|
@ -975,12 +924,11 @@ class Localuser{
|
||||||
full.hide();
|
full.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
],
|
form.addFileInput(I18n.getTranslation("guild.icon:"),"icon",{files:"one"});
|
||||||
],
|
form.addTextInput(I18n.getTranslation("guild.name:"),"name",{required:true});
|
||||||
],
|
|
||||||
],
|
}
|
||||||
]);
|
|
||||||
full.show();
|
full.show();
|
||||||
}
|
}
|
||||||
async makeGuild(fields: { name: string; icon: string | null }){
|
async makeGuild(fields: { name: string; icon: string | null }){
|
||||||
|
@ -996,7 +944,8 @@ class Localuser{
|
||||||
const content = document.createElement("div");
|
const content = document.createElement("div");
|
||||||
content.classList.add("flexttb","guildy");
|
content.classList.add("flexttb","guildy");
|
||||||
content.textContent = I18n.getTranslation("guild.loadingDiscovery");
|
content.textContent = I18n.getTranslation("guild.loadingDiscovery");
|
||||||
const full = new Dialog(["html", content]);
|
const full = new BDialog("");
|
||||||
|
full.options.addHTMLArea(content);
|
||||||
full.show();
|
full.show();
|
||||||
|
|
||||||
const res = await fetch(this.info.api + "/discoverable-guilds?limit=50", {
|
const res = await fetch(this.info.api + "/discoverable-guilds?limit=50", {
|
||||||
|
@ -2147,15 +2096,12 @@ class Localuser{
|
||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
});
|
});
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
|
const dialog = new BDialog("");
|
||||||
const dialog = new Dialog([
|
dialog.options.addTitle(I18n.getTranslation("instanceStats.name",this.instancePing.name));
|
||||||
"vdiv",
|
dialog.options.addText(I18n.getTranslation("instanceStats.users",json.counts.user));
|
||||||
["title", I18n.getTranslation("instanceStats.name",this.instancePing.name) ],
|
dialog.options.addText(I18n.getTranslation("instanceStats.servers",json.counts.guild));
|
||||||
["text", I18n.getTranslation("instanceStats.users",json.counts.user)],
|
dialog.options.addText(I18n.getTranslation("instanceStats.messages",json.counts.message));
|
||||||
["text", I18n.getTranslation("instanceStats.servers",json.counts.guild)],
|
dialog.options.addText(I18n.getTranslation("instanceStats.members",json.counts.members));
|
||||||
["text", I18n.getTranslation("instanceStats.messages",json.counts.message)],
|
|
||||||
["text", I18n.getTranslation("instanceStats.members",json.counts.members)],
|
|
||||||
]);
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
|
import { BDialog, FormError } from "./settings.js";
|
||||||
|
|
||||||
const mobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
const mobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
||||||
const iOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
const iOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
||||||
|
@ -517,38 +517,10 @@ async function login(username: string, password: string, captcha: string){
|
||||||
}else{
|
}else{
|
||||||
console.log(response);
|
console.log(response);
|
||||||
if(response.ticket){
|
if(response.ticket){
|
||||||
let onetimecode = "";
|
const better=new BDialog("");
|
||||||
new Dialog([
|
const form=better.options.addForm("",(res:any)=>{
|
||||||
"vdiv",
|
|
||||||
["title", I18n.getTranslation("2faCode")],
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
function(this: HTMLInputElement){
|
|
||||||
// eslint-disable-next-line no-invalid-this
|
|
||||||
onetimecode = this.value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
function(){
|
|
||||||
fetch(api + "/auth/mfa/totp", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
code: onetimecode,
|
|
||||||
ticket: response.ticket,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.then(r=>r.json())
|
|
||||||
.then(res=>{
|
|
||||||
if(res.message){
|
if(res.message){
|
||||||
alert(res.message);
|
throw new FormError(ti,res.message);
|
||||||
}else{
|
}else{
|
||||||
console.warn(res);
|
console.warn(res);
|
||||||
if(!res.token)return;
|
if(!res.token)return;
|
||||||
|
@ -566,10 +538,16 @@ async function login(username: string, password: string, captcha: string){
|
||||||
window.location.href = "/channels/@me";
|
window.location.href = "/channels/@me";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},{
|
||||||
|
fetchURL:api + "/auth/mfa/totp",
|
||||||
|
method:"POST",
|
||||||
|
headers:{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
form.addTitle(I18n.getTranslation("2faCode"));
|
||||||
],
|
const ti=form.addTextInput("","code");
|
||||||
]).show();
|
better.show()
|
||||||
}else{
|
}else{
|
||||||
console.warn(response);
|
console.warn(response);
|
||||||
if(!response.token)return;
|
if(!response.token)return;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import{ Channel }from"./channel.js";
|
import{ Channel }from"./channel.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import{ Emoji }from"./emoji.js";
|
import{ Emoji }from"./emoji.js";
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
import{ Member }from"./member.js";
|
import{ Member }from"./member.js";
|
||||||
|
import { BDialog } from "./settings.js";
|
||||||
|
|
||||||
class MarkDown{
|
class MarkDown{
|
||||||
txt: string[];
|
txt: string[];
|
||||||
|
@ -781,37 +781,20 @@ txt[j + 1] === undefined)
|
||||||
if(this.trustedDomains.has(Url.host)){
|
if(this.trustedDomains.has(Url.host)){
|
||||||
open();
|
open();
|
||||||
}else{
|
}else{
|
||||||
const full: Dialog = new Dialog([
|
const full=new BDialog("");
|
||||||
"vdiv",
|
full.options.addTitle(I18n.getTranslation("leaving"));
|
||||||
["title", I18n.getTranslation("leaving")],
|
full.options.addText(I18n.getTranslation("goingToURL",Url.host));
|
||||||
[
|
const options=full.options.addOptions("",{ltr:true});
|
||||||
"text",
|
options.addButtonInput("",I18n.getTranslation("nevermind"),()=>full.hide());
|
||||||
I18n.getTranslation("goingToURL",Url.host)
|
options.addButtonInput("",I18n.getTranslation("goThere"),()=>{
|
||||||
],
|
|
||||||
[
|
|
||||||
"hdiv",
|
|
||||||
["button", "", I18n.getTranslation("nevermind"), (_: any)=>full.hide()],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("goThere"),
|
|
||||||
(_: any)=>{
|
|
||||||
open();
|
open();
|
||||||
full.hide();
|
full.hide();
|
||||||
},
|
});
|
||||||
],
|
options.addButtonInput("",I18n.getTranslation("goThereTrust"),()=>{
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("goThereTrust"),
|
|
||||||
(_: any)=>{
|
|
||||||
open();
|
open();
|
||||||
full.hide();
|
full.hide();
|
||||||
this.trustedDomains.add(Url.host);
|
this.trustedDomains.add(Url.host);
|
||||||
},
|
});
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
full.show();
|
full.show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,8 +3,8 @@ import{ Role }from"./role.js";
|
||||||
import{ Guild }from"./guild.js";
|
import{ Guild }from"./guild.js";
|
||||||
import{ SnowFlake }from"./snowflake.js";
|
import{ SnowFlake }from"./snowflake.js";
|
||||||
import{ memberjson, presencejson }from"./jsontypes.js";
|
import{ memberjson, presencejson }from"./jsontypes.js";
|
||||||
import{ Dialog }from"./dialog.js";
|
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
|
import { BDialog } from "./settings.js";
|
||||||
|
|
||||||
class Member extends SnowFlake{
|
class Member extends SnowFlake{
|
||||||
static already = {};
|
static already = {};
|
||||||
|
@ -229,28 +229,13 @@ class Member extends SnowFlake{
|
||||||
return this.nick || this.user.username;
|
return this.nick || this.user.username;
|
||||||
}
|
}
|
||||||
kick(){
|
kick(){
|
||||||
let reason = "";
|
const menu = new BDialog("");
|
||||||
const menu = new Dialog([
|
const form=menu.options.addForm("",((e:any)=>{
|
||||||
"vdiv",
|
this.kickAPI(e.reason);
|
||||||
["title", I18n.getTranslation("member.kick",this.name,this.guild.properties.name)],
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("member.reason:"),
|
|
||||||
"",
|
|
||||||
function(e: Event){
|
|
||||||
reason = (e.target as HTMLInputElement).value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit"),
|
|
||||||
()=>{
|
|
||||||
this.kickAPI(reason);
|
|
||||||
menu.hide();
|
menu.hide();
|
||||||
},
|
}));
|
||||||
],
|
form.addTitle(I18n.getTranslation("member.kick",this.name,this.guild.properties.name));
|
||||||
]);
|
form.addTextInput(I18n.getTranslation("member.reason:"),"reason");
|
||||||
menu.show();
|
menu.show();
|
||||||
}
|
}
|
||||||
kickAPI(reason: string){
|
kickAPI(reason: string){
|
||||||
|
@ -262,28 +247,13 @@ class Member extends SnowFlake{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ban(){
|
ban(){
|
||||||
let reason = "";
|
const menu = new BDialog("");
|
||||||
const menu = new Dialog([
|
const form=menu.options.addForm("",((e:any)=>{
|
||||||
"vdiv",
|
this.banAPI(e.reason);
|
||||||
["title", I18n.getTranslation("member.ban",this.name,this.guild.properties.name)],
|
|
||||||
[
|
|
||||||
"textbox",
|
|
||||||
I18n.getTranslation("member.reason:",this.name,this.guild.properties.name),
|
|
||||||
"",
|
|
||||||
function(e: Event){
|
|
||||||
reason = (e.target as HTMLInputElement).value;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("submit",this.name,this.guild.properties.name),
|
|
||||||
()=>{
|
|
||||||
this.banAPI(reason);
|
|
||||||
menu.hide();
|
menu.hide();
|
||||||
},
|
}));
|
||||||
],
|
form.addTitle(I18n.getTranslation("member.ban",this.name,this.guild.properties.name));
|
||||||
]);
|
form.addTextInput(I18n.getTranslation("member.reason:"),"reason");
|
||||||
menu.show();
|
menu.show();
|
||||||
}
|
}
|
||||||
addRole(role:Role){
|
addRole(role:Role){
|
||||||
|
|
|
@ -10,10 +10,10 @@ 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{ Dialog }from"./dialog.js";
|
|
||||||
import{ mobile }from"./login.js";
|
import{ mobile }from"./login.js";
|
||||||
import { I18n } from "./i18n.js";
|
import { I18n } from "./i18n.js";
|
||||||
import { Hover } from "./hover.js";
|
import { Hover } from "./hover.js";
|
||||||
|
import { BDialog } from "./settings.js";
|
||||||
|
|
||||||
class Message extends SnowFlake{
|
class Message extends SnowFlake{
|
||||||
static contextmenu = new Contextmenu<Message, undefined>("message menu");
|
static contextmenu = new Contextmenu<Message, undefined>("message menu");
|
||||||
|
@ -87,7 +87,7 @@ class Message extends SnowFlake{
|
||||||
Message.contextmenu.addbutton(
|
Message.contextmenu.addbutton(
|
||||||
()=>I18n.getTranslation("message.delete"),
|
()=>I18n.getTranslation("message.delete"),
|
||||||
function(this: Message){
|
function(this: Message){
|
||||||
this.delete();
|
this.confirmDelete();
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
function(){
|
function(){
|
||||||
|
@ -674,31 +674,7 @@ class Message extends SnowFlake{
|
||||||
this.delete();
|
this.delete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const diaolog = new Dialog([
|
this.confirmDelete();
|
||||||
"vdiv",
|
|
||||||
["title", I18n.getTranslation("deleteConfirm")],
|
|
||||||
[
|
|
||||||
"hdiv",
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("yes"),
|
|
||||||
()=>{
|
|
||||||
this.delete();
|
|
||||||
diaolog.hide();
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"button",
|
|
||||||
"",
|
|
||||||
I18n.getTranslation("no"),
|
|
||||||
()=>{
|
|
||||||
diaolog.hide();
|
|
||||||
},
|
|
||||||
],
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
diaolog.show();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(buttons.childNodes.length !== 0){
|
if(buttons.childNodes.length !== 0){
|
||||||
|
@ -714,6 +690,19 @@ class Message extends SnowFlake{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
confirmDelete(){
|
||||||
|
const diaolog=new BDialog("");
|
||||||
|
diaolog.options.addTitle(I18n.getTranslation("deleteConfirm"));
|
||||||
|
const options=diaolog.options.addOptions("",{ltr:true});
|
||||||
|
options.addButtonInput("",I18n.getTranslation("yes"),()=>{
|
||||||
|
this.delete();
|
||||||
|
diaolog.hide();
|
||||||
|
});
|
||||||
|
options.addButtonInput("",I18n.getTranslation("no"),()=>{
|
||||||
|
diaolog.hide();
|
||||||
|
})
|
||||||
|
diaolog.show();
|
||||||
|
}
|
||||||
updateReactions(){
|
updateReactions(){
|
||||||
const reactdiv = this.reactdiv.deref();
|
const reactdiv = this.reactdiv.deref();
|
||||||
if(!reactdiv)return;
|
if(!reactdiv)return;
|
||||||
|
|
|
@ -14,7 +14,9 @@ class Buttons implements OptionsElement<unknown>{
|
||||||
buttonList!: HTMLDivElement;
|
buttonList!: HTMLDivElement;
|
||||||
warndiv!: HTMLElement;
|
warndiv!: HTMLElement;
|
||||||
value: unknown;
|
value: unknown;
|
||||||
constructor(name: string){
|
top=false;
|
||||||
|
constructor(name: string,{top=false}={}){
|
||||||
|
this.top=top;
|
||||||
this.buttons = [];
|
this.buttons = [];
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +30,7 @@ class Buttons implements OptionsElement<unknown>{
|
||||||
generateHTML(){
|
generateHTML(){
|
||||||
const buttonList = document.createElement("div");
|
const buttonList = document.createElement("div");
|
||||||
buttonList.classList.add("Buttons");
|
buttonList.classList.add("Buttons");
|
||||||
buttonList.classList.add("flexltr");
|
buttonList.classList.add(this.top?"flexttb":"flexltr");
|
||||||
this.buttonList = buttonList;
|
this.buttonList = buttonList;
|
||||||
const htmlarea = document.createElement("div");
|
const htmlarea = document.createElement("div");
|
||||||
htmlarea.classList.add("flexgrow");
|
htmlarea.classList.add("flexgrow");
|
||||||
|
@ -43,6 +45,9 @@ class Buttons implements OptionsElement<unknown>{
|
||||||
generateButtons(optionsArea:HTMLElement){
|
generateButtons(optionsArea:HTMLElement){
|
||||||
const buttonTable = document.createElement("div");
|
const buttonTable = document.createElement("div");
|
||||||
buttonTable.classList.add("settingbuttons");
|
buttonTable.classList.add("settingbuttons");
|
||||||
|
if(this.top){
|
||||||
|
buttonTable.classList.add("flexltr");
|
||||||
|
}
|
||||||
for(const thing of this.buttons){
|
for(const thing of this.buttons){
|
||||||
const button = document.createElement("button");
|
const button = document.createElement("button");
|
||||||
button.classList.add("SettingsButton");
|
button.classList.add("SettingsButton");
|
||||||
|
@ -328,6 +333,7 @@ class SelectInput implements OptionsElement<number>{
|
||||||
options: string[];
|
options: string[];
|
||||||
index: number;
|
index: number;
|
||||||
select!: WeakRef<HTMLSelectElement>;
|
select!: WeakRef<HTMLSelectElement>;
|
||||||
|
radio:boolean;
|
||||||
get value(){
|
get value(){
|
||||||
return this.index;
|
return this.index;
|
||||||
}
|
}
|
||||||
|
@ -336,15 +342,61 @@ class SelectInput implements OptionsElement<number>{
|
||||||
onSubmit: (str: number) => void,
|
onSubmit: (str: number) => void,
|
||||||
options: string[],
|
options: string[],
|
||||||
owner: Options,
|
owner: Options,
|
||||||
{ defaultIndex = 0 } = {}
|
{ defaultIndex = 0,radio=false } = {}
|
||||||
){
|
){
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.index = defaultIndex;
|
this.index = defaultIndex;
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.onSubmit = onSubmit;
|
this.onSubmit = onSubmit;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.radio=radio;
|
||||||
}
|
}
|
||||||
generateHTML(): HTMLDivElement{
|
generateHTML(): HTMLDivElement{
|
||||||
|
if(this.radio){
|
||||||
|
const map=new WeakMap<HTMLInputElement,number>();
|
||||||
|
const div = document.createElement("div");
|
||||||
|
const fieldset = document.createElement("fieldset");
|
||||||
|
fieldset.addEventListener("change", ()=>{
|
||||||
|
let i = -1;
|
||||||
|
for(const thing of Array.from(fieldset.children)){
|
||||||
|
i++;
|
||||||
|
if(i === 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const checkbox = thing.children[0].children[0] as HTMLInputElement;
|
||||||
|
if(checkbox.checked){
|
||||||
|
this.onChange(map.get(checkbox));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const legend = document.createElement("legend");
|
||||||
|
legend.textContent = this.label;
|
||||||
|
fieldset.appendChild(legend);
|
||||||
|
let i = 0;
|
||||||
|
for(const thing of this.options){
|
||||||
|
const div = document.createElement("div");
|
||||||
|
const input = document.createElement("input");
|
||||||
|
input.classList.add("radio");
|
||||||
|
input.type = "radio";
|
||||||
|
input.name = this.label;
|
||||||
|
input.value = thing;
|
||||||
|
map.set(input,i);
|
||||||
|
if(i === this.index){
|
||||||
|
input.checked = true;
|
||||||
|
}
|
||||||
|
const label = document.createElement("label");
|
||||||
|
|
||||||
|
label.appendChild(input);
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.textContent = thing;
|
||||||
|
label.appendChild(span);
|
||||||
|
div.appendChild(label);
|
||||||
|
fieldset.appendChild(div);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
div.appendChild(fieldset);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
span.textContent = this.label;
|
span.textContent = this.label;
|
||||||
|
@ -353,7 +405,7 @@ class SelectInput implements OptionsElement<number>{
|
||||||
selectSpan.classList.add("selectspan");
|
selectSpan.classList.add("selectspan");
|
||||||
const select = document.createElement("select");
|
const select = document.createElement("select");
|
||||||
|
|
||||||
select.onchange = this.onChange.bind(this);
|
select.onchange = this.onChange.bind(this,-1);
|
||||||
for(const thing of this.options){
|
for(const thing of this.options){
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.textContent = thing;
|
option.textContent = thing;
|
||||||
|
@ -368,8 +420,13 @@ class SelectInput implements OptionsElement<number>{
|
||||||
div.append(selectSpan);
|
div.append(selectSpan);
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
private onChange(){
|
private onChange(index=-1){
|
||||||
this.owner.changed();
|
this.owner.changed();
|
||||||
|
if(index!==-1){
|
||||||
|
this.onchange(index);
|
||||||
|
this.index = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const select = this.select.deref();
|
const select = this.select.deref();
|
||||||
if(select){
|
if(select){
|
||||||
const value = select.selectedIndex;
|
const value = select.selectedIndex;
|
||||||
|
@ -524,7 +581,7 @@ class Float{
|
||||||
/**
|
/**
|
||||||
* This is a simple wrapper class for Options to make it happy so it can be used outside of Settings.
|
* This is a simple wrapper class for Options to make it happy so it can be used outside of Settings.
|
||||||
*/
|
*/
|
||||||
constructor(name:string, options={ ltr:false, noSubmit:false}){
|
constructor(name:string, options={ ltr:false, noSubmit:true}){
|
||||||
this.options=new Options(name,this,options)
|
this.options=new Options(name,this,options)
|
||||||
}
|
}
|
||||||
changed=()=>{};
|
changed=()=>{};
|
||||||
|
@ -532,6 +589,38 @@ class Float{
|
||||||
return this.options.generateHTML();
|
return this.options.generateHTML();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class BDialog{
|
||||||
|
float:Float;
|
||||||
|
get options(){
|
||||||
|
return this.float.options;
|
||||||
|
}
|
||||||
|
background=new WeakRef(document.createElement("div"));
|
||||||
|
constructor(name:string, { ltr=false, noSubmit=true}={}){
|
||||||
|
this.float=new Float(name,{ltr,noSubmit});
|
||||||
|
}
|
||||||
|
show(){
|
||||||
|
const background = document.createElement("div");
|
||||||
|
background.classList.add("background");
|
||||||
|
const center=this.float.generateHTML();
|
||||||
|
center.classList.add("centeritem","nonimagecenter");
|
||||||
|
center.classList.remove("titlediv");
|
||||||
|
background.append(center);
|
||||||
|
center.onclick=e=>{
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
}
|
||||||
|
document.body.append(background);
|
||||||
|
this.background=new WeakRef(background);
|
||||||
|
background.onclick = _=>{
|
||||||
|
background.remove();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
hide(){
|
||||||
|
const background=this.background.deref();
|
||||||
|
if(!background) return;
|
||||||
|
background.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export{BDialog};
|
||||||
class Options implements OptionsElement<void>{
|
class Options implements OptionsElement<void>{
|
||||||
name: string;
|
name: string;
|
||||||
haschanged = false;
|
haschanged = false;
|
||||||
|
@ -571,6 +660,12 @@ class Options implements OptionsElement<void>{
|
||||||
this.generate(options);
|
this.generate(options);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
addButtons(name: string, { top = false } = {}){
|
||||||
|
const buttons = new Buttons(name, { top });
|
||||||
|
this.options.push(buttons);
|
||||||
|
this.generate(buttons);
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
subOptions: Options | Form | undefined;
|
subOptions: Options | Form | undefined;
|
||||||
genTop(){
|
genTop(){
|
||||||
const container = this.container.deref();
|
const container = this.container.deref();
|
||||||
|
@ -596,7 +691,7 @@ class Options implements OptionsElement<void>{
|
||||||
}
|
}
|
||||||
addSubForm(
|
addSubForm(
|
||||||
name: string,
|
name: string,
|
||||||
onSubmit: (arg1: object) => void,
|
onSubmit: (arg1: object,sent:object) => void,
|
||||||
{
|
{
|
||||||
ltr = false,
|
ltr = false,
|
||||||
submitText = "Submit",
|
submitText = "Submit",
|
||||||
|
@ -626,10 +721,10 @@ class Options implements OptionsElement<void>{
|
||||||
label: string,
|
label: string,
|
||||||
onSubmit: (str: number) => void,
|
onSubmit: (str: number) => void,
|
||||||
selections: string[],
|
selections: string[],
|
||||||
{ defaultIndex = 0 } = {}
|
{ defaultIndex = 0,radio=false } = {}
|
||||||
){
|
){
|
||||||
const select = new SelectInput(label, onSubmit, selections, this, {
|
const select = new SelectInput(label, onSubmit, selections, this, {
|
||||||
defaultIndex,
|
defaultIndex,radio
|
||||||
});
|
});
|
||||||
this.options.push(select);
|
this.options.push(select);
|
||||||
this.generate(select);
|
this.generate(select);
|
||||||
|
@ -717,7 +812,7 @@ class Options implements OptionsElement<void>{
|
||||||
}
|
}
|
||||||
addForm(
|
addForm(
|
||||||
name: string,
|
name: string,
|
||||||
onSubmit: (arg1: object) => void,
|
onSubmit: (arg1: object,sent:object) => void,
|
||||||
{
|
{
|
||||||
ltr = false,
|
ltr = false,
|
||||||
submitText = "Submit",
|
submitText = "Submit",
|
||||||
|
@ -901,7 +996,7 @@ class Form implements OptionsElement<object>{
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
owner: Options,
|
owner: Options,
|
||||||
onSubmit: (arg1: object) => void,
|
onSubmit: (arg1: object,sent:object) => void,
|
||||||
{
|
{
|
||||||
ltr = false,
|
ltr = false,
|
||||||
submitText = I18n.getTranslation("submit"),
|
submitText = I18n.getTranslation("submit"),
|
||||||
|
@ -934,7 +1029,7 @@ class Form implements OptionsElement<object>{
|
||||||
}
|
}
|
||||||
addSubForm(
|
addSubForm(
|
||||||
name: string,
|
name: string,
|
||||||
onSubmit: (arg1: object) => void,
|
onSubmit: (arg1: object,sent:object) => void,
|
||||||
{
|
{
|
||||||
ltr = false,
|
ltr = false,
|
||||||
submitText = I18n.getTranslation("submit"),
|
submitText = I18n.getTranslation("submit"),
|
||||||
|
@ -956,16 +1051,16 @@ class Form implements OptionsElement<object>{
|
||||||
(this.button.deref() as HTMLElement).hidden=false;
|
(this.button.deref() as HTMLElement).hidden=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectMap=new WeakMap<SelectInput,string[]>();
|
selectMap=new WeakMap<SelectInput,(number|string)[]>();
|
||||||
addSelect(
|
addSelect(
|
||||||
label: string,
|
label: string,
|
||||||
formName: string,
|
formName: string,
|
||||||
selections: string[],
|
selections: string[],
|
||||||
{ defaultIndex = 0, required = false}={},
|
{ defaultIndex = 0, required = false,radio=false}={},
|
||||||
correct:string[]=selections
|
correct:(string|number)[]=selections
|
||||||
){
|
){
|
||||||
const select = this.options.addSelect(label, _=>{}, selections, {
|
const select = this.options.addSelect(label, _=>{}, selections, {
|
||||||
defaultIndex,
|
defaultIndex,radio
|
||||||
});
|
});
|
||||||
this.selectMap.set(select,correct);
|
this.selectMap.set(select,correct);
|
||||||
this.names.set(formName, select);
|
this.names.set(formName, select);
|
||||||
|
@ -1084,7 +1179,7 @@ class Form implements OptionsElement<object>{
|
||||||
}
|
}
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
onSubmit: (arg1: object) => void;
|
onSubmit: ((arg1: object,sent:object) => void )|((arg1: object,sent:object) => Promise<void> );
|
||||||
watchForChange(func: (arg1: object) => void){
|
watchForChange(func: (arg1: object) => void){
|
||||||
this.onSubmit = func;
|
this.onSubmit = func;
|
||||||
}
|
}
|
||||||
|
@ -1187,14 +1282,14 @@ class Form implements OptionsElement<object>{
|
||||||
if(_==="") return {};
|
if(_==="") return {};
|
||||||
return JSON.parse(_)
|
return JSON.parse(_)
|
||||||
})
|
})
|
||||||
.then(json=>{
|
.then(async json=>{
|
||||||
if(json.errors){
|
if(json.errors){
|
||||||
if(this.errors(json)){
|
if(this.errors(json)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
this.onSubmit(json);
|
await this.onSubmit(json,build);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e);
|
console.error(e);
|
||||||
if(e instanceof FormError){
|
if(e instanceof FormError){
|
||||||
|
@ -1211,7 +1306,7 @@ class Form implements OptionsElement<object>{
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
this.onSubmit(build);
|
await this.onSubmit(build,build);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
if(e instanceof FormError){
|
if(e instanceof FormError){
|
||||||
const elm = this.options.html.get(e.elem);
|
const elm = this.options.html.get(e.elem);
|
||||||
|
|
|
@ -1614,12 +1614,12 @@ img.bigembedimg {
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.nonimagecenter .flexttb, .nonimagecenter .flexltr {
|
.nonimagecenter & .flexttb, .nonimagecenter & .flexltr {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
.nonimagecenter > .flexttb, .nonimagecenter > .flexltr {
|
.nonimagecenter > .flexttb, .nonimagecenter > .flexltr {
|
||||||
padding: 16px;
|
padding: 16px !important;
|
||||||
background: var(--primary-bg);
|
background: var(--primary-bg);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
@ -1758,6 +1758,12 @@ fieldset input[type="radio"] {
|
||||||
.Buttons {
|
.Buttons {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
.settingbuttons.flexltr{
|
||||||
|
width: 100%;
|
||||||
|
.SettingsButton{
|
||||||
|
width:auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
.settingbuttons {
|
.settingbuttons {
|
||||||
flex: none;
|
flex: none;
|
||||||
width: 192px;
|
width: 192px;
|
||||||
|
@ -1800,7 +1806,8 @@ fieldset input[type="radio"] {
|
||||||
}
|
}
|
||||||
.optionElement, .FormSettings > button {
|
.optionElement, .FormSettings > button {
|
||||||
margin: 16px 16px 0 16px;
|
margin: 16px 16px 0 16px;
|
||||||
word-break: break-word;
|
/* word-break: break-word; */
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.optionElement:has(.optionElement) {
|
.optionElement:has(.optionElement) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -1915,7 +1922,7 @@ fieldset input[type="radio"] {
|
||||||
height: calc(100svh - 50px);
|
height: calc(100svh - 50px);
|
||||||
}
|
}
|
||||||
.flexspace {
|
.flexspace {
|
||||||
flex-direction: column;
|
/*flex-direction: column;*/
|
||||||
}
|
}
|
||||||
.optionElement input[type="text"],
|
.optionElement input[type="text"],
|
||||||
.optionElement textarea,
|
.optionElement textarea,
|
||||||
|
|
|
@ -152,7 +152,7 @@
|
||||||
"nsfw:":"NSFW:",
|
"nsfw:":"NSFW:",
|
||||||
"selectType":"Select channel type",
|
"selectType":"Select channel type",
|
||||||
"selectName":"Name of channel",
|
"selectName":"Name of channel",
|
||||||
"selectCatName":"Name of channel",
|
"selectCatName":"Name of category",
|
||||||
"createChannel":"Create channel",
|
"createChannel":"Create channel",
|
||||||
"createCatagory":"Create category"
|
"createCatagory":"Create category"
|
||||||
},
|
},
|
||||||
|
@ -219,7 +219,7 @@
|
||||||
"selectnoti":"Select notifications type",
|
"selectnoti":"Select notifications type",
|
||||||
"all":"all",
|
"all":"all",
|
||||||
"onlyMentions":"only mentions",
|
"onlyMentions":"only mentions",
|
||||||
"none":"node",
|
"none":"none",
|
||||||
"confirmLeave":"Are you sure you want to leave?",
|
"confirmLeave":"Are you sure you want to leave?",
|
||||||
"yesLeave":"Yes, I'm sure",
|
"yesLeave":"Yes, I'm sure",
|
||||||
"noLeave":"Nevermind",
|
"noLeave":"Nevermind",
|
||||||
|
@ -231,7 +231,8 @@
|
||||||
"loadingDiscovery":"Loading...",
|
"loadingDiscovery":"Loading...",
|
||||||
"disoveryTitle":"Guild discovery ($1) {{PLURAL:$1|entry|entries}}",
|
"disoveryTitle":"Guild discovery ($1) {{PLURAL:$1|entry|entries}}",
|
||||||
"emptytitle":"Weird spot",
|
"emptytitle":"Weird spot",
|
||||||
"emptytext":"You're in a weird spot, this guild has no channels"
|
"emptytext":"You're in a weird spot, this guild has no channels",
|
||||||
|
"default":"Default ($1)"
|
||||||
},
|
},
|
||||||
"role":{
|
"role":{
|
||||||
"displaySettings":"Display settings",
|
"displaySettings":"Display settings",
|
||||||
|
@ -345,7 +346,9 @@
|
||||||
"longInvitedBy":"$1 invited you to join $2",
|
"longInvitedBy":"$1 invited you to join $2",
|
||||||
"loginOrCreateAccount":"Login or create an account ⇌",
|
"loginOrCreateAccount":"Login or create an account ⇌",
|
||||||
"joinUsing":"Join using invite",
|
"joinUsing":"Join using invite",
|
||||||
"inviteLinkCode":"Invite Link/Code"
|
"inviteLinkCode":"Invite Link/Code",
|
||||||
|
"subtext":"to $1 in $2",
|
||||||
|
"expireAfter":"Expire after:"
|
||||||
},
|
},
|
||||||
"friends":{
|
"friends":{
|
||||||
"blocked":"Blocked",
|
"blocked":"Blocked",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue