"use strict" import { Message } from "./message.js"; import {Voice} from "./audio.js"; import {Contextmenu} from "./contextmenu.js"; import {Fullscreen} from "./fullscreen.js"; import {markdown} from "./markdown.js"; import {Guild} from "./guild.js"; import { Localuser } from "./localuser.js"; import { Permissions } from "./permissions.js"; declare global { interface NotificationOptions { image?: string } } class Channel{ editing:Message; type:number; owner:Guild; headers:Localuser["headers"]; messages:Message[]; name:string; id:string; parent_id:string; parrent:Channel; children:Channel[]; guild_id:string; messageids:{[key : string]:Message}; permission_overwrites:{[key:string]:Permissions}; topic:string; nsfw:boolean; position:number; lastreadmessageid:string; lastmessageid:string; mentions:number; lastpin:string; move_id:string; typing:number; message_notifications:number; allthewayup:boolean; static contextmenu=new Contextmenu("channel menu"); static setupcontextmenu(){ Channel.contextmenu.addbutton("Copy channel id",function(){ console.log(this) navigator.clipboard.writeText(this.id); }); Channel.contextmenu.addbutton("Mark as read",function(){ console.log(this) this.readbottom(); }); Channel.contextmenu.addbutton("Delete channel",function(){ console.log(this) this.deleteChannel(); },null,_=>{console.log(_);return _.isAdmin()}); Channel.contextmenu.addbutton("Edit channel",function(){ this.editChannel(this); },null,_=>{return _.isAdmin()}); } constructor(JSON,owner:Guild){ if(JSON===-1){ return; } this.editing; this.type=JSON.type; this.owner=owner; this.headers=this.owner.headers; this.messages=[]; this.name=JSON.name; this.id=JSON.id; this.parent_id=JSON.parent_id; this.parrent=null; this.children=[]; this.guild_id=JSON.guild_id; this.messageids={}; this.permission_overwrites={}; for(const thing of JSON.permission_overwrites){ this.permission_overwrites[thing.id]=new Permissions(thing.allow,thing.deny); } console.log(this.permission_overwrites) this.topic=JSON.topic; this.nsfw=JSON.nsfw; this.position=JSON.position; this.lastreadmessageid=null; this.lastmessageid=JSON.last_message_id; } isAdmin(){ return this.guild.isAdmin(); } get guild(){ return this.owner; } get localuser(){ return this.guild.localuser; } get info(){ return this.owner.info; } readStateInfo(json){ this.lastreadmessageid=json.last_message_id; this.mentions=json.mention_count; this.mentions??=0; this.lastpin=json.last_pin_timestamp; } get hasunreads(){ return this.lastmessageid!==this.lastreadmessageid&&this.type!==4; } get canMessage(){ console.log("this should run"); for(const thing of Object.entries(this.permission_overwrites)){ const perm=thing[1].getPermision("SEND_MESSAGES"); if(perm===1){ return true } if(perm===-1){ return false; } } return true; } sortchildren(){ this.children.sort((a,b)=>{return a.position-b.position}); } resolveparent(guild:Guild){ this.parrent=guild.channelids[this.parent_id]; this.parrent??=null; if(this.parrent!==null){ this.parrent.children.push(this); } return this.parrent===null; } calculateReorder(){ let position=-1; let build=[]; for(const thing of this.children){ const thisthing={id:thing.id,position:undefined,parent_id:undefined}; if(thing.position{Channel.dragged=[this,div];e.stopImmediatePropagation()}) div.addEventListener("dragend",()=>{Channel.dragged=[]}) if(this.type===4){ this.sortchildren(); const caps=document.createElement("div"); const decdiv=document.createElement("div"); const decoration=document.createElement("b"); decoration.textContent="▼" decdiv.appendChild(decoration) const myhtml=document.createElement("p2"); myhtml.textContent=this.name; decdiv.appendChild(myhtml); caps.appendChild(decdiv); const childrendiv=document.createElement("div"); if(admin){ const addchannel=document.createElement("span"); addchannel.textContent="+"; addchannel.classList.add("addchannel"); caps.appendChild(addchannel); addchannel.onclick=function(){ this.guild.createchannels(this.createChannel.bind(this)); }.bind(this); this.coatDropDiv(decdiv,childrendiv); } div.appendChild(caps) caps.classList.add("capsflex") decdiv.classList.add("channeleffects"); decdiv.classList.add("channel"); Channel.contextmenu.bind(decdiv,this); decdiv["all"]=this; for(const channel of this.children){ childrendiv.appendChild(channel.createguildHTML(admin)); } childrendiv.classList.add("channels"); setTimeout(_=>{childrendiv.style.height = childrendiv.scrollHeight + 'px';},100) decdiv.onclick=function(){ if(decoration.textContent==="▼"){// decoration.textContent="▲"; //childrendiv.classList.add("colapsediv"); childrendiv.style.height = '0px'; }else{ decoration.textContent="▼"; //childrendiv.classList.remove("colapsediv") childrendiv.style.height = childrendiv.scrollHeight + 'px'; } } div.appendChild(childrendiv); }else{ div.classList.add("channel"); if(this.hasunreads){ div.classList.add("cunread"); } Channel.contextmenu.bind(div,this); if(admin){this.coatDropDiv(div);} div["all"]=this; const myhtml=document.createElement("span"); myhtml.textContent=this.name; if(this.type===0){ const decoration=document.createElement("b"); decoration.textContent="#" div.appendChild(decoration) decoration.classList.add("space"); }else if(this.type===2){// const decoration=document.createElement("b"); decoration.textContent="🕪" div.appendChild(decoration) decoration.classList.add("spacee"); }else if(this.type===5){// const decoration=document.createElement("b"); decoration.textContent="📣" div.appendChild(decoration) decoration.classList.add("spacee"); }else{ console.log(this.type) } div.appendChild(myhtml); div.onclick=_=>{ this.getHTML(); } } return div; } get myhtml(){ const search=document.getElementById("channels").children[0].children if(this.guild!==this.localuser.lookingguild){ return null }else if(this.parrent){ for(const thing of search){ if(thing["all"]===this.parrent){ for(const thing2 of thing.children[1].children){ if(thing2["all"]===this){ return thing2; } } } } }else{ for(const thing of search){ if(thing["all"]===this){ return thing; } } } return null; } readbottom(){ if(!this.hasunreads){ return; } fetch(this.info.api.toString()+"/v9/channels/"+this.id+"/messages/"+this.lastmessageid+"/ack",{ method:"POST", headers:this.headers, body:JSON.stringify({}) }); this.lastreadmessageid=this.lastmessageid; this.guild.unreads(); if(this.myhtml!==null){ this.myhtml.classList.remove("cunread"); } } coatDropDiv(div:HTMLDivElement,container:HTMLElement|boolean=false){ div.addEventListener("dragenter", (event) => { console.log("enter") event.preventDefault(); }); div.addEventListener("dragover", (event) => { event.preventDefault(); }); div.addEventListener("drop", (event) => { const that=Channel.dragged[0]; event.preventDefault(); if(container){ that.move_id=this.id; if(that.parrent){ that.parrent.children.splice(that.parrent.children.indexOf(that),1); } that.parrent=this; (container as HTMLElement).prepend(Channel.dragged[1]); this.children.unshift(that); }else{ console.log(this,Channel.dragged); that.move_id=this.parent_id; if(that.parrent){ that.parrent.children.splice(that.parrent.children.indexOf(that),1); }else{ this.guild.headchannels.splice(this.guild.headchannels.indexOf(that),1); } that.parrent=this.parrent; if(that.parrent){ const build=[]; for(let i=0;i{return j.json()}).then(responce=>{ document.getElementById("messages").innerHTML = ''; for(const thing of responce){ const messager=new Message(thing,this) if(out.messageids[messager.id]==undefined){ out.messageids[messager.id]=messager; out.messages.push(messager); } } out.buildmessages(); }) } delChannel(JSON){ const build=[]; for(const thing of this.children){ if(thing.id!==JSON.id){ build.push(thing) } } this.children=build; } async grabmoremessages(){ if(this.messages.length===0||this.allthewayup){ return; } const out=this; await fetch(this.info.api.toString()+"/channels/"+this.id+"/messages?before="+this.messages[this.messages.length-1].id+"&limit=100",{ method:"GET", headers:this.headers }).then((j)=>{return j.json()}).then(responce=>{ //messages.innerHTML = ''; //responce.reverse() let next:Message; if(responce.length===0){ out.allthewayup=true; } for(const i in responce){ let messager:Message; if(!next){ messager=new Message(responce[i],this) }else{ messager=next; } if(responce[+i+1]!==undefined){ next=new Message(responce[+i+1],this); }else{ next=undefined; console.log("ohno",+i+1) } if(out.messageids[messager.id]==undefined){ out.messageids[messager.id]=messager; out.buildmessage(messager,next); out.messages.push(messager); }else{ console.log("How???") } } //out.buildmessages(); }) return; } buildmessage(message:Message,next:Message){ const built=message.buildhtml(next); document.getElementById("messages").prepend(built); } buildmessages(){ for(const i in this.messages){ const prev=this.messages[(+i)+1]; const built=this.messages[i].buildhtml(prev); document.getElementById("messages").prepend(built); } document.getElementById("messagecontainer").scrollTop = document.getElementById("messagecontainer").scrollHeight; } updateChannel(JSON){ this.type=JSON.type; this.name=JSON.name; this.parent_id=JSON.parent_id; this.parrent=null; this.children=[]; this.guild_id=JSON.guild_id; this.messageids={}; this.permission_overwrites=JSON.permission_overwrites; this.topic=JSON.topic; this.nsfw=JSON.nsfw; } typingstart(){ if(this.typing>new Date().getTime()){ return; } this.typing=new Date().getTime()+6000; fetch(this.info.api.toString()+"/channels/"+this.id+"/typing",{ method:"POST", headers:this.headers }) } get notification(){ let notinumber=this.message_notifications; if(+notinumber===3){notinumber=null;} notinumber??=this.guild.message_notifications; switch(+notinumber){ case 0: return "all"; case 1: return "mentions"; case 2: return "none"; case 3: return "default"; } } async sendMessage(content:string,{attachments=[],embeds=[],replyingto=null}){ let replyjson:any; if(replyingto){ replyjson= { "guild_id":replyingto.guild.id, "channel_id": replyingto.channel.id, "message_id": replyingto.id, }; }; if(attachments.length===0){ const body={ content:content, nonce:Math.floor(Math.random()*1000000000), message_reference:undefined }; if(replyjson){ body.message_reference=replyjson; } console.log(body) return await fetch(this.info.api.toString()+"/channels/"+this.id+"/messages",{ method:"POST", headers:this.headers, body:JSON.stringify(body) }) }else{ const formData = new FormData(); const body={ content:content, nonce:Math.floor(Math.random()*1000000000), message_reference:undefined } if(replyjson){ body.message_reference=replyjson; } formData.append('payload_json', JSON.stringify(body)); for(const i in attachments){ console.log(attachments[i]) formData.append("files["+i+"]",attachments[i]); } return await fetch(this.info.api.toString()+"/channels/"+this.id+"/messages", { method: 'POST', body: formData, headers:{"Authorization":this.headers.Authorization} }); } } messageCreate(messagep:any):void{ const messagez=new Message(messagep.d,this); this.lastmessageid=messagez.id; if(messagez.author===this.localuser.user){ this.lastreadmessageid=messagez.id; if(this.myhtml){ this.myhtml.classList.remove("cunread"); } }else{ if(this.myhtml){ this.myhtml.classList.add("cunread"); } } this.guild.unreads(); this.messages.unshift(messagez); const scrolly=document.getElementById("messagecontainer"); this.messageids[messagez.id]=messagez; if(this.localuser.lookingguild.prevchannel===this){ var shouldScroll=scrolly.scrollTop+scrolly.clientHeight>scrolly.scrollHeight-20; document.getElementById("messages").appendChild(messagez.buildhtml(this.messages[1])); } if(shouldScroll){ scrolly.scrollTop = scrolly.scrollHeight; } if(messagez.author===this.localuser.user){ return; } if(this.localuser.lookingguild.prevchannel===this&&document.hasFocus()){ return; } if(this.notification==="all"){ this.notify(messagez); }else if(this.notification==="mentions"&&messagez.mentionsuser(this.localuser.user)){ this.notify(messagez); } } notititle(message:Message):string{ return message.author.username+" > "+this.guild.properties.name+" > "+this.name; } notify(message:Message,deep=0){ Voice.noises(Voice.getNotificationSound()); if (!("Notification" in window)) { } else if (Notification.permission === "granted") { let noticontent=markdown(message.content).textContent; if(message.embeds[0]){ noticontent||=message.embeds[0].json.title; noticontent||=markdown(message.embeds[0].json.description).textContent; } noticontent||="Blank Message"; let imgurl=null; const images=message.getimages(); if(images.length){ const image = images[0]; imgurl||=image.proxy_url; imgurl||=image.url; } const notification = new Notification(this.notititle(message),{ body:noticontent, icon:message.author.getpfpsrc(), image:imgurl, }); notification.addEventListener("click",_=>{ window.focus(); this.getHTML(); }) } else if (Notification.permission !== "denied") { Notification.requestPermission().then(() => { if(deep===3){return}; this.notify(message,deep+1); }); } } } Channel.setupcontextmenu(); export {Channel};