mirror of
https://github.com/MathMan05/Fermi.git
synced 2026-05-13 19:23:16 +00:00
admin finder Menu
This commit is contained in:
@@ -147,6 +147,7 @@ class Contextmenu<x, y> {
|
||||
static setup() {
|
||||
Contextmenu.declareMenu();
|
||||
document.addEventListener("click", (event) => {
|
||||
console.log(event.target, Contextmenu.currentmenu);
|
||||
while (Contextmenu.currentmenu && !Contextmenu.currentmenu.contains(event.target as Node)) {
|
||||
Contextmenu.declareMenu();
|
||||
}
|
||||
@@ -270,7 +271,6 @@ class Contextmenu<x, y> {
|
||||
obj.style.left = Math.floor(docwidth - box.width) + "px";
|
||||
}
|
||||
if (box.bottom > docheight) {
|
||||
debugger;
|
||||
obj.style.top = Math.floor(docheight - box.height) + "px";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +263,13 @@ class Guild extends SnowFlake {
|
||||
},
|
||||
},
|
||||
);
|
||||
//TODO make icon for this
|
||||
Guild.contextmenu.addButton(
|
||||
() => I18n.guild.admins(),
|
||||
function (this: Guild) {
|
||||
this.findAdmin();
|
||||
},
|
||||
);
|
||||
|
||||
Guild.contextmenu.addSeperator();
|
||||
Guild.contextmenu.addButton(
|
||||
@@ -273,6 +280,180 @@ class Guild extends SnowFlake {
|
||||
);
|
||||
//TODO mute guild button
|
||||
}
|
||||
async findAdmin() {
|
||||
const menu = new Dialog(I18n.guild.admins());
|
||||
menu.options.addText("Loading");
|
||||
menu.show();
|
||||
const roles = new Set(
|
||||
Object.entries(
|
||||
(await (
|
||||
await fetch(this.info.api + `/guilds/${this.id}/roles/member-counts/`, {
|
||||
headers: this.headers,
|
||||
})
|
||||
).json()) as {[key: string]: number},
|
||||
)
|
||||
.map(([id, count]) => {
|
||||
return [this.roleids.get(id), count] as [Role, number];
|
||||
})
|
||||
//Just in case, this should never fire
|
||||
.filter((_) => _[0] !== undefined)
|
||||
//Filter out those who have too many users
|
||||
.filter((_) => _[1] > 1000)
|
||||
.map((_) => _[0]),
|
||||
);
|
||||
const everyone = this.roleids.get(this.id);
|
||||
if (everyone) roles.add(everyone);
|
||||
menu.options.removeAll();
|
||||
let owner = true;
|
||||
let perms = [
|
||||
"ADMINISTRATOR",
|
||||
"BAN_MEMBERS",
|
||||
"KICK_MEMBERS",
|
||||
"MANAGE_GUILD",
|
||||
"MANAGE_CHANNELS",
|
||||
"MODERATE_MEMBERS",
|
||||
"MANAGE_ROLES",
|
||||
"MANAGE_MESSAGES",
|
||||
"MANAGE_NICKNAMES",
|
||||
"MANAGE_WEBHOOKS",
|
||||
"MANAGE_EVENTS",
|
||||
"MANAGE_THREADS",
|
||||
].filter((_) => {
|
||||
for (const role of roles) {
|
||||
if (role.permissions.hasPermission(_, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
menu.options.addButtonInput("", I18n.guild.adminMenu.changePerms(), () => {
|
||||
const d = new Dialog("", {noSubmit: false});
|
||||
const opt = d.options;
|
||||
opt
|
||||
.addCheckboxInput(
|
||||
I18n.guild.adminMenu.owner(),
|
||||
(b) => {
|
||||
owner = b;
|
||||
d.hide();
|
||||
queueMicrotask(() => loadResults());
|
||||
},
|
||||
{
|
||||
initState: owner,
|
||||
},
|
||||
)
|
||||
.watchForChange(() => opt.changed());
|
||||
for (const perm of Permissions.info().filter((_) => {
|
||||
for (const role of roles) {
|
||||
if (role.permissions.hasPermission(_.name, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})) {
|
||||
opt.addHR();
|
||||
opt
|
||||
.addCheckboxInput(
|
||||
perm.readableName,
|
||||
(b) => {
|
||||
if (b) {
|
||||
perms.push(perm.name);
|
||||
} else {
|
||||
perms = perms.filter((_) => _ !== perm.name);
|
||||
}
|
||||
},
|
||||
{
|
||||
initState: perms.includes(perm.name),
|
||||
},
|
||||
)
|
||||
.watchForChange(() => opt.changed());
|
||||
opt.addText(perm.description);
|
||||
}
|
||||
d.show().style.width = "80%";
|
||||
});
|
||||
|
||||
const retDiv = document.createElement("div");
|
||||
menu.options.addHTMLArea(retDiv);
|
||||
const loadResults = async () => {
|
||||
retDiv.textContent = I18n.guild.adminMenu.finding();
|
||||
const results = new Set(
|
||||
(
|
||||
await Promise.all(
|
||||
this.roles
|
||||
.filter((_) => {
|
||||
for (const perm of perms) {
|
||||
if (_.permissions.hasPermission(perm, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(async (_) => {
|
||||
return (
|
||||
await fetch(`${this.info.api}/guilds/${this.id}/roles/${_.id}/member-ids`, {
|
||||
headers: this.headers,
|
||||
})
|
||||
).json() as Promise<string[]>;
|
||||
}),
|
||||
)
|
||||
).flat(),
|
||||
);
|
||||
if (owner) {
|
||||
results.add(this.properties.owner_id);
|
||||
}
|
||||
const members = (
|
||||
await Promise.all(
|
||||
[...results].map(async (_) => {
|
||||
const json = await this.localuser.resolvemember(_, this.id);
|
||||
return json ? Member.new(json, this) : undefined;
|
||||
}),
|
||||
)
|
||||
).filter((_) => _ !== undefined);
|
||||
members.sort((a, b) => {
|
||||
return a.name < b.name ? 1 : -1;
|
||||
});
|
||||
retDiv.innerHTML = "";
|
||||
retDiv.append(
|
||||
...members.map((memb) => {
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("flexltr", "adminList");
|
||||
const name = document.createElement("b");
|
||||
name.textContent = memb.name;
|
||||
const nameBox = document.createElement("div");
|
||||
nameBox.classList.add("flexttb");
|
||||
|
||||
const roles = document.createElement("div");
|
||||
roles.classList.add("flexltr");
|
||||
roles.append(
|
||||
...perms
|
||||
.filter((_) => memb.hasPermission(_, false))
|
||||
.map((perm) => {
|
||||
const span = document.createElement("span");
|
||||
//@ts-ignore
|
||||
span.textContent = I18n.permissions.readableNames[perm]();
|
||||
return span;
|
||||
}),
|
||||
);
|
||||
if (owner && memb.id === this.properties.owner_id) {
|
||||
const span = document.createElement("span");
|
||||
span.textContent = I18n.guild.adminMenu.ownName();
|
||||
roles.append(span);
|
||||
}
|
||||
|
||||
nameBox.append(name, roles);
|
||||
|
||||
const pfp = memb.user.buildpfp(memb, div);
|
||||
|
||||
div.append(pfp, nameBox);
|
||||
|
||||
memb.user.bind(div, this, undefined);
|
||||
return div;
|
||||
}),
|
||||
);
|
||||
console.log(members);
|
||||
};
|
||||
loadResults();
|
||||
}
|
||||
generateSettings() {
|
||||
const settings = new Settings(I18n.getTranslation("guild.settingsFor", this.properties.name));
|
||||
const textChannels = this.channels.filter((e) => {
|
||||
|
||||
+12
-7
@@ -824,15 +824,22 @@ class HtmlArea implements OptionsElement<void> {
|
||||
*/
|
||||
class Float {
|
||||
options: Options;
|
||||
html: WeakRef<HTMLElement> = new WeakRef(document.createElement("div"));
|
||||
/**
|
||||
* 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: true}) {
|
||||
this.options = new Options(name, this, options);
|
||||
}
|
||||
changed = () => {};
|
||||
changed(d: HTMLElement) {
|
||||
const html = this.html.deref();
|
||||
if (!html) return;
|
||||
html.append(d);
|
||||
}
|
||||
generateHTML() {
|
||||
return this.options.generateHTML();
|
||||
const html = this.options.generateHTML();
|
||||
this.html = new WeakRef(html);
|
||||
return html;
|
||||
}
|
||||
}
|
||||
class Dialog {
|
||||
@@ -852,16 +859,14 @@ class Dialog {
|
||||
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 = (_) => {
|
||||
if (hideOnClick) {
|
||||
if (hideOnClick && _.target === background) {
|
||||
background.remove();
|
||||
}
|
||||
};
|
||||
return center;
|
||||
}
|
||||
hide() {
|
||||
const background = this.background.deref();
|
||||
@@ -1098,7 +1103,7 @@ class Options implements OptionsElement<void> {
|
||||
}
|
||||
addEmojiInput(
|
||||
label: string,
|
||||
onSubmit: (str: Emoji | undefined) => void,
|
||||
onSubmit: (str: Emoji | null | undefined) => void,
|
||||
localuser?: Localuser,
|
||||
{initEmoji = undefined, clear = false} = {} as {initEmoji?: Emoji; clear?: boolean},
|
||||
) {
|
||||
|
||||
+35
-3
@@ -74,6 +74,35 @@ body {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
.adminList {
|
||||
width: 95%;
|
||||
background: var(--secondary-bg);
|
||||
padding: 6px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
.flexttb {
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.flexltr {
|
||||
span {
|
||||
margin-right: 4px;
|
||||
text-wrap: nowrap;
|
||||
background: var(--primary-bg);
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.flexltr {
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
@@ -2923,17 +2952,20 @@ fieldset input[type="radio"] {
|
||||
.tritoggle input:last-child {
|
||||
accent-color: var(--red);
|
||||
}
|
||||
.nonimagecenter > .flexltr.savediv {
|
||||
padding: 16px !important;
|
||||
}
|
||||
.savediv {
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 50%;
|
||||
transform: translateX(50%);
|
||||
padding: 16px;
|
||||
background: var(--secondary-bg);
|
||||
padding: 16px !important;
|
||||
background: var(--secondary-bg) !important;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
color: var(--secondary-text);
|
||||
border-radius: 8px;
|
||||
border-radius: 8px !important;
|
||||
align-items: center;
|
||||
box-shadow:
|
||||
0 0 24px var(--shadow),
|
||||
|
||||
+24
-6
@@ -496,7 +496,7 @@ class User extends SnowFlake {
|
||||
nameBox.append(notFound);
|
||||
}
|
||||
});
|
||||
this.bind(div, guild);
|
||||
this.bind(div, guild, undefined);
|
||||
return div;
|
||||
}
|
||||
buildstatuspfp(guild: Guild | void | Member | null): HTMLDivElement {
|
||||
@@ -541,7 +541,12 @@ class User extends SnowFlake {
|
||||
}
|
||||
}
|
||||
|
||||
bind(html: HTMLElement, guild: Guild | null = null, error = true): void {
|
||||
bind(
|
||||
html: HTMLElement,
|
||||
guild: Guild | null = null,
|
||||
error = true,
|
||||
button: "right" | "left" = "right",
|
||||
): void {
|
||||
if (guild && guild.id !== "@me") {
|
||||
Member.resolveMember(this, guild)
|
||||
.then((member) => {
|
||||
@@ -557,14 +562,14 @@ class User extends SnowFlake {
|
||||
if (member) {
|
||||
member.bind(html);
|
||||
} else {
|
||||
User.contextmenu.bindContextmenu(html, this, undefined);
|
||||
User.contextmenu.bindContextmenu(html, this, undefined, undefined, undefined, button);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
} else {
|
||||
User.contextmenu.bindContextmenu(html, this, undefined);
|
||||
User.contextmenu.bindContextmenu(html, this, undefined, undefined, undefined, button);
|
||||
}
|
||||
if (guild) {
|
||||
this.profileclick(html, guild);
|
||||
@@ -913,6 +918,7 @@ class User extends SnowFlake {
|
||||
x: number,
|
||||
y: number,
|
||||
guild: Guild | null | Member = null,
|
||||
zIndex = -1,
|
||||
): Promise<HTMLDivElement> {
|
||||
const membres = (async () => {
|
||||
if (!guild) return;
|
||||
@@ -925,7 +931,9 @@ class User extends SnowFlake {
|
||||
return member;
|
||||
})();
|
||||
const div = document.createElement("div");
|
||||
|
||||
if (zIndex !== -1) {
|
||||
div.style.zIndex = zIndex + "";
|
||||
}
|
||||
if (this.accent_color) {
|
||||
div.style.setProperty(
|
||||
"--accent_color",
|
||||
@@ -1100,8 +1108,18 @@ class User extends SnowFlake {
|
||||
}
|
||||
}
|
||||
profileclick(obj: HTMLElement, guild?: Guild): void {
|
||||
const getIndex = (elm: HTMLElement) => {
|
||||
const index = getComputedStyle(elm).zIndex;
|
||||
if (index === "auto") {
|
||||
if (elm.parentElement) {
|
||||
return getIndex(elm.parentElement);
|
||||
}
|
||||
}
|
||||
return +index;
|
||||
};
|
||||
obj.onclick = (e: MouseEvent) => {
|
||||
this.buildprofile(e.clientX, e.clientY, guild);
|
||||
const index = 1 + getIndex(obj);
|
||||
this.buildprofile(e.clientX, e.clientY, guild, index);
|
||||
e.stopPropagation();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -288,6 +288,13 @@
|
||||
"edit": "Edit",
|
||||
"guild": {
|
||||
"template": "Template:",
|
||||
"admins":"Find Admins",
|
||||
"adminMenu":{
|
||||
"finding":"Finding Admins",
|
||||
"permission":"Permissions:",
|
||||
"changePerms":"Change Permissions to find",
|
||||
"owner":"Find the owner","ownName":"Owner"
|
||||
},
|
||||
"viewTemplate": "View Template",
|
||||
"createFromTemplate": "Guild From Template",
|
||||
"tempUseCount": "Template has been used $1 {{PLURAL:$1|time|times}}",
|
||||
|
||||
Reference in New Issue
Block a user