invites menus

This commit is contained in:
MathMan05 2025-04-16 10:49:14 -05:00
parent 5963d6f43d
commit 38e3e13b26
5 changed files with 153 additions and 5 deletions

View file

@ -2,7 +2,7 @@
import {Message} from "./message.js";
import {AVoice} from "./audio/voice.js";
import {Contextmenu} from "./contextmenu.js";
import {Guild} from "./guild.js";
import {Guild, makeInviteMenu} from "./guild.js";
import {Localuser} from "./localuser.js";
import {Permissions} from "./permissions.js";
import {Dialog, Float, Settings} from "./settings.js";
@ -270,6 +270,9 @@ class Channel extends SnowFlake {
),
);
const inviteMenu = settings.addButton(I18n.guild.invites());
makeInviteMenu(inviteMenu, this.owner, this.info.api + `/channels/${this.id}/invites`);
const webhooks = settings.addButton(I18n.webhooks.base());
webhookMenu(this.guild, this.info.api + `/channels/${this.id}/webhooks`, webhooks, this.id);

View file

@ -24,7 +24,138 @@ import {webhookMenu} from "./webhooks.js";
import {createImg} from "./utils/utils.js";
import {Sticker} from "./sticker.js";
import {ProgessiveDecodeJSON} from "./utils/progessiveLoad.js";
export async function makeInviteMenu(inviteMenu: Options, guild: Guild, url: string) {
const invDiv = document.createElement("div");
const bansp = ProgessiveDecodeJSON<invitejson[]>(url, {
headers: guild.headers,
});
const createInviteHTML = (invite: invitejson) => {
const div = document.createElement("div");
div.classList.add("templateMiniBox");
const edit = document.createElement("button");
edit.textContent = I18n.edit();
const code = document.createElement("span");
code.textContent = invite.code;
const used = document.createElement("span");
used.textContent = I18n.invite.used(invite.uses + "");
edit.onclick = () => {
const opt = inviteMenu.addSubOptions(invite.code);
const inviter = new User(invite.inviter, guild.localuser);
opt.addMDText(
window.location.origin +
"/invite/" +
invite.code +
"?" +
new URLSearchParams([["instance", guild.info.wellknown]]),
);
opt.addText(I18n.invite.used(invite.uses + ""));
if (invite.max_uses !== 0) opt.addText(I18n.invite.maxUses(invite.max_uses + ""));
const channel = guild.channels.find((_) => _.id == invite.channel_id);
if (channel) {
opt.addText(I18n.invite.forChannel(channel.name));
}
opt.addText(I18n.invite.createdAt(new Date(invite.created_at).toLocaleDateString(I18n.lang)));
let expires = I18n.invite.never();
if (invite.expires_at) {
expires = new Date(invite.expires_at).toLocaleDateString(I18n.lang);
}
opt.addText(I18n.invite.expires(expires));
opt.addText(I18n.webhooks.createdBy());
opt.addHTMLArea(inviter.createWidget(guild));
opt.addButtonInput("", I18n.delete(), async () => {
if (
(
await fetch(guild.info.api + "/invites/" + invite.code, {
method: "DELETE",
headers: guild.headers,
})
).ok
) {
invsArr = invsArr.filter((_) => _ !== invite);
inviteMenu.returnFromSub();
loadPage(currentPage);
}
});
};
div.append(used, code, edit);
return div;
};
let invsArr: invitejson[] = [];
let onpage = 0;
async function loadArr() {
let invsArr2: invitejson[] = [];
let waiting = false;
async function addHTML() {
if (waiting) return;
waiting = true;
await new Promise((res) => setTimeout(res, 0));
waiting = false;
invDiv.append(...invsArr2.map((inv) => createInviteHTML(inv)));
invsArr2 = [];
}
while (!(await bansp).done) {
const inv = await (await (await bansp).getNext()).getWhole();
invsArr.push(inv);
if (onpage < 50) {
invsArr2.push(inv);
addHTML();
onpage++;
} else {
next.disabled = false;
}
}
}
let currentPage = 0;
function loadPage(page = 0) {
invDiv.innerHTML = "";
for (onpage = 0; onpage < 50; onpage++) {
const inv = invsArr[onpage + page * 50];
if (!inv) break;
invDiv.append(createInviteHTML(inv));
}
if (onpage === 50 && invsArr[onpage + page * 50]) {
next.disabled = false;
} else {
next.disabled = true;
}
}
const pageNav = document.createElement("div");
const back = document.createElement("button");
back.textContent = I18n.search.back();
back.disabled = !currentPage;
back.onclick = () => {
back.disabled = !(currentPage - 1);
next.disabled = false;
loadPage(--currentPage);
};
const next = document.createElement("button");
next.textContent = I18n.search.next();
next.disabled = true;
pageNav.append(back, next);
inviteMenu.addHTMLArea(pageNav);
next.onclick = () => {
loadPage(++currentPage);
back.disabled = false;
};
loadArr();
loadPage(currentPage);
inviteMenu.addHTMLArea(invDiv);
}
class Guild extends SnowFlake {
owner!: Localuser;
headers!: Localuser["headers"];
@ -426,6 +557,9 @@ class Guild extends SnowFlake {
genDiv();
emoji.addHTMLArea(containdiv);
}
const inviteMenu = settings.addButton(I18n.guild.invites());
makeInviteMenu(inviteMenu, this, this.info.api + `/guilds/${this.id}/invites`);
const banMenu = settings.addButton(I18n.guild.bans());
const makeBanMenu = () => {
const banDiv = document.createElement("div");

View file

@ -467,10 +467,10 @@ type invitejson = {
code: string;
temporary: boolean;
uses: number;
max_use: number;
max_uses: number;
max_age: number;
created_at: string;
expires_at: string;
expires_at: string | null;
guild_id: string;
channel_id: string;
inviter_id: string;

View file

@ -66,7 +66,10 @@ body {
border-radius: 4px;
width: fit-content;
background: var(--secondary-bg);
margin-bottom: 8px;
span {
margin-right: 4px;
}
button {
margin-left: 4px;
}

View file

@ -179,6 +179,7 @@
"createCatagory": "Create category",
"permissions": "Permissions"
},
"delete": "Delete",
"webhooks": {
"createdAt": "Created at $1",
"name": "Name:",
@ -259,6 +260,7 @@
"templateName": "Template Name:",
"templateDesc": "Template Description:",
"templcateMetaDesc": "A template allows others to use this guild as a base for their own guilds, it'll copy the channels, roles, and settings of this guild, but not the messages from within the guild, the bots, or the guilds icon.",
"invites": "Invites",
"templateNameShort": "Template name must at least be 2 characters long",
"templateURL": "Template URL: $1",
"bannedBy": "Banned by:",
@ -474,7 +476,13 @@
"expireAfter": "Expire after:",
"channel:": "Channel:",
"inviteMaker": "Invite Maker",
"createInvite": "Create invite"
"createInvite": "Create invite",
"used": "Used $1 {{PLURAL:$1|time|times}}.",
"forChannel": "For channel: $1",
"createdAt": "Created at $1",
"expires": "Expires: $1",
"never": "Never",
"maxUses": "Max uses: $1"
},
"friends": {
"blocked": "Blocked",