diff --git a/.dist/guild.js b/.dist/guild.js index 023d43e..5e97801 100644 --- a/.dist/guild.js +++ b/.dist/guild.js @@ -5,6 +5,7 @@ import { Dialog } from "./dialog.js"; import { Member } from "./member.js"; import { Settings, RoleList } from "./settings.js"; import { SnowFlake } from "./snowflake.js"; +import { User } from "./user.js"; class Guild { owner; headers; @@ -92,7 +93,12 @@ class Guild { this.roles.push(roleh); this.roleids.set(roleh.snowflake, roleh); } - Member.resolve(member, this).then(_ => this.member = _); + if (member instanceof User) { + Member.resolveMember(member, this).then(_ => this.member = _); + } + else { + Member.new(member, this).then(_ => this.member = _); + } for (const thing of json.channels) { const temp = new Channel(thing, this); this.channels.push(temp); diff --git a/.dist/localuser.js b/.dist/localuser.js index 25e1103..d09e961 100644 --- a/.dist/localuser.js +++ b/.dist/localuser.js @@ -161,7 +161,7 @@ class Localuser { if (temp.op === 0 && temp.t === "READY") { returny(); } - this.handleEvent(temp); + await this.handleEvent(temp); } catch { } } @@ -196,7 +196,7 @@ class Localuser { if (temp.op === 0 && temp.t === "READY") { returny(); } - this.handleEvent(temp); + await this.handleEvent(temp); } catch (e) { console.error(e); @@ -240,7 +240,7 @@ class Localuser { await promise; return; } - handleEvent(temp) { + async handleEvent(temp) { console.debug(temp); if (temp.s) this.lastSequence = temp.s; @@ -314,7 +314,7 @@ class Localuser { const guild = SnowFlake.getSnowFlakeFromID(temp.d.guild_id, Guild).getObject(); let thing; if (temp.d.member) { - thing = new Member(temp.d.member, guild); + thing = await Member.new(temp.d.member, guild); } else { thing = { id: temp.d.user_id }; @@ -1033,8 +1033,6 @@ class Localuser { //---------- resolving members code ----------- waitingmembers = new Map(); async resolvemember(id, guildid) { - console.warn("this function may or may not work on any instance, use at your own risk"); - //throw new Error("Not implemented on the server side and not fully implemented, do not use"); if (!this.waitingmembers.has(guildid)) { this.waitingmembers.set(guildid, new Map()); } diff --git a/.dist/member.js b/.dist/member.js index 9de0979..d654111 100644 --- a/.dist/member.js +++ b/.dist/member.js @@ -1,14 +1,12 @@ import { User } from "./user.js"; import { Role } from "./role.js"; -import { Guild } from "./guild.js"; import { Contextmenu } from "./contextmenu.js"; import { SnowFlake } from "./snowflake.js"; class Member { static already = {}; owner; user; - roles; - error; + roles = []; id; static contextmenu = new Contextmenu("User Menu"); static setUpContextMenu() { @@ -22,19 +20,15 @@ class Member { }); }); } - constructor(memberjson, owner, error = false) { - this.error = error; - this.owner = owner; - let membery = memberjson; - this.roles = []; - if (!error) { - if (memberjson["guild_member"]) { - memberjson = memberjson; - membery = memberjson.guild_member; - } + constructor(memberjson, owner) { + if (User.userids[memberjson.id]) { + this.user = User.userids[memberjson.id]; } - membery = membery; - for (const thing of Object.keys(membery)) { + else { + this.user = new User(memberjson.user, owner.localuser); + } + this.owner = owner; + for (const thing of Object.keys(memberjson)) { if (thing === "guild") { continue; } @@ -42,23 +36,17 @@ class Member { continue; } if (thing === "roles") { - for (const strrole of membery["roles"]) { + for (const strrole of memberjson["roles"]) { const role = SnowFlake.getSnowFlakeFromID(strrole, Role).getObject(); this.roles.push(role); } continue; } - this[thing] = membery[thing]; + this[thing] = memberjson[thing]; } - if (error) { - this.user = memberjson; - } - else { - if (SnowFlake.getSnowFlakeFromID(this?.id, User)) { - this.user = SnowFlake.getSnowFlakeFromID(this.id, User).getObject(); - return; - } - this.user = new User(membery.user, owner.localuser); + if (SnowFlake.getSnowFlakeFromID(this?.id, User)) { + this.user = SnowFlake.getSnowFlakeFromID(this.id, User).getObject(); + return; } } get guild() { @@ -70,53 +58,59 @@ class Member { get info() { return this.owner.info; } - static async resolve(unkown, guild) { - if (!(guild instanceof Guild)) { - console.error(guild); - } - let user; - let id; - if (unkown instanceof User) { - user = unkown; - id = user.snowflake; - } - else if (typeof unkown === typeof "") { - id = new SnowFlake(unkown, undefined); + static async new(memberjson, owner) { + const user = new User(memberjson.user, owner.localuser); + 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 { + return memb; + } } else { - return new Member(unkown, guild); + const memb = new Member(memberjson, owner); + user.members.set(owner, memb); + return memb; } - if (guild.id === "@me") { - return null; - } - if (!Member.already[guild.id]) { - Member.already[guild.id] = {}; - } - else if (Member.already[guild.id][id]) { - const memb = Member.already[guild.id][id]; - if (memb instanceof Promise) { - return await memb; + } + static async resolveMember(user, guild) { + const maybe = user.members.get(guild); + if (!user.members.has(guild)) { + const membpromise = guild.localuser.resolvemember(user.id, guild.id); + let res; + const promise = new Promise(r => { res = r; }); + user.members.set(guild, promise); + const membjson = await membpromise; + if (membjson === undefined) { + res(undefined); + return undefined; + } + else { + const member = new Member(membjson, guild); + res(member); + return member; } - return memb; } - guild.localuser.resolvemember(id.id, guild.id); - const prom1 = fetch(guild.info.api.toString() + "/users/" + id + "/profile?with_mutual_guilds=true&with_mutual_friends_count=true&guild_id=" + guild.snowflake, { headers: guild.headers }); - prom1.catch(_ => { console.log(_); }); - const promoise = prom1.then(_ => _.json()).then(json => { - const memb = new Member(json, guild); - Member.already[guild.id][id] = memb; - return memb; - }); - Member.already[guild.id][id] = promoise; - try { - return await promoise; + if (maybe instanceof Promise) { + return await maybe; } - catch (_) { - const memb = new Member(user, guild, true); - Member.already[guild.id][id] = memb; - return memb; + else { + return maybe; } } + /** + * @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) { console.log(this.roles, ID); for (const thing of this.roles) { @@ -149,13 +143,11 @@ class Member { return; } ; - if (this.error) { - const error = document.createElement("span"); - error.textContent = "!"; - error.classList.add("membererror"); - html.after(error); - return; + /* + if(this.error){ + } + */ html.style.color = this.getColor(); } this.profileclick(html); diff --git a/.dist/message.js b/.dist/message.js index d6d43d8..c6c961b 100644 --- a/.dist/message.js +++ b/.dist/message.js @@ -107,7 +107,7 @@ class Message { continue; } else if (thing === "member") { - this.member = new Member(messagejson.member, this.guild); + Member.new(messagejson.member, this.guild).then(_ => { this.member = _; }); continue; } else if (thing === "embeds") { diff --git a/.dist/user.js b/.dist/user.js index ab9a848..ea0a61e 100644 --- a/.dist/user.js +++ b/.dist/user.js @@ -21,6 +21,7 @@ class User { premium_type; theme_colors; badge_ids; + members = new WeakMap(); clone() { return new User({ username: this.username, @@ -97,7 +98,7 @@ class User { } } async resolvemember(guild) { - return await Member.resolve(this, guild); + return await Member.resolveMember(this, guild); } buildpfp() { const pfp = document.createElement('img'); @@ -114,7 +115,14 @@ class User { } bind(html, guild = null) { if (guild && guild.id !== "@me") { - Member.resolve(this, guild).then(_ => { + Member.resolveMember(this, guild).then(_ => { + if (_ === undefined) { + const error = document.createElement("span"); + error.textContent = "!"; + error.classList.add("membererror"); + html.after(error); + return; + } _.bind(html); }).catch(_ => { console.log(_); diff --git a/webpage/guild.ts b/webpage/guild.ts index 1a4838d..8bef811 100644 --- a/webpage/guild.ts +++ b/webpage/guild.ts @@ -7,7 +7,8 @@ import {Member} from "./member.js"; import {Settings,RoleList} from "./settings.js"; import {Permissions} from "./permissions.js"; import { SnowFlake } from "./snowflake.js"; -import { channeljson, guildjson, emojijson } from "./jsontypes.js"; +import { channeljson, guildjson, emojijson, memberjson } from "./jsontypes.js"; +import { User } from "./user.js"; class Guild{ owner:Localuser; headers:Localuser["headers"]; @@ -81,7 +82,7 @@ class Guild{ s1.options.push(new RoleList(permlist,this,this.updateRolePermissions.bind(this))); settings.show(); } - constructor(json:guildjson|-1,owner:Localuser,member){ + constructor(json:guildjson|-1,owner:Localuser,member:memberjson|User){ if(json===-1){ return; } @@ -101,7 +102,12 @@ class Guild{ this.roles.push(roleh) this.roleids.set(roleh.snowflake,roleh); } - Member.resolve(member,this).then(_=>this.member=_); + if(member instanceof User){ + Member.resolveMember(member,this).then(_=>this.member=_); + }else{ + Member.new(member,this).then(_=>this.member=_); + } + for(const thing of json.channels){ const temp=new Channel(thing,this); this.channels.push(temp); diff --git a/webpage/localuser.ts b/webpage/localuser.ts index ac87410..4434502 100644 --- a/webpage/localuser.ts +++ b/webpage/localuser.ts @@ -167,7 +167,7 @@ class Localuser{ if(temp.op===0&&temp.t==="READY"){ returny(); } - this.handleEvent(temp); + await this.handleEvent(temp); }catch{} } })(); @@ -205,7 +205,7 @@ class Localuser{ if(temp.op===0&&temp.t==="READY"){ returny(); } - this.handleEvent(temp); + await this.handleEvent(temp); }catch(e){ console.error(e); }finally{ @@ -247,7 +247,7 @@ class Localuser{ await promise; return; } - handleEvent(temp){ + async handleEvent(temp){ console.debug(temp); if (temp.s) this.lastSequence=temp.s; if(temp.op==0){ @@ -320,7 +320,7 @@ class Localuser{ const guild=SnowFlake.getSnowFlakeFromID(temp.d.guild_id,Guild).getObject(); let thing:Member|{id:string}; if(temp.d.member){ - thing=new Member(temp.d.member,guild); + thing=await Member.new(temp.d.member,guild); }else{ thing={id:temp.d.user_id} } @@ -1065,8 +1065,6 @@ class Localuser{ //---------- resolving members code ----------- waitingmembers:Mapvoid>>=new Map(); async resolvemember(id:string,guildid:string):Promise{ - console.warn("this function may or may not work on any instance, use at your own risk"); - //throw new Error("Not implemented on the server side and not fully implemented, do not use"); if(!this.waitingmembers.has(guildid)){ this.waitingmembers.set(guildid,new Map()); } diff --git a/webpage/member.ts b/webpage/member.ts index 8087d37..eab8217 100644 --- a/webpage/member.ts +++ b/webpage/member.ts @@ -9,8 +9,7 @@ class Member{ static already={}; owner:Guild; user:User; - roles:Role[]; - error:boolean; + roles:Role[]=[]; id:string; static contextmenu:Contextmenu=new Contextmenu("User Menu"); static setUpContextMenu(){ @@ -25,39 +24,31 @@ class Member{ }); }); } - constructor(memberjson:memberjson|User|{guild_member:memberjson,user:userjson},owner:Guild,error=false){ - this.error=error; - this.owner=owner; - let membery=memberjson; - this.roles=[]; - if(!error){ - if(memberjson["guild_member"]){ - memberjson=memberjson as {guild_member:memberjson,user:userjson}; - membery=memberjson.guild_member; - } + private constructor(memberjson:memberjson,owner:Guild){ + if(User.userids[memberjson.id]){ + this.user=User.userids[memberjson.id]; + }else{ + this.user=new User(memberjson.user,owner.localuser); } - membery=membery as User|memberjson; - for(const thing of Object.keys(membery)){ + this.owner=owner; + for(const thing of Object.keys(memberjson)){ if(thing==="guild"){continue} if(thing==="owner"){continue} if(thing==="roles"){ - for(const strrole of membery["roles"]){ + for(const strrole of memberjson["roles"]){ const role=SnowFlake.getSnowFlakeFromID(strrole,Role).getObject(); this.roles.push(role); } continue; } - this[thing]=membery[thing]; + this[thing]=memberjson[thing]; } - if(error){ - this.user=memberjson as User; - }else{ - if(SnowFlake.getSnowFlakeFromID(this?.id,User)){ - this.user=SnowFlake.getSnowFlakeFromID(this.id,User).getObject(); - return; - } - this.user=new User((membery as memberjson).user,owner.localuser); + if(SnowFlake.getSnowFlakeFromID(this?.id,User)){ + this.user=SnowFlake.getSnowFlakeFromID(this.id,User).getObject(); + return; } + + } get guild(){ return this.owner; @@ -68,47 +59,53 @@ class Member{ get info(){ return this.owner.info; } - static async resolve(unkown:User|memberjson|string,guild:Guild):Promise{ - if(!(guild instanceof Guild)){ - console.error(guild) - } - let user:User; - let id:SnowFlake; - if(unkown instanceof User){ - user=unkown as User; - id=user.snowflake; - }else if(typeof unkown===typeof ""){ - id=new SnowFlake(unkown as string,undefined); - }else{ - return new Member(unkown as User|memberjson,guild); - } - if(guild.id==="@me"){return null} - if(!Member.already[guild.id]){ - Member.already[guild.id]={}; - }else if(Member.already[guild.id][id]){ - const memb=Member.already[guild.id][id] - if(memb instanceof Promise){ - return await memb; + static async new(memberjson:memberjson,owner:Guild):Promise{ + const user=new User(memberjson.user,owner.localuser); + 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{ + return memb; } + }else{ + const memb=new Member(memberjson,owner); + user.members.set(owner,memb); return memb; } - guild.localuser.resolvemember(id.id,guild.id); - const prom1= fetch(guild.info.api.toString()+"/users/"+id+"/profile?with_mutual_guilds=true&with_mutual_friends_count=true&guild_id="+guild.snowflake,{headers:guild.headers}) - prom1.catch(_=>{console.log(_)}) - const promoise=prom1.then(_=>_.json()).then(json=>{ - const memb=new Member(json,guild); - Member.already[guild.id][id]=memb; - return memb - }) - Member.already[guild.id][id]=promoise; - try{ - return await promoise - }catch(_){ - - const memb=new Member(user,guild,true); - Member.already[guild.id][id]=memb; - return memb; + } + static async resolveMember(user:User,guild:Guild):Promise{ + const maybe=user.members.get(guild); + if(!user.members.has(guild)){ + const membpromise=guild.localuser.resolvemember(user.id,guild.id); + let res:Function; + const promise=new Promise(r=>{res=r}) + user.members.set(guild,promise); + const membjson=await membpromise; + if(membjson===undefined){ + res(undefined); + return undefined; + }else{ + const member=new Member(membjson,guild); + res(member); + return member; + } } + if(maybe instanceof Promise){ + return await maybe; + }else{ + return maybe + } + } + /** + * @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); @@ -139,13 +136,11 @@ class Member{ bind(html:HTMLElement){ if(html.tagName==="SPAN"){ if(!this) {return}; + /* if(this.error){ - const error=document.createElement("span"); - error.textContent="!"; - error.classList.add("membererror"); - html.after(error); - return; + } + */ html.style.color=this.getColor(); } diff --git a/webpage/message.ts b/webpage/message.ts index 25a66dc..e84dc41 100644 --- a/webpage/message.ts +++ b/webpage/message.ts @@ -111,7 +111,7 @@ class Message{ this.snowflake=new SnowFlake(messagejson.id,this); continue; }else if(thing==="member"){ - this.member=new Member(messagejson.member,this.guild); + Member.new(messagejson.member,this.guild).then(_=>{this.member=_}); continue; }else if(thing ==="embeds"){ this.embeds=[]; diff --git a/webpage/user.ts b/webpage/user.ts index 6bf7e1e..a328223 100644 --- a/webpage/user.ts +++ b/webpage/user.ts @@ -25,6 +25,7 @@ class User{ premium_type: number; theme_colors: string; badge_ids: string; + members: WeakMap>=new WeakMap(); clone(){ return new User({ username:this.username, @@ -98,7 +99,7 @@ class User{ } } async resolvemember(guild:Guild){ - return await Member.resolve(this,guild); + return await Member.resolveMember(this,guild); } buildpfp(){ const pfp=document.createElement('img'); @@ -115,7 +116,14 @@ class User{ } bind(html:HTMLElement,guild:Guild=null){ if(guild&&guild.id!=="@me"){ - Member.resolve(this,guild).then(_=>{ + Member.resolveMember(this,guild).then(_=>{ + if(_===undefined){ + const error=document.createElement("span"); + error.textContent="!"; + error.classList.add("membererror"); + html.after(error); + return; + } _.bind(html); }).catch(_=>{ console.log(_)