jank-client-fork/.dist/message.js
2024-07-28 14:53:39 -05:00

391 lines
15 KiB
JavaScript

import { Contextmenu } from "./contextmenu.js";
import { User } from "./user.js";
import { Member } from "./member.js";
import { MarkDown } from "./markdown.js";
import { Embed } from "./embed.js";
import { File } from "./file.js";
import { SnowFlake } from "./snowflake.js";
class Message {
static contextmenu = new Contextmenu("message menu");
owner;
headers;
embeds;
author;
mentions;
mention_roles;
attachments; //probably should be its own class tbh, should be Attachments[]
snowflake;
message_reference;
type;
timestamp;
content;
static del;
static resolve;
div;
member;
get id() {
return this.snowflake.id;
}
static setup() {
this.del = new Promise(_ => { this.resolve = _; });
Message.setupcmenu();
}
static async wipeChanel() {
this.resolve();
document.getElementById("messages").innerHTML = "";
await Promise.allSettled([this.resolve]);
this.del = new Promise(_ => { this.resolve = _; });
}
static setupcmenu() {
Message.contextmenu.addbutton("Copy raw text", function () {
navigator.clipboard.writeText(this.content.rawString);
});
Message.contextmenu.addbutton("Reply", function (div) {
this.channel.setReplying(this);
});
Message.contextmenu.addbutton("Copy message id", function () {
navigator.clipboard.writeText(this.id);
});
Message.contextmenu.addbutton("Edit", function () {
this.channel.editing = this;
const markdown = (document.getElementById("typebox"))["markdown"];
markdown.txt = this.content.rawString;
markdown.boxupdate(document.getElementById("typebox"));
}, null, _ => { return _.author.id === _.localuser.user.id; });
Message.contextmenu.addbutton("Delete message", function () {
this.delete();
}, null, _ => { return _.canDelete(); });
}
constructor(messagejson, owner) {
this.owner = owner;
this.headers = this.owner.headers;
this.giveData(messagejson);
}
giveData(messagejson) {
for (const thing of Object.keys(messagejson)) {
if (thing === "attachments") {
this.attachments = [];
for (const thing of messagejson.attachments) {
this.attachments.push(new File(thing, this));
}
continue;
}
else if (thing === "content") {
this.content = new MarkDown(messagejson[thing], this.channel);
continue;
}
else if (thing === "id") {
this.snowflake = new SnowFlake(messagejson.id, this);
continue;
}
else if (thing === "member") {
this.member = new Member(messagejson.member, this.guild);
continue;
}
else if (thing === "embeds") {
this.embeds = [];
for (const thing in messagejson.embeds) {
console.log(thing, messagejson.embeds);
this.embeds[thing] = new Embed(messagejson.embeds[thing], this);
}
continue;
}
this[thing] = messagejson[thing];
}
this.author = new User(messagejson.author, this.localuser);
for (const thing in messagejson.mentions) {
this.mentions[thing] = new User(messagejson.mentions[thing], this.localuser);
}
if (!this.member && this.guild.id !== "@me") {
this.author.resolvemember(this.guild).then(_ => {
this.member = _;
});
}
if (this.mentions.length || this.mention_roles.length) { //currently mention_roles isn't implemented on the spacebar servers
console.log(this.mentions, this.mention_roles);
}
if (this.mentionsuser(this.localuser.user)) {
console.log(this);
}
if (this.div) {
this.generateMessage();
}
}
canDelete() {
return this.channel.hasPermission("MANAGE_MESSAGES") || this.author.snowflake === this.localuser.user.snowflake;
}
get channel() {
return this.owner;
}
get guild() {
return this.owner.guild;
}
get localuser() {
return this.owner.localuser;
}
get info() {
return this.owner.info;
}
messageevents(obj, del = Message.del) {
const func = Message.contextmenu.bind(obj, this);
this.div = obj;
del.then(_ => {
obj.removeEventListener("click", func);
this.div.remove();
this.div = null;
});
obj.classList.add("messagediv");
}
mentionsuser(userd) {
if (userd instanceof User) {
return this.mentions.includes(userd);
}
else if (userd instanceof Member) {
return this.mentions.includes(userd.user);
}
}
getimages() {
const build = [];
for (const thing of this.attachments) {
if (thing.content_type.startsWith('image/')) {
build.push(thing);
}
}
return build;
}
async edit(content) {
return await fetch(this.info.api.toString() + "/channels/" + this.channel.snowflake + "/messages/" + this.id, {
method: "PATCH",
headers: this.headers,
body: JSON.stringify({ content: content })
});
}
delete() {
fetch(`${this.info.api.toString()}/channels/${this.channel.snowflake}/messages/${this.id}`, {
headers: this.headers,
method: "DELETE",
});
}
deleteEvent() {
if (this.div) {
this.div.innerHTML = "";
this.div = null;
}
const prev = this.channel.idToPrev.get(this.snowflake);
const next = this.channel.idToNext.get(this.snowflake);
this.channel.idToNext.set(prev, next);
this.channel.idToPrev.set(next, prev);
this.channel.messageids.delete(this.snowflake);
const regen = prev.getObject();
if (regen) {
regen.generateMessage();
}
if (this.channel.lastmessage === this) {
this.channel.lastmessage = prev.getObject();
}
}
generateMessage(premessage = null) {
if (!premessage) {
premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
}
const div = this.div;
if (this === this.channel.replyingto) {
div.classList.add("replying");
}
div.innerHTML = "";
const build = document.createElement('div');
build.classList.add("flexltr");
if (this.message_reference) {
const replyline = document.createElement("div");
const line = document.createElement("hr");
const minipfp = document.createElement("img");
minipfp.classList.add("replypfp");
replyline.appendChild(line);
replyline.appendChild(minipfp);
const username = document.createElement("span");
replyline.appendChild(username);
const reply = document.createElement("div");
username.classList.add("username");
this.author.bind(username, this.guild);
/*
Member.resolve(this.author,this.guild).then(_=>{
if(!_) {return};
console.log(_.error);
if(_.error){
username.textContent+="Error";
alert("Should've gotten here")
const error=document.createElement("span");
error.textContent="!";
error.classList.add("membererror");
username.after(error);
return;
}
username.style.color=_.getColor();
}).catch(_=>{
console.log(_)
});
*/
reply.classList.add("replytext");
replyline.appendChild(reply);
const line2 = document.createElement("hr");
replyline.appendChild(line2);
line2.classList.add("reply");
line.classList.add("startreply");
replyline.classList.add("replyflex");
this.channel.getmessage(this.message_reference.message_id).then(message => {
const author = message.author;
reply.appendChild(message.content.makeHTML({ stdsize: true }));
minipfp.src = author.getpfpsrc();
author.bind(minipfp);
username.textContent = author.username;
author.bind(username);
});
reply.onclick = _ => {
console.log("this got clicked :3");
this.channel.infinite.focus(this.message_reference.message_id);
};
div.appendChild(replyline);
}
build.classList.add("message");
div.appendChild(build);
if ({ 0: true, 19: true }[this.type] || this.attachments.length !== 0) {
const pfpRow = document.createElement('div');
pfpRow.classList.add("flexltr");
let pfpparent, current;
if (premessage != null) {
pfpparent ??= premessage;
let pfpparent2 = pfpparent.all;
pfpparent2 ??= pfpparent;
const old = (new Date(pfpparent2.timestamp).getTime()) / 1000;
const newt = (new Date(this.timestamp).getTime()) / 1000;
current = (newt - old) > 600;
}
const combine = (premessage?.author?.snowflake != this.author.snowflake) || (current) || this.message_reference;
if (combine) {
const pfp = this.author.buildpfp();
this.author.bind(pfp);
pfpRow.appendChild(pfp);
}
else {
div["pfpparent"] = pfpparent;
}
pfpRow.classList.add("pfprow");
build.appendChild(pfpRow);
const text = document.createElement("div");
text.classList.add("flexttb");
const texttxt = document.createElement("div");
texttxt.classList.add("commentrow", "flexttb");
text.appendChild(texttxt);
if (combine) {
const username = document.createElement("span");
username.classList.add("username");
this.author.bind(username, this.guild);
div.classList.add("topMessage");
username.textContent = this.author.username;
const userwrap = document.createElement("div");
userwrap.classList.add("flexltr");
userwrap.appendChild(username);
if (this.author.bot) {
const username = document.createElement("span");
username.classList.add("bot");
username.textContent = "BOT";
userwrap.appendChild(username);
}
const time = document.createElement("span");
time.textContent = " " + formatTime(new Date(this.timestamp));
time.classList.add("timestamp");
userwrap.appendChild(time);
texttxt.appendChild(userwrap);
}
else {
div.classList.remove("topMessage");
}
const messaged = this.content.makeHTML();
div["txt"] = messaged;
const messagedwrap = document.createElement("div");
messagedwrap.classList.add("flexttb");
messagedwrap.appendChild(messaged);
texttxt.appendChild(messagedwrap);
build.appendChild(text);
if (this.attachments.length) {
console.log(this.attachments);
const attach = document.createElement("div");
attach.classList.add("flexltr");
for (const thing of this.attachments) {
attach.appendChild(thing.getHTML());
}
messagedwrap.appendChild(attach);
}
if (this.embeds.length) {
console.log(this.embeds);
const embeds = document.createElement("div");
embeds.classList.add("flexltr");
for (const thing of this.embeds) {
embeds.appendChild(thing.generateHTML());
}
messagedwrap.appendChild(embeds);
}
//
}
else if (this.type === 7) {
const text = document.createElement("div");
text.classList.add("flexttb");
const texttxt = document.createElement("div");
text.appendChild(texttxt);
build.appendChild(text);
texttxt.classList.add("flexltr");
const messaged = document.createElement("span");
div["txt"] = messaged;
messaged.textContent = "welcome: ";
texttxt.appendChild(messaged);
const username = document.createElement("span");
username.textContent = this.author.username;
this.author.profileclick(username);
this.author.bind(username, this.guild);
texttxt.appendChild(username);
username.classList.add("username");
const time = document.createElement("span");
time.textContent = " " + formatTime(new Date(this.timestamp));
time.classList.add("timestamp");
texttxt.append(time);
div.classList.add("topMessage");
}
div["all"] = this;
return (div);
}
buildhtml(premessage, del = Message.del) {
if (this.div) {
console.error(`HTML for ${this.snowflake} already exists, aborting`);
return;
}
//premessage??=messages.lastChild;
const div = document.createElement("div");
this.div = div;
this.messageevents(div, del);
return this.generateMessage(premessage);
}
}
function formatTime(date) {
const now = new Date();
const sameDay = date.getDate() === now.getDate() &&
date.getMonth() === now.getMonth() &&
date.getFullYear() === now.getFullYear();
const yesterday = new Date(now);
yesterday.setDate(now.getDate() - 1);
const isYesterday = date.getDate() === yesterday.getDate() &&
date.getMonth() === yesterday.getMonth() &&
date.getFullYear() === yesterday.getFullYear();
const formatTime = date => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
if (sameDay) {
return `Today at ${formatTime(date)}`;
}
else if (isYesterday) {
return `Yesterday at ${formatTime(date)}`;
}
else {
return `${date.toLocaleDateString()} at ${formatTime(date)}`;
}
}
Message.setup();
export { Message };