Bug fixes, blocking and various other changes
This commit is contained in:
parent
42a438f6dc
commit
dbee2f3628
22 changed files with 679 additions and 370 deletions
|
@ -58,14 +58,14 @@ class Channel {
|
||||||
this.contextmenu.addbutton("Delete channel", function () {
|
this.contextmenu.addbutton("Delete channel", function () {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
this.deleteChannel();
|
this.deleteChannel();
|
||||||
}, null, _ => { console.log(_); return _.isAdmin(); });
|
}, null, function () { return this.isAdmin(); });
|
||||||
this.contextmenu.addbutton("Edit channel", function () {
|
this.contextmenu.addbutton("Edit channel", function () {
|
||||||
this.editChannel();
|
this.editChannel();
|
||||||
}, null, _ => { return _.isAdmin(); });
|
}, null, function () { return this.isAdmin(); });
|
||||||
this.contextmenu.addbutton("Make invite", function () {
|
this.contextmenu.addbutton("Make invite", function () {
|
||||||
this.createInvite();
|
this.createInvite();
|
||||||
}, null, (_) => {
|
}, null, function () {
|
||||||
return _.hasPermission("CREATE_INSTANT_INVITE") && _.type !== 4;
|
return this.hasPermission("CREATE_INSTANT_INVITE") && this.type !== 4;
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
this.contextmenu.addbutton("Test button",function(){
|
this.contextmenu.addbutton("Test button",function(){
|
||||||
|
@ -154,7 +154,7 @@ class Channel {
|
||||||
}
|
}
|
||||||
setUpInfiniteScroller() {
|
setUpInfiniteScroller() {
|
||||||
this.infinite = new InfiniteScroller(async function (id, offset) {
|
this.infinite = new InfiniteScroller(async function (id, offset) {
|
||||||
const snowflake = SnowFlake.getSnowFlakeFromID(id, Message);
|
const snowflake = this.messages.get(id).snowflake;
|
||||||
if (offset === 1) {
|
if (offset === 1) {
|
||||||
if (this.idToPrev.has(snowflake)) {
|
if (this.idToPrev.has(snowflake)) {
|
||||||
return this.idToPrev.get(snowflake)?.id;
|
return this.idToPrev.get(snowflake)?.id;
|
||||||
|
@ -184,12 +184,15 @@ class Channel {
|
||||||
const html = messgage.buildhtml();
|
const html = messgage.buildhtml();
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
console.error(id + " not found");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}.bind(this), async function (id) {
|
}.bind(this), async function (id) {
|
||||||
const message = SnowFlake.getSnowFlakeFromID(id, Message).getObject();
|
const message = this.messages.get(id);
|
||||||
try {
|
try {
|
||||||
if (message) {
|
if (message) {
|
||||||
message.deleteDiv();
|
message.deleteDiv();
|
||||||
|
@ -374,7 +377,7 @@ class Channel {
|
||||||
caps.classList.add("capsflex");
|
caps.classList.add("capsflex");
|
||||||
decdiv.classList.add("channeleffects");
|
decdiv.classList.add("channeleffects");
|
||||||
decdiv.classList.add("channel");
|
decdiv.classList.add("channel");
|
||||||
Channel.contextmenu.bind(decdiv, this);
|
Channel.contextmenu.bindContextmenu(decdiv, this, undefined);
|
||||||
decdiv["all"] = this;
|
decdiv["all"] = this;
|
||||||
for (const channel of this.children) {
|
for (const channel of this.children) {
|
||||||
childrendiv.appendChild(channel.createguildHTML(admin));
|
childrendiv.appendChild(channel.createguildHTML(admin));
|
||||||
|
@ -400,7 +403,7 @@ class Channel {
|
||||||
if (this.hasunreads) {
|
if (this.hasunreads) {
|
||||||
div.classList.add("cunread");
|
div.classList.add("cunread");
|
||||||
}
|
}
|
||||||
Channel.contextmenu.bind(div, this);
|
Channel.contextmenu.bindContextmenu(div, this, undefined);
|
||||||
if (admin) {
|
if (admin) {
|
||||||
this.coatDropDiv(div);
|
this.coatDropDiv(div);
|
||||||
}
|
}
|
||||||
|
@ -815,12 +818,6 @@ class Channel {
|
||||||
async grabArround(id) {
|
async grabArround(id) {
|
||||||
throw new Error("please don't call this, no one has implemented it :P");
|
throw new Error("please don't call this, no one has implemented it :P");
|
||||||
}
|
}
|
||||||
buildmessage(message, next) {
|
|
||||||
const built = message.buildhtml(next);
|
|
||||||
if (built) {
|
|
||||||
document.getElementById("messages").prepend(built);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async buildmessages() {
|
async buildmessages() {
|
||||||
/*
|
/*
|
||||||
if(((!this.lastmessage)||(!this.lastmessage.snowflake)||(!this.goBackIds(this.lastmessage.snowflake,50,false)))&&this.lastreadmessageid){
|
if(((!this.lastmessage)||(!this.lastmessage.snowflake)||(!this.goBackIds(this.lastmessage.snowflake,50,false)))&&this.lastreadmessageid){
|
||||||
|
|
|
@ -27,23 +27,23 @@ class Contextmenu {
|
||||||
this.buttons.push([text, onclick, img, shown, enabled, "submenu"]);
|
this.buttons.push([text, onclick, img, shown, enabled, "submenu"]);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
makemenu(x, y, addinfo, obj) {
|
makemenu(x, y, addinfo, other) {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.classList.add("contextmenu", "flexttb");
|
div.classList.add("contextmenu", "flexttb");
|
||||||
for (const thing of this.buttons) {
|
for (const thing of this.buttons) {
|
||||||
if (!thing[3](addinfo)) {
|
if (!thing[3].bind(addinfo)(other)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const intext = document.createElement("button");
|
const intext = document.createElement("button");
|
||||||
intext.disabled = !thing[4]();
|
intext.disabled = !thing[4].bind(addinfo)(other);
|
||||||
intext.classList.add("contextbutton");
|
intext.classList.add("contextbutton");
|
||||||
intext.textContent = thing[0];
|
intext.textContent = thing[0];
|
||||||
console.log(thing);
|
console.log(thing);
|
||||||
if (thing[5] === "button") {
|
if (thing[5] === "button") {
|
||||||
intext.onclick = thing[1].bind(addinfo, obj);
|
intext.onclick = thing[1].bind(addinfo, other);
|
||||||
}
|
}
|
||||||
else if (thing[5] === "submenu") {
|
else if (thing[5] === "submenu") {
|
||||||
intext.onclick = thing[1].bind(addinfo);
|
intext.onclick = thing[1].bind(addinfo, other);
|
||||||
}
|
}
|
||||||
div.appendChild(intext);
|
div.appendChild(intext);
|
||||||
}
|
}
|
||||||
|
@ -58,11 +58,11 @@ class Contextmenu {
|
||||||
Contextmenu.currentmenu = div;
|
Contextmenu.currentmenu = div;
|
||||||
return this.div;
|
return this.div;
|
||||||
}
|
}
|
||||||
bind(obj, addinfo = undefined) {
|
bindContextmenu(obj, addinfo, other) {
|
||||||
const func = (event) => {
|
const func = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
this.makemenu(event.clientX, event.clientY, addinfo, obj);
|
this.makemenu(event.clientX, event.clientY, addinfo, other);
|
||||||
};
|
};
|
||||||
obj.addEventListener("contextmenu", func);
|
obj.addEventListener("contextmenu", func);
|
||||||
return func;
|
return func;
|
||||||
|
|
|
@ -42,10 +42,14 @@ class Guild {
|
||||||
});
|
});
|
||||||
Guild.contextmenu.addbutton("Leave guild", function () {
|
Guild.contextmenu.addbutton("Leave guild", function () {
|
||||||
this.confirmleave();
|
this.confirmleave();
|
||||||
}, null, function (_) { return _.properties.owner_id !== _.member.user.id; });
|
}, null, function (_) {
|
||||||
|
return this.properties.owner_id !== this.member.user.id;
|
||||||
|
});
|
||||||
Guild.contextmenu.addbutton("Delete guild", function () {
|
Guild.contextmenu.addbutton("Delete guild", function () {
|
||||||
this.confirmDelete();
|
this.confirmDelete();
|
||||||
}, null, function (_) { return _.properties.owner_id === _.member.user.id; });
|
}, null, function (_) {
|
||||||
|
return this.properties.owner_id === this.member.user.id;
|
||||||
|
});
|
||||||
Guild.contextmenu.addbutton("Create invite", function () {
|
Guild.contextmenu.addbutton("Create invite", function () {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
}, null, _ => true, _ => false);
|
}, null, _ => true, _ => false);
|
||||||
|
@ -271,7 +275,7 @@ class Guild {
|
||||||
this.loadGuild();
|
this.loadGuild();
|
||||||
this.loadChannel();
|
this.loadChannel();
|
||||||
};
|
};
|
||||||
Guild.contextmenu.bind(img, this);
|
Guild.contextmenu.bindContextmenu(img, this, undefined);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
|
@ -283,7 +287,7 @@ class Guild {
|
||||||
this.loadGuild();
|
this.loadGuild();
|
||||||
this.loadChannel();
|
this.loadChannel();
|
||||||
};
|
};
|
||||||
Guild.contextmenu.bind(div, this);
|
Guild.contextmenu.bindContextmenu(div, this, undefined);
|
||||||
}
|
}
|
||||||
return divy;
|
return divy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ catch (e) {
|
||||||
thisuser = new Localuser(-1);
|
thisuser = new Localuser(-1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const menu = new Contextmenu("create rightclick");
|
const menu = new Contextmenu("create rightclick"); //Really should go into the localuser class, but that's a later thing
|
||||||
menu.addbutton("Create channel", function () {
|
menu.addbutton("Create channel", function () {
|
||||||
if (thisuser.lookingguild) {
|
if (thisuser.lookingguild) {
|
||||||
thisuser.lookingguild.createchannels();
|
thisuser.lookingguild.createchannels();
|
||||||
|
@ -114,7 +114,7 @@ catch (e) {
|
||||||
thisuser.lookingguild.createcategory();
|
thisuser.lookingguild.createcategory();
|
||||||
}
|
}
|
||||||
}, null, _ => { return thisuser.isAdmin(); });
|
}, null, _ => { return thisuser.isAdmin(); });
|
||||||
menu.bind(document.getElementById("channels"));
|
menu.bindContextmenu(document.getElementById("channels"), 0, 0);
|
||||||
}
|
}
|
||||||
const pasteimage = document.getElementById("pasteimage");
|
const pasteimage = document.getElementById("pasteimage");
|
||||||
let replyingto = null;
|
let replyingto = null;
|
||||||
|
|
|
@ -3,8 +3,9 @@ class InfiniteScroller {
|
||||||
getHTMLFromID;
|
getHTMLFromID;
|
||||||
destroyFromID;
|
destroyFromID;
|
||||||
reachesBottom;
|
reachesBottom;
|
||||||
minDist = 3000;
|
minDist = 2000;
|
||||||
maxDist = 8000;
|
fillDist = 3000;
|
||||||
|
maxDist = 6000;
|
||||||
HTMLElements = [];
|
HTMLElements = [];
|
||||||
div;
|
div;
|
||||||
scroll;
|
scroll;
|
||||||
|
@ -25,11 +26,21 @@ class InfiniteScroller {
|
||||||
this.div = div;
|
this.div = div;
|
||||||
//this.interval=setInterval(this.updatestuff.bind(this,true),100);
|
//this.interval=setInterval(this.updatestuff.bind(this,true),100);
|
||||||
this.scroll = scroll;
|
this.scroll = scroll;
|
||||||
this.div.addEventListener("scroll", this.watchForChange.bind(this));
|
this.div.addEventListener("scroll", _ => {
|
||||||
this.scroll.addEventListener("scroll", this.watchForChange.bind(this));
|
if (this.scroll)
|
||||||
|
this.scrollTop = this.scroll.scrollTop;
|
||||||
|
this.watchForChange();
|
||||||
|
});
|
||||||
|
this.scroll.addEventListener("scroll", _ => {
|
||||||
|
if (null === this.timeout) {
|
||||||
|
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
|
||||||
|
}
|
||||||
|
this.watchForChange();
|
||||||
|
});
|
||||||
{
|
{
|
||||||
let oldheight = 0;
|
let oldheight = 0;
|
||||||
new ResizeObserver(_ => {
|
new ResizeObserver(_ => {
|
||||||
|
this.updatestuff();
|
||||||
const change = oldheight - div.offsetHeight;
|
const change = oldheight - div.offsetHeight;
|
||||||
if (change > 0 && this.scroll) {
|
if (change > 0 && this.scroll) {
|
||||||
this.scroll.scrollTop += change;
|
this.scroll.scrollTop += change;
|
||||||
|
@ -49,11 +60,16 @@ class InfiniteScroller {
|
||||||
scrollBottom;
|
scrollBottom;
|
||||||
scrollTop;
|
scrollTop;
|
||||||
needsupdate = true;
|
needsupdate = true;
|
||||||
|
averageheight = 60;
|
||||||
async updatestuff() {
|
async updatestuff() {
|
||||||
|
this.timeout = null;
|
||||||
if (!this.scroll)
|
if (!this.scroll)
|
||||||
return;
|
return;
|
||||||
this.timeout = null;
|
|
||||||
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
|
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
|
||||||
|
this.averageheight = this.scroll.scrollHeight / this.HTMLElements.length;
|
||||||
|
if (this.averageheight < 10) {
|
||||||
|
this.averageheight = 60;
|
||||||
|
}
|
||||||
this.scrollTop = this.scroll.scrollTop;
|
this.scrollTop = this.scroll.scrollTop;
|
||||||
if (!this.scrollBottom) {
|
if (!this.scrollBottom) {
|
||||||
if (!await this.watchForChange()) {
|
if (!await this.watchForChange()) {
|
||||||
|
@ -84,120 +100,160 @@ class InfiniteScroller {
|
||||||
const scrollBottom = this.scrollBottom;
|
const scrollBottom = this.scrollBottom;
|
||||||
return () => {
|
return () => {
|
||||||
if (this.scroll && scrollBottom < 30) {
|
if (this.scroll && scrollBottom < 30) {
|
||||||
this.scroll.scrollTop = this.scroll.scrollHeight;
|
this.scroll.scrollTop = this.scroll.scrollHeight + 20;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async watchForTop() {
|
async watchForTop(already = false, fragement = new DocumentFragment()) {
|
||||||
if (!this.scroll)
|
if (!this.scroll)
|
||||||
return false;
|
return false;
|
||||||
let again = false;
|
try {
|
||||||
if (this.scrollTop === 0) {
|
let again = false;
|
||||||
this.scrollTop = 1;
|
if (this.scrollTop < (already ? this.fillDist : this.minDist)) {
|
||||||
this.scroll.scrollTop = 1;
|
let nextid;
|
||||||
}
|
const firstelm = this.HTMLElements.at(0);
|
||||||
if (this.scrollTop < this.minDist) {
|
if (firstelm) {
|
||||||
let nextid;
|
const previd = firstelm[1];
|
||||||
const firstelm = this.HTMLElements.at(0);
|
nextid = await this.getIDFromOffset(previd, 1);
|
||||||
if (firstelm) {
|
|
||||||
const previd = firstelm[1];
|
|
||||||
nextid = await this.getIDFromOffset(previd, 1);
|
|
||||||
}
|
|
||||||
if (!nextid) {
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
again = true;
|
|
||||||
const html = await this.getHTMLFromID(nextid);
|
|
||||||
if (!html) {
|
|
||||||
this.destroyFromID(nextid);
|
|
||||||
console.error("html isn't defined");
|
|
||||||
throw Error("html isn't defined");
|
|
||||||
}
|
}
|
||||||
this.scroll.prepend(html);
|
if (!nextid) {
|
||||||
this.HTMLElements.unshift([html, nextid]);
|
}
|
||||||
this.scrollTop += 60;
|
else {
|
||||||
|
const html = await this.getHTMLFromID(nextid);
|
||||||
|
if (!html) {
|
||||||
|
this.destroyFromID(nextid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
again = true;
|
||||||
|
fragement.prepend(html);
|
||||||
|
this.HTMLElements.unshift([html, nextid]);
|
||||||
|
this.scrollTop += this.averageheight;
|
||||||
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
;
|
if (this.scrollTop > this.maxDist) {
|
||||||
|
const html = this.HTMLElements.shift();
|
||||||
|
if (html) {
|
||||||
|
again = true;
|
||||||
|
await this.destroyFromID(html[1]);
|
||||||
|
this.scrollTop -= this.averageheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (again) {
|
||||||
|
await this.watchForTop(true, fragement);
|
||||||
|
}
|
||||||
|
return again;
|
||||||
}
|
}
|
||||||
if (this.scrollTop > this.maxDist) {
|
finally {
|
||||||
const html = this.HTMLElements.shift();
|
if (!already) {
|
||||||
if (html) {
|
if (this.scroll.scrollTop === 0) {
|
||||||
again = true;
|
this.scrollTop = 1;
|
||||||
await this.destroyFromID(html[1]);
|
this.scroll.scrollTop = 10;
|
||||||
this.scrollTop -= 60;
|
}
|
||||||
|
this.scroll.prepend(fragement, fragement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (again) {
|
|
||||||
await this.watchForTop();
|
|
||||||
}
|
|
||||||
return again;
|
|
||||||
}
|
}
|
||||||
async watchForBottom() {
|
async watchForBottom(already = false, fragement = new DocumentFragment()) {
|
||||||
if (!this.scroll)
|
if (!this.scroll)
|
||||||
return false;
|
return false;
|
||||||
let again = false;
|
try {
|
||||||
const scrollBottom = this.scrollBottom;
|
let again = false;
|
||||||
if (scrollBottom < this.minDist) {
|
const scrollBottom = this.scrollBottom;
|
||||||
let nextid;
|
if (scrollBottom < (already ? this.fillDist : this.minDist)) {
|
||||||
const lastelm = this.HTMLElements.at(-1);
|
let nextid;
|
||||||
if (lastelm) {
|
const lastelm = this.HTMLElements.at(-1);
|
||||||
const previd = lastelm[1];
|
if (lastelm) {
|
||||||
nextid = await this.getIDFromOffset(previd, -1);
|
const previd = lastelm[1];
|
||||||
|
nextid = await this.getIDFromOffset(previd, -1);
|
||||||
|
}
|
||||||
|
if (!nextid) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
again = true;
|
||||||
|
const html = await this.getHTMLFromID(nextid);
|
||||||
|
fragement.appendChild(html);
|
||||||
|
this.HTMLElements.push([html, nextid]);
|
||||||
|
this.scrollBottom += this.averageheight;
|
||||||
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
if (!nextid) {
|
if (scrollBottom > this.maxDist) {
|
||||||
|
const html = this.HTMLElements.pop();
|
||||||
|
if (html) {
|
||||||
|
await this.destroyFromID(html[1]);
|
||||||
|
this.scrollBottom -= this.averageheight;
|
||||||
|
again = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
if (again) {
|
||||||
again = true;
|
await this.watchForBottom(true, fragement);
|
||||||
const html = await this.getHTMLFromID(nextid);
|
}
|
||||||
this.scroll.appendChild(html);
|
return again;
|
||||||
this.HTMLElements.push([html, nextid]);
|
}
|
||||||
this.scrollBottom += 60;
|
finally {
|
||||||
if (scrollBottom < 30) {
|
if (!already) {
|
||||||
|
this.scroll.append(fragement);
|
||||||
|
if (this.scrollBottom < 30) {
|
||||||
this.scroll.scrollTop = this.scroll.scrollHeight;
|
this.scroll.scrollTop = this.scroll.scrollHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
|
||||||
}
|
}
|
||||||
if (scrollBottom > this.maxDist) {
|
|
||||||
const html = this.HTMLElements.pop();
|
|
||||||
if (html) {
|
|
||||||
await this.destroyFromID(html[1]);
|
|
||||||
this.scrollBottom -= 60;
|
|
||||||
again = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (again) {
|
|
||||||
await this.watchForBottom();
|
|
||||||
}
|
|
||||||
return again;
|
|
||||||
}
|
}
|
||||||
|
watchtime = false;
|
||||||
|
changePromise;
|
||||||
async watchForChange() {
|
async watchForChange() {
|
||||||
try {
|
if (this.currrunning) {
|
||||||
if (this.currrunning) {
|
this.watchtime = true;
|
||||||
return false;
|
if (this.changePromise) {
|
||||||
|
return await this.changePromise;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currrunning = true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!this.div) {
|
}
|
||||||
this.currrunning = false;
|
else {
|
||||||
|
this.watchtime = false;
|
||||||
|
this.currrunning = true;
|
||||||
|
}
|
||||||
|
this.changePromise = new Promise(async (res) => {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (!this.div) {
|
||||||
|
res(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const out = await Promise.allSettled([this.watchForTop(), this.watchForBottom()]);
|
||||||
|
const changed = (out[0].value || out[1].value);
|
||||||
|
if (null === this.timeout && changed) {
|
||||||
|
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
|
||||||
|
}
|
||||||
|
if (!this.currrunning) {
|
||||||
|
console.error("something really bad happened");
|
||||||
|
}
|
||||||
|
res(!!changed);
|
||||||
|
return !!changed;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
res(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const out = await Promise.allSettled([this.watchForTop(), this.watchForBottom()]);
|
catch (e) {
|
||||||
const changed = (out[0].value || out[1].value);
|
throw e;
|
||||||
if (null === this.timeout && changed) {
|
|
||||||
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
|
|
||||||
}
|
}
|
||||||
if (!this.currrunning) {
|
finally {
|
||||||
console.error("something really bad happened");
|
this.changePromise = undefined;
|
||||||
|
setTimeout(_ => {
|
||||||
|
this.currrunning = false;
|
||||||
|
if (this.watchtime) {
|
||||||
|
this.watchForChange();
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
}
|
}
|
||||||
this.currrunning = false;
|
});
|
||||||
return !!changed;
|
return await this.changePromise;
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
async focus(id, flash = true) {
|
async focus(id, flash = true) {
|
||||||
let element;
|
let element;
|
||||||
|
@ -206,6 +262,7 @@ class InfiniteScroller {
|
||||||
element = thing[0];
|
element = thing[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log(id, element, this.HTMLElements.length, ":3");
|
||||||
if (element) {
|
if (element) {
|
||||||
if (flash) {
|
if (flash) {
|
||||||
element.scrollIntoView({
|
element.scrollIntoView({
|
||||||
|
|
|
@ -89,6 +89,11 @@ class Localuser {
|
||||||
const guildid = guild.snowflake;
|
const guildid = guild.snowflake;
|
||||||
this.guildids.get(guildid.id).channelids[thing.channel_id].readStateInfo(thing);
|
this.guildids.get(guildid.id).channelids[thing.channel_id].readStateInfo(thing);
|
||||||
}
|
}
|
||||||
|
for (const thing of ready.d.relationships) {
|
||||||
|
const user = new User(thing.user, this);
|
||||||
|
user.nickname = thing.nickname;
|
||||||
|
user.relationshipType = thing.type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
outoffocus() {
|
outoffocus() {
|
||||||
const servers = document.getElementById("servers");
|
const servers = document.getElementById("servers");
|
||||||
|
|
|
@ -22,7 +22,6 @@ function trimswitcher() {
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
for (const thing in json.users) {
|
for (const thing in json.users) {
|
||||||
const user = json.users[thing];
|
const user = json.users[thing];
|
||||||
console.log(user, json.users);
|
|
||||||
let wellknown = user.serverurls.wellknown;
|
let wellknown = user.serverurls.wellknown;
|
||||||
if (wellknown[wellknown.length - 1] !== "/") {
|
if (wellknown[wellknown.length - 1] !== "/") {
|
||||||
wellknown += "/";
|
wellknown += "/";
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { User } from "./user.js";
|
import { User } from "./user.js";
|
||||||
import { Role } from "./role.js";
|
import { Role } from "./role.js";
|
||||||
import { Contextmenu } from "./contextmenu.js";
|
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
class Member {
|
class Member {
|
||||||
static already = {};
|
static already = {};
|
||||||
|
@ -9,18 +8,6 @@ class Member {
|
||||||
roles = [];
|
roles = [];
|
||||||
id;
|
id;
|
||||||
nick;
|
nick;
|
||||||
static contextmenu = new Contextmenu("User Menu");
|
|
||||||
static setUpContextMenu() {
|
|
||||||
this.contextmenu.addbutton("Copy user id", function () {
|
|
||||||
navigator.clipboard.writeText(this.id);
|
|
||||||
});
|
|
||||||
this.contextmenu.addbutton("Message user", function () {
|
|
||||||
fetch(this.info.api + "/users/@me/channels", { method: "POST",
|
|
||||||
body: JSON.stringify({ "recipients": [this.id] }),
|
|
||||||
headers: this.localuser.headers
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
constructor(memberjson, owner) {
|
constructor(memberjson, owner) {
|
||||||
if (User.userids[memberjson.id]) {
|
if (User.userids[memberjson.id]) {
|
||||||
this.user = User.userids[memberjson.id];
|
this.user = User.userids[memberjson.id];
|
||||||
|
@ -169,12 +156,10 @@ class Member {
|
||||||
*/
|
*/
|
||||||
html.style.color = this.getColor();
|
html.style.color = this.getColor();
|
||||||
}
|
}
|
||||||
this.profileclick(html);
|
//this.profileclick(html);
|
||||||
Member.contextmenu.bind(html);
|
|
||||||
}
|
}
|
||||||
profileclick(html) {
|
profileclick(html) {
|
||||||
//to be implemented
|
//to be implemented
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Member.setUpContextMenu();
|
|
||||||
export { Member };
|
export { Member };
|
||||||
|
|
110
.dist/message.js
110
.dist/message.js
|
@ -49,7 +49,7 @@ class Message {
|
||||||
Message.contextmenu.addbutton("Copy raw text", function () {
|
Message.contextmenu.addbutton("Copy raw text", function () {
|
||||||
navigator.clipboard.writeText(this.content.rawString);
|
navigator.clipboard.writeText(this.content.rawString);
|
||||||
});
|
});
|
||||||
Message.contextmenu.addbutton("Reply", function (div) {
|
Message.contextmenu.addbutton("Reply", function () {
|
||||||
this.channel.setReplying(this);
|
this.channel.setReplying(this);
|
||||||
});
|
});
|
||||||
Message.contextmenu.addbutton("Copy message id", function () {
|
Message.contextmenu.addbutton("Copy message id", function () {
|
||||||
|
@ -65,10 +65,14 @@ class Message {
|
||||||
const markdown = document.getElementById("typebox")["markdown"];
|
const markdown = document.getElementById("typebox")["markdown"];
|
||||||
markdown.txt = this.content.rawString.split('');
|
markdown.txt = this.content.rawString.split('');
|
||||||
markdown.boxupdate(document.getElementById("typebox"));
|
markdown.boxupdate(document.getElementById("typebox"));
|
||||||
}, null, _ => { return _.author.id === _.localuser.user.id; });
|
}, null, function () {
|
||||||
|
return this.author.id === this.localuser.user.id;
|
||||||
|
});
|
||||||
Message.contextmenu.addbutton("Delete message", function () {
|
Message.contextmenu.addbutton("Delete message", function () {
|
||||||
this.delete();
|
this.delete();
|
||||||
}, null, _ => { return _.canDelete(); });
|
}, null, function () {
|
||||||
|
return this.canDelete();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
constructor(messagejson, owner) {
|
constructor(messagejson, owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
@ -169,7 +173,7 @@ class Message {
|
||||||
return this.owner.info;
|
return this.owner.info;
|
||||||
}
|
}
|
||||||
messageevents(obj) {
|
messageevents(obj) {
|
||||||
const func = Message.contextmenu.bind(obj, this);
|
const func = Message.contextmenu.bindContextmenu(obj, this, undefined);
|
||||||
this.div = obj;
|
this.div = obj;
|
||||||
obj.classList.add("messagediv");
|
obj.classList.add("messagediv");
|
||||||
}
|
}
|
||||||
|
@ -245,7 +249,16 @@ class Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reactdiv;
|
reactdiv;
|
||||||
generateMessage(premessage = undefined) {
|
blockedPropigate() {
|
||||||
|
const premessage = this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||||
|
if (premessage?.author === this.author) {
|
||||||
|
premessage.blockedPropigate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generateMessage(premessage = undefined, ignoredblock = false) {
|
||||||
if (!this.div)
|
if (!this.div)
|
||||||
return;
|
return;
|
||||||
if (!premessage) {
|
if (!premessage) {
|
||||||
|
@ -257,7 +270,66 @@ class Message {
|
||||||
}
|
}
|
||||||
div.innerHTML = "";
|
div.innerHTML = "";
|
||||||
const build = document.createElement('div');
|
const build = document.createElement('div');
|
||||||
build.classList.add("flexltr");
|
build.classList.add("flexltr", "message");
|
||||||
|
div.classList.remove("zeroheight");
|
||||||
|
if (this.author.relationshipType === 2) {
|
||||||
|
if (ignoredblock) {
|
||||||
|
if (premessage?.author !== this.author) {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.textContent = `You have this user blocked, click to hide these messages.`;
|
||||||
|
div.append(span);
|
||||||
|
span.classList.add("blocked");
|
||||||
|
span.onclick = _ => {
|
||||||
|
const scroll = this.channel.infinite.scrollTop;
|
||||||
|
let next = this;
|
||||||
|
while (next?.author === this.author) {
|
||||||
|
next.generateMessage(undefined);
|
||||||
|
next = this.channel.idToNext.get(next.snowflake)?.getObject();
|
||||||
|
}
|
||||||
|
if (this.channel.infinite.scroll && scroll) {
|
||||||
|
this.channel.infinite.scroll.scrollTop = scroll;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
div.classList.remove("topMessage");
|
||||||
|
if (premessage?.author === this.author) {
|
||||||
|
div.classList.add("zeroheight");
|
||||||
|
premessage.blockedPropigate();
|
||||||
|
div.appendChild(build);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
build.classList.add("blocked", "topMessage");
|
||||||
|
const span = document.createElement("span");
|
||||||
|
let count = 1;
|
||||||
|
let next = this.channel.idToNext.get(this.snowflake)?.getObject();
|
||||||
|
while (next?.author === this.author) {
|
||||||
|
count++;
|
||||||
|
next = this.channel.idToNext.get(next.snowflake)?.getObject();
|
||||||
|
}
|
||||||
|
span.textContent = `You have this user blocked, click to see the ${count} blocked messages.`;
|
||||||
|
build.append(span);
|
||||||
|
span.onclick = _ => {
|
||||||
|
const scroll = this.channel.infinite.scrollTop;
|
||||||
|
const func = this.channel.infinite.snapBottom();
|
||||||
|
let next = this;
|
||||||
|
while (next?.author === this.author) {
|
||||||
|
next.generateMessage(undefined, true);
|
||||||
|
next = this.channel.idToNext.get(next.snowflake)?.getObject();
|
||||||
|
console.log("loopy");
|
||||||
|
}
|
||||||
|
if (this.channel.infinite.scroll && scroll) {
|
||||||
|
func();
|
||||||
|
this.channel.infinite.scroll.scrollTop = scroll;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
div.appendChild(build);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.message_reference) {
|
if (this.message_reference) {
|
||||||
const replyline = document.createElement("div");
|
const replyline = document.createElement("div");
|
||||||
const line = document.createElement("hr");
|
const line = document.createElement("hr");
|
||||||
|
@ -269,7 +341,6 @@ class Message {
|
||||||
replyline.appendChild(username);
|
replyline.appendChild(username);
|
||||||
const reply = document.createElement("div");
|
const reply = document.createElement("div");
|
||||||
username.classList.add("username");
|
username.classList.add("username");
|
||||||
this.author.bind(username, this.guild);
|
|
||||||
reply.classList.add("replytext");
|
reply.classList.add("replytext");
|
||||||
replyline.appendChild(reply);
|
replyline.appendChild(reply);
|
||||||
const line2 = document.createElement("hr");
|
const line2 = document.createElement("hr");
|
||||||
|
@ -278,6 +349,10 @@ class Message {
|
||||||
line.classList.add("startreply");
|
line.classList.add("startreply");
|
||||||
replyline.classList.add("replyflex");
|
replyline.classList.add("replyflex");
|
||||||
this.channel.getmessage(this.message_reference.message_id).then(message => {
|
this.channel.getmessage(this.message_reference.message_id).then(message => {
|
||||||
|
if (message.author.relationshipType === 2) {
|
||||||
|
username.textContent = "Blocked user";
|
||||||
|
return;
|
||||||
|
}
|
||||||
const author = message.author;
|
const author = message.author;
|
||||||
reply.appendChild(message.content.makeHTML({ stdsize: true }));
|
reply.appendChild(message.content.makeHTML({ stdsize: true }));
|
||||||
minipfp.src = author.getpfpsrc();
|
minipfp.src = author.getpfpsrc();
|
||||||
|
@ -290,7 +365,6 @@ class Message {
|
||||||
};
|
};
|
||||||
div.appendChild(replyline);
|
div.appendChild(replyline);
|
||||||
}
|
}
|
||||||
build.classList.add("message");
|
|
||||||
div.appendChild(build);
|
div.appendChild(build);
|
||||||
if ({ 0: true, 19: true }[this.type] || this.attachments.length !== 0) {
|
if ({ 0: true, 19: true }[this.type] || this.attachments.length !== 0) {
|
||||||
const pfpRow = document.createElement('div');
|
const pfpRow = document.createElement('div');
|
||||||
|
@ -491,21 +565,17 @@ class Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let now = new Date().toLocaleDateString();
|
||||||
|
const yesterday = new Date(now);
|
||||||
|
yesterday.setDate(new Date().getDate() - 1);
|
||||||
|
let yesterdayStr = yesterday.toLocaleDateString();
|
||||||
function formatTime(date) {
|
function formatTime(date) {
|
||||||
const now = new Date();
|
const datestring = date.toLocaleDateString();
|
||||||
const sameDay = date.getDate() === now.getDate() &&
|
const formatTime = (date) => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||||
date.getMonth() === now.getMonth() &&
|
if (datestring === now) {
|
||||||
date.getFullYear() === now.getFullYear();
|
|
||||||
const yesterday = new Date(now);
|
|
||||||
yesterday.setDate(now.getDate() - 1);
|
|
||||||
const isYesterday = date.getDate() === yesterday.getDate() &&
|
|
||||||
date.getMonth() === yesterday.getMonth() &&
|
|
||||||
date.getFullYear() === yesterday.getFullYear();
|
|
||||||
const formatTime = date => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
||||||
if (sameDay) {
|
|
||||||
return `Today at ${formatTime(date)}`;
|
return `Today at ${formatTime(date)}`;
|
||||||
}
|
}
|
||||||
else if (isYesterday) {
|
else if (datestring === yesterdayStr) {
|
||||||
return `Yesterday at ${formatTime(date)}`;
|
return `Yesterday at ${formatTime(date)}`;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -10,6 +10,8 @@ class User {
|
||||||
snowflake;
|
snowflake;
|
||||||
avatar;
|
avatar;
|
||||||
username;
|
username;
|
||||||
|
nickname = null;
|
||||||
|
relationshipType = 0;
|
||||||
bio;
|
bio;
|
||||||
discriminator;
|
discriminator;
|
||||||
pronouns;
|
pronouns;
|
||||||
|
@ -75,6 +77,25 @@ class User {
|
||||||
headers: this.localuser.headers
|
headers: this.localuser.headers
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
this.contextmenu.addbutton("Block user", function () {
|
||||||
|
this.block();
|
||||||
|
}, null, function () {
|
||||||
|
return this.relationshipType !== 2;
|
||||||
|
});
|
||||||
|
this.contextmenu.addbutton("Unblock user", function () {
|
||||||
|
this.unblock();
|
||||||
|
}, null, function () {
|
||||||
|
return this.relationshipType === 2;
|
||||||
|
});
|
||||||
|
this.contextmenu.addbutton("Friend request", function () {
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: this.owner.headers,
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 1
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
static clear() {
|
static clear() {
|
||||||
this.userids = {};
|
this.userids = {};
|
||||||
|
@ -148,6 +169,7 @@ class User {
|
||||||
}
|
}
|
||||||
buildpfp() {
|
buildpfp() {
|
||||||
const pfp = document.createElement('img');
|
const pfp = document.createElement('img');
|
||||||
|
pfp.loading = "lazy";
|
||||||
pfp.src = this.getpfpsrc();
|
pfp.src = this.getpfpsrc();
|
||||||
pfp.classList.add("pfp");
|
pfp.classList.add("pfp");
|
||||||
pfp.classList.add("userid:" + this.id);
|
pfp.classList.add("userid:" + this.id);
|
||||||
|
@ -183,6 +205,7 @@ class User {
|
||||||
bind(html, guild = null, error = true) {
|
bind(html, guild = null, error = true) {
|
||||||
if (guild && guild.id !== "@me") {
|
if (guild && guild.id !== "@me") {
|
||||||
Member.resolveMember(this, guild).then(_ => {
|
Member.resolveMember(this, guild).then(_ => {
|
||||||
|
User.contextmenu.bindContextmenu(html, this, _);
|
||||||
if (_ === undefined && error) {
|
if (_ === undefined && error) {
|
||||||
const error = document.createElement("span");
|
const error = document.createElement("span");
|
||||||
error.textContent = "!";
|
error.textContent = "!";
|
||||||
|
@ -203,7 +226,6 @@ class User {
|
||||||
else {
|
else {
|
||||||
this.profileclick(html);
|
this.profileclick(html);
|
||||||
}
|
}
|
||||||
User.contextmenu.bind(html, this);
|
|
||||||
}
|
}
|
||||||
static async resolve(id, localuser) {
|
static async resolve(id, localuser) {
|
||||||
const json = await fetch(localuser.info.api.toString() + "/users/" + id + "/profile", { headers: localuser.headers }).then(_ => _.json());
|
const json = await fetch(localuser.info.api.toString() + "/users/" + id + "/profile", { headers: localuser.headers }).then(_ => _.json());
|
||||||
|
@ -218,6 +240,35 @@ class User {
|
||||||
thing.src = src;
|
thing.src = src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
block() {
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: this.owner.headers,
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 2
|
||||||
|
})
|
||||||
|
});
|
||||||
|
this.relationshipType = 2;
|
||||||
|
const channel = this.localuser.channelfocus;
|
||||||
|
if (channel) {
|
||||||
|
for (const thing of channel.messages) {
|
||||||
|
thing[1].generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unblock() {
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: this.owner.headers,
|
||||||
|
});
|
||||||
|
this.relationshipType = 0;
|
||||||
|
const channel = this.localuser.channelfocus;
|
||||||
|
if (channel) {
|
||||||
|
for (const thing of channel.messages) {
|
||||||
|
thing[1].generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
getpfpsrc() {
|
getpfpsrc() {
|
||||||
if (this.hypotheticalpfp) {
|
if (this.hypotheticalpfp) {
|
||||||
return this.avatar;
|
return this.avatar;
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Channel{
|
||||||
typing:number;
|
typing:number;
|
||||||
message_notifications:number;
|
message_notifications:number;
|
||||||
allthewayup:boolean;
|
allthewayup:boolean;
|
||||||
static contextmenu=new Contextmenu("channel menu");
|
static contextmenu=new Contextmenu<Channel,undefined>("channel menu");
|
||||||
replyingto:Message|null;
|
replyingto:Message|null;
|
||||||
infinite:InfiniteScroller;
|
infinite:InfiniteScroller;
|
||||||
idToPrev:Map<SnowFlake<Message>,SnowFlake<Message>>=new Map();
|
idToPrev:Map<SnowFlake<Message>,SnowFlake<Message>>=new Map();
|
||||||
|
@ -70,16 +70,16 @@ class Channel{
|
||||||
this.contextmenu.addbutton("Delete channel",function(this:Channel){
|
this.contextmenu.addbutton("Delete channel",function(this:Channel){
|
||||||
console.log(this)
|
console.log(this)
|
||||||
this.deleteChannel();
|
this.deleteChannel();
|
||||||
},null,_=>{console.log(_);return _.isAdmin()});
|
},null,function(){return this.isAdmin()});
|
||||||
|
|
||||||
this.contextmenu.addbutton("Edit channel",function(this:Channel){
|
this.contextmenu.addbutton("Edit channel",function(this:Channel){
|
||||||
this.editChannel();
|
this.editChannel();
|
||||||
},null,_=>{return _.isAdmin()});
|
},null,function(){return this.isAdmin()});
|
||||||
|
|
||||||
this.contextmenu.addbutton("Make invite",function(this:Channel){
|
this.contextmenu.addbutton("Make invite",function(this:Channel){
|
||||||
this.createInvite();
|
this.createInvite();
|
||||||
},null,(_:Channel)=>{
|
},null,function(){
|
||||||
return _.hasPermission("CREATE_INSTANT_INVITE")&&_.type!==4
|
return this.hasPermission("CREATE_INSTANT_INVITE")&&this.type!==4
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
this.contextmenu.addbutton("Test button",function(){
|
this.contextmenu.addbutton("Test button",function(){
|
||||||
|
@ -170,7 +170,7 @@ class Channel{
|
||||||
}
|
}
|
||||||
setUpInfiniteScroller(){
|
setUpInfiniteScroller(){
|
||||||
this.infinite=new InfiniteScroller(async function(this:Channel,id:string,offset:number):Promise<string|undefined>{
|
this.infinite=new InfiniteScroller(async function(this:Channel,id:string,offset:number):Promise<string|undefined>{
|
||||||
const snowflake=SnowFlake.getSnowFlakeFromID(id,Message) as SnowFlake<Message>;
|
const snowflake=(this.messages.get(id) as Message).snowflake;
|
||||||
if(offset===1){
|
if(offset===1){
|
||||||
if(this.idToPrev.has(snowflake)){
|
if(this.idToPrev.has(snowflake)){
|
||||||
return this.idToPrev.get(snowflake)?.id;
|
return this.idToPrev.get(snowflake)?.id;
|
||||||
|
@ -196,13 +196,15 @@ class Channel{
|
||||||
if(messgage){
|
if(messgage){
|
||||||
const html=messgage.buildhtml();
|
const html=messgage.buildhtml();
|
||||||
return html;
|
return html;
|
||||||
|
}else{
|
||||||
|
console.error(id+" not found")
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
async function(this:Channel,id:string){
|
async function(this:Channel,id:string){
|
||||||
const message=SnowFlake.getSnowFlakeFromID(id,Message).getObject();
|
const message=this.messages.get(id);
|
||||||
try{
|
try{
|
||||||
if(message){
|
if(message){
|
||||||
message.deleteDiv();
|
message.deleteDiv();
|
||||||
|
@ -383,7 +385,7 @@ class Channel{
|
||||||
decdiv.classList.add("channeleffects");
|
decdiv.classList.add("channeleffects");
|
||||||
decdiv.classList.add("channel");
|
decdiv.classList.add("channel");
|
||||||
|
|
||||||
Channel.contextmenu.bind(decdiv,this);
|
Channel.contextmenu.bindContextmenu(decdiv,this,undefined);
|
||||||
decdiv["all"]=this;
|
decdiv["all"]=this;
|
||||||
|
|
||||||
|
|
||||||
|
@ -409,7 +411,7 @@ class Channel{
|
||||||
if(this.hasunreads){
|
if(this.hasunreads){
|
||||||
div.classList.add("cunread");
|
div.classList.add("cunread");
|
||||||
}
|
}
|
||||||
Channel.contextmenu.bind(div,this);
|
Channel.contextmenu.bindContextmenu(div,this,undefined);
|
||||||
if(admin){this.coatDropDiv(div);}
|
if(admin){this.coatDropDiv(div);}
|
||||||
div["all"]=this;
|
div["all"]=this;
|
||||||
const myhtml=document.createElement("span");
|
const myhtml=document.createElement("span");
|
||||||
|
@ -817,12 +819,6 @@ class Channel{
|
||||||
async grabArround(id:string){//currently unused and no plans to use it yet
|
async grabArround(id:string){//currently unused and no plans to use it yet
|
||||||
throw new Error("please don't call this, no one has implemented it :P")
|
throw new Error("please don't call this, no one has implemented it :P")
|
||||||
}
|
}
|
||||||
buildmessage(message:Message,next:Message){
|
|
||||||
const built=message.buildhtml(next);
|
|
||||||
if(built){
|
|
||||||
(document.getElementById("messages") as HTMLDivElement).prepend(built);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async buildmessages(){
|
async buildmessages(){
|
||||||
/*
|
/*
|
||||||
if(((!this.lastmessage)||(!this.lastmessage.snowflake)||(!this.goBackIds(this.lastmessage.snowflake,50,false)))&&this.lastreadmessageid){
|
if(((!this.lastmessage)||(!this.lastmessage.snowflake)||(!this.goBackIds(this.lastmessage.snowflake,50,false)))&&this.lastreadmessageid){
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class Contextmenu{
|
class Contextmenu<x,y>{
|
||||||
static currentmenu;
|
static currentmenu;
|
||||||
name:string;
|
name:string;
|
||||||
buttons:[string,Function,string|null,Function,Function,string][];
|
buttons:[string,(e:MouseEvent)=>void,string|null,(this:x,arg:y)=>boolean,(this:x,arg:y)=>boolean,string][];
|
||||||
div:HTMLDivElement;
|
div:HTMLDivElement;
|
||||||
static setup(){
|
static setup(){
|
||||||
Contextmenu.currentmenu="";
|
Contextmenu.currentmenu="";
|
||||||
|
@ -19,28 +19,28 @@ class Contextmenu{
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.buttons=[]
|
this.buttons=[]
|
||||||
}
|
}
|
||||||
addbutton(text:string,onclick:Function,img:null|string=null,shown=_=>true,enabled=_=>true){
|
addbutton(text:string,onclick:(e:MouseEvent)=>void,img:null|string=null,shown:(this:x,arg:y)=>boolean=_=>true,enabled:(this:x,arg:y)=>boolean=_=>true){
|
||||||
this.buttons.push([text,onclick,img,shown,enabled,"button"]);
|
this.buttons.push([text,onclick,img,shown,enabled,"button"]);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
addsubmenu(text:string,onclick:(e:MouseEvent)=>void,img=null,shown=_=>true,enabled=_=>true){
|
addsubmenu(text:string,onclick:(e:MouseEvent)=>void,img=null,shown:(this:x,arg:y)=>boolean=_=>true,enabled:(this:x,arg:y)=>boolean=_=>true){
|
||||||
this.buttons.push([text,onclick,img,shown,enabled,"submenu"])
|
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,other:y){
|
||||||
const div=document.createElement("div");
|
const div=document.createElement("div");
|
||||||
div.classList.add("contextmenu","flexttb");
|
div.classList.add("contextmenu","flexttb");
|
||||||
for(const thing of this.buttons){
|
for(const thing of this.buttons){
|
||||||
if(!thing[3](addinfo)){continue;}
|
if(!thing[3].bind(addinfo)(other)){continue;}
|
||||||
const intext=document.createElement("button")
|
const intext=document.createElement("button")
|
||||||
intext.disabled=!thing[4]();
|
intext.disabled=!thing[4].bind(addinfo)(other);
|
||||||
intext.classList.add("contextbutton")
|
intext.classList.add("contextbutton")
|
||||||
intext.textContent=thing[0]
|
intext.textContent=thing[0]
|
||||||
console.log(thing)
|
console.log(thing)
|
||||||
if(thing[5]==="button"){
|
if(thing[5]==="button"){
|
||||||
intext.onclick=thing[1].bind(addinfo,obj);
|
intext.onclick=thing[1].bind(addinfo,other);
|
||||||
}else if(thing[5]==="submenu"){
|
}else if(thing[5]==="submenu"){
|
||||||
intext.onclick=thing[1].bind(addinfo);
|
intext.onclick=thing[1].bind(addinfo,other);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.appendChild(intext);
|
div.appendChild(intext);
|
||||||
|
@ -56,11 +56,11 @@ class Contextmenu{
|
||||||
Contextmenu.currentmenu=div;
|
Contextmenu.currentmenu=div;
|
||||||
return this.div;
|
return this.div;
|
||||||
}
|
}
|
||||||
bind(obj:HTMLElement,addinfo:any=undefined){
|
bindContextmenu(obj:HTMLElement,addinfo:x,other:y){
|
||||||
const func=(event) => {
|
const func=(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
this.makemenu(event.clientX,event.clientY,addinfo,obj)
|
this.makemenu(event.clientX,event.clientY,addinfo,other);
|
||||||
}
|
}
|
||||||
obj.addEventListener("contextmenu", func);
|
obj.addEventListener("contextmenu", func);
|
||||||
return func;
|
return func;
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Guild{
|
||||||
get id(){
|
get id(){
|
||||||
return this.snowflake.id;
|
return this.snowflake.id;
|
||||||
}
|
}
|
||||||
static contextmenu=new Contextmenu("guild menu");
|
static contextmenu=new Contextmenu<Guild,undefined>("guild menu");
|
||||||
static setupcontextmenu(){
|
static setupcontextmenu(){
|
||||||
Guild.contextmenu.addbutton("Copy Guild id",function(this:Guild){
|
Guild.contextmenu.addbutton("Copy Guild id",function(this:Guild){
|
||||||
console.log(this)
|
console.log(this)
|
||||||
|
@ -49,11 +49,15 @@ class Guild{
|
||||||
|
|
||||||
Guild.contextmenu.addbutton("Leave guild",function(this:Guild){
|
Guild.contextmenu.addbutton("Leave guild",function(this:Guild){
|
||||||
this.confirmleave();
|
this.confirmleave();
|
||||||
},null,function(_){return _.properties.owner_id!==_.member.user.id});
|
},null,function(_){
|
||||||
|
return this.properties.owner_id!==this.member.user.id
|
||||||
|
});
|
||||||
|
|
||||||
Guild.contextmenu.addbutton("Delete guild",function(this:Guild){
|
Guild.contextmenu.addbutton("Delete guild",function(this:Guild){
|
||||||
this.confirmDelete();
|
this.confirmDelete();
|
||||||
},null,function(_){return _.properties.owner_id===_.member.user.id});
|
},null,function(_){
|
||||||
|
return this.properties.owner_id===this.member.user.id
|
||||||
|
});
|
||||||
|
|
||||||
Guild.contextmenu.addbutton("Create invite",function(this:Guild){
|
Guild.contextmenu.addbutton("Create invite",function(this:Guild){
|
||||||
console.log(this);
|
console.log(this);
|
||||||
|
@ -282,7 +286,7 @@ class Guild{
|
||||||
this.loadGuild();
|
this.loadGuild();
|
||||||
this.loadChannel();
|
this.loadChannel();
|
||||||
}
|
}
|
||||||
Guild.contextmenu.bind(img,this);
|
Guild.contextmenu.bindContextmenu(img,this,undefined);
|
||||||
}else{
|
}else{
|
||||||
const div=document.createElement("div");
|
const div=document.createElement("div");
|
||||||
let build=this.properties.name.replace(/'s /g, " ").replace(/\w+/g, word => word[0]).replace(/\s/g, "");
|
let build=this.properties.name.replace(/'s /g, " ").replace(/\w+/g, word => word[0]).replace(/\s/g, "");
|
||||||
|
@ -293,7 +297,7 @@ class Guild{
|
||||||
this.loadGuild();
|
this.loadGuild();
|
||||||
this.loadChannel();
|
this.loadChannel();
|
||||||
}
|
}
|
||||||
Guild.contextmenu.bind(div,this)
|
Guild.contextmenu.bindContextmenu(div,this,undefined)
|
||||||
}
|
}
|
||||||
return divy;
|
return divy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ try{
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const menu=new Contextmenu("create rightclick");
|
const menu=new Contextmenu("create rightclick");//Really should go into the localuser class, but that's a later thing
|
||||||
menu.addbutton("Create channel",function(){
|
menu.addbutton("Create channel",function(){
|
||||||
if(thisuser.lookingguild){
|
if(thisuser.lookingguild){
|
||||||
thisuser.lookingguild.createchannels();
|
thisuser.lookingguild.createchannels();
|
||||||
|
@ -126,7 +126,7 @@ try{
|
||||||
thisuser.lookingguild.createcategory();
|
thisuser.lookingguild.createcategory();
|
||||||
}
|
}
|
||||||
},null,_=>{return thisuser.isAdmin()})
|
},null,_=>{return thisuser.isAdmin()})
|
||||||
menu.bind(document.getElementById("channels") as HTMLDivElement)
|
menu.bindContextmenu(document.getElementById("channels") as HTMLDivElement,0,0)
|
||||||
}
|
}
|
||||||
|
|
||||||
const pasteimage=document.getElementById("pasteimage") as HTMLDivElement;
|
const pasteimage=document.getElementById("pasteimage") as HTMLDivElement;
|
||||||
|
|
|
@ -3,8 +3,9 @@ class InfiniteScroller{
|
||||||
readonly getHTMLFromID:(ID:string)=>Promise<HTMLElement>;
|
readonly getHTMLFromID:(ID:string)=>Promise<HTMLElement>;
|
||||||
readonly destroyFromID:(ID:string)=>Promise<boolean>;
|
readonly destroyFromID:(ID:string)=>Promise<boolean>;
|
||||||
readonly reachesBottom:()=>void;
|
readonly reachesBottom:()=>void;
|
||||||
private readonly minDist=3000;
|
private readonly minDist=2000;
|
||||||
private readonly maxDist=8000;
|
private readonly fillDist=3000;
|
||||||
|
private readonly maxDist=6000;
|
||||||
HTMLElements:[HTMLElement,string][]=[];
|
HTMLElements:[HTMLElement,string][]=[];
|
||||||
div:HTMLDivElement|null;
|
div:HTMLDivElement|null;
|
||||||
scroll:HTMLDivElement|null;
|
scroll:HTMLDivElement|null;
|
||||||
|
@ -26,11 +27,21 @@ class InfiniteScroller{
|
||||||
//this.interval=setInterval(this.updatestuff.bind(this,true),100);
|
//this.interval=setInterval(this.updatestuff.bind(this,true),100);
|
||||||
|
|
||||||
this.scroll=scroll;
|
this.scroll=scroll;
|
||||||
this.div.addEventListener("scroll",this.watchForChange.bind(this));
|
this.div.addEventListener("scroll",_=>{
|
||||||
this.scroll.addEventListener("scroll",this.watchForChange.bind(this));
|
if(this.scroll) this.scrollTop=this.scroll.scrollTop;
|
||||||
|
this.watchForChange()
|
||||||
|
});
|
||||||
|
this.scroll.addEventListener("scroll",_=>{
|
||||||
|
if(null===this.timeout){
|
||||||
|
this.timeout=setTimeout(this.updatestuff.bind(this),300);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.watchForChange()
|
||||||
|
});
|
||||||
{
|
{
|
||||||
let oldheight=0;
|
let oldheight=0;
|
||||||
new ResizeObserver(_=>{
|
new ResizeObserver(_=>{
|
||||||
|
this.updatestuff();
|
||||||
const change=oldheight-div.offsetHeight;
|
const change=oldheight-div.offsetHeight;
|
||||||
if(change>0&&this.scroll){
|
if(change>0&&this.scroll){
|
||||||
this.scroll.scrollTop+=change;
|
this.scroll.scrollTop+=change;
|
||||||
|
@ -51,10 +62,15 @@ class InfiniteScroller{
|
||||||
scrollBottom:number;
|
scrollBottom:number;
|
||||||
scrollTop:number;
|
scrollTop:number;
|
||||||
needsupdate=true;
|
needsupdate=true;
|
||||||
|
averageheight:number=60;
|
||||||
async updatestuff(){
|
async updatestuff(){
|
||||||
if(!this.scroll) return;
|
|
||||||
this.timeout=null;
|
this.timeout=null;
|
||||||
|
if(!this.scroll) return;
|
||||||
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
|
this.scrollBottom = this.scroll.scrollHeight - this.scroll.scrollTop - this.scroll.clientHeight;
|
||||||
|
this.averageheight=this.scroll.scrollHeight/this.HTMLElements.length;
|
||||||
|
if(this.averageheight<10){
|
||||||
|
this.averageheight=60;
|
||||||
|
}
|
||||||
this.scrollTop=this.scroll.scrollTop;
|
this.scrollTop=this.scroll.scrollTop;
|
||||||
if(!this.scrollBottom){
|
if(!this.scrollBottom){
|
||||||
if(!await this.watchForChange()){
|
if(!await this.watchForChange()){
|
||||||
|
@ -84,124 +100,166 @@ class InfiniteScroller{
|
||||||
const scrollBottom=this.scrollBottom;
|
const scrollBottom=this.scrollBottom;
|
||||||
return ()=>{
|
return ()=>{
|
||||||
if(this.scroll&&scrollBottom<30){
|
if(this.scroll&&scrollBottom<30){
|
||||||
this.scroll.scrollTop=this.scroll.scrollHeight;
|
this.scroll.scrollTop=this.scroll.scrollHeight+20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async watchForTop():Promise<boolean>{
|
private async watchForTop(already=false,fragement=new DocumentFragment()):Promise<boolean>{
|
||||||
if(!this.scroll) return false;
|
if(!this.scroll) return false;
|
||||||
let again=false;
|
try{
|
||||||
if(this.scrollTop===0){
|
let again=false;
|
||||||
this.scrollTop=1;
|
if(this.scrollTop<(already?this.fillDist:this.minDist)){
|
||||||
this.scroll.scrollTop=1;
|
let nextid:string|undefined;
|
||||||
}
|
const firstelm=this.HTMLElements.at(0);
|
||||||
if(this.scrollTop<this.minDist){
|
if(firstelm){
|
||||||
let nextid:string|undefined;
|
const previd=firstelm[1];
|
||||||
const firstelm=this.HTMLElements.at(0);
|
nextid=await this.getIDFromOffset(previd,1);
|
||||||
if(firstelm){
|
|
||||||
const previd=firstelm[1];
|
|
||||||
nextid=await this.getIDFromOffset(previd,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!nextid){
|
|
||||||
|
|
||||||
}else{
|
|
||||||
again=true;
|
|
||||||
const html=await this.getHTMLFromID(nextid);
|
|
||||||
if(!html){
|
|
||||||
this.destroyFromID(nextid);
|
|
||||||
console.error("html isn't defined");
|
|
||||||
throw Error("html isn't defined");
|
|
||||||
}
|
}
|
||||||
this.scroll.prepend(html);
|
|
||||||
this.HTMLElements.unshift([html,nextid]);
|
|
||||||
this.scrollTop+=60;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if(this.scrollTop>this.maxDist){
|
|
||||||
|
|
||||||
|
|
||||||
const html=this.HTMLElements.shift();
|
if(!nextid){
|
||||||
if(html){
|
|
||||||
again=true;
|
}else{
|
||||||
await this.destroyFromID(html[1]);
|
const html=await this.getHTMLFromID(nextid);
|
||||||
this.scrollTop-=60;
|
if(!html){
|
||||||
|
this.destroyFromID(nextid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
again=true;
|
||||||
|
fragement.prepend(html);
|
||||||
|
this.HTMLElements.unshift([html,nextid]);
|
||||||
|
this.scrollTop+=this.averageheight;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if(this.scrollTop>this.maxDist){
|
||||||
|
|
||||||
|
|
||||||
|
const html=this.HTMLElements.shift();
|
||||||
|
if(html){
|
||||||
|
again=true;
|
||||||
|
await this.destroyFromID(html[1]);
|
||||||
|
this.scrollTop-=this.averageheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(again){
|
||||||
|
await this.watchForTop(true,fragement);
|
||||||
|
}
|
||||||
|
return again;
|
||||||
|
}finally{
|
||||||
|
if(!already){
|
||||||
|
if(this.scroll.scrollTop===0){
|
||||||
|
this.scrollTop=1;
|
||||||
|
this.scroll.scrollTop=10;
|
||||||
|
}
|
||||||
|
this.scroll.prepend(fragement,fragement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(again){
|
|
||||||
await this.watchForTop();
|
|
||||||
}
|
|
||||||
return again;
|
|
||||||
}
|
}
|
||||||
async watchForBottom():Promise<boolean>{
|
async watchForBottom(already=false,fragement=new DocumentFragment()):Promise<boolean>{
|
||||||
if(!this.scroll) return false;
|
if(!this.scroll) return false;
|
||||||
let again=false;
|
try{
|
||||||
const scrollBottom = this.scrollBottom;
|
let again=false;
|
||||||
if(scrollBottom<this.minDist){
|
const scrollBottom = this.scrollBottom;
|
||||||
|
if(scrollBottom<(already?this.fillDist:this.minDist)){
|
||||||
|
|
||||||
let nextid:string|undefined;
|
let nextid:string|undefined;
|
||||||
const lastelm=this.HTMLElements.at(-1);
|
const lastelm=this.HTMLElements.at(-1);
|
||||||
if(lastelm){
|
if(lastelm){
|
||||||
const previd=lastelm[1];
|
const previd=lastelm[1];
|
||||||
nextid=await this.getIDFromOffset(previd,-1);
|
nextid=await this.getIDFromOffset(previd,-1);
|
||||||
|
}
|
||||||
|
if(!nextid){
|
||||||
|
}else{
|
||||||
|
again=true;
|
||||||
|
const html=await this.getHTMLFromID(nextid);
|
||||||
|
fragement.appendChild(html);
|
||||||
|
this.HTMLElements.push([html,nextid]);
|
||||||
|
this.scrollBottom+=this.averageheight;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if(!nextid){
|
if(scrollBottom>this.maxDist){
|
||||||
}else{
|
|
||||||
again=true;
|
|
||||||
const html=await this.getHTMLFromID(nextid);
|
const html=this.HTMLElements.pop();
|
||||||
this.scroll.appendChild(html);
|
if(html){
|
||||||
this.HTMLElements.push([html,nextid]);
|
await this.destroyFromID(html[1]);
|
||||||
this.scrollBottom+=60;
|
this.scrollBottom-=this.averageheight;
|
||||||
if(scrollBottom<30){
|
again=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(again){
|
||||||
|
await this.watchForBottom(true,fragement);
|
||||||
|
}
|
||||||
|
return again;
|
||||||
|
}finally{
|
||||||
|
if(!already){
|
||||||
|
this.scroll.append(fragement);
|
||||||
|
if(this.scrollBottom<30){
|
||||||
this.scroll.scrollTop=this.scroll.scrollHeight;
|
this.scroll.scrollTop=this.scroll.scrollHeight;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
if(scrollBottom>this.maxDist){
|
|
||||||
|
|
||||||
|
|
||||||
const html=this.HTMLElements.pop();
|
|
||||||
if(html){
|
|
||||||
await this.destroyFromID(html[1]);
|
|
||||||
this.scrollBottom-=60;
|
|
||||||
again=true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(again){
|
|
||||||
await this.watchForBottom();
|
|
||||||
}
|
|
||||||
return again;
|
|
||||||
}
|
}
|
||||||
|
watchtime:boolean=false;
|
||||||
|
changePromise:Promise<boolean>|undefined;
|
||||||
async watchForChange():Promise<boolean>{
|
async watchForChange():Promise<boolean>{
|
||||||
|
|
||||||
try{
|
|
||||||
if(this.currrunning){
|
if(this.currrunning){
|
||||||
return false;
|
this.watchtime=true;
|
||||||
|
if(this.changePromise){
|
||||||
|
return await this.changePromise;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
|
this.watchtime=false;
|
||||||
this.currrunning=true;
|
this.currrunning=true;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(!this.div){this.currrunning=false;return false}
|
this.changePromise=new Promise<boolean>(async res=>{
|
||||||
const out=await Promise.allSettled([this.watchForTop(),this.watchForBottom()]) as {value:boolean}[];
|
try{
|
||||||
const changed=(out[0].value||out[1].value);
|
|
||||||
if(null===this.timeout&&changed){
|
try{
|
||||||
this.timeout=setTimeout(this.updatestuff.bind(this),300);
|
if(!this.div){res(false);return false}
|
||||||
}
|
const out=await Promise.allSettled([this.watchForTop(),this.watchForBottom()]) as {value:boolean}[];
|
||||||
if(!this.currrunning){console.error("something really bad happened")}
|
const changed=(out[0].value||out[1].value);
|
||||||
this.currrunning=false;
|
if(null===this.timeout&&changed){
|
||||||
return !!changed;
|
this.timeout=setTimeout(this.updatestuff.bind(this),300);
|
||||||
}catch(e){
|
}
|
||||||
console.error(e);
|
if(!this.currrunning){console.error("something really bad happened")}
|
||||||
}
|
|
||||||
return false;
|
res(!!changed);
|
||||||
|
return !!changed;
|
||||||
|
|
||||||
|
}catch(e){
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
res(false);
|
||||||
|
return false;
|
||||||
|
}catch(e){
|
||||||
|
throw e;
|
||||||
|
}finally{
|
||||||
|
|
||||||
|
this.changePromise=undefined;
|
||||||
|
setTimeout(_=>{
|
||||||
|
this.currrunning=false;
|
||||||
|
if(this.watchtime){
|
||||||
|
this.watchForChange();
|
||||||
|
}
|
||||||
|
},300)
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return await this.changePromise;
|
||||||
}
|
}
|
||||||
async focus(id:string,flash=true){
|
async focus(id:string,flash=true){
|
||||||
|
|
||||||
let element:HTMLElement|undefined;
|
let element:HTMLElement|undefined;
|
||||||
for(const thing of this.HTMLElements){
|
for(const thing of this.HTMLElements){
|
||||||
if(thing[1]===id){
|
if(thing[1]===id){
|
||||||
element=thing[0];
|
element=thing[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log(id,element,this.HTMLElements.length,":3");
|
||||||
if(element){
|
if(element){
|
||||||
|
|
||||||
if(flash){
|
if(flash){
|
||||||
|
|
|
@ -44,7 +44,12 @@ type readyjson={
|
||||||
view_nsfw_guilds: boolean
|
view_nsfw_guilds: boolean
|
||||||
};
|
};
|
||||||
guilds:guildjson[];
|
guilds:guildjson[];
|
||||||
relationships:any[];
|
relationships:{
|
||||||
|
id:string,
|
||||||
|
type:0|1|2|3|4,
|
||||||
|
nickname:string|null,
|
||||||
|
user:userjson
|
||||||
|
}[];
|
||||||
read_state:{
|
read_state:{
|
||||||
entries:{
|
entries:{
|
||||||
id: string,
|
id: string,
|
||||||
|
|
|
@ -95,6 +95,11 @@ class Localuser{
|
||||||
const guildid=guild.snowflake;
|
const guildid=guild.snowflake;
|
||||||
(this.guildids.get(guildid.id) as Guild).channelids[thing.channel_id].readStateInfo(thing);
|
(this.guildids.get(guildid.id) as Guild).channelids[thing.channel_id].readStateInfo(thing);
|
||||||
}
|
}
|
||||||
|
for(const thing of ready.d.relationships){
|
||||||
|
const user=new User(thing.user,this);
|
||||||
|
user.nickname=thing.nickname;
|
||||||
|
user.relationshipType=thing.type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
outoffocus():void{
|
outoffocus():void{
|
||||||
const servers=document.getElementById("servers") as HTMLDivElement;
|
const servers=document.getElementById("servers") as HTMLDivElement;
|
||||||
|
|
|
@ -23,7 +23,6 @@ function trimswitcher(){
|
||||||
const map=new Map();
|
const map=new Map();
|
||||||
for(const thing in json.users){
|
for(const thing in json.users){
|
||||||
const user=json.users[thing];
|
const user=json.users[thing];
|
||||||
console.log(user,json.users);
|
|
||||||
let wellknown=user.serverurls.wellknown;
|
let wellknown=user.serverurls.wellknown;
|
||||||
if(wellknown[wellknown.length-1]!=="/"){
|
if(wellknown[wellknown.length-1]!=="/"){
|
||||||
wellknown+="/";
|
wellknown+="/";
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {User} from "./user.js";
|
import {User} from "./user.js";
|
||||||
import {Role} from "./role.js";
|
import {Role} from "./role.js";
|
||||||
import {Guild} from "./guild.js";
|
import {Guild} from "./guild.js";
|
||||||
import { Contextmenu } from "./contextmenu.js";
|
|
||||||
import { SnowFlake } from "./snowflake.js";
|
import { SnowFlake } from "./snowflake.js";
|
||||||
import { memberjson, presencejson, userjson } from "./jsontypes.js";
|
import { memberjson, presencejson, userjson } from "./jsontypes.js";
|
||||||
|
|
||||||
|
@ -12,19 +11,6 @@ class Member{
|
||||||
roles:Role[]=[];
|
roles:Role[]=[];
|
||||||
id:string;
|
id:string;
|
||||||
nick:string;
|
nick:string;
|
||||||
static contextmenu:Contextmenu=new Contextmenu("User Menu");
|
|
||||||
static setUpContextMenu(){
|
|
||||||
this.contextmenu.addbutton("Copy user id",function(this:Member){
|
|
||||||
navigator.clipboard.writeText(this.id);
|
|
||||||
});
|
|
||||||
this.contextmenu.addbutton("Message user",function(this:Member){
|
|
||||||
fetch(this.info.api+"/users/@me/channels",
|
|
||||||
{method:"POST",
|
|
||||||
body:JSON.stringify({"recipients":[this.id]}),
|
|
||||||
headers: this.localuser.headers
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
private constructor(memberjson:memberjson,owner:Guild){
|
private constructor(memberjson:memberjson,owner:Guild){
|
||||||
if(User.userids[memberjson.id]){
|
if(User.userids[memberjson.id]){
|
||||||
this.user=User.userids[memberjson.id];
|
this.user=User.userids[memberjson.id];
|
||||||
|
@ -39,6 +25,7 @@ class Member{
|
||||||
if(thing==="owner"){continue}
|
if(thing==="owner"){continue}
|
||||||
if(thing==="roles"){
|
if(thing==="roles"){
|
||||||
for(const strrole of memberjson["roles"]){
|
for(const strrole of memberjson["roles"]){
|
||||||
|
|
||||||
const role=SnowFlake.getSnowFlakeFromID(strrole,Role).getObject();
|
const role=SnowFlake.getSnowFlakeFromID(strrole,Role).getObject();
|
||||||
this.roles.push(role);
|
this.roles.push(role);
|
||||||
}
|
}
|
||||||
|
@ -160,12 +147,10 @@ class Member{
|
||||||
html.style.color=this.getColor();
|
html.style.color=this.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.profileclick(html);
|
//this.profileclick(html);
|
||||||
Member.contextmenu.bind(html);
|
|
||||||
}
|
}
|
||||||
profileclick(html:HTMLElement){
|
profileclick(html:HTMLElement){
|
||||||
//to be implemented
|
//to be implemented
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Member.setUpContextMenu();
|
|
||||||
export {Member};
|
export {Member};
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { memberjson, messagejson } from "./jsontypes.js";
|
||||||
import {Emoji} from "./emoji.js";
|
import {Emoji} from "./emoji.js";
|
||||||
|
|
||||||
class Message{
|
class Message{
|
||||||
static contextmenu=new Contextmenu("message menu");
|
static contextmenu=new Contextmenu<Message,undefined>("message menu");
|
||||||
owner:Channel;
|
owner:Channel;
|
||||||
headers:Localuser["headers"];
|
headers:Localuser["headers"];
|
||||||
embeds:Embed[];
|
embeds:Embed[];
|
||||||
|
@ -54,7 +54,7 @@ class Message{
|
||||||
Message.contextmenu.addbutton("Copy raw text",function(this:Message){
|
Message.contextmenu.addbutton("Copy raw text",function(this:Message){
|
||||||
navigator.clipboard.writeText(this.content.rawString);
|
navigator.clipboard.writeText(this.content.rawString);
|
||||||
});
|
});
|
||||||
Message.contextmenu.addbutton("Reply",function(this:Message,div:HTMLDivElement){
|
Message.contextmenu.addbutton("Reply",function(this:Message){
|
||||||
this.channel.setReplying(this);
|
this.channel.setReplying(this);
|
||||||
});
|
});
|
||||||
Message.contextmenu.addbutton("Copy message id",function(this:Message){
|
Message.contextmenu.addbutton("Copy message id",function(this:Message){
|
||||||
|
@ -70,10 +70,15 @@ class Message{
|
||||||
const markdown=(document.getElementById("typebox") as HTMLDivElement)["markdown"] as MarkDown;
|
const markdown=(document.getElementById("typebox") as HTMLDivElement)["markdown"] as MarkDown;
|
||||||
markdown.txt=this.content.rawString.split('');
|
markdown.txt=this.content.rawString.split('');
|
||||||
markdown.boxupdate(document.getElementById("typebox") as HTMLDivElement);
|
markdown.boxupdate(document.getElementById("typebox") as HTMLDivElement);
|
||||||
},null,_=>{return _.author.id===_.localuser.user.id});
|
},null,function(){
|
||||||
|
return this.author.id===this.localuser.user.id
|
||||||
|
});
|
||||||
Message.contextmenu.addbutton("Delete message",function(this:Message){
|
Message.contextmenu.addbutton("Delete message",function(this:Message){
|
||||||
this.delete();
|
this.delete();
|
||||||
},null,_=>{return _.canDelete()})
|
},null,function(){
|
||||||
|
return this.canDelete()
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
constructor(messagejson:messagejson,owner:Channel){
|
constructor(messagejson:messagejson,owner:Channel){
|
||||||
this.owner=owner;
|
this.owner=owner;
|
||||||
|
@ -172,7 +177,7 @@ class Message{
|
||||||
return this.owner.info;
|
return this.owner.info;
|
||||||
}
|
}
|
||||||
messageevents(obj:HTMLDivElement){
|
messageevents(obj:HTMLDivElement){
|
||||||
const func=Message.contextmenu.bind(obj,this);
|
const func=Message.contextmenu.bindContextmenu(obj,this,undefined);
|
||||||
this.div=obj;
|
this.div=obj;
|
||||||
obj.classList.add("messagediv");
|
obj.classList.add("messagediv");
|
||||||
}
|
}
|
||||||
|
@ -244,7 +249,15 @@ class Message{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reactdiv:WeakRef<HTMLDivElement>;
|
reactdiv:WeakRef<HTMLDivElement>;
|
||||||
generateMessage(premessage:Message|undefined=undefined){
|
blockedPropigate(){
|
||||||
|
const premessage=this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||||
|
if(premessage?.author===this.author){
|
||||||
|
premessage.blockedPropigate();
|
||||||
|
}else{
|
||||||
|
this.generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generateMessage(premessage:Message|undefined=undefined,ignoredblock=false){
|
||||||
if(!this.div) return;
|
if(!this.div) return;
|
||||||
if(!premessage){
|
if(!premessage){
|
||||||
premessage=this.channel.idToPrev.get(this.snowflake)?.getObject();
|
premessage=this.channel.idToPrev.get(this.snowflake)?.getObject();
|
||||||
|
@ -255,7 +268,65 @@ class Message{
|
||||||
}
|
}
|
||||||
div.innerHTML="";
|
div.innerHTML="";
|
||||||
const build = document.createElement('div');
|
const build = document.createElement('div');
|
||||||
build.classList.add("flexltr");
|
|
||||||
|
build.classList.add("flexltr","message");
|
||||||
|
div.classList.remove("zeroheight")
|
||||||
|
if(this.author.relationshipType===2){
|
||||||
|
if(ignoredblock){
|
||||||
|
if(premessage?.author!==this.author){
|
||||||
|
const span=document.createElement("span");
|
||||||
|
span.textContent=`You have this user blocked, click to hide these messages.`;
|
||||||
|
div.append(span);
|
||||||
|
span.classList.add("blocked")
|
||||||
|
span.onclick=_=>{
|
||||||
|
const scroll=this.channel.infinite.scrollTop;
|
||||||
|
let next:Message|undefined=this;
|
||||||
|
while(next?.author===this.author){
|
||||||
|
next.generateMessage(undefined);
|
||||||
|
next=this.channel.idToNext.get(next.snowflake)?.getObject();
|
||||||
|
}
|
||||||
|
if(this.channel.infinite.scroll&&scroll){
|
||||||
|
this.channel.infinite.scroll.scrollTop=scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
div.classList.remove("topMessage");
|
||||||
|
if(premessage?.author===this.author){
|
||||||
|
div.classList.add("zeroheight")
|
||||||
|
premessage.blockedPropigate();
|
||||||
|
div.appendChild(build);
|
||||||
|
return div;
|
||||||
|
}else{
|
||||||
|
build.classList.add("blocked","topMessage")
|
||||||
|
const span=document.createElement("span");
|
||||||
|
let count=1;
|
||||||
|
let next=this.channel.idToNext.get(this.snowflake)?.getObject()
|
||||||
|
while(next?.author===this.author){
|
||||||
|
count++;
|
||||||
|
next=this.channel.idToNext.get(next.snowflake)?.getObject()
|
||||||
|
}
|
||||||
|
span.textContent=`You have this user blocked, click to see the ${count} blocked messages.`;
|
||||||
|
build.append(span);
|
||||||
|
span.onclick=_=>{
|
||||||
|
const scroll=this.channel.infinite.scrollTop;
|
||||||
|
const func=this.channel.infinite.snapBottom();
|
||||||
|
let next:Message|undefined=this;
|
||||||
|
while(next?.author===this.author){
|
||||||
|
next.generateMessage(undefined,true);
|
||||||
|
next=this.channel.idToNext.get(next.snowflake)?.getObject();
|
||||||
|
console.log("loopy")
|
||||||
|
}
|
||||||
|
if(this.channel.infinite.scroll&&scroll){
|
||||||
|
func();
|
||||||
|
this.channel.infinite.scroll.scrollTop=scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div.appendChild(build);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(this.message_reference){
|
if(this.message_reference){
|
||||||
const replyline=document.createElement("div");
|
const replyline=document.createElement("div");
|
||||||
const line=document.createElement("hr");
|
const line=document.createElement("hr");
|
||||||
|
@ -267,7 +338,6 @@ class Message{
|
||||||
replyline.appendChild(username);
|
replyline.appendChild(username);
|
||||||
const reply=document.createElement("div");
|
const reply=document.createElement("div");
|
||||||
username.classList.add("username");
|
username.classList.add("username");
|
||||||
this.author.bind(username,this.guild);
|
|
||||||
reply.classList.add("replytext");
|
reply.classList.add("replytext");
|
||||||
replyline.appendChild(reply);
|
replyline.appendChild(reply);
|
||||||
const line2=document.createElement("hr");
|
const line2=document.createElement("hr");
|
||||||
|
@ -276,6 +346,10 @@ class Message{
|
||||||
line.classList.add("startreply");
|
line.classList.add("startreply");
|
||||||
replyline.classList.add("replyflex")
|
replyline.classList.add("replyflex")
|
||||||
this.channel.getmessage(this.message_reference.message_id).then(message=>{
|
this.channel.getmessage(this.message_reference.message_id).then(message=>{
|
||||||
|
if(message.author.relationshipType===2){
|
||||||
|
username.textContent="Blocked user";
|
||||||
|
return;
|
||||||
|
}
|
||||||
const author=message.author;
|
const author=message.author;
|
||||||
reply.appendChild(message.content.makeHTML({stdsize:true}));
|
reply.appendChild(message.content.makeHTML({stdsize:true}));
|
||||||
minipfp.src=author.getpfpsrc()
|
minipfp.src=author.getpfpsrc()
|
||||||
|
@ -288,7 +362,6 @@ class Message{
|
||||||
}
|
}
|
||||||
div.appendChild(replyline);
|
div.appendChild(replyline);
|
||||||
}
|
}
|
||||||
build.classList.add("message");
|
|
||||||
div.appendChild(build);
|
div.appendChild(build);
|
||||||
if({0:true,19:true}[this.type]||this.attachments.length!==0){
|
if({0:true,19:true}[this.type]||this.attachments.length!==0){
|
||||||
const pfpRow = document.createElement('div');
|
const pfpRow = document.createElement('div');
|
||||||
|
@ -486,24 +559,18 @@ class Message{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let now = new Date().toLocaleDateString();
|
||||||
|
const yesterday = new Date(now);
|
||||||
|
yesterday.setDate(new Date().getDate() - 1);
|
||||||
|
let yesterdayStr=yesterday.toLocaleDateString();
|
||||||
|
function formatTime(date:Date) {
|
||||||
|
|
||||||
function formatTime(date) {
|
const datestring=date.toLocaleDateString();
|
||||||
const now = new Date();
|
const formatTime = (date:Date) => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||||
const sameDay = date.getDate() === now.getDate() &&
|
|
||||||
date.getMonth() === now.getMonth() &&
|
|
||||||
date.getFullYear() === now.getFullYear();
|
|
||||||
|
|
||||||
const yesterday = new Date(now);
|
if (datestring=== now) {
|
||||||
yesterday.setDate(now.getDate() - 1);
|
|
||||||
const isYesterday = date.getDate() === yesterday.getDate() &&
|
|
||||||
date.getMonth() === yesterday.getMonth() &&
|
|
||||||
date.getFullYear() === yesterday.getFullYear();
|
|
||||||
|
|
||||||
const formatTime = date => date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
||||||
|
|
||||||
if (sameDay) {
|
|
||||||
return `Today at ${formatTime(date)}`;
|
return `Today at ${formatTime(date)}`;
|
||||||
} else if (isYesterday) {
|
} else if (datestring===yesterdayStr) {
|
||||||
return `Yesterday at ${formatTime(date)}`;
|
return `Yesterday at ${formatTime(date)}`;
|
||||||
} else {
|
} else {
|
||||||
return `${date.toLocaleDateString()} at ${formatTime(date)}`;
|
return `${date.toLocaleDateString()} at ${formatTime(date)}`;
|
||||||
|
|
|
@ -58,10 +58,6 @@ video{
|
||||||
padding:.03in;
|
padding:.03in;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
|
||||||
font-weight: 400;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background {
|
.background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -305,13 +301,10 @@ img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/* flex-grow: 1; */
|
/* flex-grow: 1; */
|
||||||
overflow-x: clip;
|
overflow-x: clip;
|
||||||
|
transform: translateZ(0);
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#messages {
|
|
||||||
max-width: 100%;
|
|
||||||
/* height: 100%; */
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
@ -334,9 +327,6 @@ p {
|
||||||
/* height: 100%; */
|
/* height: 100%; */
|
||||||
}
|
}
|
||||||
|
|
||||||
#channels p {
|
|
||||||
text-indent: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.space {
|
.space {
|
||||||
margin: .02in;
|
margin: .02in;
|
||||||
|
@ -348,13 +338,6 @@ p {
|
||||||
height: .175in;
|
height: .175in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacee {
|
|
||||||
text-indent: .15in;
|
|
||||||
margin-right: .02in;
|
|
||||||
font-size: .15in;
|
|
||||||
display: inline-block;
|
|
||||||
width: .2in;
|
|
||||||
}
|
|
||||||
|
|
||||||
#channels p2 {
|
#channels p2 {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -753,13 +736,6 @@ textarea:focus-visible,
|
||||||
background-color: var(--channel-hover);
|
background-color: var(--channel-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dm-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.dm-container div img {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.messageimg {
|
.messageimg {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -799,17 +775,6 @@ textarea:focus-visible,
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#channels-td {
|
|
||||||
padding-right: 240px;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
flex-shrink: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#userinfo {
|
#userinfo {
|
||||||
position:relative;
|
position:relative;
|
||||||
background-color: var(--user-info-bg);
|
background-color: var(--user-info-bg);
|
||||||
|
@ -1109,12 +1074,6 @@ span {
|
||||||
.switchtable:hover{
|
.switchtable:hover{
|
||||||
background:var(--profile-info-bg);
|
background:var(--profile-info-bg);
|
||||||
}
|
}
|
||||||
.accountSwitcher tr:hover{
|
|
||||||
background:var(--profile-info-bg);
|
|
||||||
}
|
|
||||||
.switchtable tr{
|
|
||||||
background-color:transparent;
|
|
||||||
}
|
|
||||||
.serverURL{
|
.serverURL{
|
||||||
color: var(--pronouns);
|
color: var(--pronouns);
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
|
@ -1540,6 +1499,8 @@ span {
|
||||||
}
|
}
|
||||||
.scroller{
|
.scroller{
|
||||||
padding-bottom: .2in;
|
padding-bottom: .2in;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
.suberror{
|
.suberror{
|
||||||
animation: goout 6s forwards;
|
animation: goout 6s forwards;
|
||||||
|
@ -1955,3 +1916,14 @@ form div{
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.blocked{
|
||||||
|
padding-left: .45in;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.zeroheight{
|
||||||
|
height: 0px;
|
||||||
|
flex-shrink:1;
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ class User{
|
||||||
snowflake:SnowFlake<User>;
|
snowflake:SnowFlake<User>;
|
||||||
avatar:string;
|
avatar:string;
|
||||||
username:string;
|
username:string;
|
||||||
|
nickname:string|null=null;
|
||||||
|
relationshipType:0|1|2|3|4=0;
|
||||||
bio:MarkDown;
|
bio:MarkDown;
|
||||||
discriminator:string;
|
discriminator:string;
|
||||||
pronouns:string;
|
pronouns:string;
|
||||||
|
@ -66,7 +68,7 @@ class User{
|
||||||
get id(){
|
get id(){
|
||||||
return this.snowflake.id;
|
return this.snowflake.id;
|
||||||
}
|
}
|
||||||
static contextmenu:Contextmenu=new Contextmenu("User Menu");
|
static contextmenu=new Contextmenu<User,Member|undefined>("User Menu");
|
||||||
static setUpContextMenu(){
|
static setUpContextMenu(){
|
||||||
this.contextmenu.addbutton("Copy user id",function(this:User){
|
this.contextmenu.addbutton("Copy user id",function(this:User){
|
||||||
navigator.clipboard.writeText(this.id);
|
navigator.clipboard.writeText(this.id);
|
||||||
|
@ -78,7 +80,26 @@ class User{
|
||||||
headers: this.localuser.headers
|
headers: this.localuser.headers
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
this.contextmenu.addbutton("Block user",function(this:User){
|
||||||
|
this.block();
|
||||||
|
},null,function(){
|
||||||
|
return this.relationshipType!==2
|
||||||
|
});
|
||||||
|
|
||||||
|
this.contextmenu.addbutton("Unblock user",function(this:User){
|
||||||
|
this.unblock();
|
||||||
|
},null,function(){
|
||||||
|
return this.relationshipType===2
|
||||||
|
});
|
||||||
|
this.contextmenu.addbutton("Friend request",function(this:User){
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`,{
|
||||||
|
method:"PUT",
|
||||||
|
headers:this.owner.headers,
|
||||||
|
body:JSON.stringify({
|
||||||
|
type:1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
static clear(){
|
static clear(){
|
||||||
this.userids={};
|
this.userids={};
|
||||||
|
@ -150,6 +171,7 @@ class User{
|
||||||
}
|
}
|
||||||
buildpfp(){
|
buildpfp(){
|
||||||
const pfp=document.createElement('img');
|
const pfp=document.createElement('img');
|
||||||
|
pfp.loading="lazy";
|
||||||
pfp.src=this.getpfpsrc();
|
pfp.src=this.getpfpsrc();
|
||||||
pfp.classList.add("pfp");
|
pfp.classList.add("pfp");
|
||||||
pfp.classList.add("userid:"+this.id);
|
pfp.classList.add("userid:"+this.id);
|
||||||
|
@ -185,6 +207,7 @@ class User{
|
||||||
bind(html:HTMLElement,guild:Guild|null=null,error=true){
|
bind(html:HTMLElement,guild:Guild|null=null,error=true){
|
||||||
if(guild&&guild.id!=="@me"){
|
if(guild&&guild.id!=="@me"){
|
||||||
Member.resolveMember(this,guild).then(_=>{
|
Member.resolveMember(this,guild).then(_=>{
|
||||||
|
User.contextmenu.bindContextmenu(html,this,_);
|
||||||
if(_===undefined&&error){
|
if(_===undefined&&error){
|
||||||
const error=document.createElement("span");
|
const error=document.createElement("span");
|
||||||
error.textContent="!";
|
error.textContent="!";
|
||||||
|
@ -204,8 +227,6 @@ class User{
|
||||||
}else{
|
}else{
|
||||||
this.profileclick(html);
|
this.profileclick(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
User.contextmenu.bind(html,this);
|
|
||||||
}
|
}
|
||||||
static async resolve(id:string,localuser:Localuser){
|
static async resolve(id:string,localuser:Localuser){
|
||||||
const json=await fetch(localuser.info.api.toString()+"/users/"+id+"/profile",
|
const json=await fetch(localuser.info.api.toString()+"/users/"+id+"/profile",
|
||||||
|
@ -222,6 +243,35 @@ class User{
|
||||||
(thing as HTMLImageElement).src=src;
|
(thing as HTMLImageElement).src=src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
block(){
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`,{
|
||||||
|
method:"PUT",
|
||||||
|
headers:this.owner.headers,
|
||||||
|
body:JSON.stringify({
|
||||||
|
type:2
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.relationshipType=2;
|
||||||
|
const channel=this.localuser.channelfocus;
|
||||||
|
if(channel){
|
||||||
|
for(const thing of channel.messages){
|
||||||
|
thing[1].generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unblock(){
|
||||||
|
fetch(`${this.info.api}/users/@me/relationships/${this.id}`,{
|
||||||
|
method:"DELETE",
|
||||||
|
headers:this.owner.headers,
|
||||||
|
})
|
||||||
|
this.relationshipType=0;
|
||||||
|
const channel=this.localuser.channelfocus;
|
||||||
|
if(channel){
|
||||||
|
for(const thing of channel.messages){
|
||||||
|
thing[1].generateMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
getpfpsrc(){
|
getpfpsrc(){
|
||||||
if(this.hypotheticalpfp){
|
if(this.hypotheticalpfp){
|
||||||
return this.avatar;
|
return this.avatar;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue