improving context menus
This commit is contained in:
parent
ec08cdfde0
commit
3d06440053
10 changed files with 404 additions and 251 deletions
|
@ -73,56 +73,73 @@ class Channel extends SnowFlake {
|
|||
this.mute_config = settings.mute_config;
|
||||
}
|
||||
static setupcontextmenu() {
|
||||
this.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("channel.copyId"),
|
||||
function (this: Channel) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("channel.markRead"),
|
||||
function (this: Channel) {
|
||||
this.readbottom();
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("channel.settings"),
|
||||
//TODO invite icon
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("channel.makeInvite"),
|
||||
function (this: Channel) {
|
||||
this.generateSettings();
|
||||
this.createInvite();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
return this.hasPermission("MANAGE_CHANNELS");
|
||||
{
|
||||
visable: function () {
|
||||
return this.hasPermission("CREATE_INSTANT_INVITE") && this.type !== 4;
|
||||
},
|
||||
color: "blue",
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("channel.delete"),
|
||||
function (this: Channel) {
|
||||
this.deleteChannel();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
return this.isAdmin();
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addSeperator();
|
||||
//TODO notifcations icon
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.notifications"),
|
||||
function () {
|
||||
this.setnotifcation();
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("channel.makeInvite"),
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("channel.settings"),
|
||||
function (this: Channel) {
|
||||
this.createInvite();
|
||||
this.generateSettings();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
return this.hasPermission("CREATE_INSTANT_INVITE") && this.type !== 4;
|
||||
{
|
||||
visable: function () {
|
||||
return this.hasPermission("MANAGE_CHANNELS");
|
||||
},
|
||||
icon: {
|
||||
css: "svg-settings",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("channel.delete"),
|
||||
function (this: Channel) {
|
||||
this.deleteChannel();
|
||||
},
|
||||
{
|
||||
visable: function () {
|
||||
//TODO there is no way that this is correct
|
||||
return this.isAdmin();
|
||||
},
|
||||
icon: {
|
||||
css: "svg-delete",
|
||||
},
|
||||
color: "red",
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addSeperator();
|
||||
//TODO copy ID icon
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("channel.copyId"),
|
||||
function (this: Channel) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,114 @@
|
|||
import {iOS} from "./utils/utils.js";
|
||||
import {mobile} from "./utils/utils.js";
|
||||
type iconJson =
|
||||
| {
|
||||
src: string;
|
||||
}
|
||||
| {
|
||||
css: string;
|
||||
}
|
||||
| {
|
||||
html: HTMLElement;
|
||||
};
|
||||
|
||||
interface menuPart<x, y> {
|
||||
makeContextHTML(obj1: x, obj2: y, menu: HTMLDivElement): void;
|
||||
}
|
||||
|
||||
class ContextButton<x, y> implements menuPart<x, y> {
|
||||
private text: string | (() => string);
|
||||
private onClick: (this: x, arg: y, e: MouseEvent) => void;
|
||||
private icon?: iconJson;
|
||||
private visable?: (this: x, arg: y) => boolean;
|
||||
private enabled?: (this: x, arg: y) => boolean;
|
||||
//TODO there *will* be more colors
|
||||
private color?: "red" | "blue";
|
||||
constructor(
|
||||
text: ContextButton<x, y>["text"],
|
||||
onClick: ContextButton<x, y>["onClick"],
|
||||
addProps: {
|
||||
icon?: iconJson;
|
||||
visable?: (this: x, arg: y) => boolean;
|
||||
enabled?: (this: x, arg: y) => boolean;
|
||||
color?: "red" | "blue";
|
||||
} = {},
|
||||
) {
|
||||
this.text = text;
|
||||
this.onClick = onClick;
|
||||
this.icon = addProps.icon;
|
||||
this.visable = addProps.visable;
|
||||
this.enabled = addProps.enabled;
|
||||
this.color = addProps.color;
|
||||
}
|
||||
isVisable(obj1: x, obj2: y): boolean {
|
||||
if (!this.visable) return true;
|
||||
return this.visable.call(obj1, obj2);
|
||||
}
|
||||
makeContextHTML(obj1: x, obj2: y, menu: HTMLDivElement) {
|
||||
if (!this.isVisable(obj1, obj2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const intext = document.createElement("button");
|
||||
intext.classList.add("contextbutton");
|
||||
intext.append(this.textContent);
|
||||
|
||||
intext.disabled = !!this.enabled && !this.enabled.call(obj1, obj2);
|
||||
|
||||
if (this.icon) {
|
||||
if ("src" in this.icon) {
|
||||
const icon = document.createElement("img");
|
||||
icon.classList.add("svgicon");
|
||||
icon.src = this.icon.src;
|
||||
intext.append(icon);
|
||||
} else if ("css" in this.icon) {
|
||||
const icon = document.createElement("span");
|
||||
icon.classList.add(this.icon.css, "svgicon");
|
||||
switch (this.color) {
|
||||
case "red":
|
||||
icon.style.background = "var(--red)";
|
||||
break;
|
||||
case "blue":
|
||||
icon.style.background = "var(--blue)";
|
||||
break;
|
||||
}
|
||||
intext.append(icon);
|
||||
} else {
|
||||
intext.append(this.icon.html);
|
||||
}
|
||||
}
|
||||
|
||||
switch (this.color) {
|
||||
case "red":
|
||||
intext.style.color = "var(--red)";
|
||||
break;
|
||||
case "blue":
|
||||
intext.style.color = "var(--blue)";
|
||||
break;
|
||||
}
|
||||
|
||||
intext.onclick = (e) => {
|
||||
menu.remove();
|
||||
this.onClick.call(obj1, obj2, e);
|
||||
};
|
||||
|
||||
menu.append(intext);
|
||||
}
|
||||
get textContent() {
|
||||
if (this.text instanceof Function) {
|
||||
return this.text();
|
||||
}
|
||||
return this.text;
|
||||
}
|
||||
}
|
||||
class Seperator<x, y> implements menuPart<x, y> {
|
||||
makeContextHTML(_obj1: x, _obj2: y, menu: HTMLDivElement): void {
|
||||
menu.append(document.createElement("hr"));
|
||||
}
|
||||
}
|
||||
class Contextmenu<x, y> {
|
||||
static currentmenu: HTMLElement | "";
|
||||
name: string;
|
||||
buttons: [
|
||||
string | (() => string),
|
||||
(this: x, arg: y, e: MouseEvent) => void,
|
||||
string | null,
|
||||
(this: x, arg: y) => boolean,
|
||||
(this: x, arg: y) => boolean,
|
||||
string,
|
||||
][];
|
||||
buttons: menuPart<x, y>[];
|
||||
div!: HTMLDivElement;
|
||||
static setup() {
|
||||
Contextmenu.currentmenu = "";
|
||||
|
@ -27,56 +126,33 @@ class Contextmenu<x, y> {
|
|||
this.name = name;
|
||||
this.buttons = [];
|
||||
}
|
||||
addbutton(
|
||||
text: string | (() => string),
|
||||
onclick: (this: x, arg: y, e: MouseEvent) => void,
|
||||
img: null | string = null,
|
||||
shown: (this: x, arg: y) => boolean = (_) => true,
|
||||
enabled: (this: x, arg: y) => boolean = (_) => true,
|
||||
|
||||
addButton(
|
||||
text: ContextButton<x, y>["text"],
|
||||
onClick: ContextButton<x, y>["onClick"],
|
||||
addProps: {
|
||||
icon?: iconJson;
|
||||
visable?: (this: x, arg: y) => boolean;
|
||||
enabled?: (this: x, arg: y) => boolean;
|
||||
color?: "red" | "blue";
|
||||
} = {},
|
||||
) {
|
||||
this.buttons.push([text, onclick, img, shown, enabled, "button"]);
|
||||
return {};
|
||||
this.buttons.push(new ContextButton(text, onClick, addProps));
|
||||
}
|
||||
addsubmenu(
|
||||
text: string | (() => string),
|
||||
onclick: (this: x, arg: y, e: MouseEvent) => void,
|
||||
img = null,
|
||||
shown: (this: x, arg: y) => boolean = (_) => true,
|
||||
enabled: (this: x, arg: y) => boolean = (_) => true,
|
||||
) {
|
||||
this.buttons.push([text, onclick, img, shown, enabled, "submenu"]);
|
||||
return {};
|
||||
addSeperator() {
|
||||
this.buttons.push(new Seperator());
|
||||
}
|
||||
private makemenu(x: number, y: number, addinfo: x, other: y) {
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("contextmenu", "flexttb");
|
||||
|
||||
let visibleButtons = 0;
|
||||
for (const thing of this.buttons) {
|
||||
if (!thing[3].call(addinfo, other)) continue;
|
||||
visibleButtons++;
|
||||
|
||||
const intext = document.createElement("button");
|
||||
intext.disabled = !thing[4].call(addinfo, other);
|
||||
intext.classList.add("contextbutton");
|
||||
if (thing[0] instanceof Function) {
|
||||
intext.textContent = thing[0]();
|
||||
} else {
|
||||
intext.textContent = thing[0];
|
||||
}
|
||||
console.log(thing);
|
||||
if (thing[5] === "button" || thing[5] === "submenu") {
|
||||
intext.onclick = (e) => {
|
||||
div.remove();
|
||||
thing[1].call(addinfo, other, e);
|
||||
};
|
||||
for (const button of this.buttons) {
|
||||
button.makeContextHTML(addinfo, other, div);
|
||||
}
|
||||
//NOTE I don't know if this'll ever actually happen in reality
|
||||
if (div.childNodes.length === 0) return;
|
||||
|
||||
div.appendChild(intext);
|
||||
}
|
||||
if (visibleButtons == 0) return;
|
||||
|
||||
if (Contextmenu.currentmenu != "") {
|
||||
if (Contextmenu.currentmenu !== "") {
|
||||
Contextmenu.currentmenu.remove();
|
||||
}
|
||||
div.style.top = y + "px";
|
||||
|
@ -100,7 +176,8 @@ class Contextmenu<x, y> {
|
|||
this.makemenu(event.clientX, event.clientY, addinfo, other);
|
||||
};
|
||||
obj.addEventListener("contextmenu", func);
|
||||
if (iOS) {
|
||||
//NOTE not sure if this code is correct, seems fine at least for now
|
||||
if (mobile) {
|
||||
let hold: NodeJS.Timeout | undefined;
|
||||
let x!: number;
|
||||
let y!: number;
|
||||
|
|
|
@ -342,28 +342,28 @@ class Group extends Channel {
|
|||
user: User;
|
||||
static contextmenu = new Contextmenu<Group, undefined>("channel menu");
|
||||
static setupcontextmenu() {
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("DMs.copyId"),
|
||||
function (this: Group) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("DMs.markRead"),
|
||||
function (this: Group) {
|
||||
this.readbottom();
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("DMs.close"),
|
||||
function (this: Group) {
|
||||
this.deleteChannel();
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.copyId"),
|
||||
function () {
|
||||
navigator.clipboard.writeText(this.user.id);
|
||||
|
|
|
@ -39,89 +39,96 @@ class Guild extends SnowFlake {
|
|||
members = new Set<Member>();
|
||||
static contextmenu = new Contextmenu<Guild, undefined>("guild menu");
|
||||
static setupcontextmenu() {
|
||||
Guild.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("guild.copyId"),
|
||||
function (this: Guild) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("guild.markRead"),
|
||||
function (this: Guild) {
|
||||
this.markAsRead();
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("guild.notifications"),
|
||||
function (this: Guild) {
|
||||
this.setnotifcation();
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("user.editServerProfile"),
|
||||
function () {
|
||||
this.member.showEditProfile();
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("guild.leave"),
|
||||
function (this: Guild) {
|
||||
this.confirmleave();
|
||||
},
|
||||
null,
|
||||
function (_) {
|
||||
return this.properties.owner_id !== this.member.user.id;
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("guild.delete"),
|
||||
function (this: Guild) {
|
||||
this.confirmDelete();
|
||||
},
|
||||
null,
|
||||
function (_) {
|
||||
return this.properties.owner_id === this.member.user.id;
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addbutton(
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.makeInvite"),
|
||||
function (this: Guild) {
|
||||
const d = new Dialog("");
|
||||
this.makeInviteMenu(d.options);
|
||||
d.show();
|
||||
},
|
||||
null,
|
||||
(_) => true,
|
||||
function () {
|
||||
{
|
||||
enabled: function () {
|
||||
return this.member.hasPermission("CREATE_INSTANT_INVITE");
|
||||
},
|
||||
color: "blue",
|
||||
},
|
||||
);
|
||||
Guild.contextmenu.addbutton(
|
||||
Guild.contextmenu.addSeperator();
|
||||
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.markRead"),
|
||||
function (this: Guild) {
|
||||
this.markAsRead();
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.notifications"),
|
||||
function (this: Guild) {
|
||||
this.setnotifcation();
|
||||
},
|
||||
);
|
||||
Guild.contextmenu.addSeperator();
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.editServerProfile"),
|
||||
function () {
|
||||
this.member.showEditProfile();
|
||||
},
|
||||
);
|
||||
Guild.contextmenu.addSeperator();
|
||||
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.leave"),
|
||||
function (this: Guild) {
|
||||
this.confirmleave();
|
||||
},
|
||||
{
|
||||
visable: function (_) {
|
||||
return this.properties.owner_id !== this.member.user.id;
|
||||
},
|
||||
color: "red",
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.delete"),
|
||||
function (this: Guild) {
|
||||
this.confirmDelete();
|
||||
},
|
||||
{
|
||||
visable: function (_) {
|
||||
return this.properties.owner_id === this.member.user.id;
|
||||
},
|
||||
color: "red",
|
||||
icon: {
|
||||
css: "svg-delete",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.settings"),
|
||||
function (this: Guild) {
|
||||
this.generateSettings();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return this.member.hasPermission("MANAGE_GUILD");
|
||||
},
|
||||
icon: {
|
||||
css: "svg-settings",
|
||||
},
|
||||
},
|
||||
);
|
||||
/* -----things left for later-----
|
||||
guild.contextmenu.addbutton("Leave Guild",function(){
|
||||
console.log(this)
|
||||
this.deleteChannel();
|
||||
},null,_=>{return thisuser.isAdmin()})
|
||||
|
||||
guild.contextmenu.addbutton("Mute Guild",function(){
|
||||
editchannelf(this);
|
||||
},null,_=>{return thisuser.isAdmin()})
|
||||
*/
|
||||
Guild.contextmenu.addSeperator();
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.getTranslation("guild.copyId"),
|
||||
function (this: Guild) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
//TODO mute guild button
|
||||
}
|
||||
generateSettings() {
|
||||
const settings = new Settings(I18n.getTranslation("guild.settingsFor", this.properties.name));
|
||||
|
|
|
@ -127,26 +127,24 @@ import {I18n} from "./i18n.js";
|
|||
}
|
||||
|
||||
const menu = new Contextmenu<void, void>("create rightclick");
|
||||
menu.addbutton(
|
||||
menu.addButton(
|
||||
I18n.getTranslation("channel.createChannel"),
|
||||
() => {
|
||||
if (thisUser.lookingguild) {
|
||||
thisUser.lookingguild.createchannels();
|
||||
}
|
||||
},
|
||||
null,
|
||||
() => thisUser.isAdmin(),
|
||||
{visable: () => thisUser.isAdmin()},
|
||||
);
|
||||
|
||||
menu.addbutton(
|
||||
menu.addButton(
|
||||
I18n.getTranslation("channel.createCatagory"),
|
||||
() => {
|
||||
if (thisUser.lookingguild) {
|
||||
thisUser.lookingguild.createcategory();
|
||||
}
|
||||
},
|
||||
null,
|
||||
() => thisUser.isAdmin(),
|
||||
{visable: () => thisUser.isAdmin()},
|
||||
);
|
||||
|
||||
menu.bindContextmenu(document.getElementById("channels") as HTMLDivElement);
|
||||
|
|
|
@ -57,51 +57,82 @@ class Message extends SnowFlake {
|
|||
Message.setupcmenu();
|
||||
}
|
||||
static setupcmenu() {
|
||||
Message.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("copyrawtext"),
|
||||
function (this: Message) {
|
||||
navigator.clipboard.writeText(this.content.rawString);
|
||||
},
|
||||
);
|
||||
Message.contextmenu.addbutton(
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("reply"),
|
||||
function (this: Message) {
|
||||
this.channel.setReplying(this);
|
||||
},
|
||||
);
|
||||
Message.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("copymessageid"),
|
||||
function (this: Message) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
{
|
||||
icon: {
|
||||
css: "svg-reply",
|
||||
},
|
||||
},
|
||||
);
|
||||
Message.contextmenu.addsubmenu(
|
||||
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("message.edit"),
|
||||
function (this: Message) {
|
||||
this.setEdit();
|
||||
},
|
||||
{
|
||||
visable: function () {
|
||||
return this.author.id === this.localuser.user.id;
|
||||
},
|
||||
|
||||
icon: {
|
||||
css: "svg-edit",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("message.reactionAdd"),
|
||||
function (this: Message, _, e: MouseEvent) {
|
||||
Emoji.emojiPicker(e.x, e.y, this.localuser).then((_) => {
|
||||
this.reactionToggle(_);
|
||||
});
|
||||
},
|
||||
{
|
||||
icon: {
|
||||
css: "svg-emoji",
|
||||
},
|
||||
},
|
||||
);
|
||||
Message.contextmenu.addbutton(
|
||||
() => I18n.getTranslation("message.edit"),
|
||||
|
||||
Message.contextmenu.addSeperator();
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("copyrawtext"),
|
||||
function (this: Message) {
|
||||
this.setEdit();
|
||||
navigator.clipboard.writeText(this.content.rawString);
|
||||
},
|
||||
{
|
||||
icon: {
|
||||
css: "svg-copy",
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
return this.author.id === this.localuser.user.id;
|
||||
},
|
||||
);
|
||||
Message.contextmenu.addbutton(
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("copymessageid"),
|
||||
function (this: Message) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
|
||||
Message.contextmenu.addSeperator();
|
||||
Message.contextmenu.addButton(
|
||||
() => I18n.getTranslation("message.delete"),
|
||||
function (this: Message) {
|
||||
this.confirmDelete();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return this.canDelete();
|
||||
},
|
||||
icon: {
|
||||
css: "svg-delete",
|
||||
},
|
||||
color: "red",
|
||||
},
|
||||
);
|
||||
}
|
||||
setEdit() {
|
||||
|
|
|
@ -236,7 +236,7 @@ class RoleList extends Buttons {
|
|||
static guildrolemenu = this.GuildRoleMenu();
|
||||
private static ChannelRoleMenu() {
|
||||
const menu = new Contextmenu<RoleList, Role>("role settings");
|
||||
menu.addbutton(
|
||||
menu.addButton(
|
||||
() => I18n.getTranslation("role.remove"),
|
||||
function (role) {
|
||||
if (!this.channel) return;
|
||||
|
@ -246,13 +246,12 @@ class RoleList extends Buttons {
|
|||
headers: this.headers,
|
||||
});
|
||||
},
|
||||
null,
|
||||
);
|
||||
return menu;
|
||||
}
|
||||
private static GuildRoleMenu() {
|
||||
const menu = new Contextmenu<RoleList, Role>("role settings");
|
||||
menu.addbutton(
|
||||
menu.addButton(
|
||||
() => I18n.getTranslation("role.delete"),
|
||||
function (role) {
|
||||
if (!confirm(I18n.getTranslation("role.confirmDelete"))) return;
|
||||
|
@ -262,7 +261,6 @@ class RoleList extends Buttons {
|
|||
headers: this.headers,
|
||||
});
|
||||
},
|
||||
null,
|
||||
);
|
||||
return menu;
|
||||
}
|
||||
|
|
|
@ -318,6 +318,7 @@ textarea {
|
|||
width: 100%;
|
||||
background: var(--primary-text-soft);
|
||||
mask-repeat: no-repeat;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
.selectarrow {
|
||||
position: absolute;
|
||||
|
@ -1534,8 +1535,13 @@ img.bigembedimg {
|
|||
background: var(--secondary-bg);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 8px var(--shadow);
|
||||
hr{
|
||||
width:90%;
|
||||
height: 1px;
|
||||
}
|
||||
}
|
||||
.contextbutton {
|
||||
position: relative;
|
||||
width: 180px;
|
||||
padding: 8px;
|
||||
background: transparent;
|
||||
|
@ -1544,6 +1550,15 @@ img.bigembedimg {
|
|||
color: var(--secondary-text);
|
||||
border: none;
|
||||
transition: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.svgicon {
|
||||
height: 0.2in;
|
||||
width: 0.2in;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
}
|
||||
}
|
||||
.contextbutton:enabled:hover {
|
||||
background: var(--secondary-hover);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
--red: #ff5555;
|
||||
--yellow: #ffc159;
|
||||
--green: #1c907b;
|
||||
--blue: #779bff;
|
||||
}
|
||||
|
||||
/* Themes. See themes.txt */
|
||||
|
|
|
@ -164,69 +164,73 @@ class User extends SnowFlake {
|
|||
this.relationshipType = type;
|
||||
}
|
||||
static setUpContextMenu(): void {
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.copyId"),
|
||||
function (this: User) {
|
||||
navigator.clipboard.writeText(this.id);
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.message"),
|
||||
function (this: User) {
|
||||
this.opendm();
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.block"),
|
||||
function (this: User) {
|
||||
this.block();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return this.relationshipType !== 2 && this.id !== this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.unblock"),
|
||||
function (this: User) {
|
||||
this.unblock();
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return this.relationshipType === 2 && this.id !== this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.friendReq"),
|
||||
function (this: User) {
|
||||
this.changeRelationship(1);
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return (
|
||||
(this.relationshipType === 0 || this.relationshipType === 3) &&
|
||||
this.id !== this.localuser.user.id
|
||||
);
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("friends.removeFriend"),
|
||||
function (this: User) {
|
||||
this.changeRelationship(0);
|
||||
},
|
||||
null,
|
||||
function () {
|
||||
{
|
||||
visable: function () {
|
||||
return this.relationshipType === 1 && this.id !== this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.kick"),
|
||||
function (this: User, member: Member | undefined) {
|
||||
member?.kick();
|
||||
},
|
||||
null,
|
||||
function (member) {
|
||||
{
|
||||
visable: function (member) {
|
||||
if (!member) return false;
|
||||
const us = member.guild.member;
|
||||
if (member.id === us.id) {
|
||||
|
@ -237,26 +241,28 @@ class User extends SnowFlake {
|
|||
}
|
||||
return us.hasPermission("KICK_MEMBERS") && this.id !== this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.editServerProfile"),
|
||||
function (this: User, member: Member | undefined) {
|
||||
if (!member) return;
|
||||
member.showEditProfile();
|
||||
},
|
||||
null,
|
||||
function (member) {
|
||||
{
|
||||
visable: function (member) {
|
||||
return member?.id === this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.ban"),
|
||||
function (this: User, member: Member | undefined) {
|
||||
member?.ban();
|
||||
},
|
||||
null,
|
||||
function (member) {
|
||||
{
|
||||
visable: function (member) {
|
||||
if (!member) return false;
|
||||
const us = member.guild.member;
|
||||
if (member.id === us.id) {
|
||||
|
@ -267,8 +273,9 @@ class User extends SnowFlake {
|
|||
}
|
||||
return us.hasPermission("BAN_MEMBERS") && this.id !== this.localuser.user.id;
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.addRole"),
|
||||
async function (this: User, member: Member | undefined, e) {
|
||||
if (member) {
|
||||
|
@ -286,15 +293,16 @@ class User extends SnowFlake {
|
|||
member.addRole(result);
|
||||
}
|
||||
},
|
||||
null,
|
||||
(member) => {
|
||||
{
|
||||
visable: (member) => {
|
||||
if (!member) return false;
|
||||
const us = member.guild.member;
|
||||
console.log(us.hasPermission("MANAGE_ROLES"));
|
||||
return us.hasPermission("MANAGE_ROLES") || false;
|
||||
},
|
||||
},
|
||||
);
|
||||
this.contextmenu.addbutton(
|
||||
this.contextmenu.addButton(
|
||||
() => I18n.getTranslation("user.removeRole"),
|
||||
async function (this: User, member: Member | undefined, e) {
|
||||
if (member) {
|
||||
|
@ -312,13 +320,14 @@ class User extends SnowFlake {
|
|||
member.removeRole(result);
|
||||
}
|
||||
},
|
||||
null,
|
||||
(member) => {
|
||||
{
|
||||
visable: (member) => {
|
||||
if (!member) return false;
|
||||
const us = member.guild.member;
|
||||
console.log(us.hasPermission("MANAGE_ROLES"));
|
||||
return us.hasPermission("MANAGE_ROLES") || false;
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue