lint and merge

This commit is contained in:
MathMan05 2024-09-19 12:49:50 -05:00
parent 49f2234e81
commit e12b99c38b
34 changed files with 10323 additions and 10330 deletions

View file

@ -1,489 +1,489 @@
import { Member } from "./member.js";
import { MarkDown } from "./markdown.js";
import { Contextmenu } from "./contextmenu.js";
import { Localuser } from "./localuser.js";
import { Guild } from "./guild.js";
import { SnowFlake } from "./snowflake.js";
import { presencejson, userjson } from "./jsontypes.js";
import{ Member }from"./member.js";
import{ MarkDown }from"./markdown.js";
import{ Contextmenu }from"./contextmenu.js";
import{ Localuser }from"./localuser.js";
import{ Guild }from"./guild.js";
import{ SnowFlake }from"./snowflake.js";
import{ presencejson, userjson }from"./jsontypes.js";
class User extends SnowFlake {
owner: Localuser;
hypotheticalpfp!: boolean;
avatar!: string | null;
username!: string;
nickname: string | null = null;
relationshipType: 0 | 1 | 2 | 3 | 4 = 0;
bio!: MarkDown;
discriminator!: string;
pronouns!: string;
bot!: boolean;
public_flags!: number;
accent_color!: number;
banner: string | undefined;
hypotheticalbanner!: boolean;
premium_since!: string;
premium_type!: number;
theme_colors!: string;
badge_ids!: string[];
members: WeakMap<Guild, Member | undefined | Promise<Member | undefined>> =
new WeakMap();
class User extends SnowFlake{
owner: Localuser;
hypotheticalpfp!: boolean;
avatar!: string | null;
username!: string;
nickname: string | null = null;
relationshipType: 0 | 1 | 2 | 3 | 4 = 0;
bio!: MarkDown;
discriminator!: string;
pronouns!: string;
bot!: boolean;
public_flags!: number;
accent_color!: number;
banner: string | undefined;
hypotheticalbanner!: boolean;
premium_since!: string;
premium_type!: number;
theme_colors!: string;
badge_ids!: string[];
members: WeakMap<Guild, Member | undefined | Promise<Member | undefined>> =
new WeakMap();
private status!: string;
resolving: false | Promise<any> = false;
constructor(userjson: userjson, owner: Localuser, dontclone = false) {
constructor(userjson: userjson, owner: Localuser, dontclone = false){
super(userjson.id);
this.owner = owner;
if (!owner) {
console.error("missing localuser");
if(!owner){
console.error("missing localuser");
}
if (dontclone) {
for (const key of Object.keys(userjson)) {
if (key === "bio") {
this.bio = new MarkDown(userjson[key], this.localuser);
continue;
}
if (key === "id") {
continue;
}
(this as any)[key] = (userjson as any)[key];
}
this.hypotheticalpfp = false;
} else {
return User.checkuser(userjson, owner);
}
}
clone(): User {
return new User(
{
username: this.username,
id: this.id + "#clone",
public_flags: this.public_flags,
discriminator: this.discriminator,
avatar: this.avatar,
accent_color: this.accent_color,
banner: this.banner,
bio: this.bio.rawString,
premium_since: this.premium_since,
premium_type: this.premium_type,
bot: this.bot,
theme_colors: this.theme_colors,
pronouns: this.pronouns,
badge_ids: this.badge_ids,
},
this.owner
);
}
public getPresence(presence: presencejson | undefined): void {
if (presence) {
this.setstatus(presence.status);
} else {
this.setstatus("offline");
}
}
setstatus(status: string): void {
this.status = status;
}
async getStatus(): Promise<string> {
return this.status || "offline";
if(dontclone){
for(const key of Object.keys(userjson)){
if(key === "bio"){
this.bio = new MarkDown(userjson[key], this.localuser);
continue;
}
if(key === "id"){
continue;
}
(this as any)[key] = (userjson as any)[key];
}
this.hypotheticalpfp = false;
}else{
return User.checkuser(userjson, owner);
}
}
static contextmenu = new Contextmenu<User, Member | undefined>("User Menu");
clone(): User{
return new User(
{
username: this.username,
id: this.id + "#clone",
public_flags: this.public_flags,
discriminator: this.discriminator,
avatar: this.avatar,
accent_color: this.accent_color,
banner: this.banner,
bio: this.bio.rawString,
premium_since: this.premium_since,
premium_type: this.premium_type,
bot: this.bot,
theme_colors: this.theme_colors,
pronouns: this.pronouns,
badge_ids: this.badge_ids,
},
this.owner
);
}
static setUpContextMenu(): void {
this.contextmenu.addbutton("Copy user id", function (this: User) {
navigator.clipboard.writeText(this.id);
});
this.contextmenu.addbutton("Message user", function (this: User) {
fetch(this.info.api + "/users/@me/channels", {
public getPresence(presence: presencejson | undefined): void{
if(presence){
this.setstatus(presence.status);
}else{
this.setstatus("offline");
}
}
setstatus(status: string): void{
this.status = status;
}
async getStatus(): Promise<string>{
return this.status || "offline";
}
static contextmenu = new Contextmenu<User, Member | undefined>("User Menu");
static setUpContextMenu(): void{
this.contextmenu.addbutton("Copy user id", function(this: User){
navigator.clipboard.writeText(this.id);
});
this.contextmenu.addbutton("Message user", function(this: User){
fetch(this.info.api + "/users/@me/channels", {
method: "POST",
body: JSON.stringify({ recipients: [this.id] }),
headers: this.localuser.headers,
})
.then((res) => res.json())
.then((json) => {
this.localuser.goToChannel(json.id);
})
.then(res=>res.json())
.then(json=>{
this.localuser.goToChannel(json.id);
});
});
this.contextmenu.addbutton(
"Block user",
function (this: User) {
});
this.contextmenu.addbutton(
"Block user",
function(this: User){
this.block();
},
null,
function () {
},
null,
function(){
return this.relationshipType !== 2;
}
);
}
);
this.contextmenu.addbutton(
"Unblock user",
function (this: User) {
this.contextmenu.addbutton(
"Unblock user",
function(this: User){
this.unblock();
},
null,
function () {
},
null,
function(){
return this.relationshipType === 2;
}
);
this.contextmenu.addbutton("Friend request", function (this: User) {
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
}
);
this.contextmenu.addbutton("Friend request", function(this: User){
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
method: "PUT",
headers: this.owner.headers,
body: JSON.stringify({
type: 1,
type: 1,
}),
});
});
this.contextmenu.addbutton(
"Kick member",
function (this: User, member: Member | undefined) {
});
});
this.contextmenu.addbutton(
"Kick member",
(this: User, member: Member | undefined)=>{
member?.kick();
},
null,
(member) => {
if (!member) return false;
},
null,
member=>{
if(!member)return false;
const us = member.guild.member;
if (member.id === us.id) {
return false;
if(member.id === us.id){
return false;
}
if (member.id === member.guild.properties.owner_id) {
return false;
if(member.id === member.guild.properties.owner_id){
return false;
}
return us.hasPermission("KICK_MEMBERS") || false;
}
);
this.contextmenu.addbutton(
"Ban member",
function (this: User, member: Member | undefined) {
}
);
this.contextmenu.addbutton(
"Ban member",
(this: User, member: Member | undefined)=>{
member?.ban();
},
null,
(member) => {
if (!member) return false;
},
null,
member=>{
if(!member)return false;
const us = member.guild.member;
if (member.id === us.id) {
return false;
if(member.id === us.id){
return false;
}
if (member.id === member.guild.properties.owner_id) {
return false;
if(member.id === member.guild.properties.owner_id){
return false;
}
return us.hasPermission("BAN_MEMBERS") || false;
}
);
}
}
);
}
static checkuser(user: User | userjson, owner: Localuser): User {
if (owner.userMap.has(user.id)) {
return owner.userMap.get(user.id) as User;
} else {
const tempuser = new User(user as userjson, owner, true);
owner.userMap.set(user.id, tempuser);
return tempuser;
}
}
static checkuser(user: User | userjson, owner: Localuser): User{
if(owner.userMap.has(user.id)){
return owner.userMap.get(user.id) as User;
}else{
const tempuser = new User(user as userjson, owner, true);
owner.userMap.set(user.id, tempuser);
return tempuser;
}
}
get info() {
return this.owner.info;
}
get info(){
return this.owner.info;
}
get localuser() {
return this.owner;
}
get localuser(){
return this.owner;
}
get name() {
return this.username;
}
get name(){
return this.username;
}
async resolvemember(guild: Guild): Promise<Member | undefined> {
return await Member.resolveMember(this, guild);
async resolvemember(guild: Guild): Promise<Member | undefined>{
return await Member.resolveMember(this, guild);
}
async getUserProfile(): Promise<any>{
return await fetch(
`${this.info.api}/users/${this.id.replace(
"#clone",
""
)}/profile?with_mutual_guilds=true&with_mutual_friends=true`,
{
headers: this.localuser.headers,
}
).then(res=>res.json());
}
async getBadge(id: string): Promise<any>{
if(this.localuser.badges.has(id)){
return this.localuser.badges.get(id);
}else{
if(this.resolving){
await this.resolving;
return this.localuser.badges.get(id);
}
const prom = await this.getUserProfile();
this.resolving = prom;
const badges = prom.badges;
this.resolving = false;
for(const badge of badges){
this.localuser.badges.set(badge.id, badge);
}
return this.localuser.badges.get(id);
}
}
buildpfp(): HTMLImageElement{
const pfp = document.createElement("img");
pfp.loading = "lazy";
pfp.src = this.getpfpsrc();
pfp.classList.add("pfp");
pfp.classList.add("userid:" + this.id);
return pfp;
}
async buildstatuspfp(): Promise<HTMLDivElement>{
const div = document.createElement("div");
div.style.position = "relative";
const pfp = this.buildpfp();
div.append(pfp);
const status = document.createElement("div");
status.classList.add("statusDiv");
switch(await this.getStatus()){
case"offline":
status.classList.add("offlinestatus");
break;
case"online":
default:
status.classList.add("onlinestatus");
break;
}
div.append(status);
return div;
}
userupdate(json: userjson): void{
if(json.avatar !== this.avatar){
this.changepfp(json.avatar);
}
}
bind(html: HTMLElement, guild: Guild | null = null, error = true): void{
if(guild && guild.id !== "@me"){
Member.resolveMember(this, guild)
.then(member=>{
User.contextmenu.bindContextmenu(html, this, member);
if(member === undefined && error){
const errorSpan = document.createElement("span");
errorSpan.textContent = "!";
errorSpan.classList.add("membererror");
html.after(errorSpan);
return;
}
if(member){
member.bind(html);
}
})
.catch(err=>{
console.log(err);
});
}
if(guild){
this.profileclick(html, guild);
}else{
this.profileclick(html);
}
}
async getUserProfile(): Promise<any> {
return await fetch(
`${this.info.api}/users/${this.id.replace(
"#clone",
""
)}/profile?with_mutual_guilds=true&with_mutual_friends=true`,
{
headers: this.localuser.headers,
}
).then((res) => res.json());
}
static async resolve(id: string, localuser: Localuser): Promise<User>{
const json = await fetch(
localuser.info.api.toString() + "/users/" + id + "/profile",
{ headers: localuser.headers }
).then(res=>res.json());
return new User(json, localuser);
}
async getBadge(id: string): Promise<any> {
if (this.localuser.badges.has(id)) {
return this.localuser.badges.get(id);
} else {
if (this.resolving) {
await this.resolving;
return this.localuser.badges.get(id);
}
changepfp(update: string | null): void{
this.avatar = update;
this.hypotheticalpfp = false;
const src = this.getpfpsrc();
Array.from(document.getElementsByClassName("userid:" + this.id)).forEach(
element=>{
(element as HTMLImageElement).src = src;
}
);
}
const prom = await this.getUserProfile();
this.resolving = prom;
const badges = prom.badges;
this.resolving = false;
for (const badge of badges) {
this.localuser.badges.set(badge.id, badge);
}
return this.localuser.badges.get(id);
}
}
block(): void{
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
method: "PUT",
headers: this.owner.headers,
body: JSON.stringify({
type: 2,
}),
});
this.relationshipType = 2;
const channel = this.localuser.channelfocus;
if(channel){
for(const message of channel.messages){
message[1].generateMessage();
}
}
}
buildpfp(): HTMLImageElement {
const pfp = document.createElement("img");
pfp.loading = "lazy";
pfp.src = this.getpfpsrc();
pfp.classList.add("pfp");
pfp.classList.add("userid:" + this.id);
return pfp;
}
unblock(): void{
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
method: "DELETE",
headers: this.owner.headers,
});
this.relationshipType = 0;
const channel = this.localuser.channelfocus;
if(channel){
for(const message of channel.messages){
message[1].generateMessage();
}
}
}
async buildstatuspfp(): Promise<HTMLDivElement> {
const div = document.createElement("div");
div.style.position = "relative";
const pfp = this.buildpfp();
div.append(pfp);
const status = document.createElement("div");
status.classList.add("statusDiv");
switch (await this.getStatus()) {
case "offline":
status.classList.add("offlinestatus");
break;
case "online":
default:
status.classList.add("onlinestatus");
break;
}
div.append(status);
return div;
}
getpfpsrc(): string{
if(this.hypotheticalpfp && this.avatar){
return this.avatar;
}
if(this.avatar !== null){
return`${this.info.cdn}/avatars/${this.id.replace("#clone", "")}/${
this.avatar
}.png`;
}else{
const int = Number((BigInt(this.id.replace("#clone", "")) >> 22n) % 6n);
return`${this.info.cdn}/embed/avatars/${int}.png`;
}
}
userupdate(json: userjson): void {
if (json.avatar !== this.avatar) {
this.changepfp(json.avatar);
}
}
async buildprofile(
x: number,
y: number,
guild: Guild | null = null
): Promise<HTMLDivElement>{
if(Contextmenu.currentmenu != ""){
Contextmenu.currentmenu.remove();
}
bind(html: HTMLElement, guild: Guild | null = null, error = true): void {
if (guild && guild.id !== "@me") {
Member.resolveMember(this, guild)
.then((member) => {
User.contextmenu.bindContextmenu(html, this, member);
if (member === undefined && error) {
const errorSpan = document.createElement("span");
errorSpan.textContent = "!";
errorSpan.classList.add("membererror");
html.after(errorSpan);
return;
}
if (member) {
member.bind(html);
}
})
.catch((err) => {
console.log(err);
});
}
if (guild) {
this.profileclick(html, guild);
} else {
this.profileclick(html);
}
}
const div = document.createElement("div");
static async resolve(id: string, localuser: Localuser): Promise<User> {
const json = await fetch(
localuser.info.api.toString() + "/users/" + id + "/profile",
{ headers: localuser.headers }
).then((res) => res.json());
return new User(json, localuser);
}
if(this.accent_color){
div.style.setProperty(
"--accent_color",
`#${this.accent_color.toString(16).padStart(6, "0")}`
);
}else{
div.style.setProperty("--accent_color", "transparent");
}
if(this.banner){
const banner = document.createElement("img");
let src: string;
if(!this.hypotheticalbanner){
src = `${this.info.cdn}/avatars/${this.id.replace("#clone", "")}/${
this.banner
}.png`;
}else{
src = this.banner;
}
banner.src = src;
banner.classList.add("banner");
div.append(banner);
}
if(x !== -1){
div.style.left = `${x}px`;
div.style.top = `${y}px`;
div.classList.add("profile", "flexttb");
}else{
this.setstatus("online");
div.classList.add("hypoprofile", "flexttb");
}
const badgediv = document.createElement("div");
badgediv.classList.add("badges");
(async ()=>{
if(!this.badge_ids)return;
for(const id of this.badge_ids){
const badgejson = await this.getBadge(id);
if(badgejson){
const badge = document.createElement(badgejson.link ? "a" : "div");
badge.classList.add("badge");
const img = document.createElement("img");
img.src = badgejson.icon;
badge.append(img);
const span = document.createElement("span");
span.textContent = badgejson.description;
badge.append(span);
if(badge instanceof HTMLAnchorElement){
badge.href = badgejson.link;
}
badgediv.append(badge);
}
}
})();
const pfp = await this.buildstatuspfp();
div.appendChild(pfp);
const userbody = document.createElement("div");
userbody.classList.add("infosection");
div.appendChild(userbody);
const usernamehtml = document.createElement("h2");
usernamehtml.textContent = this.username;
userbody.appendChild(usernamehtml);
userbody.appendChild(badgediv);
const discrimatorhtml = document.createElement("h3");
discrimatorhtml.classList.add("tag");
discrimatorhtml.textContent = `${this.username}#${this.discriminator}`;
userbody.appendChild(discrimatorhtml);
changepfp(update: string | null): void {
this.avatar = update;
this.hypotheticalpfp = false;
const src = this.getpfpsrc();
Array.from(document.getElementsByClassName("userid:" + this.id)).forEach(
(element) => {
(element as HTMLImageElement).src = src;
}
);
}
const pronounshtml = document.createElement("p");
pronounshtml.textContent = this.pronouns;
pronounshtml.classList.add("pronouns");
userbody.appendChild(pronounshtml);
block(): void {
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
method: "PUT",
headers: this.owner.headers,
body: JSON.stringify({
type: 2,
}),
});
this.relationshipType = 2;
const channel = this.localuser.channelfocus;
if (channel) {
for (const message of channel.messages) {
message[1].generateMessage();
}
}
}
const rule = document.createElement("hr");
userbody.appendChild(rule);
const biohtml = this.bio.makeHTML();
userbody.appendChild(biohtml);
if(guild){
Member.resolveMember(this, guild).then(member=>{
if(!member)return;
const roles = document.createElement("div");
roles.classList.add("rolesbox");
for(const role of member.roles){
const roleDiv = document.createElement("div");
roleDiv.classList.add("rolediv");
const color = document.createElement("div");
roleDiv.append(color);
color.style.setProperty(
"--role-color",
`#${role.color.toString(16).padStart(6, "0")}`
);
color.classList.add("colorrolediv");
const span = document.createElement("span");
roleDiv.append(span);
span.textContent = role.name;
roles.append(roleDiv);
}
userbody.append(roles);
});
}
if(x !== -1){
Contextmenu.currentmenu = div;
document.body.appendChild(div);
Contextmenu.keepOnScreen(div);
}
return div;
}
unblock(): void {
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
method: "DELETE",
headers: this.owner.headers,
});
this.relationshipType = 0;
const channel = this.localuser.channelfocus;
if (channel) {
for (const message of channel.messages) {
message[1].generateMessage();
}
}
}
profileclick(obj: HTMLElement, guild?: Guild): void{
obj.onclick = (e: MouseEvent)=>{
this.buildprofile(e.clientX, e.clientY, guild);
e.stopPropagation();
};
}
}
getpfpsrc(): string {
if (this.hypotheticalpfp && this.avatar) {
return this.avatar;
}
if (this.avatar !== null) {
return `${this.info.cdn}/avatars/${this.id.replace("#clone", "")}/${
this.avatar
}.png`;
} else {
const int = Number((BigInt(this.id.replace("#clone", "")) >> 22n) % 6n);
return `${this.info.cdn}/embed/avatars/${int}.png`;
}
}
async buildprofile(
x: number,
y: number,
guild: Guild | null = null
): Promise<HTMLDivElement> {
if (Contextmenu.currentmenu != "") {
Contextmenu.currentmenu.remove();
}
const div = document.createElement("div");
if (this.accent_color) {
div.style.setProperty(
"--accent_color",
`#${this.accent_color.toString(16).padStart(6, "0")}`
);
} else {
div.style.setProperty("--accent_color", "transparent");
}
if (this.banner) {
const banner = document.createElement("img");
let src: string;
if (!this.hypotheticalbanner) {
src = `${this.info.cdn}/avatars/${this.id.replace("#clone", "")}/${
this.banner
}.png`;
} else {
src = this.banner;
}
banner.src = src;
banner.classList.add("banner");
div.append(banner);
}
if (x !== -1) {
div.style.left = `${x}px`;
div.style.top = `${y}px`;
div.classList.add("profile", "flexttb");
} else {
this.setstatus("online");
div.classList.add("hypoprofile", "flexttb");
}
const badgediv = document.createElement("div");
badgediv.classList.add("badges");
(async () => {
if (!this.badge_ids) return;
for (const id of this.badge_ids) {
const badgejson = await this.getBadge(id);
if (badgejson) {
const badge = document.createElement(badgejson.link ? "a" : "div");
badge.classList.add("badge");
const img = document.createElement("img");
img.src = badgejson.icon;
badge.append(img);
const span = document.createElement("span");
span.textContent = badgejson.description;
badge.append(span);
if (badge instanceof HTMLAnchorElement) {
badge.href = badgejson.link;
}
badgediv.append(badge);
}
}
})();
const pfp = await this.buildstatuspfp();
div.appendChild(pfp);
const userbody = document.createElement("div");
userbody.classList.add("infosection");
div.appendChild(userbody);
const usernamehtml = document.createElement("h2");
usernamehtml.textContent = this.username;
userbody.appendChild(usernamehtml);
userbody.appendChild(badgediv);
const discrimatorhtml = document.createElement("h3");
discrimatorhtml.classList.add("tag");
discrimatorhtml.textContent = `${this.username}#${this.discriminator}`;
userbody.appendChild(discrimatorhtml);
const pronounshtml = document.createElement("p");
pronounshtml.textContent = this.pronouns;
pronounshtml.classList.add("pronouns");
userbody.appendChild(pronounshtml);
const rule = document.createElement("hr");
userbody.appendChild(rule);
const biohtml = this.bio.makeHTML();
userbody.appendChild(biohtml);
if (guild) {
Member.resolveMember(this, guild).then((member) => {
if (!member) return;
const roles = document.createElement("div");
roles.classList.add("rolesbox");
for (const role of member.roles) {
const roleDiv = document.createElement("div");
roleDiv.classList.add("rolediv");
const color = document.createElement("div");
roleDiv.append(color);
color.style.setProperty(
"--role-color",
`#${role.color.toString(16).padStart(6, "0")}`
);
color.classList.add("colorrolediv");
const span = document.createElement("span");
roleDiv.append(span);
span.textContent = role.name;
roles.append(roleDiv);
}
userbody.append(roles);
});
}
if (x !== -1) {
Contextmenu.currentmenu = div;
document.body.appendChild(div);
Contextmenu.keepOnScreen(div);
}
return div;
}
profileclick(obj: HTMLElement, guild?: Guild): void {
obj.onclick = (e: MouseEvent) => {
this.buildprofile(e.clientX, e.clientY, guild);
e.stopPropagation();
};
}
}
User.setUpContextMenu();
export { User };
User.setUpContextMenu();
export{ User };