Reaction support
This commit is contained in:
parent
8b3fe48a74
commit
24bdde1968
12 changed files with 458 additions and 51 deletions
|
@ -8,8 +8,6 @@ import { Settings, RoleList } from "./settings.js";
|
||||||
import { Role } from "./role.js";
|
import { Role } from "./role.js";
|
||||||
import { InfiniteScroller } from "./infiniteScroller.js";
|
import { InfiniteScroller } from "./infiniteScroller.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { Emoji } from "./emoji.js";
|
|
||||||
new Emoji();
|
|
||||||
class Channel {
|
class Channel {
|
||||||
editing;
|
editing;
|
||||||
type;
|
type;
|
||||||
|
|
|
@ -20,7 +20,11 @@ class Contextmenu {
|
||||||
this.buttons = [];
|
this.buttons = [];
|
||||||
}
|
}
|
||||||
addbutton(text, onclick, img = null, shown = _ => true, enabled = _ => true) {
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
makemenu(x, y, addinfo, obj) {
|
makemenu(x, y, addinfo, obj) {
|
||||||
|
@ -38,7 +42,12 @@ class Contextmenu {
|
||||||
intext.textContent = thing[0];
|
intext.textContent = thing[0];
|
||||||
textb.appendChild(intext);
|
textb.appendChild(intext);
|
||||||
console.log(thing);
|
console.log(thing);
|
||||||
|
if (thing[5] === "button") {
|
||||||
intext.onclick = thing[1].bind(addinfo, obj);
|
intext.onclick = thing[1].bind(addinfo, obj);
|
||||||
|
}
|
||||||
|
else if (thing[5] === "submenu") {
|
||||||
|
intext.onclick = thing[1].bind(addinfo);
|
||||||
|
}
|
||||||
div.appendChild(textb);
|
div.appendChild(textb);
|
||||||
}
|
}
|
||||||
if (Contextmenu.currentmenu != "") {
|
if (Contextmenu.currentmenu != "") {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { Contextmenu } from "./contextmenu.js";
|
||||||
class Emoji {
|
class Emoji {
|
||||||
static emojis;
|
static emojis;
|
||||||
static decodeEmojiList(buffer) {
|
static decodeEmojiList(buffer) {
|
||||||
|
@ -62,6 +63,62 @@ class Emoji {
|
||||||
Emoji.decodeEmojiList(e);
|
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();
|
Emoji.grabEmoji();
|
||||||
export { Emoji };
|
export { Emoji };
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Fullscreen } from "./fullscreen.js";
|
||||||
import { setTheme } from "./login.js";
|
import { setTheme } from "./login.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { Message } from "./message.js";
|
import { Message } from "./message.js";
|
||||||
|
import { Member } from "./member.js";
|
||||||
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
|
const wsCodesRetry = new Set([4000, 4003, 4005, 4007, 4008, 4009]);
|
||||||
class Localuser {
|
class Localuser {
|
||||||
lastSequence = null;
|
lastSequence = null;
|
||||||
|
@ -282,7 +283,23 @@ class Localuser {
|
||||||
this.guilds.push(guildy);
|
this.guilds.push(guildy);
|
||||||
this.guildids.set(guildy.id, guildy);
|
this.guildids.set(guildy.id, guildy);
|
||||||
document.getElementById("servers").insertBefore(guildy.generateGuildIcon(), document.getElementById("bottomseparator"));
|
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) {
|
else if (temp.op === 10) {
|
||||||
|
|
118
.dist/message.js
118
.dist/message.js
|
@ -5,6 +5,8 @@ import { MarkDown } from "./markdown.js";
|
||||||
import { Embed } from "./embed.js";
|
import { Embed } from "./embed.js";
|
||||||
import { File } from "./file.js";
|
import { File } from "./file.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
|
import { Emoji } from "./emoji.js";
|
||||||
|
new Emoji();
|
||||||
class Message {
|
class Message {
|
||||||
static contextmenu = new Contextmenu("message menu");
|
static contextmenu = new Contextmenu("message menu");
|
||||||
owner;
|
owner;
|
||||||
|
@ -23,6 +25,7 @@ class Message {
|
||||||
static resolve;
|
static resolve;
|
||||||
div;
|
div;
|
||||||
member;
|
member;
|
||||||
|
reactions;
|
||||||
get id() {
|
get id() {
|
||||||
return this.snowflake.id;
|
return this.snowflake.id;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +49,12 @@ class Message {
|
||||||
Message.contextmenu.addbutton("Copy message id", function () {
|
Message.contextmenu.addbutton("Copy message id", function () {
|
||||||
navigator.clipboard.writeText(this.id);
|
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 () {
|
Message.contextmenu.addbutton("Edit", function () {
|
||||||
this.channel.editing = this;
|
this.channel.editing = this;
|
||||||
const markdown = (document.getElementById("typebox"))["markdown"];
|
const markdown = (document.getElementById("typebox"))["markdown"];
|
||||||
|
@ -61,6 +70,24 @@ class Message {
|
||||||
this.headers = this.owner.headers;
|
this.headers = this.owner.headers;
|
||||||
this.giveData(messagejson);
|
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) {
|
giveData(messagejson) {
|
||||||
for (const thing of Object.keys(messagejson)) {
|
for (const thing of Object.keys(messagejson)) {
|
||||||
if (thing === "attachments") {
|
if (thing === "attachments") {
|
||||||
|
@ -92,6 +119,9 @@ class Message {
|
||||||
}
|
}
|
||||||
this[thing] = messagejson[thing];
|
this[thing] = messagejson[thing];
|
||||||
}
|
}
|
||||||
|
if (messagejson.reactions?.length) {
|
||||||
|
console.log(messagejson.reactions, ":3");
|
||||||
|
}
|
||||||
this.author = new User(messagejson.author, this.localuser);
|
this.author = new User(messagejson.author, this.localuser);
|
||||||
for (const thing in messagejson.mentions) {
|
for (const thing in messagejson.mentions) {
|
||||||
this.mentions[thing] = new User(messagejson.mentions[thing], this.localuser);
|
this.mentions[thing] = new User(messagejson.mentions[thing], this.localuser);
|
||||||
|
@ -184,6 +214,7 @@ class Message {
|
||||||
this.channel.lastmessage = prev.getObject();
|
this.channel.lastmessage = prev.getObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
reactdiv;
|
||||||
generateMessage(premessage = null) {
|
generateMessage(premessage = null) {
|
||||||
if (!premessage) {
|
if (!premessage) {
|
||||||
premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
|
premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||||
|
@ -207,25 +238,6 @@ class Message {
|
||||||
const reply = document.createElement("div");
|
const reply = document.createElement("div");
|
||||||
username.classList.add("username");
|
username.classList.add("username");
|
||||||
this.author.bind(username, this.guild);
|
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");
|
reply.classList.add("replytext");
|
||||||
replyline.appendChild(reply);
|
replyline.appendChild(reply);
|
||||||
const line2 = document.createElement("hr");
|
const line2 = document.createElement("hr");
|
||||||
|
@ -352,8 +364,76 @@ class Message {
|
||||||
div.classList.add("topMessage");
|
div.classList.add("topMessage");
|
||||||
}
|
}
|
||||||
div["all"] = this;
|
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);
|
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) {
|
buildhtml(premessage, del = Message.del) {
|
||||||
if (this.div) {
|
if (this.div) {
|
||||||
console.error(`HTML for ${this.snowflake} already exists, aborting`);
|
console.error(`HTML for ${this.snowflake} already exists, aborting`);
|
||||||
|
|
|
@ -11,8 +11,7 @@ import { Role } from "./role.js";
|
||||||
import {InfiniteScroller} from "./infiniteScroller.js";
|
import {InfiniteScroller} from "./infiniteScroller.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { channeljson, messagejson, readyjson } from "./jsontypes.js";
|
import { channeljson, messagejson, readyjson } from "./jsontypes.js";
|
||||||
import {Emoji} from "./emoji.js";
|
|
||||||
new Emoji();
|
|
||||||
declare global {
|
declare global {
|
||||||
interface NotificationOptions {
|
interface NotificationOptions {
|
||||||
image?: string
|
image?: string
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class Contextmenu{
|
class Contextmenu{
|
||||||
static currentmenu;
|
static currentmenu;
|
||||||
name:string;
|
name:string;
|
||||||
buttons:[string,Function,string,Function,Function][];
|
buttons:[string,Function,string,Function,Function,string][];
|
||||||
div:HTMLDivElement;
|
div:HTMLDivElement;
|
||||||
static setup(){
|
static setup(){
|
||||||
Contextmenu.currentmenu="";
|
Contextmenu.currentmenu="";
|
||||||
|
@ -20,7 +20,11 @@ class Contextmenu{
|
||||||
this.buttons=[]
|
this.buttons=[]
|
||||||
}
|
}
|
||||||
addbutton(text:string,onclick:Function,img=null,shown=_=>true,enabled=_=>true){
|
addbutton(text:string,onclick:Function,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:string,onclick:(e:MouseEvent)=>void,img=null,shown=_=>true,enabled=_=>true){
|
||||||
|
this.buttons.push([text,onclick,img,shown,enabled,"submenu"])
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
makemenu(x:number,y:number,addinfo:any,obj:HTMLElement){
|
makemenu(x:number,y:number,addinfo:any,obj:HTMLElement){
|
||||||
|
@ -36,7 +40,12 @@ class Contextmenu{
|
||||||
intext.textContent=thing[0]
|
intext.textContent=thing[0]
|
||||||
textb.appendChild(intext)
|
textb.appendChild(intext)
|
||||||
console.log(thing)
|
console.log(thing)
|
||||||
|
if(thing[5]==="button"){
|
||||||
intext.onclick=thing[1].bind(addinfo,obj);
|
intext.onclick=thing[1].bind(addinfo,obj);
|
||||||
|
}else if(thing[5]==="submenu"){
|
||||||
|
intext.onclick=thing[1].bind(addinfo);
|
||||||
|
}
|
||||||
|
|
||||||
div.appendChild(textb);
|
div.appendChild(textb);
|
||||||
}
|
}
|
||||||
if(Contextmenu.currentmenu!=""){
|
if(Contextmenu.currentmenu!=""){
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { Contextmenu } from "./contextmenu.js";
|
||||||
|
|
||||||
class Emoji{
|
class Emoji{
|
||||||
static emojis:{
|
static emojis:{
|
||||||
name:string,
|
name:string,
|
||||||
|
@ -70,6 +72,65 @@ class Emoji{
|
||||||
Emoji.decodeEmojiList(e);
|
Emoji.decodeEmojiList(e);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
static async emojiPicker(x:number,y:number):Promise<Emoji|string>{
|
||||||
|
let res:(r:Emoji|string)=>void;
|
||||||
|
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();
|
Emoji.grabEmoji();
|
||||||
export {Emoji};
|
export {Emoji};
|
||||||
|
|
|
@ -271,7 +271,13 @@ type messagejson={
|
||||||
mention_roles: [], //need examples to fix
|
mention_roles: [], //need examples to fix
|
||||||
attachments: filejson[],
|
attachments: filejson[],
|
||||||
embeds: embedjson[],
|
embeds: embedjson[],
|
||||||
reactions: [], //ToDo
|
reactions: {
|
||||||
|
count:number,
|
||||||
|
emoji:{
|
||||||
|
name:string
|
||||||
|
},//very likely needs expanding
|
||||||
|
me:boolean,
|
||||||
|
}[],
|
||||||
nonce: string,
|
nonce: string,
|
||||||
pinned: boolean,
|
pinned: boolean,
|
||||||
type: number
|
type: number
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {setTheme, Specialuser} from "./login.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { Message } from "./message.js";
|
import { Message } from "./message.js";
|
||||||
import { channeljson, guildjson, memberjson, readyjson, userjson } from "./jsontypes.js";
|
import { channeljson, guildjson, memberjson, readyjson, userjson } from "./jsontypes.js";
|
||||||
|
import { Member } from "./member.js";
|
||||||
|
|
||||||
const wsCodesRetry=new Set([4000,4003,4005,4007,4008,4009]);
|
const wsCodesRetry=new Set([4000,4003,4005,4007,4008,4009]);
|
||||||
|
|
||||||
|
@ -291,7 +292,24 @@ class Localuser{
|
||||||
this.guilds.push(guildy);
|
this.guilds.push(guildy);
|
||||||
this.guildids.set(guildy.id,guildy);
|
this.guildids.set(guildy.id,guildy);
|
||||||
document.getElementById("servers").insertBefore(guildy.generateGuildIcon(),document.getElementById("bottomseparator"));
|
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){
|
}else if(temp.op===10){
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { Role } from "./role.js";
|
||||||
import {File} from "./file.js";
|
import {File} from "./file.js";
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { messagejson } from "./jsontypes.js";
|
import { messagejson } from "./jsontypes.js";
|
||||||
|
import {Emoji} from "./emoji.js";
|
||||||
|
new Emoji();
|
||||||
|
|
||||||
class Message{
|
class Message{
|
||||||
static contextmenu=new Contextmenu("message menu");
|
static contextmenu=new Contextmenu("message menu");
|
||||||
|
@ -28,6 +30,7 @@ class Message{
|
||||||
static resolve:Function;
|
static resolve:Function;
|
||||||
div:HTMLDivElement;
|
div:HTMLDivElement;
|
||||||
member:Member;
|
member:Member;
|
||||||
|
reactions:messagejson["reactions"];
|
||||||
get id(){
|
get id(){
|
||||||
return this.snowflake.id;
|
return this.snowflake.id;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +54,12 @@ class Message{
|
||||||
Message.contextmenu.addbutton("Copy message id",function(){
|
Message.contextmenu.addbutton("Copy message id",function(){
|
||||||
navigator.clipboard.writeText(this.id);
|
navigator.clipboard.writeText(this.id);
|
||||||
});
|
});
|
||||||
|
Message.contextmenu.addsubmenu("Add reaction",function(this:Message,e){
|
||||||
|
Emoji.emojiPicker(e.x,e.y).then(_=>{
|
||||||
|
console.log(_,":3")
|
||||||
|
this.reactionToggle(_);
|
||||||
|
});
|
||||||
|
});
|
||||||
Message.contextmenu.addbutton("Edit",function(){
|
Message.contextmenu.addbutton("Edit",function(){
|
||||||
this.channel.editing=this;
|
this.channel.editing=this;
|
||||||
const markdown=(document.getElementById("typebox"))["markdown"] as MarkDown;
|
const markdown=(document.getElementById("typebox"))["markdown"] as MarkDown;
|
||||||
|
@ -67,6 +76,24 @@ class Message{
|
||||||
this.giveData(messagejson);
|
this.giveData(messagejson);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
reactionToggle(emoji:string|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:messagejson){
|
giveData(messagejson:messagejson){
|
||||||
for(const thing of Object.keys(messagejson)){
|
for(const thing of Object.keys(messagejson)){
|
||||||
if(thing==="attachments"){
|
if(thing==="attachments"){
|
||||||
|
@ -94,7 +121,9 @@ class Message{
|
||||||
}
|
}
|
||||||
this[thing]=messagejson[thing];
|
this[thing]=messagejson[thing];
|
||||||
}
|
}
|
||||||
|
if(messagejson.reactions?.length){
|
||||||
|
console.log(messagejson.reactions,":3");
|
||||||
|
}
|
||||||
|
|
||||||
this.author=new User(messagejson.author,this.localuser);
|
this.author=new User(messagejson.author,this.localuser);
|
||||||
for(const thing in messagejson.mentions){
|
for(const thing in messagejson.mentions){
|
||||||
|
@ -187,6 +216,7 @@ class Message{
|
||||||
this.channel.lastmessage=prev.getObject();
|
this.channel.lastmessage=prev.getObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
reactdiv:WeakRef<HTMLDivElement>;
|
||||||
generateMessage(premessage:Message=null){
|
generateMessage(premessage:Message=null){
|
||||||
if(!premessage){
|
if(!premessage){
|
||||||
premessage=this.channel.idToPrev.get(this.snowflake)?.getObject();
|
premessage=this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||||
|
@ -210,27 +240,6 @@ class Message{
|
||||||
const reply=document.createElement("div");
|
const reply=document.createElement("div");
|
||||||
username.classList.add("username");
|
username.classList.add("username");
|
||||||
this.author.bind(username,this.guild);
|
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");
|
reply.classList.add("replytext");
|
||||||
replyline.appendChild(reply);
|
replyline.appendChild(reply);
|
||||||
const line2=document.createElement("hr");
|
const line2=document.createElement("hr");
|
||||||
|
@ -360,8 +369,76 @@ class Message{
|
||||||
|
|
||||||
}
|
}
|
||||||
div["all"]=this;
|
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)
|
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:{name:string},member: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:{name:string},id:string){
|
||||||
|
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:Message,del:Promise<void>=Message.del){
|
buildhtml(premessage:Message,del:Promise<void>=Message.del){
|
||||||
if(this.div){console.error(`HTML for ${this.snowflake} already exists, aborting`);return;}
|
if(this.div){console.error(`HTML for ${this.snowflake} already exists, aborting`);return;}
|
||||||
//premessage??=messages.lastChild;
|
//premessage??=messages.lastChild;
|
||||||
|
|
|
@ -1233,6 +1233,7 @@ span {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.flexttb{
|
.flexttb{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1536,3 +1537,78 @@ form div{
|
||||||
width:.5in;
|
width:.5in;
|
||||||
height:.5in;
|
height:.5in;
|
||||||
}
|
}
|
||||||
|
.emojiPicker{
|
||||||
|
position:absolute;
|
||||||
|
width:3.5in;
|
||||||
|
height:4in;
|
||||||
|
background:var(--profile-info-bg);
|
||||||
|
border-radius:.15in;
|
||||||
|
border:solid var(--black) .03in;
|
||||||
|
box-shadow:black .03in .03in .2in;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.emojiSelect{
|
||||||
|
font-size:.23in;
|
||||||
|
text-align: center;
|
||||||
|
cursor:pointer;
|
||||||
|
width:.4in;
|
||||||
|
height:.4in;
|
||||||
|
background:color-mix(in hsl, var(--profile-info-bg),black);
|
||||||
|
border-radius:2in;
|
||||||
|
display:flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
border:solid var(--black) .03in;
|
||||||
|
flex-shrink:0;
|
||||||
|
}
|
||||||
|
.emojiTitle{
|
||||||
|
padding: .03in;
|
||||||
|
padding-left: .1in;
|
||||||
|
border-bottom: solid var(--black);
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: .025in;
|
||||||
|
}
|
||||||
|
.emojiBody{
|
||||||
|
display:flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: stretch;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
/* height: 100%; */
|
||||||
|
overflow-y: scroll;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.reactionCount{
|
||||||
|
position:absolute;
|
||||||
|
font-size:.125in;
|
||||||
|
padding:0 .01in;
|
||||||
|
bottom:-.03in;
|
||||||
|
left:-.03in;
|
||||||
|
background: var(--channels-bg);
|
||||||
|
border:solid var(--black) .021in;
|
||||||
|
border-radius:.05in;
|
||||||
|
}
|
||||||
|
.reactiondiv{
|
||||||
|
|
||||||
|
}
|
||||||
|
.reaction{
|
||||||
|
width:.25in;
|
||||||
|
position:relative;
|
||||||
|
height:.25in;
|
||||||
|
display:flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: stretch;
|
||||||
|
background: var(--profile-info-bg);
|
||||||
|
border-radius:.05in;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
border:solid var(--black);
|
||||||
|
margin-right:.05in;
|
||||||
|
p{
|
||||||
|
flex-grow:0;
|
||||||
|
flex-shrink:0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue