ghost messages and some fixes
This commit is contained in:
parent
8e98535407
commit
c479d9a683
11 changed files with 222 additions and 29 deletions
|
@ -12,6 +12,7 @@ import {SnowFlake} from "./snowflake.js";
|
||||||
import {
|
import {
|
||||||
channeljson,
|
channeljson,
|
||||||
embedjson,
|
embedjson,
|
||||||
|
filejson,
|
||||||
messageCreateJson,
|
messageCreateJson,
|
||||||
messagejson,
|
messagejson,
|
||||||
readyjson,
|
readyjson,
|
||||||
|
@ -24,6 +25,7 @@ import {User} from "./user.js";
|
||||||
import {I18n} from "./i18n.js";
|
import {I18n} from "./i18n.js";
|
||||||
import {mobile} from "./utils/utils.js";
|
import {mobile} from "./utils/utils.js";
|
||||||
import {webhookMenu} from "./webhooks.js";
|
import {webhookMenu} from "./webhooks.js";
|
||||||
|
import {File} from "./file.js";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface NotificationOptions {
|
interface NotificationOptions {
|
||||||
|
@ -926,6 +928,11 @@ class Channel extends SnowFlake {
|
||||||
messages.append(html);
|
messages.append(html);
|
||||||
}
|
}
|
||||||
async getHTML(addstate = true) {
|
async getHTML(addstate = true) {
|
||||||
|
const ghostMessages = document.getElementById("ghostMessages") as HTMLElement;
|
||||||
|
ghostMessages.innerHTML = "";
|
||||||
|
for (const thing of this.fakeMessages) {
|
||||||
|
ghostMessages.append(thing[1]);
|
||||||
|
}
|
||||||
if (addstate) {
|
if (addstate) {
|
||||||
history.pushState([this.guild_id, this.id], "", "/channels/" + this.guild_id + "/" + this.id);
|
history.pushState([this.guild_id, this.id], "", "/channels/" + this.guild_id + "/" + this.id);
|
||||||
}
|
}
|
||||||
|
@ -1438,6 +1445,91 @@ class Channel extends SnowFlake {
|
||||||
return "default";
|
return "default";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fakeMessages: [Message, HTMLElement][] = [];
|
||||||
|
fakeMessageMap = new Map<string, [Message, HTMLElement]>();
|
||||||
|
destroyFakeMessage(id: string) {
|
||||||
|
const message = this.fakeMessageMap.get(id);
|
||||||
|
if (!message) return;
|
||||||
|
this.fakeMessages = this.fakeMessages.filter((_) => _[0] !== message[0]);
|
||||||
|
message[1].remove();
|
||||||
|
for (const {url} of message[0].attachments) {
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
this.fakeMessageMap.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
makeFakeMessage(content: string, files: filejson[] = []) {
|
||||||
|
const m = new Message(
|
||||||
|
{
|
||||||
|
author: this.localuser.user.tojson(),
|
||||||
|
channel_id: this.id,
|
||||||
|
guild_id: this.guild.id,
|
||||||
|
id: "fake" + Math.random(),
|
||||||
|
content,
|
||||||
|
timestamp: new Date() + "",
|
||||||
|
edited_timestamp: null,
|
||||||
|
mentions: [],
|
||||||
|
mention_roles: [],
|
||||||
|
mention_everyone: false,
|
||||||
|
attachments: files,
|
||||||
|
tts: false,
|
||||||
|
embeds: [],
|
||||||
|
reactions: [],
|
||||||
|
nonce: Math.random() + "",
|
||||||
|
type: 0,
|
||||||
|
pinned: false,
|
||||||
|
},
|
||||||
|
this,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
const ghostMessages = document.getElementById("ghostMessages");
|
||||||
|
if (!ghostMessages) throw Error("oops");
|
||||||
|
const html = m.buildhtml(this.lastmessage, true);
|
||||||
|
html.classList.add("messagediv", "loadingMessage");
|
||||||
|
console.log(html);
|
||||||
|
ghostMessages.append(html);
|
||||||
|
this.fakeMessages.push([m, html]);
|
||||||
|
let loadingP = document.createElement("span");
|
||||||
|
|
||||||
|
const buttons = document.createElement("div");
|
||||||
|
buttons.classList.add("flexltr");
|
||||||
|
|
||||||
|
const retryB = document.createElement("button");
|
||||||
|
retryB.textContent = I18n.message.retry();
|
||||||
|
|
||||||
|
const dont = document.createElement("button");
|
||||||
|
dont.textContent = I18n.message.delete();
|
||||||
|
dont.onclick = (_) => html.remove();
|
||||||
|
dont.style.marginLeft = "4px";
|
||||||
|
buttons.append(retryB, dont);
|
||||||
|
return {
|
||||||
|
gotid: (id: string) => {
|
||||||
|
this.fakeMessageMap.set(id, [m, html]);
|
||||||
|
const m2 = this.messages.get(id);
|
||||||
|
if (m2 && m2.div) {
|
||||||
|
this.destroyFakeMessage(id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
progress: (total: number, sofar: number) => {
|
||||||
|
if (total < 20000 || sofar === total) {
|
||||||
|
loadingP.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
html.append(loadingP);
|
||||||
|
loadingP.textContent = File.filesizehuman(sofar) + " / " + File.filesizehuman(total);
|
||||||
|
},
|
||||||
|
failed: (retry: () => void) => {
|
||||||
|
loadingP.remove();
|
||||||
|
html.append(buttons);
|
||||||
|
retryB.onclick = () => {
|
||||||
|
retry();
|
||||||
|
html.classList.remove("erroredMessage");
|
||||||
|
buttons.remove();
|
||||||
|
};
|
||||||
|
html.classList.add("erroredMessage");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
async sendMessage(
|
async sendMessage(
|
||||||
content: string,
|
content: string,
|
||||||
{
|
{
|
||||||
|
@ -1453,6 +1545,36 @@ class Channel extends SnowFlake {
|
||||||
message_id: replyingto.id,
|
message_id: replyingto.id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let prom: Promise<void>;
|
||||||
|
let res: XMLHttpRequest;
|
||||||
|
let funcs: {
|
||||||
|
gotid: (id: string) => void;
|
||||||
|
progress: (total: number, sofar: number) => void;
|
||||||
|
failed: (restart: () => void) => void;
|
||||||
|
};
|
||||||
|
const progress = (e: ProgressEvent<EventTarget>) => {
|
||||||
|
funcs.progress(e.total, e.loaded);
|
||||||
|
};
|
||||||
|
const promiseHandler = (resolve: () => void) => {
|
||||||
|
res.onload = () => {
|
||||||
|
resolve();
|
||||||
|
console.log(res.response);
|
||||||
|
funcs.gotid(res.response.id);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const fail = () => {
|
||||||
|
funcs.failed(() => {
|
||||||
|
res.open("POST", this.info.api + "/channels/" + this.id + "/messages");
|
||||||
|
res.setRequestHeader("Authorization", this.headers.Authorization);
|
||||||
|
if (ctype) {
|
||||||
|
res.setRequestHeader("Content-type", ctype);
|
||||||
|
}
|
||||||
|
res.send(rbody);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let rbody: string | FormData;
|
||||||
|
let ctype: string | undefined;
|
||||||
if (attachments.length === 0) {
|
if (attachments.length === 0) {
|
||||||
const body = {
|
const body = {
|
||||||
content,
|
content,
|
||||||
|
@ -1462,11 +1584,23 @@ class Channel extends SnowFlake {
|
||||||
if (replyjson) {
|
if (replyjson) {
|
||||||
body.message_reference = replyjson;
|
body.message_reference = replyjson;
|
||||||
}
|
}
|
||||||
return await fetch(this.info.api + "/channels/" + this.id + "/messages", {
|
res = new XMLHttpRequest();
|
||||||
|
res.responseType = "json";
|
||||||
|
res.upload.onprogress = progress;
|
||||||
|
res.onerror = fail;
|
||||||
|
prom = new Promise<void>(promiseHandler);
|
||||||
|
res.open("POST", this.info.api + "/channels/" + this.id + "/messages");
|
||||||
|
res.setRequestHeader("Content-type", (ctype = this.headers["Content-type"]));
|
||||||
|
res.setRequestHeader("Authorization", this.headers.Authorization);
|
||||||
|
funcs = this.makeFakeMessage(content);
|
||||||
|
res.send((rbody = JSON.stringify(body)));
|
||||||
|
/*
|
||||||
|
res = fetch(this.info.api + "/channels/" + this.id + "/messages", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
const body = {
|
const body = {
|
||||||
|
@ -1481,12 +1615,36 @@ class Channel extends SnowFlake {
|
||||||
for (const i in attachments) {
|
for (const i in attachments) {
|
||||||
formData.append("files[" + i + "]", attachments[i]);
|
formData.append("files[" + i + "]", attachments[i]);
|
||||||
}
|
}
|
||||||
return await fetch(this.info.api + "/channels/" + this.id + "/messages", {
|
|
||||||
|
res = new XMLHttpRequest();
|
||||||
|
res.responseType = "json";
|
||||||
|
res.upload.onprogress = progress;
|
||||||
|
res.onerror = fail;
|
||||||
|
prom = new Promise<void>(promiseHandler);
|
||||||
|
res.open("POST", this.info.api + "/channels/" + this.id + "/messages", true);
|
||||||
|
|
||||||
|
res.setRequestHeader("Authorization", this.headers.Authorization);
|
||||||
|
funcs = this.makeFakeMessage(
|
||||||
|
content,
|
||||||
|
attachments.map((_) => ({
|
||||||
|
id: "string",
|
||||||
|
filename: "",
|
||||||
|
content_type: _.type,
|
||||||
|
size: _.size,
|
||||||
|
url: URL.createObjectURL(_),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
res.send((rbody = formData));
|
||||||
|
/*
|
||||||
|
res = fetch(this.info.api + "/channels/" + this.id + "/messages", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
headers: {Authorization: this.headers.Authorization},
|
headers: {Authorization: this.headers.Authorization},
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return prom;
|
||||||
}
|
}
|
||||||
unreads() {
|
unreads() {
|
||||||
if (!this.hasunreads) {
|
if (!this.hasunreads) {
|
||||||
|
@ -1502,7 +1660,12 @@ class Channel extends SnowFlake {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
messageCreate(messagep: messageCreateJson): void {
|
async messageCreate(messagep: messageCreateJson): Promise<void> {
|
||||||
|
if (this.localuser.channelfocus !== this) {
|
||||||
|
if (this.fakeMessageMap.has(this.id)) {
|
||||||
|
this.destroyFakeMessage(this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!this.hasPermission("VIEW_CHANNEL")) {
|
if (!this.hasPermission("VIEW_CHANNEL")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1528,9 +1691,9 @@ class Channel extends SnowFlake {
|
||||||
this.guild.unreads();
|
this.guild.unreads();
|
||||||
if (this === this.localuser.channelfocus) {
|
if (this === this.localuser.channelfocus) {
|
||||||
if (!this.infinitefocus) {
|
if (!this.infinitefocus) {
|
||||||
this.tryfocusinfinate();
|
await this.tryfocusinfinate();
|
||||||
}
|
}
|
||||||
this.infinite.addedBottom();
|
await this.infinite.addedBottom();
|
||||||
}
|
}
|
||||||
if (messagez.author === this.localuser.user) {
|
if (messagez.author === this.localuser.user) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -429,6 +429,11 @@ class Group extends Channel {
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
async getHTML(addstate = true) {
|
async getHTML(addstate = true) {
|
||||||
|
const ghostMessages = document.getElementById("ghostMessages") as HTMLElement;
|
||||||
|
ghostMessages.innerHTML = "";
|
||||||
|
for (const thing of this.fakeMessages) {
|
||||||
|
ghostMessages.append(thing[1]);
|
||||||
|
}
|
||||||
const id = ++Channel.genid;
|
const id = ++Channel.genid;
|
||||||
if (this.localuser.channelfocus) {
|
if (this.localuser.channelfocus) {
|
||||||
this.localuser.channelfocus.infinite.delete();
|
this.localuser.channelfocus.infinite.delete();
|
||||||
|
@ -462,7 +467,15 @@ class Group extends Channel {
|
||||||
}
|
}
|
||||||
this.buildmessages();
|
this.buildmessages();
|
||||||
}
|
}
|
||||||
messageCreate(messagep: {d: messagejson}) {
|
async messageCreate(messagep: {d: messagejson}) {
|
||||||
|
if (this.localuser.channelfocus !== this) {
|
||||||
|
if (this.fakeMessageMap.has(this.id)) {
|
||||||
|
this.destroyFakeMessage(this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.fakeMessageMap.has(messagep.d.id)) {
|
||||||
|
this.destroyFakeMessage(messagep.d.id);
|
||||||
|
}
|
||||||
this.mentions++;
|
this.mentions++;
|
||||||
const messagez = new Message(messagep.d, this);
|
const messagez = new Message(messagep.d, this);
|
||||||
|
|
||||||
|
@ -501,9 +514,9 @@ class Group extends Channel {
|
||||||
}
|
}
|
||||||
if (this === this.localuser.channelfocus) {
|
if (this === this.localuser.channelfocus) {
|
||||||
if (!this.infinitefocus) {
|
if (!this.infinitefocus) {
|
||||||
this.tryfocusinfinate();
|
await this.tryfocusinfinate();
|
||||||
}
|
}
|
||||||
this.infinite.addedBottom();
|
await this.infinite.addedBottom();
|
||||||
}
|
}
|
||||||
this.unreads();
|
this.unreads();
|
||||||
if (messagez.author === this.localuser.user) {
|
if (messagez.author === this.localuser.user) {
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
<div style="position: relative">
|
<div style="position: relative">
|
||||||
<div id="searchOptions" class="flexttb searchOptions"></div>
|
<div id="searchOptions" class="flexttb searchOptions"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="ghostMessages"></div>
|
||||||
<div id="pasteimage" class="flexltr"></div>
|
<div id="pasteimage" class="flexltr"></div>
|
||||||
<div id="replybox" class="hideReplyBox"></div>
|
<div id="replybox" class="hideReplyBox"></div>
|
||||||
<div id="typediv">
|
<div id="typediv">
|
||||||
|
|
|
@ -188,11 +188,11 @@ import {I18n} from "./i18n.js";
|
||||||
(document.getElementById("settings") as HTMLImageElement).onclick = userSettings;
|
(document.getElementById("settings") as HTMLImageElement).onclick = userSettings;
|
||||||
const memberListToggle = document.getElementById("memberlisttoggle") as HTMLInputElement;
|
const memberListToggle = document.getElementById("memberlisttoggle") as HTMLInputElement;
|
||||||
memberListToggle.checked = !localStorage.getItem("memberNotChecked");
|
memberListToggle.checked = !localStorage.getItem("memberNotChecked");
|
||||||
memberListToggle.onclick = () => {
|
memberListToggle.onchange = () => {
|
||||||
if (!memberListToggle.checked) {
|
if (!memberListToggle.checked) {
|
||||||
localStorage.setItem("memberNotChecked", "true");
|
localStorage.setItem("memberNotChecked", "true");
|
||||||
} else {
|
} else {
|
||||||
localStorage.delete("memberNotChecked");
|
localStorage.removeItem("memberNotChecked");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (mobile) {
|
if (mobile) {
|
||||||
|
|
|
@ -130,7 +130,13 @@ class InfiniteScroller {
|
||||||
async addedBottom(): Promise<void> {
|
async addedBottom(): Promise<void> {
|
||||||
await this.updatestuff();
|
await this.updatestuff();
|
||||||
const func = this.snapBottom();
|
const func = this.snapBottom();
|
||||||
|
if (this.changePromise) {
|
||||||
|
while (this.changePromise) {
|
||||||
|
await new Promise((res) => setTimeout(res, 30));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
await this.watchForChange();
|
await this.watchForChange();
|
||||||
|
}
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +251,7 @@ class InfiniteScroller {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changePromise = new Promise<boolean>(async (res) => {
|
this.changePromise = new Promise<boolean>(async (res) => {
|
||||||
|
//debugger;
|
||||||
try {
|
try {
|
||||||
if (!this.div) {
|
if (!this.div) {
|
||||||
res(false);
|
res(false);
|
||||||
|
|
|
@ -334,7 +334,7 @@ type messagejson = {
|
||||||
member?: memberjson;
|
member?: memberjson;
|
||||||
content: string;
|
content: string;
|
||||||
timestamp: string;
|
timestamp: string;
|
||||||
edited_timestamp: string;
|
edited_timestamp: string | null;
|
||||||
tts: boolean;
|
tts: boolean;
|
||||||
mention_everyone: boolean;
|
mention_everyone: boolean;
|
||||||
mentions: []; //need examples to fix
|
mentions: []; //need examples to fix
|
||||||
|
@ -349,7 +349,7 @@ type messagejson = {
|
||||||
nonce: string;
|
nonce: string;
|
||||||
pinned: boolean;
|
pinned: boolean;
|
||||||
type: number;
|
type: number;
|
||||||
webhook: webhookInfo;
|
webhook?: webhookInfo;
|
||||||
};
|
};
|
||||||
type filejson = {
|
type filejson = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -156,7 +156,6 @@ function makePlayBox(mor: string | media, player: MediaPlayer, ctime = 0) {
|
||||||
};
|
};
|
||||||
function followUpdates(cur: mediaEvents) {
|
function followUpdates(cur: mediaEvents) {
|
||||||
if (audio && cur.type !== "playing") {
|
if (audio && cur.type !== "playing") {
|
||||||
console.log(cur);
|
|
||||||
}
|
}
|
||||||
if (cur.type == "audio" && audio) {
|
if (cur.type == "audio" && audio) {
|
||||||
if (cur.t == "start") {
|
if (cur.t == "start") {
|
||||||
|
@ -220,7 +219,6 @@ function makePlayBox(mor: string | media, player: MediaPlayer, ctime = 0) {
|
||||||
regenTime(+bar.value * 1000);
|
regenTime(+bar.value * 1000);
|
||||||
};
|
};
|
||||||
async function regenTime(curTime: number = 0) {
|
async function regenTime(curTime: number = 0) {
|
||||||
console.log(med.length);
|
|
||||||
const len = await med.length;
|
const len = await med.length;
|
||||||
bar.disabled = false;
|
bar.disabled = false;
|
||||||
bar.max = "" + len / 1000;
|
bar.max = "" + len / 1000;
|
||||||
|
@ -229,7 +227,6 @@ function makePlayBox(mor: string | media, player: MediaPlayer, ctime = 0) {
|
||||||
}
|
}
|
||||||
regenTime();
|
regenTime();
|
||||||
title.textContent = thing.title;
|
title.textContent = thing.title;
|
||||||
console.log(thing);
|
|
||||||
});
|
});
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +271,6 @@ class MediaPlayer {
|
||||||
if (!document.contains(elm)) {
|
if (!document.contains(elm)) {
|
||||||
clearInterval(int);
|
clearInterval(int);
|
||||||
this.listeners = this.listeners.filter((_) => _[0] !== updates);
|
this.listeners = this.listeners.filter((_) => _[0] !== updates);
|
||||||
console.log("cleared data");
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
@ -352,7 +348,6 @@ class MediaPlayer {
|
||||||
if (size !== 0) {
|
if (size !== 0) {
|
||||||
cbuff = (await read.read()).value;
|
cbuff = (await read.read()).value;
|
||||||
index = 0;
|
index = 0;
|
||||||
console.log("got more buffer", index, arri, size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
|
@ -372,7 +367,6 @@ class MediaPlayer {
|
||||||
const Identify = String.fromCharCode(await next(), await next(), await next());
|
const Identify = String.fromCharCode(await next(), await next(), await next());
|
||||||
const sizeArr = await get8BitArray(3);
|
const sizeArr = await get8BitArray(3);
|
||||||
const size = (sizeArr[0] << 16) + (sizeArr[1] << 8) + sizeArr[2];
|
const size = (sizeArr[0] << 16) + (sizeArr[1] << 8) + sizeArr[2];
|
||||||
console.log(sizeLeft, size, index);
|
|
||||||
if (Identify === String.fromCharCode(0, 0, 0)) {
|
if (Identify === String.fromCharCode(0, 0, 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +383,6 @@ class MediaPlayer {
|
||||||
} else {
|
} else {
|
||||||
mappy.set(Identify, await get8BitArray(size));
|
mappy.set(Identify, await get8BitArray(size));
|
||||||
}
|
}
|
||||||
console.warn(sizeLeft);
|
|
||||||
}
|
}
|
||||||
const pic = mappy.get("PIC");
|
const pic = mappy.get("PIC");
|
||||||
if (pic) {
|
if (pic) {
|
||||||
|
@ -400,7 +393,6 @@ class MediaPlayer {
|
||||||
}
|
}
|
||||||
const description = new TextDecoder().decode(new Uint8Array(desc));
|
const description = new TextDecoder().decode(new Uint8Array(desc));
|
||||||
i++;
|
i++;
|
||||||
console.warn(pic, i);
|
|
||||||
const blob = new Blob([pic.slice(i, pic.length).buffer], {type: "image/jpeg"});
|
const blob = new Blob([pic.slice(i, pic.length).buffer], {type: "image/jpeg"});
|
||||||
const urlmaker = window.URL || window.webkitURL;
|
const urlmaker = window.URL || window.webkitURL;
|
||||||
const url = urlmaker.createObjectURL(blob);
|
const url = urlmaker.createObjectURL(blob);
|
||||||
|
@ -467,7 +459,6 @@ class MediaPlayer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(sizeLeft, size, index);
|
|
||||||
if (Identify === String.fromCharCode(0, 0, 0, 0)) {
|
if (Identify === String.fromCharCode(0, 0, 0, 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -484,7 +475,6 @@ class MediaPlayer {
|
||||||
} else {
|
} else {
|
||||||
mappy.set(Identify, await get8BitArray(size));
|
mappy.set(Identify, await get8BitArray(size));
|
||||||
}
|
}
|
||||||
console.warn(sizeLeft);
|
|
||||||
}
|
}
|
||||||
const pic = mappy.get("APIC");
|
const pic = mappy.get("APIC");
|
||||||
if (pic) {
|
if (pic) {
|
||||||
|
@ -530,14 +520,12 @@ class MediaPlayer {
|
||||||
}
|
}
|
||||||
const TYER = mappy.get("TYER");
|
const TYER = mappy.get("TYER");
|
||||||
if (TYER) {
|
if (TYER) {
|
||||||
console.log(decodeText(TYER));
|
|
||||||
output.year = +decodeText(TYER);
|
output.year = +decodeText(TYER);
|
||||||
}
|
}
|
||||||
const TLEN = mappy.get("TLEN");
|
const TLEN = mappy.get("TLEN");
|
||||||
if (TLEN) {
|
if (TLEN) {
|
||||||
output.length = +decodeText(TLEN);
|
output.length = +decodeText(TLEN);
|
||||||
}
|
}
|
||||||
console.log(mappy);
|
|
||||||
}
|
}
|
||||||
} //TODO implement more metadata types
|
} //TODO implement more metadata types
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -550,12 +538,10 @@ class MediaPlayer {
|
||||||
const audio = document.createElement("audio");
|
const audio = document.createElement("audio");
|
||||||
audio.src = url;
|
audio.src = url;
|
||||||
audio.onloadeddata = (_) => {
|
audio.onloadeddata = (_) => {
|
||||||
console.log("Loaded!", audio.duration * 1000);
|
|
||||||
output.length = audio.duration * 1000;
|
output.length = audio.duration * 1000;
|
||||||
res(audio.duration * 1000);
|
res(audio.duration * 1000);
|
||||||
};
|
};
|
||||||
audio.load();
|
audio.load();
|
||||||
console.log(audio);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!output.title) {
|
if (!output.title) {
|
||||||
|
|
|
@ -310,6 +310,9 @@ class Message extends SnowFlake {
|
||||||
}
|
}
|
||||||
return build;
|
return build;
|
||||||
}
|
}
|
||||||
|
getUnixTime(): number {
|
||||||
|
return new Date(this.timestamp).getTime();
|
||||||
|
}
|
||||||
async edit(content: string) {
|
async edit(content: string) {
|
||||||
return await fetch(this.info.api + "/channels/" + this.channel.id + "/messages/" + this.id, {
|
return await fetch(this.info.api + "/channels/" + this.channel.id + "/messages/" + this.id, {
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
|
@ -920,6 +923,9 @@ class Message extends SnowFlake {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildhtml(premessage?: Message | undefined, dupe = false): HTMLElement {
|
buildhtml(premessage?: Message | undefined, dupe = false): HTMLElement {
|
||||||
|
if (this.channel.fakeMessageMap.has(this.id)) {
|
||||||
|
this.channel.destroyFakeMessage(this.id);
|
||||||
|
}
|
||||||
if (dupe) {
|
if (dupe) {
|
||||||
return this.generateMessage(premessage, false, document.createElement("div")) as HTMLElement;
|
return this.generateMessage(premessage, false, document.createElement("div")) as HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,9 @@ async function getfile(event: FetchEvent): Promise<Response> {
|
||||||
|
|
||||||
self.addEventListener("fetch", (e) => {
|
self.addEventListener("fetch", (e) => {
|
||||||
const event = e as FetchEvent;
|
const event = e as FetchEvent;
|
||||||
|
if (event.request.method === "POST") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
event.respondWith(getfile(event));
|
event.respondWith(getfile(event));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -1087,6 +1087,9 @@ span.instanceStatus {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
#ghostMessages {
|
||||||
|
transform: translate(0px, -22px);
|
||||||
|
}
|
||||||
#pasteimage:empty {
|
#pasteimage:empty {
|
||||||
height: 0;
|
height: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -1218,7 +1221,17 @@ span.instanceStatus {
|
||||||
.dot:nth-child(3) {
|
.dot:nth-child(3) {
|
||||||
animation-delay: 0.66s;
|
animation-delay: 0.66s;
|
||||||
}
|
}
|
||||||
|
.loadingMessage {
|
||||||
|
span {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.erroredMessage {
|
||||||
|
span {
|
||||||
|
opacity: 1;
|
||||||
|
color: var(--red);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Message */
|
/* Message */
|
||||||
.messagediv,
|
.messagediv,
|
||||||
.titlespace {
|
.titlespace {
|
||||||
|
|
|
@ -393,7 +393,8 @@
|
||||||
"edit": "Edit message",
|
"edit": "Edit message",
|
||||||
"edited": "(edited)",
|
"edited": "(edited)",
|
||||||
"deleted": "Deleted message",
|
"deleted": "Deleted message",
|
||||||
"attached": "Sent an attachment"
|
"attached": "Sent an attachment",
|
||||||
|
"retry": "Resend errored message"
|
||||||
},
|
},
|
||||||
"instanceStats": {
|
"instanceStats": {
|
||||||
"name": "Instance stats: $1",
|
"name": "Instance stats: $1",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue