Reaction support

This commit is contained in:
MathMan05 2024-08-05 21:47:40 -05:00
parent 8b3fe48a74
commit 24bdde1968
12 changed files with 458 additions and 51 deletions

View file

@ -8,8 +8,6 @@ import { Settings, RoleList } from "./settings.js";
import { Role } from "./role.js";
import { InfiniteScroller } from "./infiniteScroller.js";
import { SnowFlake } from "./snowflake.js";
import { Emoji } from "./emoji.js";
new Emoji();
class Channel {
editing;
type;

View file

@ -20,7 +20,11 @@ class Contextmenu {
this.buttons = [];
}
addbutton(text, onclick, img = null, shown = _ => true, enabled = _ => true) {
this.buttons.push([text, onclick, img, shown, enabled]);
this.buttons.push([text, onclick, img, shown, enabled, "button"]);
return {};
}
addsubmenu(text, onclick, img = null, shown = _ => true, enabled = _ => true) {
this.buttons.push([text, onclick, img, shown, enabled, "submenu"]);
return {};
}
makemenu(x, y, addinfo, obj) {
@ -38,7 +42,12 @@ class Contextmenu {
intext.textContent = thing[0];
textb.appendChild(intext);
console.log(thing);
intext.onclick = thing[1].bind(addinfo, obj);
if (thing[5] === "button") {
intext.onclick = thing[1].bind(addinfo, obj);
}
else if (thing[5] === "submenu") {
intext.onclick = thing[1].bind(addinfo);
}
div.appendChild(textb);
}
if (Contextmenu.currentmenu != "") {

View file

@ -1,3 +1,4 @@
import { Contextmenu } from "./contextmenu.js";
class Emoji {
static emojis;
static decodeEmojiList(buffer) {
@ -62,6 +63,62 @@ class Emoji {
Emoji.decodeEmojiList(e);
});
}
static async emojiPicker(x, y) {
let res;
const promise = new Promise((r) => { res = r; });
const menu = document.createElement("div");
menu.classList.add("flextttb", "emojiPicker");
menu.style.top = y + "px";
menu.style.left = x + "px";
setTimeout(() => {
if (Contextmenu.currentmenu != "") {
Contextmenu.currentmenu.remove();
}
document.body.append(menu);
Contextmenu.currentmenu = menu;
Contextmenu.keepOnScreen(menu);
}, 10);
const title = document.createElement("h2");
title.textContent = Emoji.emojis[0].name;
title.classList.add("emojiTitle");
menu.append(title);
console.log("menu :3");
const selection = document.createElement("div");
selection.classList.add("flexltr");
console.log("menu :3");
const body = document.createElement("div");
body.classList.add("emojiBody");
let i = 0;
for (const thing of Emoji.emojis) {
const select = document.createElement("div");
select.textContent = thing.emojis[0].emoji;
select.classList.add("emojiSelect");
selection.append(select);
const clickEvent = () => {
title.textContent = thing.name;
body.innerHTML = "";
for (const emojit of thing.emojis) {
const emoji = document.createElement("div");
emoji.classList.add("emojiSelect");
emoji.textContent = emojit.emoji;
body.append(emoji);
emoji.onclick = _ => {
res(emojit.emoji);
Contextmenu.currentmenu.remove();
};
}
};
select.onclick = clickEvent;
if (i === 0) {
clickEvent();
}
i++;
}
menu.append(selection);
menu.append(body);
console.log("menu :3");
return promise;
}
}
Emoji.grabEmoji();
export { Emoji };

View file

@ -6,6 +6,7 @@ import { Fullscreen } from "./fullscreen.js";
import { setTheme } from "./login.js";
import { SnowFlake } from "./snowflake.js";
import { Message } from "./message.js";
import { Member } from "./member.js";
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
class Localuser {
lastSequence = null;
@ -282,7 +283,23 @@ class Localuser {
this.guilds.push(guildy);
this.guildids.set(guildy.id, guildy);
document.getElementById("servers").insertBefore(guildy.generateGuildIcon(), document.getElementById("bottomseparator"));
break;
}
case "MESSAGE_REACTION_ADD":
if (SnowFlake.hasSnowFlakeFromID(temp.d.message_id, Message)) {
const message = SnowFlake.getSnowFlakeFromID(temp.d.message_id, Message).getObject();
const guild = SnowFlake.getSnowFlakeFromID(temp.d.guild_id, Guild).getObject();
message.giveReaction(temp.d.emoji, new Member(temp.d.member, guild));
}
break;
case "MESSAGE_REACTION_REMOVE":
if (SnowFlake.hasSnowFlakeFromID(temp.d.message_id, Message)) {
const message = SnowFlake.getSnowFlakeFromID(temp.d.message_id, Message).getObject();
const guild = SnowFlake.getSnowFlakeFromID(temp.d.guild_id, Guild).getObject();
console.log("test");
message.takeReaction(temp.d.emoji, temp.d.user_id);
}
break;
}
}
else if (temp.op === 10) {

View file

@ -5,6 +5,8 @@ import { MarkDown } from "./markdown.js";
import { Embed } from "./embed.js";
import { File } from "./file.js";
import { SnowFlake } from "./snowflake.js";
import { Emoji } from "./emoji.js";
new Emoji();
class Message {
static contextmenu = new Contextmenu("message menu");
owner;
@ -23,6 +25,7 @@ class Message {
static resolve;
div;
member;
reactions;
get id() {
return this.snowflake.id;
}
@ -46,6 +49,12 @@ class Message {
Message.contextmenu.addbutton("Copy message id", function () {
navigator.clipboard.writeText(this.id);
});
Message.contextmenu.addsubmenu("Add reaction", function (e) {
Emoji.emojiPicker(e.x, e.y).then(_ => {
console.log(_, ":3");
this.reactionToggle(_);
});
});
Message.contextmenu.addbutton("Edit", function () {
this.channel.editing = this;
const markdown = (document.getElementById("typebox"))["markdown"];
@ -61,6 +70,24 @@ class Message {
this.headers = this.owner.headers;
this.giveData(messagejson);
}
reactionToggle(emoji) {
if (typeof emoji === "string") {
let remove = false;
for (const thing of this.reactions) {
if (thing.emoji.name === emoji) {
remove = thing.me;
break;
}
}
fetch(this.info.api.toString() + "/channels/" + this.channel.id + "/messages/" + this.id + "/reactions/" + encodeURIComponent(emoji) + "/@me", {
method: remove ? "DELETE" : "PUT",
headers: this.headers,
});
}
else {
emoji;
}
}
giveData(messagejson) {
for (const thing of Object.keys(messagejson)) {
if (thing === "attachments") {
@ -92,6 +119,9 @@ class Message {
}
this[thing] = messagejson[thing];
}
if (messagejson.reactions?.length) {
console.log(messagejson.reactions, ":3");
}
this.author = new User(messagejson.author, this.localuser);
for (const thing in messagejson.mentions) {
this.mentions[thing] = new User(messagejson.mentions[thing], this.localuser);
@ -184,6 +214,7 @@ class Message {
this.channel.lastmessage = prev.getObject();
}
}
reactdiv;
generateMessage(premessage = null) {
if (!premessage) {
premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
@ -207,25 +238,6 @@ class Message {
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");
@ -352,8 +364,76 @@ class Message {
div.classList.add("topMessage");
}
div["all"] = this;
const reactions = document.createElement("div");
reactions.classList.add("flexltr", "reactiondiv");
this.reactdiv = new WeakRef(reactions);
this.updateReactions();
div.append(reactions);
return (div);
}
updateReactions() {
const reactdiv = this.reactdiv.deref();
if (!reactdiv)
return;
reactdiv.innerHTML = "";
for (const thing of this.reactions) {
console.log(thing, ":3");
const reaction = document.createElement("div");
reaction.classList.add("reaction");
if (thing.me) {
reaction.classList.add("meReacted");
}
const emoji = document.createElement("p");
emoji.textContent = thing.emoji.name;
reaction.append(emoji);
const count = document.createElement("p");
count.textContent = "" + thing.count;
count.classList.add("reactionCount");
reaction.append(count);
reactdiv.append(reaction);
reaction.onclick = _ => {
this.reactionToggle(thing.emoji.name);
};
}
}
giveReaction(data, member) {
for (const thing of this.reactions) {
if (thing.emoji.name === data.name) {
thing.count++;
if (member.id === this.localuser.user.id) {
thing.me = true;
this.updateReactions();
return;
}
}
}
this.reactions.push({
count: 1,
emoji: data,
me: member.id === this.localuser.user.id
});
this.updateReactions();
}
takeReaction(data, id) {
console.log("test");
for (const i in this.reactions) {
const thing = this.reactions[i];
console.log(thing, data);
if (thing.emoji.name === data.name) {
thing.count--;
if (thing.count === 0) {
this.reactions.splice(+i, 1);
this.updateReactions();
return;
}
if (id === this.localuser.user.id) {
thing.me = false;
this.updateReactions();
return;
}
}
}
}
buildhtml(premessage, del = Message.del) {
if (this.div) {
console.error(`HTML for ${this.snowflake} already exists, aborting`);