various updates
This commit is contained in:
parent
164aa48ea4
commit
cd15064d3a
16 changed files with 312 additions and 150 deletions
|
@ -212,7 +212,7 @@ class Channel extends SnowFlake {
|
||||||
if (json.parent_id) {
|
if (json.parent_id) {
|
||||||
this.parent_id = json.parent_id;
|
this.parent_id = json.parent_id;
|
||||||
}
|
}
|
||||||
this.parent = null;
|
this.parent = undefined;
|
||||||
this.children = [];
|
this.children = [];
|
||||||
this.guild_id = json.guild_id;
|
this.guild_id = json.guild_id;
|
||||||
this.permission_overwrites = new Map();
|
this.permission_overwrites = new Map();
|
||||||
|
@ -312,12 +312,12 @@ class Channel extends SnowFlake {
|
||||||
const parentid = this.parent_id;
|
const parentid = this.parent_id;
|
||||||
if (!parentid)
|
if (!parentid)
|
||||||
return false;
|
return false;
|
||||||
this.parent = guild.channelids[parentid];
|
this.parent = this.localuser.channelids.get(parentid);
|
||||||
this.parent ??= null;
|
this.parent ??= undefined;
|
||||||
if (this.parent !== null) {
|
if (this.parent !== undefined) {
|
||||||
this.parent.children.push(this);
|
this.parent.children.push(this);
|
||||||
}
|
}
|
||||||
return this.parent !== null;
|
return this.parent !== undefined;
|
||||||
}
|
}
|
||||||
calculateReorder() {
|
calculateReorder() {
|
||||||
let position = -1;
|
let position = -1;
|
||||||
|
@ -967,13 +967,13 @@ class Channel extends SnowFlake {
|
||||||
updateChannel(json) {
|
updateChannel(json) {
|
||||||
this.type = json.type;
|
this.type = json.type;
|
||||||
this.name = json.name;
|
this.name = json.name;
|
||||||
const parent = this.guild.channelids[json.parent_id];
|
const parent = this.localuser.channelids.get(json.parent_id);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.parent_id = parent.id;
|
this.parent_id = parent.id;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.parent = null;
|
this.parent = undefined;
|
||||||
this.parent_id = undefined;
|
this.parent_id = undefined;
|
||||||
}
|
}
|
||||||
this.children = [];
|
this.children = [];
|
||||||
|
|
|
@ -10,7 +10,6 @@ class Guild extends SnowFlake {
|
||||||
owner;
|
owner;
|
||||||
headers;
|
headers;
|
||||||
channels;
|
channels;
|
||||||
channelids;
|
|
||||||
properties;
|
properties;
|
||||||
member_count;
|
member_count;
|
||||||
roles;
|
roles;
|
||||||
|
@ -86,7 +85,6 @@ class Guild extends SnowFlake {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.headers = this.owner.headers;
|
this.headers = this.owner.headers;
|
||||||
this.channels = [];
|
this.channels = [];
|
||||||
this.channelids = {};
|
|
||||||
this.properties = json.properties;
|
this.properties = json.properties;
|
||||||
this.roles = [];
|
this.roles = [];
|
||||||
this.roleids = new Map();
|
this.roleids = new Map();
|
||||||
|
@ -117,7 +115,7 @@ class Guild extends SnowFlake {
|
||||||
for (const thing of json.channels) {
|
for (const thing of json.channels) {
|
||||||
const temp = new Channel(thing, this);
|
const temp = new Channel(thing, this);
|
||||||
this.channels.push(temp);
|
this.channels.push(temp);
|
||||||
this.channelids[temp.id] = temp;
|
this.localuser.channelids.set(temp.id, temp);
|
||||||
}
|
}
|
||||||
this.headchannels = [];
|
this.headchannels = [];
|
||||||
for (const thing of this.channels) {
|
for (const thing of this.channels) {
|
||||||
|
@ -126,7 +124,7 @@ class Guild extends SnowFlake {
|
||||||
this.headchannels.push(thing);
|
this.headchannels.push(thing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.prevchannel = this.channelids[this.perminfo.prevchannel];
|
this.prevchannel = this.localuser.channelids.get(this.perminfo.prevchannel);
|
||||||
}
|
}
|
||||||
get perminfo() {
|
get perminfo() {
|
||||||
return this.localuser.perminfo.guilds[this.id];
|
return this.localuser.perminfo.guilds[this.id];
|
||||||
|
@ -429,10 +427,13 @@ class Guild extends SnowFlake {
|
||||||
return this.member.hasRole(r);
|
return this.member.hasRole(r);
|
||||||
}
|
}
|
||||||
loadChannel(ID) {
|
loadChannel(ID) {
|
||||||
if (ID && this.channelids[ID]) {
|
if (ID) {
|
||||||
this.channelids[ID].getHTML();
|
const channel = this.localuser.channelids.get(ID);
|
||||||
|
if (channel) {
|
||||||
|
channel.getHTML();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (this.prevchannel) {
|
if (this.prevchannel) {
|
||||||
console.log(this.prevchannel);
|
console.log(this.prevchannel);
|
||||||
this.prevchannel.getHTML();
|
this.prevchannel.getHTML();
|
||||||
|
@ -449,7 +450,7 @@ class Guild extends SnowFlake {
|
||||||
this.localuser.loadGuild(this.id);
|
this.localuser.loadGuild(this.id);
|
||||||
}
|
}
|
||||||
updateChannel(json) {
|
updateChannel(json) {
|
||||||
const channel = this.channelids[json.id];
|
const channel = this.localuser.channelids.get(json.id);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
channel.updateChannel(json);
|
channel.updateChannel(json);
|
||||||
this.headchannels = [];
|
this.headchannels = [];
|
||||||
|
@ -468,7 +469,7 @@ class Guild extends SnowFlake {
|
||||||
}
|
}
|
||||||
createChannelpac(json) {
|
createChannelpac(json) {
|
||||||
const thischannel = new Channel(json, this);
|
const thischannel = new Channel(json, this);
|
||||||
this.channelids[json.id] = thischannel;
|
this.localuser.channelids.set(json.id, thischannel);
|
||||||
this.channels.push(thischannel);
|
this.channels.push(thischannel);
|
||||||
thischannel.resolveparent(this);
|
thischannel.resolveparent(this);
|
||||||
if (!thischannel.parent) {
|
if (!thischannel.parent) {
|
||||||
|
@ -515,8 +516,10 @@ class Guild extends SnowFlake {
|
||||||
channelselect.show();
|
channelselect.show();
|
||||||
}
|
}
|
||||||
delChannel(json) {
|
delChannel(json) {
|
||||||
const channel = this.channelids[json.id];
|
const channel = this.localuser.channelids.get(json.id);
|
||||||
delete this.channelids[json.id];
|
this.localuser.channelids.delete(json.id);
|
||||||
|
if (!channel)
|
||||||
|
return;
|
||||||
this.channels.splice(this.channels.indexOf(channel), 1);
|
this.channels.splice(this.channels.indexOf(channel), 1);
|
||||||
const indexy = this.headchannels.indexOf(channel);
|
const indexy = this.headchannels.indexOf(channel);
|
||||||
if (indexy !== -1) {
|
if (indexy !== -1) {
|
||||||
|
|
|
@ -24,6 +24,9 @@ class InfiniteScroller {
|
||||||
this.div = scroll;
|
this.div = scroll;
|
||||||
this.div.addEventListener("scroll", _ => {
|
this.div.addEventListener("scroll", _ => {
|
||||||
this.checkscroll();
|
this.checkscroll();
|
||||||
|
if (this.scrollBottom < 5) {
|
||||||
|
this.scrollBottom = 5;
|
||||||
|
}
|
||||||
if (this.timeout === null) {
|
if (this.timeout === null) {
|
||||||
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
|
this.timeout = setTimeout(this.updatestuff.bind(this), 300);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ class Localuser {
|
||||||
ws;
|
ws;
|
||||||
connectionSucceed = 0;
|
connectionSucceed = 0;
|
||||||
errorBackoff = 0;
|
errorBackoff = 0;
|
||||||
|
channelids = new Map();
|
||||||
userMap = new Map();
|
userMap = new Map();
|
||||||
instancePing = {
|
instancePing = {
|
||||||
name: "Unknown",
|
name: "Unknown",
|
||||||
|
@ -64,8 +65,8 @@ class Localuser {
|
||||||
this.userinfo.username = this.user.username;
|
this.userinfo.username = this.user.username;
|
||||||
this.userinfo.pfpsrc = this.user.getpfpsrc();
|
this.userinfo.pfpsrc = this.user.getpfpsrc();
|
||||||
this.status = this.ready.d.user_settings.status;
|
this.status = this.ready.d.user_settings.status;
|
||||||
this.channelfocus = null;
|
this.channelfocus = undefined;
|
||||||
this.lookingguild = null;
|
this.lookingguild = undefined;
|
||||||
this.guildhtml = new Map();
|
this.guildhtml = new Map();
|
||||||
const members = {};
|
const members = {};
|
||||||
for (const thing of ready.d.merged_members) {
|
for (const thing of ready.d.merged_members) {
|
||||||
|
@ -86,15 +87,11 @@ class Localuser {
|
||||||
this.guildids.get(thing.guild_id).notisetting(thing);
|
this.guildids.get(thing.guild_id).notisetting(thing);
|
||||||
}
|
}
|
||||||
for (const thing of ready.d.read_state.entries) {
|
for (const thing of ready.d.read_state.entries) {
|
||||||
const channel = this.resolveChannelFromID(thing.id);
|
const channel = this.channelids.get(thing.channel_id);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const guild = channel.guild;
|
channel.readStateInfo(thing);
|
||||||
if (guild === undefined) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
guild.channelids[thing.channel_id].readStateInfo(thing);
|
|
||||||
}
|
}
|
||||||
for (const thing of ready.d.relationships) {
|
for (const thing of ready.d.relationships) {
|
||||||
const user = new User(thing.user, this);
|
const user = new User(thing.user, this);
|
||||||
|
@ -112,8 +109,8 @@ class Localuser {
|
||||||
if (this.channelfocus) {
|
if (this.channelfocus) {
|
||||||
this.channelfocus.infinite.delete();
|
this.channelfocus.infinite.delete();
|
||||||
}
|
}
|
||||||
this.lookingguild = null;
|
this.lookingguild = undefined;
|
||||||
this.channelfocus = null;
|
this.channelfocus = undefined;
|
||||||
}
|
}
|
||||||
unload() {
|
unload() {
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
|
@ -307,10 +304,7 @@ class Localuser {
|
||||||
case "MESSAGE_DELETE":
|
case "MESSAGE_DELETE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id ??= "@me";
|
temp.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
break;
|
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.id);
|
const message = channel.messages.get(temp.d.id);
|
||||||
|
@ -325,10 +319,7 @@ class Localuser {
|
||||||
case "MESSAGE_UPDATE":
|
case "MESSAGE_UPDATE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id ??= "@me";
|
temp.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
break;
|
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.id);
|
const message = channel.messages.get(temp.d.id);
|
||||||
|
@ -389,7 +380,7 @@ class Localuser {
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const guild = this.guildids.get(temp.d.guild_id);
|
||||||
if (!guild)
|
if (!guild)
|
||||||
break;
|
break;
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.message_id);
|
const message = channel.messages.get(temp.d.message_id);
|
||||||
|
@ -408,10 +399,7 @@ class Localuser {
|
||||||
case "MESSAGE_REACTION_REMOVE":
|
case "MESSAGE_REACTION_REMOVE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id ??= "@me";
|
temp.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
break;
|
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.message_id);
|
const message = channel.messages.get(temp.d.message_id);
|
||||||
|
@ -423,10 +411,7 @@ class Localuser {
|
||||||
case "MESSAGE_REACTION_REMOVE_ALL":
|
case "MESSAGE_REACTION_REMOVE_ALL":
|
||||||
{
|
{
|
||||||
temp.d.guild_id ??= "@me";
|
temp.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
break;
|
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.message_id);
|
const message = channel.messages.get(temp.d.message_id);
|
||||||
|
@ -438,10 +423,7 @@ class Localuser {
|
||||||
case "MESSAGE_REACTION_REMOVE_EMOJI":
|
case "MESSAGE_REACTION_REMOVE_EMOJI":
|
||||||
{
|
{
|
||||||
temp.d.guild_id ??= "@me";
|
temp.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(temp.d.guild_id);
|
const channel = this.channelids.get(temp.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
break;
|
|
||||||
const channel = guild.channelids[temp.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
break;
|
break;
|
||||||
const message = channel.messages.get(temp.d.message_id);
|
const message = channel.messages.get(temp.d.message_id);
|
||||||
|
@ -473,13 +455,6 @@ class Localuser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
heartbeat_interval;
|
heartbeat_interval;
|
||||||
resolveChannelFromID(ID) {
|
|
||||||
const resolve = this.guilds.find(guild => guild.channelids[ID]);
|
|
||||||
if (resolve) {
|
|
||||||
return resolve.channelids[ID];
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
updateChannel(json) {
|
updateChannel(json) {
|
||||||
const guild = this.guildids.get(json.guild_id);
|
const guild = this.guildids.get(json.guild_id);
|
||||||
if (guild) {
|
if (guild) {
|
||||||
|
@ -506,13 +481,9 @@ class Localuser {
|
||||||
}
|
}
|
||||||
gotoid;
|
gotoid;
|
||||||
async goToChannel(id) {
|
async goToChannel(id) {
|
||||||
let guild;
|
const channel = this.channelids.get(id);
|
||||||
for (const thing of this.guilds) {
|
if (channel) {
|
||||||
if (thing.channelids[id]) {
|
const guild = channel.guild;
|
||||||
guild = thing;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (guild) {
|
|
||||||
guild.loadGuild();
|
guild.loadGuild();
|
||||||
guild.loadChannel(id);
|
guild.loadChannel(id);
|
||||||
}
|
}
|
||||||
|
@ -540,7 +511,7 @@ class Localuser {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
guild.loadChannel(location[5]);
|
guild.loadChannel(location[5]);
|
||||||
this.channelfocus = guild.channelids[location[5]];
|
this.channelfocus = this.channelids.get(location[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loaduser() {
|
loaduser() {
|
||||||
|
@ -770,12 +741,12 @@ class Localuser {
|
||||||
}
|
}
|
||||||
messageCreate(messagep) {
|
messageCreate(messagep) {
|
||||||
messagep.d.guild_id ??= "@me";
|
messagep.d.guild_id ??= "@me";
|
||||||
const guild = this.guildids.get(messagep.d.guild_id);
|
const channel = this.channelids.get(messagep.d.channel_id);
|
||||||
if (!guild)
|
if (channel) {
|
||||||
return;
|
channel.messageCreate(messagep);
|
||||||
guild.channelids[messagep.d.channel_id].messageCreate(messagep);
|
|
||||||
this.unreads();
|
this.unreads();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
unreads() {
|
unreads() {
|
||||||
for (const thing of this.guilds) {
|
for (const thing of this.guilds) {
|
||||||
if (thing.id === "@me") {
|
if (thing.id === "@me") {
|
||||||
|
@ -787,10 +758,7 @@ class Localuser {
|
||||||
}
|
}
|
||||||
async typingStart(typing) {
|
async typingStart(typing) {
|
||||||
//
|
//
|
||||||
const guild = this.guildids.get(typing.d.guild_id);
|
const channel = this.channelids.get(typing.d.channel_id);
|
||||||
if (!guild)
|
|
||||||
return;
|
|
||||||
const channel = guild.channelids[typing.d.channel_id];
|
|
||||||
if (!channel)
|
if (!channel)
|
||||||
return;
|
return;
|
||||||
channel.typingStart(typing);
|
channel.typingStart(typing);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { Channel } from "./channel.js";
|
import { Channel } from "./channel.js";
|
||||||
import { Dialog } from "./dialog.js";
|
import { Dialog } from "./dialog.js";
|
||||||
import { Emoji } from "./emoji.js";
|
import { Emoji } from "./emoji.js";
|
||||||
|
import { Localuser } from "./localuser.js";
|
||||||
|
import { Member } from "./member.js";
|
||||||
class MarkDown {
|
class MarkDown {
|
||||||
txt;
|
txt;
|
||||||
keep;
|
keep;
|
||||||
|
@ -22,6 +24,14 @@ class MarkDown {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.stdsize = stdsize;
|
this.stdsize = stdsize;
|
||||||
}
|
}
|
||||||
|
get localuser() {
|
||||||
|
if (this.owner instanceof Localuser) {
|
||||||
|
return this.owner;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this.owner.localuser;
|
||||||
|
}
|
||||||
|
}
|
||||||
get rawString() {
|
get rawString() {
|
||||||
return this.txt.join("");
|
return this.txt.join("");
|
||||||
}
|
}
|
||||||
|
@ -415,6 +425,68 @@ class MarkDown {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (txt[i] === "<" && (txt[i + 1] === "@" || txt[i + 1] === "#")) {
|
||||||
|
let id = "";
|
||||||
|
let j = i + 2;
|
||||||
|
const numbers = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
||||||
|
for (; txt[j] !== undefined; j++) {
|
||||||
|
const char = txt[j];
|
||||||
|
if (!numbers.has(char)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
id += char;
|
||||||
|
}
|
||||||
|
if (txt[j] === ">") {
|
||||||
|
appendcurrent();
|
||||||
|
const mention = document.createElement("span");
|
||||||
|
mention.classList.add("mentionMD");
|
||||||
|
mention.contentEditable = "false";
|
||||||
|
const char = txt[i + 1];
|
||||||
|
i = j;
|
||||||
|
switch (char) {
|
||||||
|
case "@":
|
||||||
|
const user = this.localuser.userMap.get(id);
|
||||||
|
if (user) {
|
||||||
|
mention.textContent = `@${user.name}`;
|
||||||
|
let guild = null;
|
||||||
|
if (this.owner instanceof Channel) {
|
||||||
|
guild = this.owner.guild;
|
||||||
|
}
|
||||||
|
if (!keep) {
|
||||||
|
user.bind(mention, guild);
|
||||||
|
}
|
||||||
|
if (guild) {
|
||||||
|
Member.resolveMember(user, guild).then(member => {
|
||||||
|
if (member) {
|
||||||
|
mention.textContent = `@${member.name}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mention.textContent = `@unknown`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "#":
|
||||||
|
const channel = this.localuser.channelids.get(id);
|
||||||
|
if (channel) {
|
||||||
|
mention.textContent = `#${channel.name}`;
|
||||||
|
if (!keep) {
|
||||||
|
mention.onclick = _ => {
|
||||||
|
this.localuser.goToChannel(id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mention.textContent = `#unknown`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
span.appendChild(mention);
|
||||||
|
mention.setAttribute("real", `<${char}${id}>`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (txt[i] === "<" && txt[i + 1] === "t" && txt[i + 2] === ":") {
|
if (txt[i] === "<" && txt[i + 1] === "t" && txt[i + 2] === ":") {
|
||||||
let found = false;
|
let found = false;
|
||||||
const build = ["<", "t", ":"];
|
const build = ["<", "t", ":"];
|
||||||
|
@ -571,6 +643,9 @@ class MarkDown {
|
||||||
if (element.tagName.toLowerCase() === "br") {
|
if (element.tagName.toLowerCase() === "br") {
|
||||||
return "\n";
|
return "\n";
|
||||||
}
|
}
|
||||||
|
if (element.hasAttribute("real")) {
|
||||||
|
return element.getAttribute("real");
|
||||||
|
}
|
||||||
let build = "";
|
let build = "";
|
||||||
for (const thing of element.childNodes) {
|
for (const thing of element.childNodes) {
|
||||||
if (thing instanceof Text) {
|
if (thing instanceof Text) {
|
||||||
|
@ -633,15 +708,29 @@ class MarkDown {
|
||||||
throw Error(url + " is not a valid URL");
|
throw Error(url + " is not a valid URL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static replace(base, newelm) {
|
||||||
|
const basechildren = base.children;
|
||||||
|
const newchildren = newelm.children;
|
||||||
|
for (const thing of newchildren) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//solution from https://stackoverflow.com/questions/4576694/saving-and-restoring-caret-position-for-contenteditable-div
|
//solution from https://stackoverflow.com/questions/4576694/saving-and-restoring-caret-position-for-contenteditable-div
|
||||||
|
let text = "";
|
||||||
function saveCaretPosition(context) {
|
function saveCaretPosition(context) {
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
if (!selection)
|
if (!selection)
|
||||||
return;
|
return;
|
||||||
const range = selection.getRangeAt(0);
|
const range = selection.getRangeAt(0);
|
||||||
range.setStart(context, 0);
|
range.setStart(context, 0);
|
||||||
const len = range.toString().length;
|
text = selection.toString();
|
||||||
|
let len = text.length + 1;
|
||||||
|
for (const str in text.split("\n")) {
|
||||||
|
if (str.length !== 0) {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len += +(text[text.length - 1] === "\n");
|
||||||
return function restore() {
|
return function restore() {
|
||||||
if (!selection)
|
if (!selection)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -273,6 +273,11 @@ class Message extends SnowFlake {
|
||||||
premessage = this.channel.messages.get(this.channel.idToPrev.get(this.id));
|
premessage = this.channel.messages.get(this.channel.idToPrev.get(this.id));
|
||||||
}
|
}
|
||||||
const div = this.div;
|
const div = this.div;
|
||||||
|
for (const user of this.mentions) {
|
||||||
|
if (user === this.localuser.user) {
|
||||||
|
div.classList.add("mentioned");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this === this.channel.replyingto) {
|
if (this === this.channel.replyingto) {
|
||||||
div.classList.add("replying");
|
div.classList.add("replying");
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,9 @@ class User extends SnowFlake {
|
||||||
get localuser() {
|
get localuser() {
|
||||||
return this.owner;
|
return this.owner;
|
||||||
}
|
}
|
||||||
|
get name() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
constructor(userjson, owner, dontclone = false) {
|
constructor(userjson, owner, dontclone = false) {
|
||||||
super(userjson.id);
|
super(userjson.id);
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Channel extends SnowFlake{
|
||||||
headers:Localuser["headers"];
|
headers:Localuser["headers"];
|
||||||
name:string;
|
name:string;
|
||||||
parent_id?:string;
|
parent_id?:string;
|
||||||
parent:Channel|null;
|
parent:Channel|undefined;
|
||||||
children:Channel[];
|
children:Channel[];
|
||||||
guild_id:string;
|
guild_id:string;
|
||||||
permission_overwrites:Map<string,Permissions>;
|
permission_overwrites:Map<string,Permissions>;
|
||||||
|
@ -224,7 +224,7 @@ class Channel extends SnowFlake{
|
||||||
if(json.parent_id){
|
if(json.parent_id){
|
||||||
this.parent_id=json.parent_id;
|
this.parent_id=json.parent_id;
|
||||||
}
|
}
|
||||||
this.parent=null;
|
this.parent=undefined;
|
||||||
this.children=[];
|
this.children=[];
|
||||||
this.guild_id=json.guild_id;
|
this.guild_id=json.guild_id;
|
||||||
this.permission_overwrites=new Map();
|
this.permission_overwrites=new Map();
|
||||||
|
@ -325,12 +325,12 @@ class Channel extends SnowFlake{
|
||||||
resolveparent(guild:Guild){
|
resolveparent(guild:Guild){
|
||||||
const parentid=this.parent_id;
|
const parentid=this.parent_id;
|
||||||
if(!parentid)return false;
|
if(!parentid)return false;
|
||||||
this.parent=guild.channelids[parentid];
|
this.parent=this.localuser.channelids.get(parentid);
|
||||||
this.parent??=null;
|
this.parent??=undefined;
|
||||||
if(this.parent!==null){
|
if(this.parent!==undefined){
|
||||||
this.parent.children.push(this);
|
this.parent.children.push(this);
|
||||||
}
|
}
|
||||||
return this.parent!==null;
|
return this.parent!==undefined;
|
||||||
}
|
}
|
||||||
calculateReorder(){
|
calculateReorder(){
|
||||||
let position=-1;
|
let position=-1;
|
||||||
|
@ -970,12 +970,12 @@ class Channel extends SnowFlake{
|
||||||
updateChannel(json:channeljson){
|
updateChannel(json:channeljson){
|
||||||
this.type=json.type;
|
this.type=json.type;
|
||||||
this.name=json.name;
|
this.name=json.name;
|
||||||
const parent=this.guild.channelids[json.parent_id];
|
const parent=this.localuser.channelids.get(json.parent_id);
|
||||||
if(parent){
|
if(parent){
|
||||||
this.parent=parent;
|
this.parent=parent;
|
||||||
this.parent_id=parent.id;
|
this.parent_id=parent.id;
|
||||||
}else{
|
}else{
|
||||||
this.parent=null;
|
this.parent=undefined;
|
||||||
this.parent_id=undefined;
|
this.parent_id=undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ class Guild extends SnowFlake{
|
||||||
owner:Localuser;
|
owner:Localuser;
|
||||||
headers:Localuser["headers"];
|
headers:Localuser["headers"];
|
||||||
channels:Channel[];
|
channels:Channel[];
|
||||||
channelids:{[key:string]:Channel};
|
|
||||||
properties;
|
properties;
|
||||||
member_count:number;
|
member_count:number;
|
||||||
roles:Role[];
|
roles:Role[];
|
||||||
|
@ -96,7 +95,6 @@ class Guild extends SnowFlake{
|
||||||
this.owner=owner;
|
this.owner=owner;
|
||||||
this.headers=this.owner.headers;
|
this.headers=this.owner.headers;
|
||||||
this.channels=[];
|
this.channels=[];
|
||||||
this.channelids={};
|
|
||||||
this.properties=json.properties;
|
this.properties=json.properties;
|
||||||
this.roles=[];
|
this.roles=[];
|
||||||
this.roleids=new Map();
|
this.roleids=new Map();
|
||||||
|
@ -126,7 +124,7 @@ class Guild extends SnowFlake{
|
||||||
for(const thing of json.channels){
|
for(const thing of json.channels){
|
||||||
const temp=new Channel(thing,this);
|
const temp=new Channel(thing,this);
|
||||||
this.channels.push(temp);
|
this.channels.push(temp);
|
||||||
this.channelids[temp.id]=temp;
|
this.localuser.channelids.set(temp.id,temp);
|
||||||
}
|
}
|
||||||
this.headchannels=[];
|
this.headchannels=[];
|
||||||
for(const thing of this.channels){
|
for(const thing of this.channels){
|
||||||
|
@ -135,7 +133,7 @@ class Guild extends SnowFlake{
|
||||||
this.headchannels.push(thing);
|
this.headchannels.push(thing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.prevchannel=this.channelids[this.perminfo.prevchannel];
|
this.prevchannel=this.localuser.channelids.get(this.perminfo.prevchannel);
|
||||||
}
|
}
|
||||||
get perminfo(){
|
get perminfo(){
|
||||||
return this.localuser.perminfo.guilds[this.id];
|
return this.localuser.perminfo.guilds[this.id];
|
||||||
|
@ -436,10 +434,13 @@ class Guild extends SnowFlake{
|
||||||
return this.member.hasRole(r);
|
return this.member.hasRole(r);
|
||||||
}
|
}
|
||||||
loadChannel(ID?:string|undefined){
|
loadChannel(ID?:string|undefined){
|
||||||
if(ID&&this.channelids[ID]){
|
if(ID){
|
||||||
this.channelids[ID].getHTML();
|
const channel=this.localuser.channelids.get(ID);
|
||||||
|
if(channel){
|
||||||
|
channel.getHTML();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(this.prevchannel){
|
if(this.prevchannel){
|
||||||
console.log(this.prevchannel);
|
console.log(this.prevchannel);
|
||||||
this.prevchannel.getHTML();
|
this.prevchannel.getHTML();
|
||||||
|
@ -456,7 +457,7 @@ class Guild extends SnowFlake{
|
||||||
this.localuser.loadGuild(this.id);
|
this.localuser.loadGuild(this.id);
|
||||||
}
|
}
|
||||||
updateChannel(json:channeljson){
|
updateChannel(json:channeljson){
|
||||||
const channel=this.channelids[json.id];
|
const channel=this.localuser.channelids.get(json.id);
|
||||||
if(channel){
|
if(channel){
|
||||||
channel.updateChannel(json);
|
channel.updateChannel(json);
|
||||||
this.headchannels=[];
|
this.headchannels=[];
|
||||||
|
@ -475,7 +476,7 @@ class Guild extends SnowFlake{
|
||||||
}
|
}
|
||||||
createChannelpac(json:channeljson){
|
createChannelpac(json:channeljson){
|
||||||
const thischannel=new Channel(json,this);
|
const thischannel=new Channel(json,this);
|
||||||
this.channelids[json.id]=thischannel;
|
this.localuser.channelids.set(json.id,thischannel);
|
||||||
this.channels.push(thischannel);
|
this.channels.push(thischannel);
|
||||||
thischannel.resolveparent(this);
|
thischannel.resolveparent(this);
|
||||||
if(!thischannel.parent){
|
if(!thischannel.parent){
|
||||||
|
@ -526,9 +527,9 @@ class Guild extends SnowFlake{
|
||||||
channelselect.show();
|
channelselect.show();
|
||||||
}
|
}
|
||||||
delChannel(json:channeljson){
|
delChannel(json:channeljson){
|
||||||
const channel=this.channelids[json.id];
|
const channel=this.localuser.channelids.get(json.id);
|
||||||
delete this.channelids[json.id];
|
this.localuser.channelids.delete(json.id);
|
||||||
|
if(!channel) return;
|
||||||
this.channels.splice(this.channels.indexOf(channel),1);
|
this.channels.splice(this.channels.indexOf(channel),1);
|
||||||
const indexy=this.headchannels.indexOf(channel);
|
const indexy=this.headchannels.indexOf(channel);
|
||||||
if(indexy!==-1){
|
if(indexy!==-1){
|
||||||
|
|
|
@ -25,6 +25,9 @@ class InfiniteScroller{
|
||||||
this.div=scroll;
|
this.div=scroll;
|
||||||
this.div.addEventListener("scroll",_=>{
|
this.div.addEventListener("scroll",_=>{
|
||||||
this.checkscroll();
|
this.checkscroll();
|
||||||
|
if(this.scrollBottom<5){
|
||||||
|
this.scrollBottom=5;
|
||||||
|
}
|
||||||
if(this.timeout===null){
|
if(this.timeout===null){
|
||||||
this.timeout=setTimeout(this.updatestuff.bind(this),300);
|
this.timeout=setTimeout(this.updatestuff.bind(this),300);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,13 @@ class Localuser{
|
||||||
guildids:Map<string,Guild>;
|
guildids:Map<string,Guild>;
|
||||||
user:User;
|
user:User;
|
||||||
status:string;
|
status:string;
|
||||||
channelfocus:Channel|null;
|
channelfocus:Channel|undefined;
|
||||||
lookingguild:Guild|null;
|
lookingguild:Guild|undefined;
|
||||||
guildhtml:Map<string, HTMLDivElement>;
|
guildhtml:Map<string, HTMLDivElement>;
|
||||||
ws:WebSocket|undefined;
|
ws:WebSocket|undefined;
|
||||||
connectionSucceed=0;
|
connectionSucceed=0;
|
||||||
errorBackoff=0;
|
errorBackoff=0;
|
||||||
|
channelids=new Map<string,Channel>()
|
||||||
readonly userMap=new Map<string,User>();
|
readonly userMap=new Map<string,User>();
|
||||||
instancePing={
|
instancePing={
|
||||||
name: "Unknown",
|
name: "Unknown",
|
||||||
|
@ -68,8 +69,8 @@ class Localuser{
|
||||||
this.userinfo.username=this.user.username;
|
this.userinfo.username=this.user.username;
|
||||||
this.userinfo.pfpsrc=this.user.getpfpsrc();
|
this.userinfo.pfpsrc=this.user.getpfpsrc();
|
||||||
this.status=this.ready.d.user_settings.status;
|
this.status=this.ready.d.user_settings.status;
|
||||||
this.channelfocus=null;
|
this.channelfocus=undefined;
|
||||||
this.lookingguild=null;
|
this.lookingguild=undefined;
|
||||||
this.guildhtml=new Map();
|
this.guildhtml=new Map();
|
||||||
const members={};
|
const members={};
|
||||||
for(const thing of ready.d.merged_members){
|
for(const thing of ready.d.merged_members){
|
||||||
|
@ -94,15 +95,11 @@ class Localuser{
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const thing of ready.d.read_state.entries){
|
for(const thing of ready.d.read_state.entries){
|
||||||
const channel=this.resolveChannelFromID(thing.id);
|
const channel=this.channelids.get(thing.channel_id);
|
||||||
if(!channel){
|
if(!channel){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const guild=channel.guild;
|
channel.readStateInfo(thing);
|
||||||
if(guild===undefined){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
guild.channelids[thing.channel_id].readStateInfo(thing);
|
|
||||||
}
|
}
|
||||||
for(const thing of ready.d.relationships){
|
for(const thing of ready.d.relationships){
|
||||||
const user=new User(thing.user,this);
|
const user=new User(thing.user,this);
|
||||||
|
@ -121,8 +118,8 @@ class Localuser{
|
||||||
if(this.channelfocus){
|
if(this.channelfocus){
|
||||||
this.channelfocus.infinite.delete();
|
this.channelfocus.infinite.delete();
|
||||||
}
|
}
|
||||||
this.lookingguild=null;
|
this.lookingguild=undefined;
|
||||||
this.channelfocus=null;
|
this.channelfocus=undefined;
|
||||||
}
|
}
|
||||||
unload():void{
|
unload():void{
|
||||||
this.initialized=false;
|
this.initialized=false;
|
||||||
|
@ -315,9 +312,7 @@ class Localuser{
|
||||||
case"MESSAGE_DELETE":
|
case"MESSAGE_DELETE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!guild) break;
|
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.id);
|
const message=channel.messages.get(temp.d.id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -330,9 +325,7 @@ class Localuser{
|
||||||
case"MESSAGE_UPDATE":
|
case"MESSAGE_UPDATE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!guild) break;
|
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.id);
|
const message=channel.messages.get(temp.d.id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -390,7 +383,7 @@ class Localuser{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const guild=this.guildids.get(temp.d.guild_id);
|
||||||
if(!guild) break;
|
if(!guild) break;
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.message_id);
|
const message=channel.messages.get(temp.d.message_id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -406,9 +399,7 @@ class Localuser{
|
||||||
case"MESSAGE_REACTION_REMOVE":
|
case"MESSAGE_REACTION_REMOVE":
|
||||||
{
|
{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!guild) break;
|
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.message_id);
|
const message=channel.messages.get(temp.d.message_id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -418,9 +409,7 @@ class Localuser{
|
||||||
case"MESSAGE_REACTION_REMOVE_ALL":
|
case"MESSAGE_REACTION_REMOVE_ALL":
|
||||||
{
|
{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!guild) break;
|
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.message_id);
|
const message=channel.messages.get(temp.d.message_id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -430,9 +419,7 @@ class Localuser{
|
||||||
case"MESSAGE_REACTION_REMOVE_EMOJI":
|
case"MESSAGE_REACTION_REMOVE_EMOJI":
|
||||||
{
|
{
|
||||||
temp.d.guild_id??="@me";
|
temp.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(temp.d.guild_id);
|
const channel=this.channelids.get(temp.d.channel_id);
|
||||||
if(!guild) break;
|
|
||||||
const channel=guild.channelids[temp.d.channel_id];
|
|
||||||
if(!channel) break;
|
if(!channel) break;
|
||||||
const message=channel.messages.get(temp.d.message_id);
|
const message=channel.messages.get(temp.d.message_id);
|
||||||
if(!message) break;
|
if(!message) break;
|
||||||
|
@ -457,13 +444,6 @@ class Localuser{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
heartbeat_interval:number;
|
heartbeat_interval:number;
|
||||||
resolveChannelFromID(ID:string):Channel|undefined{
|
|
||||||
const resolve=this.guilds.find(guild=>guild.channelids[ID]);
|
|
||||||
if(resolve){
|
|
||||||
return resolve.channelids[ID];
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
updateChannel(json:channeljson):void{
|
updateChannel(json:channeljson):void{
|
||||||
const guild=this.guildids.get(json.guild_id);
|
const guild=this.guildids.get(json.guild_id);
|
||||||
if(guild){
|
if(guild){
|
||||||
|
@ -489,13 +469,10 @@ class Localuser{
|
||||||
}
|
}
|
||||||
gotoid:string|undefined;
|
gotoid:string|undefined;
|
||||||
async goToChannel(id:string){
|
async goToChannel(id:string){
|
||||||
let guild:undefined|Guild;
|
|
||||||
for(const thing of this.guilds){
|
const channel=this.channelids.get(id);
|
||||||
if(thing.channelids[id]){
|
if(channel){
|
||||||
guild=thing;
|
const guild=channel.guild;
|
||||||
}
|
|
||||||
}
|
|
||||||
if(guild){
|
|
||||||
guild.loadGuild();
|
guild.loadGuild();
|
||||||
guild.loadChannel(id);
|
guild.loadChannel(id);
|
||||||
}else{
|
}else{
|
||||||
|
@ -523,7 +500,7 @@ class Localuser{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
guild.loadChannel(location[5]);
|
guild.loadChannel(location[5]);
|
||||||
this.channelfocus=guild.channelids[location[5]];
|
this.channelfocus=this.channelids.get(location[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loaduser():void{
|
loaduser():void{
|
||||||
|
@ -762,11 +739,12 @@ class Localuser{
|
||||||
}
|
}
|
||||||
messageCreate(messagep):void{
|
messageCreate(messagep):void{
|
||||||
messagep.d.guild_id??="@me";
|
messagep.d.guild_id??="@me";
|
||||||
const guild=this.guildids.get(messagep.d.guild_id);
|
const channel=this.channelids.get(messagep.d.channel_id);
|
||||||
if(!guild)return;
|
if(channel){
|
||||||
guild.channelids[messagep.d.channel_id].messageCreate(messagep);
|
channel.messageCreate(messagep);
|
||||||
this.unreads();
|
this.unreads();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
unreads():void{
|
unreads():void{
|
||||||
for(const thing of this.guilds){
|
for(const thing of this.guilds){
|
||||||
if(thing.id==="@me"){
|
if(thing.id==="@me"){
|
||||||
|
@ -778,9 +756,7 @@ class Localuser{
|
||||||
}
|
}
|
||||||
async typingStart(typing):Promise<void>{
|
async typingStart(typing):Promise<void>{
|
||||||
//
|
//
|
||||||
const guild=this.guildids.get(typing.d.guild_id);
|
const channel=this.channelids.get(typing.d.channel_id);
|
||||||
if(!guild)return;
|
|
||||||
const channel=guild.channelids[typing.d.channel_id];
|
|
||||||
if(!channel) return;
|
if(!channel) return;
|
||||||
channel.typingStart(typing);
|
channel.typingStart(typing);
|
||||||
//this.typing.set(memb,Date.now());
|
//this.typing.set(memb,Date.now());
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import{ Channel }from"./channel.js";
|
import{ Channel }from"./channel.js";
|
||||||
import { Dialog } from "./dialog.js";
|
import { Dialog } from "./dialog.js";
|
||||||
import{ Emoji }from"./emoji.js";
|
import{ Emoji }from"./emoji.js";
|
||||||
|
import { Guild } from "./guild.js";
|
||||||
import{ Localuser }from"./localuser.js";
|
import{ Localuser }from"./localuser.js";
|
||||||
|
import { Member } from "./member.js";
|
||||||
|
|
||||||
|
|
||||||
class MarkDown{
|
class MarkDown{
|
||||||
|
@ -24,6 +26,13 @@ class MarkDown{
|
||||||
this.owner=owner;
|
this.owner=owner;
|
||||||
this.stdsize=stdsize;
|
this.stdsize=stdsize;
|
||||||
}
|
}
|
||||||
|
get localuser(){
|
||||||
|
if(this.owner instanceof Localuser){
|
||||||
|
return this.owner;
|
||||||
|
}else{
|
||||||
|
return this.owner.localuser;
|
||||||
|
}
|
||||||
|
}
|
||||||
get rawString(){
|
get rawString(){
|
||||||
return this.txt.join("");
|
return this.txt.join("");
|
||||||
}
|
}
|
||||||
|
@ -406,7 +415,67 @@ class MarkDown{
|
||||||
span.appendChild(a);
|
span.appendChild(a);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(txt[i]==="<" && (txt[i + 1]==="@"||txt[i + 1]==="#")){
|
||||||
|
let id="";
|
||||||
|
let j = i+2;
|
||||||
|
const numbers=new Set(["0", "1", "2", "3", "4","5","6","7","8","9"]);
|
||||||
|
for(; txt[j] !== undefined; j++){
|
||||||
|
const char=txt[j];
|
||||||
|
if(!numbers.has(char)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
id+=char;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(txt[j]===">"){
|
||||||
|
appendcurrent();
|
||||||
|
const mention=document.createElement("span");
|
||||||
|
mention.classList.add("mentionMD");
|
||||||
|
mention.contentEditable="false";
|
||||||
|
const char=txt[i + 1];
|
||||||
|
i=j;
|
||||||
|
switch(char){
|
||||||
|
case "@":
|
||||||
|
const user=this.localuser.userMap.get(id);
|
||||||
|
if(user){
|
||||||
|
mention.textContent=`@${user.name}`;
|
||||||
|
let guild:null|Guild=null;
|
||||||
|
if(this.owner instanceof Channel){
|
||||||
|
guild=this.owner.guild;
|
||||||
|
}
|
||||||
|
if(!keep){
|
||||||
|
user.bind(mention,guild);
|
||||||
|
}
|
||||||
|
if(guild){
|
||||||
|
Member.resolveMember(user,guild).then(member=>{
|
||||||
|
if(member){
|
||||||
|
mention.textContent=`@${member.name}`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
mention.textContent=`@unknown`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "#":
|
||||||
|
const channel=this.localuser.channelids.get(id);
|
||||||
|
if(channel){
|
||||||
|
mention.textContent=`#${channel.name}`;
|
||||||
|
if(!keep){
|
||||||
|
mention.onclick=_=>{
|
||||||
|
this.localuser.goToChannel(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
mention.textContent=`#unknown`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
span.appendChild(mention);
|
||||||
|
mention.setAttribute("real",`<${char}${id}>`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(txt[i]==="<" && txt[i + 1]==="t" && txt[i + 2]===":"){
|
if(txt[i]==="<" && txt[i + 1]==="t" && txt[i + 2]===":"){
|
||||||
let found=false;
|
let found=false;
|
||||||
|
@ -561,14 +630,16 @@ class MarkDown{
|
||||||
restore();
|
restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static gatherBoxText(element:HTMLElement){
|
static gatherBoxText(element:HTMLElement):string{
|
||||||
if(element.tagName.toLowerCase()==="img"){
|
if(element.tagName.toLowerCase()==="img"){
|
||||||
return(element as HTMLImageElement).alt;
|
return(element as HTMLImageElement).alt;
|
||||||
}
|
}
|
||||||
if(element.tagName.toLowerCase()==="br"){
|
if(element.tagName.toLowerCase()==="br"){
|
||||||
return"\n";
|
return"\n";
|
||||||
}
|
}
|
||||||
|
if(element.hasAttribute("real")){
|
||||||
|
return element.getAttribute("real") as string;
|
||||||
|
}
|
||||||
let build="";
|
let build="";
|
||||||
for(const thing of element.childNodes){
|
for(const thing of element.childNodes){
|
||||||
if(thing instanceof Text){
|
if(thing instanceof Text){
|
||||||
|
@ -627,15 +698,30 @@ class MarkDown{
|
||||||
throw Error(url+" is not a valid URL")
|
throw Error(url+" is not a valid URL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static replace(base:HTMLElement,newelm:HTMLElement){
|
||||||
|
const basechildren=base.children;
|
||||||
|
const newchildren=newelm.children;
|
||||||
|
for(const thing of newchildren){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//solution from https://stackoverflow.com/questions/4576694/saving-and-restoring-caret-position-for-contenteditable-div
|
//solution from https://stackoverflow.com/questions/4576694/saving-and-restoring-caret-position-for-contenteditable-div
|
||||||
function saveCaretPosition(context){
|
let text="";
|
||||||
|
function saveCaretPosition (context){
|
||||||
const selection = window.getSelection();
|
const selection = window.getSelection();
|
||||||
if(!selection)return;
|
if(!selection)return;
|
||||||
const range = selection.getRangeAt(0);
|
const range = selection.getRangeAt(0);
|
||||||
range.setStart(context, 0);
|
range.setStart(context, 0);
|
||||||
const len = range.toString().length;
|
text=selection.toString();
|
||||||
|
let len = text.length+1;
|
||||||
|
for(const str in text.split("\n")){
|
||||||
|
if(str.length!==0){
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len+=+(text[text.length-1]==="\n");
|
||||||
|
|
||||||
return function restore(){
|
return function restore(){
|
||||||
if(!selection)return;
|
if(!selection)return;
|
||||||
|
|
|
@ -268,6 +268,11 @@ class Message extends SnowFlake{
|
||||||
premessage=this.channel.messages.get(this.channel.idToPrev.get(this.id) as string);
|
premessage=this.channel.messages.get(this.channel.idToPrev.get(this.id) as string);
|
||||||
}
|
}
|
||||||
const div=this.div;
|
const div=this.div;
|
||||||
|
for(const user of this.mentions){
|
||||||
|
if(user===this.localuser.user){
|
||||||
|
div.classList.add("mentioned");
|
||||||
|
}
|
||||||
|
}
|
||||||
if(this===this.channel.replyingto){
|
if(this===this.channel.replyingto){
|
||||||
div.classList.add("replying");
|
div.classList.add("replying");
|
||||||
}
|
}
|
||||||
|
|
|
@ -925,9 +925,9 @@ input[type="checkbox"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote {
|
.quote {
|
||||||
display: inline-flex;
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quoteline {
|
.quoteline {
|
||||||
|
@ -940,7 +940,7 @@ input[type="checkbox"] {
|
||||||
|
|
||||||
.quote > span {
|
.quote > span {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
display: block;
|
display: inline-block;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
|
@ -2191,3 +2191,17 @@ form div{
|
||||||
margin-top: .04in;
|
margin-top: .04in;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.mentioned{
|
||||||
|
background-color:color-mix(in srgb, transparent,var(--yellow) 12%);
|
||||||
|
}
|
||||||
|
.mentionMD{
|
||||||
|
background:var(--mention-md-bg);
|
||||||
|
flex-shrink:0;
|
||||||
|
padding:.03in;
|
||||||
|
border-radius:.1in;
|
||||||
|
font-weight:bold;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
.mentionMD:hover{
|
||||||
|
background:color-mix(in srgb,var(--mention-md-bg),white 10%);
|
||||||
|
}
|
|
@ -30,6 +30,7 @@
|
||||||
--textarea-bg: color-mix(in srgb, #484848 80%, var(--accent-color));
|
--textarea-bg: color-mix(in srgb, #484848 80%, var(--accent-color));
|
||||||
--filename: #47bbff;
|
--filename: #47bbff;
|
||||||
--mention-bg: #F00;
|
--mention-bg: #F00;
|
||||||
|
--mention-md-bg: #3b588b;
|
||||||
--pronouns: #797979;
|
--pronouns: #797979;
|
||||||
--profile-bg: color-mix(in srgb, #232323 90%, var(--accent-color));
|
--profile-bg: color-mix(in srgb, #232323 90%, var(--accent-color));
|
||||||
--profile-info-bg: color-mix(in srgb, #121212 90%, var(--accent-color));
|
--profile-info-bg: color-mix(in srgb, #121212 90%, var(--accent-color));
|
||||||
|
@ -84,6 +85,7 @@
|
||||||
--textarea-bg: #b1b6ce;
|
--textarea-bg: #b1b6ce;
|
||||||
--filename: #47bbff;
|
--filename: #47bbff;
|
||||||
--mention-bg: #F00;
|
--mention-bg: #F00;
|
||||||
|
--mention-md-bg: #3b588b;
|
||||||
--pronouns: #6a6a6d;
|
--pronouns: #6a6a6d;
|
||||||
--profile-bg: #cacad8;
|
--profile-bg: #cacad8;
|
||||||
--profile-info-bg: #bbbbce;
|
--profile-info-bg: #bbbbce;
|
||||||
|
@ -140,6 +142,7 @@
|
||||||
--textarea-bg: #abb1cd;
|
--textarea-bg: #abb1cd;
|
||||||
--filename: #47bbff;
|
--filename: #47bbff;
|
||||||
--mention-bg: #F00;
|
--mention-bg: #F00;
|
||||||
|
--mention-md-bg: #3b588b;
|
||||||
--pronouns: #202020;
|
--pronouns: #202020;
|
||||||
--channel-name-bg: #c0c0d4;
|
--channel-name-bg: #c0c0d4;
|
||||||
--server-name-bg: #a3a3b5;
|
--server-name-bg: #a3a3b5;
|
||||||
|
|
|
@ -139,6 +139,9 @@ class User extends SnowFlake{
|
||||||
get localuser(){
|
get localuser(){
|
||||||
return this.owner;
|
return this.owner;
|
||||||
}
|
}
|
||||||
|
get name(){
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
constructor(userjson:userjson,owner:Localuser,dontclone=false){
|
constructor(userjson:userjson,owner:Localuser,dontclone=false){
|
||||||
super(userjson.id);
|
super(userjson.id);
|
||||||
this.owner=owner;
|
this.owner=owner;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue