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()){
|
if(member.isAdmin()){
|
||||||
return true;
|
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);
|
const premission = this.permission_overwrites.get(thing.id);
|
||||||
if(premission){
|
if(premission){
|
||||||
const perm = premission.getPermission(name);
|
const perm = premission.getPermission(name);
|
||||||
|
@ -834,6 +837,7 @@ class Channel extends SnowFlake{
|
||||||
Channel.regenLoadingMessages();
|
Channel.regenLoadingMessages();
|
||||||
loading.classList.add("loading");
|
loading.classList.add("loading");
|
||||||
this.rendertyping();
|
this.rendertyping();
|
||||||
|
this.localuser.getSidePannel();
|
||||||
await this.putmessages();
|
await this.putmessages();
|
||||||
await prom;
|
await prom;
|
||||||
if(id !== Channel.genid){
|
if(id !== Channel.genid){
|
||||||
|
|
|
@ -34,6 +34,7 @@ class Guild extends SnowFlake{
|
||||||
html!: HTMLElement;
|
html!: HTMLElement;
|
||||||
emojis!: emojijson[];
|
emojis!: emojijson[];
|
||||||
large!: boolean;
|
large!: boolean;
|
||||||
|
members=new Set<Member>();
|
||||||
static contextmenu = new Contextmenu<Guild, undefined>("guild menu");
|
static contextmenu = new Contextmenu<Guild, undefined>("guild menu");
|
||||||
static setupcontextmenu(){
|
static setupcontextmenu(){
|
||||||
Guild.contextmenu.addbutton("Copy Guild id", function(this: Guild){
|
Guild.contextmenu.addbutton("Copy Guild id", function(this: Guild){
|
||||||
|
|
|
@ -56,27 +56,33 @@
|
||||||
<span id="channelname">Channel name</span>
|
<span id="channelname">Channel name</span>
|
||||||
<span id="channelTopic" hidden>Channel topic</span>
|
<span id="channelTopic" hidden>Channel topic</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="channelw">
|
<div class="flexltr">
|
||||||
<div id="loadingdiv">
|
<div class="flexttb">
|
||||||
</div>
|
<div id="channelw">
|
||||||
</div>
|
<div id="loadingdiv">
|
||||||
<div id="pasteimage"></div>
|
</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 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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -145,21 +145,22 @@ pronouns: string;
|
||||||
badge_ids: string[];
|
badge_ids: string[];
|
||||||
};
|
};
|
||||||
type memberjson = {
|
type memberjson = {
|
||||||
index?: number;
|
index?: number;
|
||||||
id: string;
|
id: string;
|
||||||
user: userjson | null;
|
user: userjson | null;
|
||||||
guild_id: string;
|
guild_id: string;
|
||||||
guild: {
|
guild: {
|
||||||
id: string;
|
id: string;
|
||||||
} | null;
|
} | null;
|
||||||
nick?: string;
|
presence?:presencejson
|
||||||
roles: string[];
|
nick?: string;
|
||||||
joined_at: string;
|
roles: string[];
|
||||||
premium_since: string;
|
joined_at: string;
|
||||||
deaf: boolean;
|
premium_since: string;
|
||||||
mute: boolean;
|
deaf: boolean;
|
||||||
pending: boolean;
|
mute: boolean;
|
||||||
last_message_id?: boolean; //What???
|
pending: boolean;
|
||||||
|
last_message_id?: boolean; //What???
|
||||||
};
|
};
|
||||||
type emojijson = {
|
type emojijson = {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -257,18 +258,18 @@ default_thread_rate_limit_per_user: number;
|
||||||
position: number;
|
position: number;
|
||||||
};
|
};
|
||||||
type rolesjson = {
|
type rolesjson = {
|
||||||
id: string;
|
id: string;
|
||||||
guild_id: string;
|
guild_id: string;
|
||||||
color: number;
|
color: number;
|
||||||
hoist: boolean;
|
hoist: boolean;
|
||||||
managed: boolean;
|
managed: boolean;
|
||||||
mentionable: boolean;
|
mentionable: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
permissions: string;
|
permissions: string;
|
||||||
position: number;
|
position: number;
|
||||||
icon: string;
|
icon: string;
|
||||||
unicode_emoji: string;
|
unicode_emoji: string;
|
||||||
flags: number;
|
flags: number;
|
||||||
};
|
};
|
||||||
type dirrectjson = {
|
type dirrectjson = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -392,20 +393,20 @@ t: "MESSAGE_CREATE";
|
||||||
};
|
};
|
||||||
type wsjson =
|
type wsjson =
|
||||||
| {
|
| {
|
||||||
op: 0;
|
op: 0;
|
||||||
d: any;
|
d: any;
|
||||||
s: number;
|
s: number;
|
||||||
t:
|
t:
|
||||||
| "TYPING_START"
|
| "TYPING_START"
|
||||||
| "USER_UPDATE"
|
| "USER_UPDATE"
|
||||||
| "CHANNEL_UPDATE"
|
| "CHANNEL_UPDATE"
|
||||||
| "CHANNEL_CREATE"
|
| "CHANNEL_CREATE"
|
||||||
| "CHANNEL_DELETE"
|
| "CHANNEL_DELETE"
|
||||||
| "GUILD_DELETE"
|
| "GUILD_DELETE"
|
||||||
| "GUILD_CREATE"
|
| "GUILD_CREATE"
|
||||||
| "MESSAGE_REACTION_REMOVE_ALL"
|
| "MESSAGE_REACTION_REMOVE_ALL"
|
||||||
| "MESSAGE_REACTION_REMOVE_EMOJI";
|
| "MESSAGE_REACTION_REMOVE_EMOJI";
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
op: 0;
|
op: 0;
|
||||||
t: "GUILD_MEMBERS_CHUNK";
|
t: "GUILD_MEMBERS_CHUNK";
|
||||||
|
@ -469,7 +470,7 @@ guild_id: string;
|
||||||
emoji: emojijson;
|
emoji: emojijson;
|
||||||
};
|
};
|
||||||
s: 3;
|
s: 3;
|
||||||
};
|
}|memberlistupdatejson;
|
||||||
type memberChunk = {
|
type memberChunk = {
|
||||||
guild_id: string;
|
guild_id: string;
|
||||||
nonce: string;
|
nonce: string;
|
||||||
|
@ -479,6 +480,39 @@ chunk_index: number;
|
||||||
chunk_count: number;
|
chunk_count: number;
|
||||||
not_found: string[];
|
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{
|
export{
|
||||||
readyjson,
|
readyjson,
|
||||||
dirrectjson,
|
dirrectjson,
|
||||||
|
@ -498,4 +532,5 @@ export{
|
||||||
messageCreateJson,
|
messageCreateJson,
|
||||||
memberChunk,
|
memberChunk,
|
||||||
invitejson,
|
invitejson,
|
||||||
|
memberlistupdatejson
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ import{
|
||||||
guildjson,
|
guildjson,
|
||||||
mainuserjson,
|
mainuserjson,
|
||||||
memberjson,
|
memberjson,
|
||||||
|
memberlistupdatejson,
|
||||||
messageCreateJson,
|
messageCreateJson,
|
||||||
presencejson,
|
presencejson,
|
||||||
readyjson,
|
readyjson,
|
||||||
|
@ -20,6 +21,7 @@ import{ Member }from"./member.js";
|
||||||
import{ Form, FormError, Options, Settings }from"./settings.js";
|
import{ Form, FormError, Options, Settings }from"./settings.js";
|
||||||
import{ MarkDown }from"./markdown.js";
|
import{ MarkDown }from"./markdown.js";
|
||||||
import { Bot } from "./bot.js";
|
import { Bot } from "./bot.js";
|
||||||
|
import { Role } from "./role.js";
|
||||||
|
|
||||||
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
|
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
|
||||||
|
|
||||||
|
@ -479,7 +481,13 @@ class Localuser{
|
||||||
case"GUILD_MEMBERS_CHUNK":
|
case"GUILD_MEMBERS_CHUNK":
|
||||||
this.gotChunk(temp.d);
|
this.gotChunk(temp.d);
|
||||||
break;
|
break;
|
||||||
|
case"GUILD_MEMBER_LIST_UPDATE":
|
||||||
|
{
|
||||||
|
this.memberListUpdate(temp)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}else if(temp.op === 10){
|
}else if(temp.op === 10){
|
||||||
if(!this.ws)return;
|
if(!this.ws)return;
|
||||||
console.log("heartbeat down");
|
console.log("heartbeat down");
|
||||||
|
@ -518,6 +526,108 @@ class Localuser{
|
||||||
}
|
}
|
||||||
return channel; // Add this line to return the 'channel' variable
|
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;
|
gotoid: string | undefined;
|
||||||
async goToChannel(id: string){
|
async goToChannel(id: string){
|
||||||
const channel = this.channelids.get(id);
|
const channel = this.channelids.get(id);
|
||||||
|
|
|
@ -11,246 +11,254 @@ class Member extends SnowFlake{
|
||||||
user: User;
|
user: User;
|
||||||
roles: Role[] = [];
|
roles: Role[] = [];
|
||||||
nick!: string;
|
nick!: string;
|
||||||
[key: string]: any;
|
|
||||||
|
|
||||||
private constructor(memberjson: memberjson, owner: Guild){
|
private constructor(memberjson: memberjson, owner: Guild){
|
||||||
super(memberjson.id);
|
super(memberjson.id);
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
if(this.localuser.userMap.has(memberjson.id)){
|
if(this.localuser.userMap.has(memberjson.id)){
|
||||||
this.user = this.localuser.userMap.get(memberjson.id) as User;
|
this.user = this.localuser.userMap.get(memberjson.id) as User;
|
||||||
}else if(memberjson.user){
|
}else if(memberjson.user){
|
||||||
this.user = new User(memberjson.user, owner.localuser);
|
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"
|
|
||||||
}else{
|
}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;
|
return memb;
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
const memb = new Member(memberjson, owner);
|
|
||||||
user.members.set(owner, memb);
|
|
||||||
return memb;
|
|
||||||
}
|
}
|
||||||
}
|
static async resolveMember(
|
||||||
static async resolveMember(
|
user: User,
|
||||||
user: User,
|
guild: Guild
|
||||||
guild: Guild
|
): Promise<Member | undefined>{
|
||||||
): Promise<Member | undefined>{
|
const maybe = user.members.get(guild);
|
||||||
const maybe = user.members.get(guild);
|
if(!user.members.has(guild)){
|
||||||
if(!user.members.has(guild)){
|
const membpromise = guild.localuser.resolvemember(user.id, guild.id);
|
||||||
const membpromise = guild.localuser.resolvemember(user.id, guild.id);
|
const promise = new Promise<Member | undefined>(async res=>{
|
||||||
const promise = new Promise<Member | undefined>(async res=>{
|
const membjson = await membpromise;
|
||||||
const membjson = await membpromise;
|
if(membjson === undefined){
|
||||||
if(membjson === undefined){
|
return res(undefined);
|
||||||
return res(undefined);
|
}else{
|
||||||
}else{
|
const member = new Member(membjson, guild);
|
||||||
const member = new Member(membjson, guild);
|
const map = guild.localuser.presences;
|
||||||
const map = guild.localuser.presences;
|
member.getPresence(map.get(member.id));
|
||||||
member.getPresence(map.get(member.id));
|
map.delete(member.id);
|
||||||
map.delete(member.id);
|
res(member);
|
||||||
res(member);
|
return 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){
|
ban(){
|
||||||
return await maybe;
|
let reason = "";
|
||||||
}else{
|
const menu = new Dialog([
|
||||||
return maybe;
|
"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){
|
||||||
public getPresence(presence: presencejson | undefined){
|
const headers = structuredClone(this.guild.headers);
|
||||||
this.user.getPresence(presence);
|
(headers as any)["x-audit-log-reason"] = reason;
|
||||||
}
|
fetch(`${this.info.api}/guilds/${this.guild.id}/bans/${this.id}`, {
|
||||||
/**
|
method: "PUT",
|
||||||
* @todo
|
headers,
|
||||||
*/
|
});
|
||||||
highInfo(){
|
}
|
||||||
fetch(
|
hasPermission(name: string): boolean{
|
||||||
this.info.api +
|
if(this.isAdmin()){
|
||||||
"/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 true;
|
||||||
}
|
}
|
||||||
}
|
for(const thing of this.roles){
|
||||||
return false;
|
if(thing.permissions.getPermission(name)){
|
||||||
}
|
return true;
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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 };
|
export{ Member };
|
||||||
|
|
|
@ -1379,6 +1379,7 @@ span {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
align-content: space-around;
|
align-content: space-around;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
.userflex{
|
.userflex{
|
||||||
display:flex;
|
display:flex;
|
||||||
|
@ -2219,3 +2220,51 @@ form div{
|
||||||
.mentionMD:hover{
|
.mentionMD:hover{
|
||||||
background:color-mix(in srgb,var(--mention-md-bg),white 10%);
|
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[];
|
badge_ids!: string[];
|
||||||
members: WeakMap<Guild, Member | undefined | Promise<Member | undefined>> =
|
members: WeakMap<Guild, Member | undefined | Promise<Member | undefined>> =
|
||||||
new WeakMap();
|
new WeakMap();
|
||||||
private status!: string;
|
status!: string;
|
||||||
resolving: false | Promise<any> = false;
|
resolving: false | Promise<any> = false;
|
||||||
|
|
||||||
constructor(userjson: userjson, owner: Localuser, dontclone = false){
|
constructor(userjson: userjson, owner: Localuser, dontclone = false){
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue