Various improvements and checks
This commit is contained in:
parent
a2abc91a2a
commit
1608d00beb
30 changed files with 541 additions and 360 deletions
|
@ -39,6 +39,7 @@ class Channel {
|
|||
infinite;
|
||||
idToPrev = new Map();
|
||||
idToNext = new Map();
|
||||
messages = new Map();
|
||||
get id() {
|
||||
return this.snowflake.id;
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ class Channel {
|
|||
if (this.idToNext.has(snowflake)) {
|
||||
return this.idToNext.get(snowflake)?.id;
|
||||
}
|
||||
else if (this.lastmessage.id !== id) {
|
||||
else if (this.lastmessage?.id !== id) {
|
||||
await this.grabAfter(id);
|
||||
return this.idToNext.get(snowflake)?.id;
|
||||
}
|
||||
|
@ -177,19 +178,11 @@ class Channel {
|
|||
}
|
||||
}.bind(this), async function (id) {
|
||||
//await new Promise(_=>{setTimeout(_,Math.random()*10)})
|
||||
const snowflake = SnowFlake.getSnowFlakeFromID(id, Message);
|
||||
if (!snowflake.getObject()) {
|
||||
//await this.grabArround(id);
|
||||
console.error("Uh...");
|
||||
}
|
||||
const messgage = this.messages.get(id);
|
||||
try {
|
||||
const prev = this.idToPrev.get(snowflake);
|
||||
if (prev) {
|
||||
const messgage = this.messageids.get(prev);
|
||||
if (messgage) {
|
||||
const html = snowflake.getObject().buildhtml(messgage);
|
||||
return html;
|
||||
}
|
||||
if (messgage) {
|
||||
const html = messgage.buildhtml();
|
||||
return html;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -595,10 +588,12 @@ class Channel {
|
|||
});
|
||||
}
|
||||
setReplying(message) {
|
||||
if (this.replyingto) {
|
||||
if (this.replyingto?.div) {
|
||||
this.replyingto.div.classList.remove("replying");
|
||||
}
|
||||
this.replyingto = message;
|
||||
if (!this.replyingto?.div)
|
||||
return;
|
||||
console.log(message);
|
||||
this.replyingto.div.classList.add("replying");
|
||||
this.makereplybox();
|
||||
|
@ -611,7 +606,7 @@ class Channel {
|
|||
span.textContent = "Replying to " + this.replyingto.author.username;
|
||||
const X = document.createElement("button");
|
||||
X.onclick = _ => {
|
||||
if (this.replyingto) {
|
||||
if (this.replyingto?.div) {
|
||||
this.replyingto.div.classList.remove("replying");
|
||||
}
|
||||
replybox.classList.add("hideReplyBox");
|
||||
|
@ -744,8 +739,7 @@ class Channel {
|
|||
this.children = build;
|
||||
}
|
||||
async grabAfter(id) {
|
||||
console.log(id, this.lastmessage.id);
|
||||
if (id === this.lastmessage.id) {
|
||||
if (id === this.lastmessage?.id) {
|
||||
return;
|
||||
}
|
||||
await fetch(this.info.api + "/channels/" + this.id + "/messages?limit=100&after=" + id, {
|
||||
|
@ -1025,8 +1019,8 @@ class Channel {
|
|||
console.log(this.lastmessageid, messagez.snowflake, ":3");
|
||||
if (this.lastmessageid) {
|
||||
this.idToNext.set(this.lastmessageid, messagez.snowflake);
|
||||
this.idToPrev.set(messagez.snowflake, this.lastmessageid);
|
||||
}
|
||||
this.idToPrev.set(messagez.snowflake, this.lastmessageid);
|
||||
this.lastmessageid = messagez.snowflake;
|
||||
this.messageids.set(messagez.snowflake, messagez);
|
||||
if (messagez.author === this.localuser.user) {
|
||||
|
@ -1078,7 +1072,9 @@ class Channel {
|
|||
const images = message.getimages();
|
||||
if (images.length) {
|
||||
const image = images[0];
|
||||
imgurl ||= image.proxy_url;
|
||||
if (image.proxy_url) {
|
||||
imgurl ||= image.proxy_url;
|
||||
}
|
||||
imgurl ||= image.url;
|
||||
}
|
||||
const notification = new Notification(this.notititle(message), {
|
||||
|
|
|
@ -35,12 +35,6 @@ class Direct extends Guild {
|
|||
this.calculateReorder();
|
||||
this.printServers();
|
||||
}
|
||||
sortchannels() {
|
||||
this.headchannels.sort((a, b) => {
|
||||
const result = (a.lastmessageid.getUnixTime() - b.lastmessageid.getUnixTime());
|
||||
return Number(-result);
|
||||
});
|
||||
}
|
||||
giveMember(_member) {
|
||||
console.error("not a real guild, can't give member object");
|
||||
}
|
||||
|
@ -105,7 +99,10 @@ class Group extends Channel {
|
|||
this.lastmessageid ??= null;
|
||||
this.mentions = 0;
|
||||
this.setUpInfiniteScroller();
|
||||
this.position = Math.max(this.lastmessageid.getUnixTime(), this.snowflake.getUnixTime());
|
||||
if (this.lastmessageid) {
|
||||
this.position = this.lastmessageid.getUnixTime();
|
||||
}
|
||||
this.position = -Math.max(this.position, this.snowflake.getUnixTime());
|
||||
}
|
||||
createguildHTML() {
|
||||
const div = document.createElement("div");
|
||||
|
@ -134,14 +131,16 @@ class Group extends Channel {
|
|||
return;
|
||||
}
|
||||
this.buildmessages();
|
||||
history.pushState(null, null, "/channels/" + this.guild_id + "/" + this.snowflake);
|
||||
history.pushState(null, "", "/channels/" + this.guild_id + "/" + this.id);
|
||||
document.getElementById("channelname").textContent = "@" + this.name;
|
||||
document.getElementById("channelTopic").setAttribute("hidden", "");
|
||||
document.getElementById("typebox").contentEditable = "" + true;
|
||||
}
|
||||
messageCreate(messagep) {
|
||||
const messagez = new Message(messagep.d, this);
|
||||
this.idToNext.set(this.lastmessageid, messagez.snowflake);
|
||||
if (this.lastmessageid) {
|
||||
this.idToNext.set(this.lastmessageid, messagez.snowflake);
|
||||
}
|
||||
this.idToPrev.set(messagez.snowflake, this.lastmessageid);
|
||||
this.lastmessageid = messagez.snowflake;
|
||||
this.messageids.set(messagez.snowflake, messagez);
|
||||
|
@ -161,7 +160,7 @@ class Group extends Channel {
|
|||
if (messagez.author === this.localuser.user) {
|
||||
return;
|
||||
}
|
||||
if (this.localuser.lookingguild.prevchannel === this && document.hasFocus()) {
|
||||
if (this.localuser.lookingguild?.prevchannel === this && document.hasFocus()) {
|
||||
return;
|
||||
}
|
||||
if (this.notification === "all") {
|
||||
|
@ -175,7 +174,7 @@ class Group extends Channel {
|
|||
return message.author.username;
|
||||
}
|
||||
unreads() {
|
||||
const sentdms = document.getElementById("sentdms");
|
||||
const sentdms = document.getElementById("sentdms"); //Need to change sometime
|
||||
let current = null;
|
||||
for (const thing of sentdms.children) {
|
||||
if (thing["all"] === this) {
|
||||
|
@ -184,7 +183,7 @@ class Group extends Channel {
|
|||
}
|
||||
if (this.hasunreads) {
|
||||
if (current) {
|
||||
current.noti.textContent = this.mentions;
|
||||
current["noti"].textContent = this.mentions;
|
||||
return;
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
|
|
|
@ -65,13 +65,15 @@ class Embed {
|
|||
authorline.append(a);
|
||||
embed.append(authorline);
|
||||
}
|
||||
const title = document.createElement("a");
|
||||
title.append(new MarkDown(this.json.title, this.channel).makeHTML());
|
||||
if (this.json.url) {
|
||||
title.href = this.json.url;
|
||||
if (this.json.title) {
|
||||
const title = document.createElement("a");
|
||||
title.append(new MarkDown(this.json.title, this.channel).makeHTML());
|
||||
if (this.json.url) {
|
||||
title.href = this.json.url;
|
||||
}
|
||||
title.classList.add("embedtitle");
|
||||
embed.append(title);
|
||||
}
|
||||
title.classList.add("embedtitle");
|
||||
embed.append(title);
|
||||
if (this.json.description) {
|
||||
const p = document.createElement("p");
|
||||
p.append(new MarkDown(this.json.description, this.channel).makeHTML());
|
||||
|
@ -150,7 +152,7 @@ class Embed {
|
|||
table.classList.add("embed", "linkembed");
|
||||
const trtop = document.createElement("tr");
|
||||
table.append(trtop);
|
||||
{
|
||||
if (this.json.url && this.json.title) {
|
||||
const td = document.createElement("td");
|
||||
const a = document.createElement("a");
|
||||
a.href = this.json.url;
|
||||
|
@ -174,9 +176,11 @@ class Embed {
|
|||
}
|
||||
const bottomtr = document.createElement("tr");
|
||||
const td = document.createElement("td");
|
||||
const span = document.createElement("span");
|
||||
span.textContent = this.json.description;
|
||||
td.append(span);
|
||||
if (this.json.description) {
|
||||
const span = document.createElement("span");
|
||||
span.textContent = this.json.description;
|
||||
td.append(span);
|
||||
}
|
||||
bottomtr.append(td);
|
||||
table.append(bottomtr);
|
||||
return table;
|
||||
|
@ -194,12 +198,16 @@ class Embed {
|
|||
div.append(provider);
|
||||
}
|
||||
const a = document.createElement("a");
|
||||
a.href = this.json.url;
|
||||
a.textContent = this.json.title;
|
||||
div.append(a);
|
||||
const description = document.createElement("p");
|
||||
description.textContent = this.json.description;
|
||||
div.append(description);
|
||||
if (this.json.url && this.json.url) {
|
||||
a.href = this.json.url;
|
||||
a.textContent = this.json.url;
|
||||
div.append(a);
|
||||
}
|
||||
if (this.json.description) {
|
||||
const description = document.createElement("p");
|
||||
description.textContent = this.json.description;
|
||||
div.append(description);
|
||||
}
|
||||
if (this.json.thumbnail) {
|
||||
const img = document.createElement("img");
|
||||
img.classList.add("bigembedimg");
|
||||
|
|
|
@ -13,7 +13,7 @@ class Emoji {
|
|||
}
|
||||
get localuser() {
|
||||
if (this.owner instanceof Guild) {
|
||||
return this.guild.localuser;
|
||||
return this.owner.localuser;
|
||||
}
|
||||
else {
|
||||
return this.owner;
|
||||
|
|
|
@ -23,7 +23,7 @@ class File {
|
|||
}
|
||||
getHTML(temp = false) {
|
||||
const src = this.proxy_url || this.url;
|
||||
if (this.width) {
|
||||
if (this.width && this.height) {
|
||||
let scale = 1;
|
||||
const max = 96 * 3;
|
||||
scale = Math.max(scale, this.width / max);
|
||||
|
@ -57,7 +57,7 @@ class File {
|
|||
video.append(source);
|
||||
source.type = this.content_type;
|
||||
video.controls = !temp;
|
||||
if (this.width) {
|
||||
if (this.width && this.height) {
|
||||
video.width = this.width;
|
||||
video.height = this.height;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class File {
|
|||
return new File({
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
id: null,
|
||||
id: "null",
|
||||
content_type: file.type,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
|
|
|
@ -97,10 +97,21 @@ class Guild {
|
|||
this.roleids.set(roleh.snowflake, roleh);
|
||||
}
|
||||
if (member instanceof User) {
|
||||
Member.resolveMember(member, this).then(_ => this.member = _);
|
||||
Member.resolveMember(member, this).then(_ => {
|
||||
if (_) {
|
||||
this.member = _;
|
||||
}
|
||||
else {
|
||||
console.error("Member was unable to resolve");
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
Member.new(member, this).then(_ => this.member = _);
|
||||
Member.new(member, this).then(_ => {
|
||||
if (_) {
|
||||
this.member = _;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const thing of json.channels) {
|
||||
const temp = new Channel(thing, this);
|
||||
|
@ -199,11 +210,10 @@ class Guild {
|
|||
if (thing.move_id && thing.move_id !== thing.parent_id) {
|
||||
thing.parent_id = thing.move_id;
|
||||
thisthing.parent_id = thing.parent_id;
|
||||
thing.move_id = undefined;
|
||||
thing.move_id = null;
|
||||
}
|
||||
if (thisthing.position || thisthing.parent_id) {
|
||||
build.push(thisthing);
|
||||
console.log(this.channelids[thisthing.parent_id]);
|
||||
}
|
||||
if (thing.children.length > 0) {
|
||||
const things = thing.calculateReorder();
|
||||
|
@ -369,6 +379,8 @@ class Guild {
|
|||
if (thing.hasunreads) {
|
||||
build.read_states.push({ channel_id: thing.snowflake, message_id: thing.lastmessageid, read_state_type: 0 });
|
||||
thing.lastreadmessageid = thing.lastmessageid;
|
||||
if (!thing.myhtml)
|
||||
continue;
|
||||
thing.myhtml.classList.remove("cunread");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,16 +38,17 @@ function showAccountSwitcher() {
|
|||
userinfo.addEventListener("click", _ => {
|
||||
thisuser.unload();
|
||||
thisuser.swapped = true;
|
||||
document.getElementById("loading").classList.remove("doneloading");
|
||||
document.getElementById("loading").classList.add("loading");
|
||||
const loading = document.getElementById("loading");
|
||||
loading.classList.remove("doneloading");
|
||||
loading.classList.add("loading");
|
||||
thisuser = new Localuser(specialuser);
|
||||
users["currentuser"] = specialuser.uid;
|
||||
localStorage.setItem("userinfos", JSON.stringify(users));
|
||||
thisuser.initwebsocket().then(_ => {
|
||||
thisuser.loaduser();
|
||||
thisuser.init();
|
||||
document.getElementById("loading").classList.add("doneloading");
|
||||
document.getElementById("loading").classList.remove("loading");
|
||||
loading.classList.add("doneloading");
|
||||
loading.classList.remove("loading");
|
||||
console.log("done loading");
|
||||
});
|
||||
userinfo.remove();
|
||||
|
@ -90,8 +91,9 @@ try {
|
|||
thisuser.initwebsocket().then(_ => {
|
||||
thisuser.loaduser();
|
||||
thisuser.init();
|
||||
document.getElementById("loading").classList.add("doneloading");
|
||||
document.getElementById("loading").classList.remove("loading");
|
||||
const loading = document.getElementById("loading");
|
||||
loading.classList.add("doneloading");
|
||||
loading.classList.remove("loading");
|
||||
console.log("done loading");
|
||||
});
|
||||
}
|
||||
|
@ -103,10 +105,14 @@ catch (e) {
|
|||
{
|
||||
const menu = new Contextmenu("create rightclick");
|
||||
menu.addbutton("Create channel", function () {
|
||||
thisuser.lookingguild.createchannels();
|
||||
if (thisuser.lookingguild) {
|
||||
thisuser.lookingguild.createchannels();
|
||||
}
|
||||
}, null, _ => { return thisuser.isAdmin(); });
|
||||
menu.addbutton("Create category", function () {
|
||||
thisuser.lookingguild.createcategory();
|
||||
if (thisuser.lookingguild) {
|
||||
thisuser.lookingguild.createcategory();
|
||||
}
|
||||
}, null, _ => { return thisuser.isAdmin(); });
|
||||
menu.bind(document.getElementById("channels"));
|
||||
}
|
||||
|
@ -114,6 +120,8 @@ const pasteimage = document.getElementById("pasteimage");
|
|||
let replyingto = null;
|
||||
async function enter(event) {
|
||||
const channel = thisuser.channelfocus;
|
||||
if (!channel || !thisuser.channelfocus)
|
||||
return;
|
||||
channel.typingstart();
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
|
@ -124,13 +132,14 @@ async function enter(event) {
|
|||
else {
|
||||
replyingto = thisuser.channelfocus.replyingto;
|
||||
let replying = replyingto;
|
||||
if (replyingto) {
|
||||
if (replyingto?.div) {
|
||||
replyingto.div.classList.remove("replying");
|
||||
}
|
||||
thisuser.channelfocus.replyingto = null;
|
||||
channel.sendMessage(markdown.rawString, {
|
||||
attachments: images,
|
||||
replyingto: replying,
|
||||
embeds: [],
|
||||
replyingto: replying
|
||||
});
|
||||
thisuser.channelfocus.makereplybox();
|
||||
}
|
||||
|
@ -165,6 +174,8 @@ const imageshtml = [];
|
|||
import { File } from "./file.js";
|
||||
import { MarkDown } from "./markdown.js";
|
||||
document.addEventListener('paste', async (e) => {
|
||||
if (!e.clipboardData)
|
||||
return;
|
||||
Array.from(e.clipboardData.files).forEach(async (f) => {
|
||||
const file = File.initFromBlob(f);
|
||||
e.preventDefault();
|
||||
|
@ -180,13 +191,13 @@ function userSettings() {
|
|||
}
|
||||
document.getElementById("settings").onclick = userSettings;
|
||||
if (mobile) {
|
||||
document.getElementById("channelw").onclick = function () {
|
||||
document.getElementById("channelw").onclick = () => {
|
||||
document.getElementById("channels").parentNode.classList.add("collapse");
|
||||
document.getElementById("servertd").classList.add("collapse");
|
||||
document.getElementById("servers").classList.add("collapse");
|
||||
};
|
||||
document.getElementById("mobileback").textContent = "#";
|
||||
document.getElementById("mobileback").onclick = function () {
|
||||
document.getElementById("mobileback").onclick = () => {
|
||||
document.getElementById("channels").parentNode.classList.remove("collapse");
|
||||
document.getElementById("servertd").classList.remove("collapse");
|
||||
document.getElementById("servers").classList.remove("collapse");
|
||||
|
|
|
@ -50,6 +50,8 @@ class InfiniteScroller {
|
|||
scrollTop;
|
||||
needsupdate = true;
|
||||
async updatestuff() {
|
||||
if (!this.scroll)
|
||||
return;
|
||||
this.timeout = null;
|
||||
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
|
||||
this.scrollTop = this.scroll.scrollTop;
|
||||
|
@ -65,6 +67,8 @@ class InfiniteScroller {
|
|||
//this.watchForChange();
|
||||
}
|
||||
async firstElement(id) {
|
||||
if (!this.scroll)
|
||||
return;
|
||||
const html = await this.getHTMLFromID(id);
|
||||
this.scroll.appendChild(html);
|
||||
this.HTMLElements.push([html, id]);
|
||||
|
@ -85,14 +89,20 @@ class InfiniteScroller {
|
|||
};
|
||||
}
|
||||
async watchForTop() {
|
||||
if (!this.scroll)
|
||||
return false;
|
||||
let again = false;
|
||||
if (this.scrollTop === 0) {
|
||||
this.scrollTop = 1;
|
||||
this.scroll.scrollTop = 1;
|
||||
}
|
||||
if (this.scrollTop < this.minDist) {
|
||||
const previd = this.HTMLElements.at(0)[1];
|
||||
const nextid = await this.getIDFromOffset(previd, 1);
|
||||
let nextid;
|
||||
const firstelm = this.HTMLElements.at(0);
|
||||
if (firstelm) {
|
||||
const previd = firstelm[1];
|
||||
nextid = await this.getIDFromOffset(previd, 1);
|
||||
}
|
||||
if (!nextid) {
|
||||
}
|
||||
else {
|
||||
|
@ -110,10 +120,12 @@ class InfiniteScroller {
|
|||
;
|
||||
}
|
||||
if (this.scrollTop > this.maxDist) {
|
||||
again = true;
|
||||
const html = this.HTMLElements.shift();
|
||||
await this.destroyFromID(html[1]);
|
||||
this.scrollTop -= 60;
|
||||
if (html) {
|
||||
again = true;
|
||||
await this.destroyFromID(html[1]);
|
||||
this.scrollTop -= 60;
|
||||
}
|
||||
}
|
||||
if (again) {
|
||||
await this.watchForTop();
|
||||
|
@ -121,11 +133,17 @@ class InfiniteScroller {
|
|||
return again;
|
||||
}
|
||||
async watchForBottom() {
|
||||
if (!this.scroll)
|
||||
return false;
|
||||
let again = false;
|
||||
const scrollBottom = this.scrollBottom;
|
||||
if (scrollBottom < this.minDist) {
|
||||
const previd = this.HTMLElements.at(-1)[1];
|
||||
const nextid = await this.getIDFromOffset(previd, -1);
|
||||
let nextid;
|
||||
const lastelm = this.HTMLElements.at(-1);
|
||||
if (lastelm) {
|
||||
const previd = lastelm[1];
|
||||
nextid = await this.getIDFromOffset(previd, -1);
|
||||
}
|
||||
if (!nextid) {
|
||||
}
|
||||
else {
|
||||
|
@ -141,10 +159,12 @@ class InfiniteScroller {
|
|||
;
|
||||
}
|
||||
if (scrollBottom > this.maxDist) {
|
||||
again = true;
|
||||
const html = this.HTMLElements.pop();
|
||||
await this.destroyFromID(html[1]);
|
||||
this.scrollBottom -= 60;
|
||||
if (html) {
|
||||
await this.destroyFromID(html[1]);
|
||||
this.scrollBottom -= 60;
|
||||
again = true;
|
||||
}
|
||||
}
|
||||
if (again) {
|
||||
await this.watchForBottom();
|
||||
|
@ -154,14 +174,14 @@ class InfiniteScroller {
|
|||
async watchForChange() {
|
||||
try {
|
||||
if (this.currrunning) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
this.currrunning = true;
|
||||
}
|
||||
if (!this.div) {
|
||||
this.currrunning = false;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const out = await Promise.allSettled([this.watchForTop(), this.watchForBottom()]);
|
||||
const changed = (out[0].value || out[1].value);
|
||||
|
@ -177,6 +197,7 @@ class InfiniteScroller {
|
|||
catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
async focus(id, flash = true) {
|
||||
let element;
|
||||
|
@ -217,7 +238,9 @@ class InfiniteScroller {
|
|||
await this.destroyFromID(thing[1]);
|
||||
}
|
||||
this.HTMLElements = [];
|
||||
clearTimeout(this.timeout);
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
if (this.div) {
|
||||
this.div.remove();
|
||||
}
|
||||
|
|
|
@ -691,6 +691,8 @@ class Localuser {
|
|||
if (!guild)
|
||||
return;
|
||||
const memb = await Member.new(typing.d.member, guild);
|
||||
if (!memb)
|
||||
return;
|
||||
if (memb.id === this.user.id) {
|
||||
console.log("you is typing");
|
||||
return;
|
||||
|
@ -834,7 +836,7 @@ class Localuser {
|
|||
});
|
||||
const bclear = settingsLeft.addButtonInput("Clear banner", "Clear", () => {
|
||||
bfile = null;
|
||||
hypouser.banner = null;
|
||||
hypouser.banner = undefined;
|
||||
settingsLeft.changed();
|
||||
regen();
|
||||
});
|
||||
|
|
|
@ -56,7 +56,7 @@ class MarkDown {
|
|||
if (first) {
|
||||
i--;
|
||||
}
|
||||
let element = null;
|
||||
let element;
|
||||
let keepys = "";
|
||||
if (txt[i + 1] === "#") {
|
||||
console.log("test");
|
||||
|
@ -97,17 +97,23 @@ class MarkDown {
|
|||
for (; txt[i] !== "\n" && txt[i] !== undefined; i++) {
|
||||
build.push(txt[i]);
|
||||
}
|
||||
if (stdsize) {
|
||||
element = document.createElement("span");
|
||||
try {
|
||||
if (stdsize) {
|
||||
element = document.createElement("span");
|
||||
}
|
||||
else
|
||||
continue;
|
||||
if (keep) {
|
||||
element.append(keepys);
|
||||
}
|
||||
element.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
|
||||
span.append(element);
|
||||
}
|
||||
if (keep) {
|
||||
element.append(keepys);
|
||||
finally {
|
||||
i -= 1;
|
||||
console.log(txt[i]);
|
||||
continue;
|
||||
}
|
||||
element.appendChild(this.markdown(build, { keep: keep, stdsize: stdsize }));
|
||||
span.append(element);
|
||||
i -= 1;
|
||||
console.log(txt[i]);
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
i++;
|
||||
|
@ -483,18 +489,24 @@ class MarkDown {
|
|||
}
|
||||
};
|
||||
box.onpaste = _ => {
|
||||
if (!_.clipboardData)
|
||||
return;
|
||||
console.log(_.clipboardData.types);
|
||||
const data = _.clipboardData.getData("text");
|
||||
document.execCommand('insertHTML', false, data);
|
||||
_.preventDefault();
|
||||
if (!box.onkeyup)
|
||||
return;
|
||||
box.onkeyup(new KeyboardEvent("_"));
|
||||
};
|
||||
}
|
||||
boxupdate(box) {
|
||||
var restore = saveCaretPosition(box);
|
||||
const restore = saveCaretPosition(box);
|
||||
box.innerHTML = "";
|
||||
box.append(this.makeHTML({ keep: true }));
|
||||
restore();
|
||||
if (restore) {
|
||||
restore();
|
||||
}
|
||||
}
|
||||
static gatherBoxText(element) {
|
||||
if (element.tagName.toLowerCase() === "img") {
|
||||
|
@ -521,10 +533,14 @@ class MarkDown {
|
|||
//solution from https://stackoverflow.com/questions/4576694/saving-and-restoring-caret-position-for-contenteditable-div
|
||||
function saveCaretPosition(context) {
|
||||
var selection = window.getSelection();
|
||||
if (!selection)
|
||||
return;
|
||||
var range = selection.getRangeAt(0);
|
||||
range.setStart(context, 0);
|
||||
var len = range.toString().length;
|
||||
return function restore() {
|
||||
if (!selection)
|
||||
return;
|
||||
var pos = getTextNodeAtPosition(context, len);
|
||||
selection.removeAllRanges();
|
||||
var range = new Range();
|
||||
|
@ -535,6 +551,8 @@ function saveCaretPosition(context) {
|
|||
function getTextNodeAtPosition(root, index) {
|
||||
const NODE_TYPE = NodeFilter.SHOW_TEXT;
|
||||
var treeWalker = document.createTreeWalker(root, NODE_TYPE, function next(elem) {
|
||||
if (!elem.textContent)
|
||||
return 0;
|
||||
if (index > elem.textContent.length) {
|
||||
index -= elem.textContent.length;
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
|
|
|
@ -25,9 +25,12 @@ class Member {
|
|||
if (User.userids[memberjson.id]) {
|
||||
this.user = User.userids[memberjson.id];
|
||||
}
|
||||
else {
|
||||
else if (memberjson.user) {
|
||||
this.user = new User(memberjson.user, owner.localuser);
|
||||
}
|
||||
else {
|
||||
throw new Error("Missing user object of this member");
|
||||
}
|
||||
this.owner = owner;
|
||||
for (const thing of Object.keys(memberjson)) {
|
||||
if (thing === "guild") {
|
||||
|
@ -64,9 +67,12 @@ class Member {
|
|||
if (User.userids[memberjson.id]) {
|
||||
user = User.userids[memberjson.id];
|
||||
}
|
||||
else {
|
||||
else if (memberjson.user) {
|
||||
user = new User(memberjson.user, owner.localuser);
|
||||
}
|
||||
else {
|
||||
throw new Error("missing user object of this member");
|
||||
}
|
||||
if (user.members.has(owner)) {
|
||||
let memb = user.members.get(owner);
|
||||
if (memb === undefined) {
|
||||
|
@ -91,22 +97,22 @@ class Member {
|
|||
const maybe = user.members.get(guild);
|
||||
if (!user.members.has(guild)) {
|
||||
const membpromise = guild.localuser.resolvemember(user.id, guild.id);
|
||||
let res;
|
||||
const promise = new Promise(r => { res = r; });
|
||||
const promise = new Promise(async (res) => {
|
||||
const membjson = await membpromise;
|
||||
if (membjson === undefined) {
|
||||
res(undefined);
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
const member = new Member(membjson, guild);
|
||||
const map = guild.localuser.presences;
|
||||
member.getPresence(map.get(member.id));
|
||||
map.delete(member.id);
|
||||
res(member);
|
||||
return member;
|
||||
}
|
||||
});
|
||||
user.members.set(guild, promise);
|
||||
const membjson = await membpromise;
|
||||
if (membjson === undefined) {
|
||||
res(undefined);
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
const member = new Member(membjson, guild);
|
||||
const map = guild.localuser.presences;
|
||||
member.getPresence(map.get(member.id));
|
||||
map.delete(member.id);
|
||||
res(member);
|
||||
return member;
|
||||
}
|
||||
}
|
||||
if (maybe instanceof Promise) {
|
||||
return await maybe;
|
||||
|
|
|
@ -45,12 +45,6 @@ class Message {
|
|||
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);
|
||||
|
@ -69,7 +63,7 @@ class Message {
|
|||
});
|
||||
Message.contextmenu.addbutton("Edit", function () {
|
||||
this.channel.editing = this;
|
||||
const markdown = (document.getElementById("typebox"))["markdown"];
|
||||
const markdown = document.getElementById("typebox")["markdown"];
|
||||
markdown.txt = this.content.rawString.split('');
|
||||
markdown.boxupdate(document.getElementById("typebox"));
|
||||
}, null, _ => { return _.author.id === _.localuser.user.id; });
|
||||
|
@ -81,6 +75,7 @@ class Message {
|
|||
this.owner = owner;
|
||||
this.headers = this.owner.headers;
|
||||
this.giveData(messagejson);
|
||||
this.owner.messages.set(this.id, this);
|
||||
}
|
||||
reactionToggle(emoji) {
|
||||
let remove = false;
|
||||
|
@ -121,7 +116,9 @@ class Message {
|
|||
continue;
|
||||
}
|
||||
else if (thing === "member") {
|
||||
Member.new(messagejson.member, this.guild).then(_ => { this.member = _; });
|
||||
Member.new(messagejson.member, this.guild).then(_ => {
|
||||
this.member = _;
|
||||
});
|
||||
continue;
|
||||
}
|
||||
else if (thing === "embeds") {
|
||||
|
@ -182,7 +179,7 @@ class Message {
|
|||
return;
|
||||
try {
|
||||
this.div.remove();
|
||||
this.div = null;
|
||||
this.div = undefined;
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
|
@ -221,23 +218,37 @@ class Message {
|
|||
deleteEvent() {
|
||||
if (this.div) {
|
||||
this.div.innerHTML = "";
|
||||
this.div = null;
|
||||
this.div = undefined;
|
||||
}
|
||||
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);
|
||||
if (prev) {
|
||||
this.channel.idToPrev.delete(this.snowflake);
|
||||
}
|
||||
if (next) {
|
||||
this.channel.idToNext.delete(this.snowflake);
|
||||
}
|
||||
if (prev && next) {
|
||||
this.channel.idToPrev.set(next, prev);
|
||||
this.channel.idToNext.set(prev, next);
|
||||
}
|
||||
this.channel.messageids.delete(this.snowflake);
|
||||
const regen = prev.getObject();
|
||||
if (regen) {
|
||||
regen.generateMessage();
|
||||
if (prev && prev.getObject()) {
|
||||
prev.getObject().generateMessage();
|
||||
}
|
||||
if (this.channel.lastmessage === this) {
|
||||
this.channel.lastmessage = prev.getObject();
|
||||
if (prev) {
|
||||
this.channel.lastmessage = prev.getObject();
|
||||
}
|
||||
else {
|
||||
this.channel.lastmessage = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
reactdiv;
|
||||
generateMessage(premessage = null) {
|
||||
generateMessage(premessage = undefined) {
|
||||
if (!this.div)
|
||||
return;
|
||||
if (!premessage) {
|
||||
premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||
}
|
||||
|
@ -467,13 +478,12 @@ class Message {
|
|||
}
|
||||
}
|
||||
}
|
||||
buildhtml(premessage) {
|
||||
buildhtml(premessage = undefined) {
|
||||
if (this.div) {
|
||||
console.error(`HTML for ${this.snowflake} already exists, aborting`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
//premessage??=messages.lastChild;
|
||||
const div = document.createElement("div");
|
||||
this.div = div;
|
||||
this.messageevents(div);
|
||||
|
|
|
@ -33,7 +33,7 @@ class SnowFlake {
|
|||
}
|
||||
/**
|
||||
* Just to clarify bc TS, it returns a SnowFlake\<type> which is what you entered with the type parameter
|
||||
*
|
||||
* @deprecated
|
||||
**/
|
||||
static getSnowFlakeFromID(id, type) {
|
||||
if (!SnowFlake.SnowFlakes.get(type)) {
|
||||
|
@ -56,6 +56,11 @@ class SnowFlake {
|
|||
return snowflake;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
*
|
||||
*/
|
||||
static hasSnowFlakeFromID(id, type) {
|
||||
if (!SnowFlake.SnowFlakes.get(type)) {
|
||||
return false;
|
||||
|
|
|
@ -191,12 +191,19 @@ class User {
|
|||
html.after(error);
|
||||
return;
|
||||
}
|
||||
_.bind(html);
|
||||
if (_) {
|
||||
_.bind(html);
|
||||
}
|
||||
}).catch(_ => {
|
||||
console.log(_);
|
||||
});
|
||||
}
|
||||
this.profileclick(html, guild);
|
||||
if (guild) {
|
||||
this.profileclick(html, guild);
|
||||
}
|
||||
else {
|
||||
this.profileclick(html);
|
||||
}
|
||||
User.contextmenu.bind(html, this);
|
||||
}
|
||||
static async resolve(id, localuser) {
|
||||
|
@ -269,18 +276,20 @@ class User {
|
|||
return;
|
||||
for (const id of this.badge_ids) {
|
||||
const badgejson = await this.getBadge(id);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
badgediv.append(badge);
|
||||
}
|
||||
})();
|
||||
{
|
||||
|
@ -337,7 +346,7 @@ class User {
|
|||
}
|
||||
return div;
|
||||
}
|
||||
profileclick(obj, guild) {
|
||||
profileclick(obj, guild = undefined) {
|
||||
obj.onclick = e => {
|
||||
this.buildprofile(e.clientX, e.clientY, guild);
|
||||
e.stopPropagation();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue