inital member list support
This commit is contained in:
parent
b2a31d7993
commit
a1902a912f
8 changed files with 501 additions and 288 deletions
|
@ -377,7 +377,10 @@ class Channel extends SnowFlake{
|
|||
if(member.isAdmin()){
|
||||
return true;
|
||||
}
|
||||
for(const thing of member.roles){
|
||||
const roles=new Set(member.roles);
|
||||
const everyone=this.guild.roles[this.guild.roles.length-1];
|
||||
roles.add(everyone)
|
||||
for(const thing of roles){
|
||||
const premission = this.permission_overwrites.get(thing.id);
|
||||
if(premission){
|
||||
const perm = premission.getPermission(name);
|
||||
|
@ -834,6 +837,7 @@ class Channel extends SnowFlake{
|
|||
Channel.regenLoadingMessages();
|
||||
loading.classList.add("loading");
|
||||
this.rendertyping();
|
||||
this.localuser.getSidePannel();
|
||||
await this.putmessages();
|
||||
await prom;
|
||||
if(id !== Channel.genid){
|
||||
|
|
|
@ -34,6 +34,7 @@ class Guild extends SnowFlake{
|
|||
html!: HTMLElement;
|
||||
emojis!: emojijson[];
|
||||
large!: boolean;
|
||||
members=new Set<Member>();
|
||||
static contextmenu = new Contextmenu<Guild, undefined>("guild menu");
|
||||
static setupcontextmenu(){
|
||||
Guild.contextmenu.addbutton("Copy Guild id", function(this: Guild){
|
||||
|
|
|
@ -56,27 +56,33 @@
|
|||
<span id="channelname">Channel name</span>
|
||||
<span id="channelTopic" hidden>Channel topic</span>
|
||||
</div>
|
||||
<div id="channelw">
|
||||
<div id="loadingdiv">
|
||||
</div>
|
||||
</div>
|
||||
<div id="pasteimage"></div>
|
||||
<div id="replybox" class="hideReplyBox"></div>
|
||||
<div id="typediv">
|
||||
<div id="realbox">
|
||||
<div id="typebox" contentEditable="true"></div>
|
||||
</div>
|
||||
<div id="typing" class="hidden">
|
||||
<p id="typingtext">typing</p>
|
||||
<div class="loading-indicator">
|
||||
<div class="dot"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="flexltr">
|
||||
<div class="flexttb">
|
||||
<div id="channelw">
|
||||
<div id="loadingdiv">
|
||||
</div>
|
||||
</div>
|
||||
<div id="pasteimage"></div>
|
||||
<div id="replybox" class="hideReplyBox"></div>
|
||||
<div id="typediv">
|
||||
<div id="realbox">
|
||||
<div id="typebox" contentEditable="true"></div>
|
||||
</div>
|
||||
<div id="typing" class="hidden">
|
||||
<p id="typingtext">typing</p>
|
||||
<div class="loading-indicator">
|
||||
<div class="dot"></div>
|
||||
<div class="dot"></div>
|
||||
<div class="dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flexttb" id="sideDiv">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -145,21 +145,22 @@ pronouns: string;
|
|||
badge_ids: string[];
|
||||
};
|
||||
type memberjson = {
|
||||
index?: number;
|
||||
id: string;
|
||||
user: userjson | null;
|
||||
guild_id: string;
|
||||
guild: {
|
||||
id: string;
|
||||
} | null;
|
||||
nick?: string;
|
||||
roles: string[];
|
||||
joined_at: string;
|
||||
premium_since: string;
|
||||
deaf: boolean;
|
||||
mute: boolean;
|
||||
pending: boolean;
|
||||
last_message_id?: boolean; //What???
|
||||
index?: number;
|
||||
id: string;
|
||||
user: userjson | null;
|
||||
guild_id: string;
|
||||
guild: {
|
||||
id: string;
|
||||
} | null;
|
||||
presence?:presencejson
|
||||
nick?: string;
|
||||
roles: string[];
|
||||
joined_at: string;
|
||||
premium_since: string;
|
||||
deaf: boolean;
|
||||
mute: boolean;
|
||||
pending: boolean;
|
||||
last_message_id?: boolean; //What???
|
||||
};
|
||||
type emojijson = {
|
||||
name: string;
|
||||
|
@ -257,18 +258,18 @@ default_thread_rate_limit_per_user: number;
|
|||
position: number;
|
||||
};
|
||||
type rolesjson = {
|
||||
id: string;
|
||||
guild_id: string;
|
||||
color: number;
|
||||
hoist: boolean;
|
||||
managed: boolean;
|
||||
mentionable: boolean;
|
||||
name: string;
|
||||
permissions: string;
|
||||
position: number;
|
||||
icon: string;
|
||||
unicode_emoji: string;
|
||||
flags: number;
|
||||
id: string;
|
||||
guild_id: string;
|
||||
color: number;
|
||||
hoist: boolean;
|
||||
managed: boolean;
|
||||
mentionable: boolean;
|
||||
name: string;
|
||||
permissions: string;
|
||||
position: number;
|
||||
icon: string;
|
||||
unicode_emoji: string;
|
||||
flags: number;
|
||||
};
|
||||
type dirrectjson = {
|
||||
id: string;
|
||||
|
@ -392,20 +393,20 @@ t: "MESSAGE_CREATE";
|
|||
};
|
||||
type wsjson =
|
||||
| {
|
||||
op: 0;
|
||||
d: any;
|
||||
s: number;
|
||||
t:
|
||||
| "TYPING_START"
|
||||
| "USER_UPDATE"
|
||||
| "CHANNEL_UPDATE"
|
||||
| "CHANNEL_CREATE"
|
||||
| "CHANNEL_DELETE"
|
||||
| "GUILD_DELETE"
|
||||
| "GUILD_CREATE"
|
||||
| "MESSAGE_REACTION_REMOVE_ALL"
|
||||
| "MESSAGE_REACTION_REMOVE_EMOJI";
|
||||
}
|
||||
op: 0;
|
||||
d: any;
|
||||
s: number;
|
||||
t:
|
||||
| "TYPING_START"
|
||||
| "USER_UPDATE"
|
||||
| "CHANNEL_UPDATE"
|
||||
| "CHANNEL_CREATE"
|
||||
| "CHANNEL_DELETE"
|
||||
| "GUILD_DELETE"
|
||||
| "GUILD_CREATE"
|
||||
| "MESSAGE_REACTION_REMOVE_ALL"
|
||||
| "MESSAGE_REACTION_REMOVE_EMOJI";
|
||||
}
|
||||
| {
|
||||
op: 0;
|
||||
t: "GUILD_MEMBERS_CHUNK";
|
||||
|
@ -469,7 +470,7 @@ guild_id: string;
|
|||
emoji: emojijson;
|
||||
};
|
||||
s: 3;
|
||||
};
|
||||
}|memberlistupdatejson;
|
||||
type memberChunk = {
|
||||
guild_id: string;
|
||||
nonce: string;
|
||||
|
@ -479,6 +480,39 @@ chunk_index: number;
|
|||
chunk_count: number;
|
||||
not_found: string[];
|
||||
};
|
||||
|
||||
type memberlistupdatejson={
|
||||
op: 0,
|
||||
s: number,
|
||||
t: "GUILD_MEMBER_LIST_UPDATE",
|
||||
d: {
|
||||
ops: [
|
||||
{
|
||||
items:({
|
||||
group:{
|
||||
count:number,
|
||||
id:string
|
||||
}
|
||||
}|{
|
||||
member:memberjson
|
||||
})[]
|
||||
op: "SYNC",
|
||||
range: [
|
||||
number,
|
||||
number
|
||||
]
|
||||
}
|
||||
],
|
||||
online_count: number,
|
||||
member_count: number,
|
||||
id: string,
|
||||
guild_id: string,
|
||||
groups: {
|
||||
count: number,
|
||||
id: string
|
||||
}[]
|
||||
}
|
||||
}
|
||||
export{
|
||||
readyjson,
|
||||
dirrectjson,
|
||||
|
@ -498,4 +532,5 @@ export{
|
|||
messageCreateJson,
|
||||
memberChunk,
|
||||
invitejson,
|
||||
memberlistupdatejson
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ import{
|
|||
guildjson,
|
||||
mainuserjson,
|
||||
memberjson,
|
||||
memberlistupdatejson,
|
||||
messageCreateJson,
|
||||
presencejson,
|
||||
readyjson,
|
||||
|
@ -20,6 +21,7 @@ import{ Member }from"./member.js";
|
|||
import{ Form, FormError, Options, Settings }from"./settings.js";
|
||||
import{ MarkDown }from"./markdown.js";
|
||||
import { Bot } from "./bot.js";
|
||||
import { Role } from "./role.js";
|
||||
|
||||
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
|
||||
|
||||
|
@ -479,7 +481,13 @@ class Localuser{
|
|||
case"GUILD_MEMBERS_CHUNK":
|
||||
this.gotChunk(temp.d);
|
||||
break;
|
||||
case"GUILD_MEMBER_LIST_UPDATE":
|
||||
{
|
||||
this.memberListUpdate(temp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}else if(temp.op === 10){
|
||||
if(!this.ws)return;
|
||||
console.log("heartbeat down");
|
||||
|
@ -518,6 +526,108 @@ class Localuser{
|
|||
}
|
||||
return channel; // Add this line to return the 'channel' variable
|
||||
}
|
||||
async memberListUpdate(list:memberlistupdatejson){
|
||||
const div=document.getElementById("sideDiv") as HTMLDivElement;
|
||||
div.innerHTML="";
|
||||
const counts=new Map<string,number>();
|
||||
const guild=this.lookingguild;
|
||||
if(!guild) return;
|
||||
const channel=this.channelfocus;
|
||||
if(!channel) return;
|
||||
for(const thing of list.d.ops[0].items){
|
||||
if("member" in thing){
|
||||
await Member.new(thing.member,guild);
|
||||
}else{
|
||||
counts.set(thing.group.id,thing.group.count);
|
||||
}
|
||||
}
|
||||
|
||||
const elms:Map<Role|"offline"|"online",Member[]>=new Map([["offline",[]],["online",[]]]);
|
||||
for(const role of guild.roles){
|
||||
console.log(guild.roles);
|
||||
if(role.hoist){
|
||||
elms.set(role,[]);
|
||||
}
|
||||
}
|
||||
const members=new Set(guild.members);
|
||||
members.forEach((member)=>{
|
||||
if(!channel.hasPermission("VIEW_CHANNEL",member)){
|
||||
members.delete(member);
|
||||
console.log(member)
|
||||
return;
|
||||
}
|
||||
})
|
||||
for(const [role, list] of elms){
|
||||
members.forEach((member)=>{
|
||||
if(role === "offline"){
|
||||
if(member.user.status === "offline"){
|
||||
list.push(member);
|
||||
members.delete(member);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(role !== "online"&&member.hasRole(role.id)){
|
||||
list.push(member);
|
||||
members.delete(member);
|
||||
}
|
||||
});
|
||||
if(!list.length) continue;
|
||||
list.sort((a,b)=>{
|
||||
return (a.name.toLowerCase()>b.name.toLowerCase())?1:-1;
|
||||
});
|
||||
}
|
||||
const online=[...members];
|
||||
online.sort((a,b)=>{
|
||||
return (a.name.toLowerCase()>b.name.toLowerCase())?1:-1;
|
||||
});
|
||||
elms.set("online",online);
|
||||
for(const [role, list] of elms){
|
||||
if(!list.length) continue;
|
||||
const category=document.createElement("div");
|
||||
category.classList.add("memberList");
|
||||
let title=document.createElement("h3");
|
||||
if(role==="offline"){
|
||||
title.textContent="Offline";
|
||||
category.classList.add("offline");
|
||||
}else if(role==="online"){
|
||||
title.textContent="Online";
|
||||
}else{
|
||||
title.textContent=role.name;
|
||||
}
|
||||
category.append(title);
|
||||
const membershtml=document.createElement("div");
|
||||
membershtml.classList.add("flexttb");
|
||||
|
||||
for(const member of list){
|
||||
const memberdiv=document.createElement("div");
|
||||
const pfp=member.user.buildpfp();
|
||||
const username=document.createElement("span");
|
||||
username.textContent=member.name;
|
||||
member.bind(username)
|
||||
member.user.bind(memberdiv,member.guild,false);
|
||||
memberdiv.append(pfp,username);
|
||||
memberdiv.classList.add("flexltr");
|
||||
membershtml.append(memberdiv);
|
||||
}
|
||||
category.append(membershtml);
|
||||
div.prepend(category);
|
||||
}
|
||||
|
||||
console.log(elms);
|
||||
}
|
||||
async getSidePannel(){
|
||||
if(this.ws&&this.channelfocus){
|
||||
this.ws.send(JSON.stringify({
|
||||
d:{
|
||||
channels:{[this.channelfocus.id]:[[0,99]]},
|
||||
guild_id:this.channelfocus.guild.id
|
||||
},
|
||||
op:14
|
||||
}))
|
||||
}else{
|
||||
console.log("false? :3")
|
||||
}
|
||||
}
|
||||
gotoid: string | undefined;
|
||||
async goToChannel(id: string){
|
||||
const channel = this.channelids.get(id);
|
||||
|
|
|
@ -11,246 +11,254 @@ class Member extends SnowFlake{
|
|||
user: User;
|
||||
roles: Role[] = [];
|
||||
nick!: string;
|
||||
[key: string]: any;
|
||||
|
||||
private constructor(memberjson: memberjson, owner: Guild){
|
||||
super(memberjson.id);
|
||||
this.owner = owner;
|
||||
if(this.localuser.userMap.has(memberjson.id)){
|
||||
this.user = this.localuser.userMap.get(memberjson.id) as User;
|
||||
}else if(memberjson.user){
|
||||
this.user = new User(memberjson.user, owner.localuser);
|
||||
}else{
|
||||
throw new Error("Missing user object of this member");
|
||||
}
|
||||
|
||||
for(const key of Object.keys(memberjson)){
|
||||
if(key === "guild" || key === "owner"){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(key === "roles"){
|
||||
for(const strrole of memberjson.roles){
|
||||
const role = this.guild.roleids.get(strrole);
|
||||
if(!role)continue;
|
||||
this.roles.push(role);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
(this as any)[key] = (memberjson as any)[key];
|
||||
}
|
||||
if(this.localuser.userMap.has(this?.id)){
|
||||
this.user = this.localuser.userMap.get(this?.id) as User;
|
||||
}
|
||||
this.roles.sort((a, b)=>{
|
||||
return this.guild.roles.indexOf(a) - this.guild.roles.indexOf(b);
|
||||
});
|
||||
}
|
||||
get guild(){
|
||||
return this.owner;
|
||||
}
|
||||
get localuser(){
|
||||
return this.guild.localuser;
|
||||
}
|
||||
get info(){
|
||||
return this.owner.info;
|
||||
}
|
||||
static async new(
|
||||
memberjson: memberjson,
|
||||
owner: Guild
|
||||
): Promise<Member | undefined>{
|
||||
let user: User;
|
||||
if(owner.localuser.userMap.has(memberjson.id)){
|
||||
user = owner.localuser.userMap.get(memberjson.id) as User;
|
||||
}else if(memberjson.user){
|
||||
user = new User(memberjson.user, owner.localuser);
|
||||
}else{
|
||||
throw new Error("missing user object of this member");
|
||||
}
|
||||
if(user.members.has(owner)){
|
||||
let memb = user.members.get(owner);
|
||||
if(memb === undefined){
|
||||
memb = new Member(memberjson, owner);
|
||||
user.members.set(owner, memb);
|
||||
return memb;
|
||||
}else if(memb instanceof Promise){
|
||||
return await memb; //I should do something else, though for now this is "good enough"
|
||||
private constructor(memberjson: memberjson, owner: Guild){
|
||||
super(memberjson.id);
|
||||
this.owner = owner;
|
||||
if(this.localuser.userMap.has(memberjson.id)){
|
||||
this.user = this.localuser.userMap.get(memberjson.id) as User;
|
||||
}else if(memberjson.user){
|
||||
this.user = new User(memberjson.user, owner.localuser);
|
||||
}else{
|
||||
throw new Error("Missing user object of this member");
|
||||
}
|
||||
if(this.localuser.userMap.has(this?.id)){
|
||||
this.user = this.localuser.userMap.get(this?.id) as User;
|
||||
}
|
||||
for(const key of Object.keys(memberjson)){
|
||||
if(key === "guild" || key === "owner" || key === "user"){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(key === "roles"){
|
||||
for(const strrole of memberjson.roles){
|
||||
const role = this.guild.roleids.get(strrole);
|
||||
if(!role)continue;
|
||||
this.roles.push(role);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(key === "presence"){
|
||||
this.getPresence(memberjson.presence);
|
||||
continue;
|
||||
}
|
||||
(this as any)[key] = (memberjson as any)[key];
|
||||
}
|
||||
|
||||
this.roles.sort((a, b)=>{
|
||||
return this.guild.roles.indexOf(a) - this.guild.roles.indexOf(b);
|
||||
});
|
||||
}
|
||||
get guild(){
|
||||
return this.owner;
|
||||
}
|
||||
get localuser(){
|
||||
return this.guild.localuser;
|
||||
}
|
||||
get info(){
|
||||
return this.owner.info;
|
||||
}
|
||||
static async new(
|
||||
memberjson: memberjson,
|
||||
owner: Guild
|
||||
): Promise<Member | undefined>{
|
||||
let user: User;
|
||||
if(owner.localuser.userMap.has(memberjson.id)){
|
||||
user = owner.localuser.userMap.get(memberjson.id) as User;
|
||||
}else if(memberjson.user){
|
||||
user = new User(memberjson.user, owner.localuser);
|
||||
}else{
|
||||
throw new Error("missing user object of this member");
|
||||
}
|
||||
if(user.members.has(owner)){
|
||||
let memb = user.members.get(owner);
|
||||
if(memb === undefined){
|
||||
memb = new Member(memberjson, owner);
|
||||
user.members.set(owner, memb);
|
||||
owner.members.add(memb);
|
||||
return memb;
|
||||
}else if(memb instanceof Promise){
|
||||
return await memb; //I should do something else, though for now this is "good enough"
|
||||
}else{
|
||||
if(memberjson.presence){
|
||||
memb.getPresence(memberjson.presence);
|
||||
}
|
||||
return memb;
|
||||
}
|
||||
}else{
|
||||
const memb = new Member(memberjson, owner);
|
||||
user.members.set(owner, memb);
|
||||
owner.members.add(memb);
|
||||
return memb;
|
||||
}
|
||||
}else{
|
||||
const memb = new Member(memberjson, owner);
|
||||
user.members.set(owner, memb);
|
||||
return memb;
|
||||
}
|
||||
}
|
||||
static async resolveMember(
|
||||
user: User,
|
||||
guild: Guild
|
||||
): Promise<Member | undefined>{
|
||||
const maybe = user.members.get(guild);
|
||||
if(!user.members.has(guild)){
|
||||
const membpromise = guild.localuser.resolvemember(user.id, guild.id);
|
||||
const promise = new Promise<Member | undefined>(async res=>{
|
||||
const membjson = await membpromise;
|
||||
if(membjson === undefined){
|
||||
return res(undefined);
|
||||
}else{
|
||||
const member = new Member(membjson, guild);
|
||||
const map = guild.localuser.presences;
|
||||
member.getPresence(map.get(member.id));
|
||||
map.delete(member.id);
|
||||
res(member);
|
||||
return member;
|
||||
static async resolveMember(
|
||||
user: User,
|
||||
guild: Guild
|
||||
): Promise<Member | undefined>{
|
||||
const maybe = user.members.get(guild);
|
||||
if(!user.members.has(guild)){
|
||||
const membpromise = guild.localuser.resolvemember(user.id, guild.id);
|
||||
const promise = new Promise<Member | undefined>(async res=>{
|
||||
const membjson = await membpromise;
|
||||
if(membjson === undefined){
|
||||
return res(undefined);
|
||||
}else{
|
||||
const member = new Member(membjson, guild);
|
||||
const map = guild.localuser.presences;
|
||||
member.getPresence(map.get(member.id));
|
||||
map.delete(member.id);
|
||||
res(member);
|
||||
return member;
|
||||
}
|
||||
});
|
||||
user.members.set(guild, promise);
|
||||
}
|
||||
if(maybe instanceof Promise){
|
||||
return await maybe;
|
||||
}else{
|
||||
return maybe;
|
||||
}
|
||||
}
|
||||
public getPresence(presence: presencejson | undefined){
|
||||
this.user.getPresence(presence);
|
||||
}
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
highInfo(){
|
||||
fetch(
|
||||
this.info.api +
|
||||
"/users/" +
|
||||
this.id +
|
||||
"/profile?with_mutual_guilds=true&with_mutual_friends_count=true&guild_id=" +
|
||||
this.guild.id,
|
||||
{ headers: this.guild.headers }
|
||||
);
|
||||
}
|
||||
hasRole(ID: string){
|
||||
console.log(this.roles, ID);
|
||||
for(const thing of this.roles){
|
||||
if(thing.id === ID){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getColor(){
|
||||
for(const thing of this.roles){
|
||||
const color = thing.getColor();
|
||||
if(color){
|
||||
return color;
|
||||
}
|
||||
}
|
||||
return"";
|
||||
}
|
||||
isAdmin(){
|
||||
for(const role of this.roles){
|
||||
if(role.permissions.getPermission("ADMINISTRATOR")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.guild.properties.owner_id === this.user.id;
|
||||
}
|
||||
bind(html: HTMLElement){
|
||||
if(html.tagName === "SPAN"){
|
||||
if(!this){
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(this.error){
|
||||
|
||||
}
|
||||
*/
|
||||
html.style.color = this.getColor();
|
||||
}
|
||||
|
||||
//this.profileclick(html);
|
||||
}
|
||||
profileclick(/* html: HTMLElement */){
|
||||
//to be implemented
|
||||
}
|
||||
get name(){
|
||||
return this.nick || this.user.username;
|
||||
}
|
||||
kick(){
|
||||
let reason = "";
|
||||
const menu = new Dialog([
|
||||
"vdiv",
|
||||
["title", "Kick " + this.name + " from " + this.guild.properties.name],
|
||||
[
|
||||
"textbox",
|
||||
"Reason:",
|
||||
"",
|
||||
function(e: Event){
|
||||
reason = (e.target as HTMLInputElement).value;
|
||||
},
|
||||
],
|
||||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
()=>{
|
||||
this.kickAPI(reason);
|
||||
menu.hide();
|
||||
},
|
||||
],
|
||||
]);
|
||||
menu.show();
|
||||
}
|
||||
kickAPI(reason: string){
|
||||
const headers = structuredClone(this.guild.headers);
|
||||
(headers as any)["x-audit-log-reason"] = reason;
|
||||
fetch(`${this.info.api}/guilds/${this.guild.id}/members/${this.id}`, {
|
||||
method: "DELETE",
|
||||
headers,
|
||||
});
|
||||
user.members.set(guild, promise);
|
||||
}
|
||||
if(maybe instanceof Promise){
|
||||
return await maybe;
|
||||
}else{
|
||||
return maybe;
|
||||
ban(){
|
||||
let reason = "";
|
||||
const menu = new Dialog([
|
||||
"vdiv",
|
||||
["title", "Ban " + this.name + " from " + this.guild.properties.name],
|
||||
[
|
||||
"textbox",
|
||||
"Reason:",
|
||||
"",
|
||||
function(e: Event){
|
||||
reason = (e.target as HTMLInputElement).value;
|
||||
},
|
||||
],
|
||||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
()=>{
|
||||
this.banAPI(reason);
|
||||
menu.hide();
|
||||
},
|
||||
],
|
||||
]);
|
||||
menu.show();
|
||||
}
|
||||
}
|
||||
public getPresence(presence: presencejson | undefined){
|
||||
this.user.getPresence(presence);
|
||||
}
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
highInfo(){
|
||||
fetch(
|
||||
this.info.api +
|
||||
"/users/" +
|
||||
this.id +
|
||||
"/profile?with_mutual_guilds=true&with_mutual_friends_count=true&guild_id=" +
|
||||
this.guild.id,
|
||||
{ headers: this.guild.headers }
|
||||
);
|
||||
}
|
||||
hasRole(ID: string){
|
||||
console.log(this.roles, ID);
|
||||
for(const thing of this.roles){
|
||||
if(thing.id === ID){
|
||||
banAPI(reason: string){
|
||||
const headers = structuredClone(this.guild.headers);
|
||||
(headers as any)["x-audit-log-reason"] = reason;
|
||||
fetch(`${this.info.api}/guilds/${this.guild.id}/bans/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers,
|
||||
});
|
||||
}
|
||||
hasPermission(name: string): boolean{
|
||||
if(this.isAdmin()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
getColor(){
|
||||
for(const thing of this.roles){
|
||||
const color = thing.getColor();
|
||||
if(color){
|
||||
return color;
|
||||
}
|
||||
}
|
||||
return"";
|
||||
}
|
||||
isAdmin(){
|
||||
for(const role of this.roles){
|
||||
if(role.permissions.getPermission("ADMINISTRATOR")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.guild.properties.owner_id === this.user.id;
|
||||
}
|
||||
bind(html: HTMLElement){
|
||||
if(html.tagName === "SPAN"){
|
||||
if(!this){
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(this.error){
|
||||
|
||||
for(const thing of this.roles){
|
||||
if(thing.permissions.getPermission(name)){
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
html.style.color = this.getColor();
|
||||
}
|
||||
|
||||
//this.profileclick(html);
|
||||
}
|
||||
profileclick(/* html: HTMLElement */){
|
||||
//to be implemented
|
||||
}
|
||||
get name(){
|
||||
return this.nick || this.user.username;
|
||||
}
|
||||
kick(){
|
||||
let reason = "";
|
||||
const menu = new Dialog([
|
||||
"vdiv",
|
||||
["title", "Kick " + this.name + " from " + this.guild.properties.name],
|
||||
[
|
||||
"textbox",
|
||||
"Reason:",
|
||||
"",
|
||||
function(e: Event){
|
||||
reason = (e.target as HTMLInputElement).value;
|
||||
},
|
||||
],
|
||||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
()=>{
|
||||
this.kickAPI(reason);
|
||||
menu.hide();
|
||||
},
|
||||
],
|
||||
]);
|
||||
menu.show();
|
||||
}
|
||||
kickAPI(reason: string){
|
||||
const headers = structuredClone(this.guild.headers);
|
||||
(headers as any)["x-audit-log-reason"] = reason;
|
||||
fetch(`${this.info.api}/guilds/${this.guild.id}/members/${this.id}`, {
|
||||
method: "DELETE",
|
||||
headers,
|
||||
});
|
||||
}
|
||||
ban(){
|
||||
let reason = "";
|
||||
const menu = new Dialog([
|
||||
"vdiv",
|
||||
["title", "Ban " + this.name + " from " + this.guild.properties.name],
|
||||
[
|
||||
"textbox",
|
||||
"Reason:",
|
||||
"",
|
||||
function(e: Event){
|
||||
reason = (e.target as HTMLInputElement).value;
|
||||
},
|
||||
],
|
||||
[
|
||||
"button",
|
||||
"",
|
||||
"submit",
|
||||
()=>{
|
||||
this.banAPI(reason);
|
||||
menu.hide();
|
||||
},
|
||||
],
|
||||
]);
|
||||
menu.show();
|
||||
}
|
||||
banAPI(reason: string){
|
||||
const headers = structuredClone(this.guild.headers);
|
||||
(headers as any)["x-audit-log-reason"] = reason;
|
||||
fetch(`${this.info.api}/guilds/${this.guild.id}/bans/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers,
|
||||
});
|
||||
}
|
||||
hasPermission(name: string): boolean{
|
||||
if(this.isAdmin()){
|
||||
return true;
|
||||
}
|
||||
for(const thing of this.roles){
|
||||
if(thing.permissions.getPermission(name)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export{ Member };
|
||||
|
|
|
@ -1379,6 +1379,7 @@ span {
|
|||
width: 100%;
|
||||
height: 100dvh;
|
||||
align-content: space-around;
|
||||
align-items: stretch;
|
||||
}
|
||||
.userflex{
|
||||
display:flex;
|
||||
|
@ -2219,3 +2220,51 @@ form div{
|
|||
.mentionMD:hover{
|
||||
background:color-mix(in srgb,var(--mention-md-bg),white 10%);
|
||||
}
|
||||
#sideDiv{
|
||||
flex-grow:0;
|
||||
flex-shrink:0;
|
||||
width:2.5in;
|
||||
box-shadow: -.02in 0 .04in black;
|
||||
&:empty{
|
||||
width:0in;
|
||||
}
|
||||
;
|
||||
align-items: stretch;
|
||||
/* overflow-x: hidden; */
|
||||
overflow-y: unset;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.memberList{
|
||||
padding:.05in;
|
||||
>div{
|
||||
width: 100%;
|
||||
>div{
|
||||
width:100%;
|
||||
padding:.04in .02in;
|
||||
margin: .01in 0.0in;
|
||||
border-radius:.1in;
|
||||
&:hover{
|
||||
background:var(--message-bg-hover);
|
||||
}
|
||||
flex-shrink: 1;
|
||||
cursor: pointer;
|
||||
box-sizing:border-box;
|
||||
gap:.05in;
|
||||
align-items: center;
|
||||
}
|
||||
img{
|
||||
width:40px;
|
||||
height:40px;
|
||||
}
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
.offline{
|
||||
h3{
|
||||
color:var(--primary-text)
|
||||
}
|
||||
>div{
|
||||
opacity:.4;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ class User extends SnowFlake{
|
|||
badge_ids!: string[];
|
||||
members: WeakMap<Guild, Member | undefined | Promise<Member | undefined>> =
|
||||
new WeakMap();
|
||||
private status!: string;
|
||||
status!: string;
|
||||
resolving: false | Promise<any> = false;
|
||||
|
||||
constructor(userjson: userjson, owner: Localuser, dontclone = false){
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue