mirror of
https://github.com/MathMan05/Fermi.git
synced 2026-09-27 04:58:36 +00:00
role icon setting and image upload improvements
This commit is contained in:
+86
-80
@@ -18,7 +18,7 @@ class Emoji {
|
||||
id?: string;
|
||||
emoji?: string;
|
||||
animated: boolean;
|
||||
owner: Guild | Localuser;
|
||||
owner?: Guild | Localuser;
|
||||
get guild() {
|
||||
if (this.owner instanceof Guild) {
|
||||
return this.owner;
|
||||
@@ -32,10 +32,7 @@ class Emoji {
|
||||
return this.owner;
|
||||
}
|
||||
}
|
||||
get info() {
|
||||
return this.owner.info;
|
||||
}
|
||||
constructor(json: emojijson, owner: Guild | Localuser) {
|
||||
constructor(json: emojijson, owner?: Guild | Localuser) {
|
||||
this.name = json.name;
|
||||
this.id = json.id;
|
||||
this.animated = json.animated || false;
|
||||
@@ -53,12 +50,18 @@ class Emoji {
|
||||
}
|
||||
getHTML(bigemoji: boolean = false) {
|
||||
if (this.id) {
|
||||
if (!this.owner) throw new Error("owner is missing for custom emoji!");
|
||||
const emojiElem = document.createElement("img");
|
||||
emojiElem.classList.add("md-emoji");
|
||||
emojiElem.classList.add(bigemoji ? "bigemoji" : "smallemoji");
|
||||
emojiElem.crossOrigin = "anonymous";
|
||||
emojiElem.src =
|
||||
this.info.cdn + "/emojis/" + this.id + "." + (this.animated ? "gif" : "png") + "?size=32";
|
||||
this.owner.info.cdn +
|
||||
"/emojis/" +
|
||||
this.id +
|
||||
"." +
|
||||
(this.animated ? "gif" : "png") +
|
||||
"?size=32";
|
||||
emojiElem.alt = this.name;
|
||||
emojiElem.loading = "lazy";
|
||||
|
||||
@@ -147,7 +150,7 @@ class Emoji {
|
||||
this: typeof Emoji,
|
||||
x: number,
|
||||
y: number,
|
||||
localuser: Localuser,
|
||||
localuser?: Localuser,
|
||||
): Promise<Emoji> {
|
||||
let res: (r: Emoji) => void;
|
||||
this;
|
||||
@@ -231,76 +234,77 @@ class Emoji {
|
||||
body.classList.add("emojiBody");
|
||||
|
||||
let isFirst = true;
|
||||
if (localuser) {
|
||||
[
|
||||
localuser.lookingguild,
|
||||
...localuser.guilds.filter((guild) => guild !== localuser.lookingguild),
|
||||
]
|
||||
.filter((_) => _ !== undefined)
|
||||
.filter((guild) => guild.id != "@me" && guild.emojis.length > 0)
|
||||
.forEach((guild) => {
|
||||
const select = document.createElement("div");
|
||||
select.classList.add("emojiSelect");
|
||||
|
||||
[
|
||||
localuser.lookingguild,
|
||||
...localuser.guilds.filter((guild) => guild !== localuser.lookingguild),
|
||||
]
|
||||
.filter((_) => _ !== undefined)
|
||||
.filter((guild) => guild.id != "@me" && guild.emojis.length > 0)
|
||||
.forEach((guild) => {
|
||||
const select = document.createElement("div");
|
||||
select.classList.add("emojiSelect");
|
||||
|
||||
if (guild.properties.icon) {
|
||||
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.alt = "Server: " + guild.properties.name;
|
||||
select.appendChild(img);
|
||||
} else {
|
||||
const div = document.createElement("span");
|
||||
div.textContent = guild.properties.name
|
||||
.replace(/'s /g, " ")
|
||||
.replace(/\w+/g, (word) => word[0])
|
||||
.replace(/\s/g, "");
|
||||
select.append(div);
|
||||
}
|
||||
|
||||
selection.append(select);
|
||||
|
||||
const clickEvent = () => {
|
||||
search.value = "";
|
||||
updateSearch.call(this);
|
||||
title.textContent = guild.properties.name;
|
||||
body.innerHTML = "";
|
||||
for (const emojit of guild.emojis) {
|
||||
const emojiElem = document.createElement("div");
|
||||
emojiElem.classList.add("emojiSelect");
|
||||
|
||||
const emojiClass = new Emoji(
|
||||
{
|
||||
id: emojit.id as string,
|
||||
name: emojit.name,
|
||||
animated: emojit.animated as boolean,
|
||||
},
|
||||
localuser,
|
||||
);
|
||||
emojiElem.append(emojiClass.getHTML());
|
||||
body.append(emojiElem);
|
||||
|
||||
emojiElem.addEventListener("click", () => {
|
||||
res(emojiClass);
|
||||
if (Contextmenu.currentmenu !== "") {
|
||||
Contextmenu.currentmenu.remove();
|
||||
}
|
||||
});
|
||||
if (guild.properties.icon) {
|
||||
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.alt = "Server: " + guild.properties.name;
|
||||
select.appendChild(img);
|
||||
} else {
|
||||
const div = document.createElement("span");
|
||||
div.textContent = guild.properties.name
|
||||
.replace(/'s /g, " ")
|
||||
.replace(/\w+/g, (word) => word[0])
|
||||
.replace(/\s/g, "");
|
||||
select.append(div);
|
||||
}
|
||||
};
|
||||
|
||||
select.addEventListener("click", clickEvent);
|
||||
if (isFirst) {
|
||||
clickEvent();
|
||||
isFirst = false;
|
||||
}
|
||||
});
|
||||
selection.append(select);
|
||||
|
||||
const clickEvent = () => {
|
||||
search.value = "";
|
||||
updateSearch.call(this);
|
||||
title.textContent = guild.properties.name;
|
||||
body.innerHTML = "";
|
||||
for (const emojit of guild.emojis) {
|
||||
const emojiElem = document.createElement("div");
|
||||
emojiElem.classList.add("emojiSelect");
|
||||
|
||||
const emojiClass = new Emoji(
|
||||
{
|
||||
id: emojit.id as string,
|
||||
name: emojit.name,
|
||||
animated: emojit.animated as boolean,
|
||||
},
|
||||
localuser,
|
||||
);
|
||||
emojiElem.append(emojiClass.getHTML());
|
||||
body.append(emojiElem);
|
||||
|
||||
emojiElem.addEventListener("click", () => {
|
||||
res(emojiClass);
|
||||
if (Contextmenu.currentmenu !== "") {
|
||||
Contextmenu.currentmenu.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
select.addEventListener("click", clickEvent);
|
||||
if (isFirst) {
|
||||
clickEvent();
|
||||
isFirst = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (Contextmenu.currentmenu !== "") {
|
||||
Contextmenu.currentmenu.remove();
|
||||
@@ -344,7 +348,7 @@ class Emoji {
|
||||
search.focus();
|
||||
return promise;
|
||||
}
|
||||
static searchEmoji(search: string, localuser: Localuser, results = 50): [Emoji, number][] {
|
||||
static searchEmoji(search: string, localuser?: Localuser, results = 50): [Emoji, number][] {
|
||||
//NOTE this function is used for searching in the emoji picker for reactions, and the emoji auto-fill
|
||||
const ranked: [emojijson, number][] = [];
|
||||
function similar(json: emojijson) {
|
||||
@@ -364,11 +368,13 @@ class Emoji {
|
||||
}
|
||||
}
|
||||
const weakGuild = new WeakMap<emojijson, Guild>();
|
||||
for (const guild of localuser.guilds) {
|
||||
if (guild.id !== "@me" && guild.emojis.length !== 0) {
|
||||
for (const emoji of guild.emojis) {
|
||||
if (similar(emoji)) {
|
||||
weakGuild.set(emoji, guild);
|
||||
if (localuser) {
|
||||
for (const guild of localuser.guilds) {
|
||||
if (guild.id !== "@me" && guild.emojis.length !== 0) {
|
||||
for (const emoji of guild.emojis) {
|
||||
if (similar(emoji)) {
|
||||
weakGuild.set(emoji, guild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-2
@@ -287,8 +287,20 @@ class Guild extends SnowFlake {
|
||||
initText: this.properties.name,
|
||||
});
|
||||
|
||||
form.addFileInput(I18n.getTranslation("guild.banner:"), "banner", {clear: true});
|
||||
form.addFileInput(I18n.getTranslation("guild.icon:"), "icon", {clear: true});
|
||||
form.addImageInput(I18n.getTranslation("guild.banner:"), "banner", {
|
||||
clear: true,
|
||||
width: 96 * 3,
|
||||
initImg: this.banner
|
||||
? this.info.cdn + "/icons/" + this.id + "/" + this.banner + ".png?size=256"
|
||||
: "",
|
||||
objectFit: "cover",
|
||||
});
|
||||
form.addImageInput(I18n.getTranslation("guild.icon:"), "icon", {
|
||||
clear: true,
|
||||
initImg: this.properties.icon
|
||||
? this.info.cdn + "/icons/" + this.id + "/" + this.properties.icon + ".png"
|
||||
: "",
|
||||
});
|
||||
|
||||
form.addHR();
|
||||
|
||||
|
||||
@@ -1295,7 +1295,9 @@ class Localuser {
|
||||
}
|
||||
});
|
||||
});
|
||||
form.addFileInput(I18n.getTranslation("guild.icon:"), "icon", {files: "one"});
|
||||
form.addImageInput(I18n.getTranslation("guild.icon:"), "icon", {
|
||||
clear: true,
|
||||
});
|
||||
form.addTextInput(I18n.getTranslation("guild.name:"), "name", {required: true});
|
||||
const loading = new Dialog("");
|
||||
loading.float.options.addTitle(I18n.guild.creating());
|
||||
@@ -1332,7 +1334,7 @@ class Localuser {
|
||||
const template = form.addTextInput(I18n.guild.template(), "template", {
|
||||
initText: templateID || "",
|
||||
});
|
||||
form.addFileInput(I18n.getTranslation("guild.icon:"), "icon", {files: "one"});
|
||||
form.addImageInput(I18n.getTranslation("guild.icon:"), "icon", {files: "one", clear: true});
|
||||
form.addTextInput(I18n.getTranslation("guild.name:"), "name", {required: true});
|
||||
|
||||
const loading = new Dialog("");
|
||||
@@ -1533,14 +1535,14 @@ class Localuser {
|
||||
const settingsRight = userOptions.addOptions("");
|
||||
settingsRight.addHTMLArea(hypotheticalProfile);
|
||||
|
||||
const finput = settingsLeft.addFileInput(
|
||||
const finput = settingsLeft.addImageInput(
|
||||
I18n.getTranslation("uploadPfp"),
|
||||
(_) => {
|
||||
if (file) {
|
||||
this.updatepfp(file);
|
||||
}
|
||||
},
|
||||
{clear: true},
|
||||
{clear: true, initImg: this.user.getpfpsrc()},
|
||||
);
|
||||
finput.watchForChange((_) => {
|
||||
if (!_) {
|
||||
@@ -1559,14 +1561,19 @@ class Localuser {
|
||||
}
|
||||
});
|
||||
let bfile: undefined | File | null;
|
||||
const binput = settingsLeft.addFileInput(
|
||||
const binput = settingsLeft.addImageInput(
|
||||
I18n.getTranslation("uploadBanner"),
|
||||
(_) => {
|
||||
if (bfile !== undefined) {
|
||||
this.updatebanner(bfile);
|
||||
}
|
||||
},
|
||||
{clear: true},
|
||||
{
|
||||
clear: true,
|
||||
width: 96 * 3,
|
||||
initImg: this.user.banner ? this.user.getBannerUrl() : "",
|
||||
objectFit: "cover",
|
||||
},
|
||||
);
|
||||
binput.watchForChange((_) => {
|
||||
if (!_) {
|
||||
@@ -2391,6 +2398,7 @@ class Localuser {
|
||||
headers: this.headers,
|
||||
});
|
||||
const json = await res.json();
|
||||
console.error(json);
|
||||
const form = container.addSubForm(json.name, () => {}, {
|
||||
fetchURL: this.info.api + "/applications/" + appId,
|
||||
method: "PATCH",
|
||||
@@ -2401,7 +2409,10 @@ class Localuser {
|
||||
form.addMDInput(I18n.getTranslation("localuser.description"), "description", {
|
||||
initText: json.description,
|
||||
});
|
||||
form.addFileInput("Icon:", "icon");
|
||||
form.addImageInput("Icon:", "icon", {
|
||||
clear: true,
|
||||
initImg: json.icon ? this.info.cdn + "/app-icons/" + appId + "/" + json.icon : "",
|
||||
});
|
||||
form.addTextInput(I18n.getTranslation("localuser.privacyPolcyURL"), "privacy_policy_url", {
|
||||
initText: json.privacy_policy_url,
|
||||
});
|
||||
@@ -2441,7 +2452,7 @@ class Localuser {
|
||||
if (!json.bot) {
|
||||
return alert(I18n.getTranslation("localuser.confuseNoBot"));
|
||||
}
|
||||
const bot: mainuserjson = json.bot;
|
||||
const bot: User = new User(json.bot, this);
|
||||
const form = container.addSubForm(
|
||||
I18n.getTranslation("localuser.editingBot", bot.username),
|
||||
(out) => {
|
||||
@@ -2457,7 +2468,10 @@ class Localuser {
|
||||
form.addTextInput(I18n.getTranslation("localuser.botUsername"), "username", {
|
||||
initText: bot.username,
|
||||
});
|
||||
form.addFileInput(I18n.getTranslation("localuser.botAvatar"), "avatar");
|
||||
form.addImageInput(I18n.getTranslation("localuser.botAvatar"), "avatar", {
|
||||
initImg: bot.getpfpsrc(),
|
||||
clear: true,
|
||||
});
|
||||
form.addButtonInput("", I18n.getTranslation("localuser.resetToken"), async () => {
|
||||
if (!confirm(I18n.getTranslation("localuser.confirmReset"))) {
|
||||
return;
|
||||
|
||||
+26
-6
@@ -86,6 +86,7 @@ export {Role};
|
||||
import {Options} from "./settings.js";
|
||||
import {createImg} from "./utils/utils.js";
|
||||
import {Hover} from "./hover.js";
|
||||
import {Emoji} from "./emoji.js";
|
||||
class PermissionToggle implements OptionsElement<number> {
|
||||
readonly rolejson: {
|
||||
name: string;
|
||||
@@ -226,11 +227,11 @@ class RoleList extends Buttons {
|
||||
this.redoButtons();
|
||||
}
|
||||
makeguildmenus(option: Options) {
|
||||
option.addButtonInput("", I18n.getTranslation("role.displaySettings"), () => {
|
||||
option.addButtonInput("", I18n.role.displaySettings(), () => {
|
||||
const role = this.guild.roleids.get(this.curid as string);
|
||||
if (!role) return;
|
||||
const form = option.addSubForm(
|
||||
I18n.getTranslation("role.displaySettings"),
|
||||
I18n.role.displaySettings(),
|
||||
(e) => {
|
||||
if ("name" in e && typeof e.name === "string") {
|
||||
option.name = e.name;
|
||||
@@ -245,19 +246,38 @@ class RoleList extends Buttons {
|
||||
traditionalSubmit: true,
|
||||
},
|
||||
);
|
||||
form.addTextInput(I18n.getTranslation("role.name"), "name", {
|
||||
form.addTextInput(I18n.role.name(), "name", {
|
||||
initText: role.name,
|
||||
});
|
||||
form.addCheckboxInput(I18n.getTranslation("role.hoisted"), "hoist", {
|
||||
form.addCheckboxInput(I18n.role.hoisted(), "hoist", {
|
||||
initState: role.hoist,
|
||||
});
|
||||
form.addCheckboxInput(I18n.getTranslation("role.mentionable"), "mentionable", {
|
||||
form.addCheckboxInput(I18n.role.mentionable(), "mentionable", {
|
||||
initState: role.mentionable,
|
||||
});
|
||||
const color = "#" + role.color.toString(16).padStart(6, "0");
|
||||
const colorI = form.addColorInput(I18n.getTranslation("role.color"), "color", {
|
||||
const colorI = form.addColorInput(I18n.role.color(), "color", {
|
||||
initColor: color,
|
||||
});
|
||||
form.addEmojiInput(I18n.role.roleEmoji(), "unicode_emoji", undefined, {
|
||||
initEmoji: role.unicode_emoji
|
||||
? new Emoji(
|
||||
{
|
||||
name: "Emoji",
|
||||
emoji: role.unicode_emoji,
|
||||
},
|
||||
undefined,
|
||||
)
|
||||
: undefined,
|
||||
required: false,
|
||||
clear: true,
|
||||
});
|
||||
form.addImageInput(I18n.role.roleFileIcon(), "icon", {
|
||||
initImg: role.icon
|
||||
? role.info.cdn + "/role-icons/" + role.id + "/" + role.icon + ".webp"
|
||||
: "",
|
||||
clear: true,
|
||||
});
|
||||
form.addPreprocessor((obj: any) => {
|
||||
obj.color = Number("0x" + colorI.colorContent.substring(1));
|
||||
|
||||
|
||||
+160
-22
@@ -564,27 +564,31 @@ class MDInput implements OptionsElement<string> {
|
||||
this.onSubmit(this.value);
|
||||
}
|
||||
}
|
||||
class EmojiInput implements OptionsElement<Emoji | undefined> {
|
||||
class EmojiInput implements OptionsElement<Emoji | undefined | null> {
|
||||
readonly label: string;
|
||||
readonly owner: Options;
|
||||
readonly onSubmit: (str: Emoji | undefined) => void;
|
||||
readonly onSubmit: (str: Emoji | undefined | null) => void;
|
||||
input!: WeakRef<HTMLInputElement>;
|
||||
value!: Emoji | undefined;
|
||||
localuser: Localuser;
|
||||
value!: Emoji | undefined | null;
|
||||
localuser?: Localuser;
|
||||
clear: boolean;
|
||||
constructor(
|
||||
label: string,
|
||||
onSubmit: (str: Emoji | undefined) => void,
|
||||
onSubmit: (str: Emoji | undefined | null) => void,
|
||||
owner: Options,
|
||||
localuser: Localuser,
|
||||
{initEmoji = undefined}: {initEmoji: undefined | Emoji},
|
||||
localuser?: Localuser,
|
||||
{initEmoji = undefined, clear = false}: {initEmoji?: undefined | Emoji; clear?: boolean} = {},
|
||||
) {
|
||||
this.label = label;
|
||||
this.owner = owner;
|
||||
this.onSubmit = onSubmit;
|
||||
this.value = initEmoji;
|
||||
this.localuser = localuser;
|
||||
this.clear = !!clear;
|
||||
}
|
||||
generateHTML(): HTMLElement {
|
||||
const outDiv = document.createElement("div");
|
||||
outDiv.classList.add("flexltr");
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("flexltr", "emojiForm");
|
||||
const label = document.createElement("span");
|
||||
@@ -614,22 +618,39 @@ class EmojiInput implements OptionsElement<Emoji | undefined> {
|
||||
})();
|
||||
};
|
||||
div.append(label, emoji);
|
||||
return div;
|
||||
outDiv.append(div);
|
||||
if (this.clear) {
|
||||
const button = document.createElement("button");
|
||||
button.textContent = I18n.settings.clear();
|
||||
button.onclick = () => {
|
||||
this.value = null;
|
||||
emoji.remove();
|
||||
this.onchange(null);
|
||||
this.owner.changed();
|
||||
emoji = document.createElement("span");
|
||||
emoji.classList.add("emptyEmoji");
|
||||
div.append(emoji);
|
||||
};
|
||||
outDiv.append(button);
|
||||
}
|
||||
|
||||
return outDiv;
|
||||
}
|
||||
onchange = (_: Emoji | undefined) => {};
|
||||
watchForChange(func: (arg1: Emoji | undefined) => void) {
|
||||
onchange = (_: Emoji | undefined | null) => {};
|
||||
watchForChange(func: (arg1: Emoji | undefined | null) => void) {
|
||||
this.onchange = func;
|
||||
}
|
||||
submit() {
|
||||
this.onSubmit(this.value);
|
||||
}
|
||||
}
|
||||
class FileInput implements OptionsElement<FileList | null> {
|
||||
|
||||
class FileInput implements OptionsElement<FileList | null | undefined> {
|
||||
readonly label: string;
|
||||
readonly owner: Options;
|
||||
readonly onSubmit: (str: FileList | null) => void;
|
||||
input!: WeakRef<HTMLInputElement>;
|
||||
value!: FileList | null;
|
||||
value: FileList | null | undefined = undefined;
|
||||
clear: boolean;
|
||||
constructor(
|
||||
label: string,
|
||||
@@ -656,7 +677,7 @@ class FileInput implements OptionsElement<FileList | null> {
|
||||
innerDiv.append(input);
|
||||
if (this.clear) {
|
||||
const button = document.createElement("button");
|
||||
button.textContent = "Clear";
|
||||
button.textContent = I18n.settings.clear();
|
||||
button.onclick = (_) => {
|
||||
if (this.onchange) {
|
||||
this.onchange(null);
|
||||
@@ -679,8 +700,8 @@ class FileInput implements OptionsElement<FileList | null> {
|
||||
}
|
||||
}
|
||||
}
|
||||
onchange: ((str: FileList | null) => void) | null = null;
|
||||
watchForChange(func: (str: FileList | null) => void) {
|
||||
onchange: ((str: FileList | null | undefined) => void) | null = null;
|
||||
watchForChange(func: (str: FileList | null | undefined) => void) {
|
||||
this.onchange = func;
|
||||
}
|
||||
submit() {
|
||||
@@ -690,6 +711,95 @@ class FileInput implements OptionsElement<FileList | null> {
|
||||
}
|
||||
}
|
||||
}
|
||||
class ImageInput extends FileInput {
|
||||
img: HTMLElement;
|
||||
constructor(
|
||||
label: string,
|
||||
onSubmit: (str: FileList | null) => void,
|
||||
owner: Options,
|
||||
{clear = false, initImg = "", width = -1, objectFit = ""} = {},
|
||||
) {
|
||||
super(label, onSubmit, owner, {clear});
|
||||
|
||||
console.log(initImg);
|
||||
let hasimg = "" !== initImg;
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.oninput = this.onChange.bind(this);
|
||||
this.input = new WeakRef(input);
|
||||
input.accept = "image/*";
|
||||
const img = document.createElement("img");
|
||||
img.src = initImg;
|
||||
|
||||
img.onclick = () => {
|
||||
input.click();
|
||||
};
|
||||
const button = document.createElement("button");
|
||||
button.textContent = I18n.settings.clear();
|
||||
button.onclick = (_) => {
|
||||
img.src = "";
|
||||
if (this.onchange) {
|
||||
this.onchange(null);
|
||||
}
|
||||
this.value = null;
|
||||
this.owner.changed();
|
||||
hasimg = false;
|
||||
genImg();
|
||||
};
|
||||
this.clearbutton = button;
|
||||
|
||||
input.addEventListener("change", () => {
|
||||
if (!input.files) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = (imgf) => {
|
||||
const res = imgf.target?.result;
|
||||
if (!res) return;
|
||||
if (typeof res !== "string") return;
|
||||
img.src = res;
|
||||
hasimg = true;
|
||||
genImg();
|
||||
};
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
});
|
||||
const div = document.createElement("div");
|
||||
const span = document.createElement("span");
|
||||
span.textContent = I18n.settings.img();
|
||||
const genImg = () => {
|
||||
console.warn(hasimg);
|
||||
if (hasimg) {
|
||||
div.append(img);
|
||||
span.remove();
|
||||
} else {
|
||||
div.append(span);
|
||||
img.remove();
|
||||
}
|
||||
};
|
||||
if (width !== -1) {
|
||||
div.style.width = width + "px";
|
||||
img.style.width = width + "px";
|
||||
}
|
||||
if (objectFit) img.style.objectFit = objectFit;
|
||||
console.warn(objectFit);
|
||||
this.img = div;
|
||||
genImg();
|
||||
}
|
||||
clearbutton: HTMLButtonElement;
|
||||
generateHTML(): HTMLDivElement {
|
||||
const div = document.createElement("div");
|
||||
const span = document.createElement("span");
|
||||
span.textContent = this.label;
|
||||
div.append(span);
|
||||
const innerDiv = document.createElement("div");
|
||||
innerDiv.classList.add("flexltr", "fileinputdiv");
|
||||
innerDiv.append(this.img);
|
||||
|
||||
if (this.clear) {
|
||||
innerDiv.append(this.clearbutton);
|
||||
}
|
||||
div.append(innerDiv);
|
||||
return div;
|
||||
}
|
||||
}
|
||||
|
||||
class HtmlArea implements OptionsElement<void> {
|
||||
submit: () => void;
|
||||
@@ -988,11 +1098,12 @@ class Options implements OptionsElement<void> {
|
||||
addEmojiInput(
|
||||
label: string,
|
||||
onSubmit: (str: Emoji | undefined) => void,
|
||||
localuser: Localuser,
|
||||
{initEmoji = undefined} = {} as {initEmoji?: Emoji},
|
||||
localuser?: Localuser,
|
||||
{initEmoji = undefined, clear = false} = {} as {initEmoji?: Emoji; clear?: boolean},
|
||||
) {
|
||||
const emoji = new EmojiInput(label, onSubmit, this, localuser, {
|
||||
initEmoji: initEmoji,
|
||||
clear,
|
||||
});
|
||||
this.options.push(emoji);
|
||||
this.generate(emoji);
|
||||
@@ -1025,6 +1136,16 @@ class Options implements OptionsElement<void> {
|
||||
this.generate(select);
|
||||
return select;
|
||||
}
|
||||
addImageInput(
|
||||
label: string,
|
||||
onSubmit: (files: FileList | null) => void,
|
||||
{clear = false, initImg = "", width = -1, objectFit = ""} = {},
|
||||
) {
|
||||
const FI = new ImageInput(label, onSubmit, this, {clear, initImg, width, objectFit});
|
||||
this.options.push(FI);
|
||||
this.generate(FI);
|
||||
return FI;
|
||||
}
|
||||
addFileInput(label: string, onSubmit: (files: FileList | null) => void, {clear = false} = {}) {
|
||||
const FI = new FileInput(label, onSubmit, this, {clear});
|
||||
this.options.push(FI);
|
||||
@@ -1547,14 +1668,33 @@ class Form implements OptionsElement<object> {
|
||||
}
|
||||
return FI;
|
||||
}
|
||||
addImageInput(
|
||||
label: string,
|
||||
formName: string,
|
||||
{required = false, files = "one", clear = false, initImg = "", width = -1, objectFit = ""} = {},
|
||||
) {
|
||||
const FI = this.options.addImageInput(label, (_) => {}, {clear, initImg, width, objectFit});
|
||||
if (files !== "one" && files !== "multi") throw new Error("files should equal one or multi");
|
||||
this.fileOptions.set(FI, {files});
|
||||
this.names.set(formName, FI);
|
||||
if (required) {
|
||||
this.required.add(FI);
|
||||
}
|
||||
return FI;
|
||||
}
|
||||
addEmojiInput(
|
||||
label: string,
|
||||
formName: string,
|
||||
localuser: Localuser,
|
||||
{initEmoji = undefined, required = false} = {} as {initEmoji?: Emoji; required: boolean},
|
||||
localuser?: Localuser,
|
||||
{initEmoji = undefined, required = false, clear = false} = {} as {
|
||||
initEmoji?: Emoji;
|
||||
required: boolean;
|
||||
clear?: boolean;
|
||||
},
|
||||
) {
|
||||
const emoji = this.options.addEmojiInput(label, () => {}, localuser, {
|
||||
initEmoji: initEmoji,
|
||||
clear,
|
||||
});
|
||||
if (required) {
|
||||
this.required.add(emoji);
|
||||
@@ -1732,15 +1872,13 @@ class Form implements OptionsElement<object> {
|
||||
});
|
||||
promises.push(promise);
|
||||
continue;
|
||||
} else if (input.value === undefined) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
console.error(options.files + " is not currently implemented");
|
||||
}
|
||||
} else if (input instanceof EmojiInput) {
|
||||
if (!input.value) {
|
||||
(build as any)[thing] = undefined;
|
||||
(build as any)[thing] = input.value;
|
||||
} else if (input.value.id) {
|
||||
(build as any)[thing] = input.value.id;
|
||||
} else if (input.value.emoji) {
|
||||
|
||||
@@ -1733,6 +1733,26 @@ span.instanceStatus {
|
||||
gap: 4px;
|
||||
width: 100%;
|
||||
}
|
||||
.fileinputdiv > div {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
object-fit: contain;
|
||||
background: var(--secondary-bg);
|
||||
border-radius: 16px;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
object-fit: contain;
|
||||
border-radius: 16px;
|
||||
}
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
span {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.username {
|
||||
margin-top: auto;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -338,11 +338,15 @@
|
||||
"color": "Color",
|
||||
"remove": "Remove role",
|
||||
"delete": "Delete Role",
|
||||
"confirmDelete": "Are you sure you want to delete $1?"
|
||||
"confirmDelete": "Are you sure you want to delete $1?",
|
||||
"roleEmoji": "Role emoji:",
|
||||
"roleFileIcon": "Role Icon:"
|
||||
},
|
||||
"settings": {
|
||||
"unsaved": "Careful, you have unsaved changes",
|
||||
"save": "Save changes"
|
||||
"save": "Save changes",
|
||||
"img": "Upload image",
|
||||
"clear": "Clear"
|
||||
},
|
||||
"trace": {
|
||||
"totalTime": "$2: $1ms",
|
||||
|
||||
Reference in New Issue
Block a user