role and everyone pings

This commit is contained in:
MathMan05
2025-09-18 23:49:40 -05:00
parent d9272c6961
commit bf0b80e954
7 changed files with 187 additions and 74 deletions
+1
View File
@@ -1439,6 +1439,7 @@ class Channel extends SnowFlake {
}
const typebox = document.getElementById("typebox") as CustomHTMLDivElement;
const md = typebox.markdown;
md.owner = this;
typebox.textContent = this.textSave;
md.boxupdate(Infinity);
this.localuser.fileExtange(this.files, this.htmls);
+9 -5
View File
@@ -353,7 +353,9 @@ dmPermissions.setPermission("STREAM", 1);
dmPermissions.setPermission("USE_VAD", 1);
//@ts-ignore No clue how to fix this dumb bug lol
class Group extends Channel {
//TODO remove user
user: User;
users: User[];
static contextmenu = new Contextmenu<Group, undefined>("channel menu");
static setupcontextmenu() {
this.contextmenu.addButton(
@@ -395,11 +397,13 @@ class Group extends Channel {
this.owner = owner;
this.headers = this.guild.headers;
this.name = json.recipients[0]?.username;
if (json.recipients[0]) {
this.user = new User(json.recipients[0], this.localuser);
} else {
this.user = this.localuser.user;
}
const userSet = new Set(json.recipients.map((user) => new User(user, this.localuser)));
userSet.add(this.localuser.user);
this.users = [...userSet];
this.user = this.users[0];
this.name ??= this.localuser.user.username;
this.parent_id!;
this.parent!;
+81 -42
View File
@@ -1,6 +1,6 @@
import {Guild} from "./guild.js";
import {Channel} from "./channel.js";
import {Direct} from "./direct.js";
import {Direct, Group} from "./direct.js";
import {AVoice} from "./audio/voice.js";
import {User} from "./user.js";
import {createImg, getapiurls, getBulkUsers, installPGet, SW} from "./utils/utils.js";
@@ -2947,18 +2947,55 @@ class Localuser {
return new User(await (await fetch(this.info.api + "/users/" + id)).json(), this);
}
MDFineMentionGen(name: string, original: string, box: HTMLDivElement, typebox: MarkDown) {
let members: [Member, number][] = [];
if (this.lookingguild) {
for (const member of this.lookingguild.members) {
const rank = member.compare(name);
if (rank > 0) {
members.push([member, rank]);
let members: [Member | Role | User | "@everyone", number][] = [];
if (this.lookingguild && name !== "everyone") {
if (this.lookingguild.id === "@me") {
const dirrect = this.channelfocus as Group;
for (const user of dirrect.users) {
const rank = user.compare(name);
if (rank > 0) {
members.push([user, rank]);
}
}
} else {
for (const member of this.lookingguild.members) {
const rank = member.compare(name);
if (rank > 0) {
members.push([member, rank]);
}
}
for (const role of this.lookingguild.roles.filter((_) => _.id !== this.lookingguild?.id)) {
const rank = role.compare(name);
if (rank > 0) {
members.push([role, rank]);
}
}
}
function similar(str2: string | null | undefined) {
if (!str2) return 0;
const strl = Math.max(name.length, 1);
if (str2.includes(name)) {
return strl / str2.length;
} else if (str2.toLowerCase().includes(name.toLowerCase())) {
return strl / str2.length / 1.2;
}
return 0;
}
const everyoneScore = similar("everyone");
if (everyoneScore) members.push(["@everyone", everyoneScore]);
}
members.sort((a, b) => b[1] - a[1]);
this.MDSearchOptions(
members.map((a) => ["@" + a[0].name, `<@${a[0].id}> `, undefined]),
members.map((a) => [
a[0] === "@everyone" ? "@everyone" : "@" + a[0].name,
a[0] instanceof Role
? `<@&${a[0].id}> `
: a[0] === "@everyone"
? "@everyone "
: `<@${a[0].id}> `,
undefined,
]),
original,
box,
typebox,
@@ -2969,43 +3006,45 @@ class Localuser {
this.MDFineMentionGen(name, original, box, typebox);
const nonce = Math.floor(Math.random() * 10 ** 8) + "";
if (this.lookingguild.member_count <= this.lookingguild.members.size) return;
this.ws.send(
JSON.stringify({
op: 8,
d: {
guild_id: [this.lookingguild.id],
query: name,
limit: 8,
presences: true,
nonce,
},
}),
);
this.searchMap.set(nonce, async (e) => {
console.log(e);
if (e.members && e.members[0]) {
if (e.members[0].user) {
for (const thing of e.members) {
await Member.new(thing, this.lookingguild as Guild);
}
} else {
const prom1: Promise<User>[] = [];
for (const thing of e.members) {
prom1.push(this.getUser(thing.id));
}
Promise.all(prom1);
for (const thing of e.members) {
if (!this.userMap.has(thing.id)) {
console.warn("Dumb server bug for this member", thing);
continue;
if (this.lookingguild.id !== "@me") {
this.ws.send(
JSON.stringify({
op: 8,
d: {
guild_id: [this.lookingguild.id],
query: name,
limit: 8,
presences: true,
nonce,
},
}),
);
this.searchMap.set(nonce, async (e) => {
console.log(e);
if (e.members && e.members[0]) {
if (e.members[0].user) {
for (const thing of e.members) {
await Member.new(thing, this.lookingguild as Guild);
}
} else {
const prom1: Promise<User>[] = [];
for (const thing of e.members) {
prom1.push(this.getUser(thing.id));
}
Promise.all(prom1);
for (const thing of e.members) {
if (!this.userMap.has(thing.id)) {
console.warn("Dumb server bug for this member", thing);
continue;
}
await Member.new(thing, this.lookingguild as Guild);
}
await Member.new(thing, this.lookingguild as Guild);
}
if (!typebox.rawString.startsWith(original)) return;
this.MDFineMentionGen(name, original, box, typebox);
}
if (!typebox.rawString.startsWith(original)) return;
this.MDFineMentionGen(name, original, box, typebox);
}
});
});
}
}
}
findEmoji(search: string, orginal: string, box: HTMLDivElement, typebox: MarkDown) {
+52 -18
View File
@@ -526,10 +526,33 @@ class MarkDown {
continue;
}
}
if (txt[i] === "@") {
let j = i + 1;
let everyone = true;
for (const char of "everyone") {
if (char !== txt[j]) {
everyone = false;
break;
}
j++;
}
if (everyone) {
i = j - 1;
const mention = document.createElement("span");
mention.classList.add("mentionMD");
mention.contentEditable = "false";
mention.textContent = "@everyone";
appendcurrent();
span.appendChild(mention);
mention.setAttribute("real", `@everyone`);
continue;
}
}
if (txt[i] === "<") {
if ((txt[i + 1] === "@" || txt[i + 1] === "#") && this.localuser) {
let id = "";
let j = i + 2;
const role = txt[i + 1] === "@" && txt[i + 2] === "&";
let j = i + 2 + +role;
const numbers = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
for (; txt[j] !== undefined; j++) {
const char = txt[j];
@@ -555,25 +578,36 @@ class MarkDown {
i = j;
switch (char) {
case "@":
const user = this.localuser.userMap.get(id);
if (user) {
mention.textContent = `@${user.name}`;
let guild: null | Guild = null;
if (role) {
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}`;
}
});
const role = this.owner.guild.roleids.get(id);
if (role) {
mention.textContent = `@${role.name}`;
} else {
mention.textContent = "@unknown-role";
}
}
} else {
mention.textContent = "@unknown";
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 "#":
@@ -592,7 +626,7 @@ class MarkDown {
break;
}
span.appendChild(mention);
mention.setAttribute("real", `<${char}${id}>`);
mention.setAttribute("real", `<${char}${role ? "&" : ""}${id}>`);
continue;
}
} else {
+13 -9
View File
@@ -272,15 +272,18 @@ class Message extends SnowFlake {
for (const thing in messagejson.mentions) {
this.mentions[thing] = new User(messagejson.mentions[thing], this.localuser);
}
this.mention_roles = messagejson.mention_roles
.map((role: string | {id: string}) => {
return this.guild.roleids.get(role instanceof Object ? role.id : role);
})
.filter((_) => _ !== undefined);
if (!this.member && this.guild.id !== "@me") {
this.author.resolvemember(this.guild).then((_) => {
this.member = _;
});
}
if (this.mentions?.length || this.mention_roles?.length) {
//currently mention_roles isn't implemented on the spacebar servers
console.log(this.mentions, this.mention_roles);
}
if (this.mentionsuser(this.localuser.user)) {
console.log(this);
}
@@ -345,14 +348,16 @@ class Message extends SnowFlake {
console.error(e);
}
}
mention_everyone!: boolean;
mentionsuser(userd: User | Member) {
if (this.mention_everyone) return true;
if (userd instanceof User) {
return this.mentions.includes(userd);
} else if (userd instanceof Member) {
if (this.mentions.includes(userd.user)) {
return true;
} else {
return !new Set(this.mentions).isDisjointFrom(new Set(userd.roles)); //if the message mentions a role the user has
return !new Set(this.mention_roles).isDisjointFrom(new Set(userd.roles)); //if the message mentions a role the user has
}
} else {
return false;
@@ -459,11 +464,10 @@ class Message extends SnowFlake {
if (!premessage && !dupe) {
premessage = this.channel.messages.get(this.channel.idToPrev.get(this.id) as string);
}
for (const user of this.mentions) {
if (user === this.localuser.user) {
div.classList.add("mentioned");
}
if (this.mentionsuser(this.guild.member)) {
div.classList.add("mentioned");
}
if (this === this.channel.replyingto) {
div.classList.add("replying");
}
+13
View File
@@ -61,6 +61,19 @@ class Role extends SnowFlake {
document.body.style.setProperty(`--role-${this.id}`, this.getColor());
this.permissions.allow = BigInt(json.permissions);
}
compare(str: string) {
function similar(str2: string | null | undefined) {
if (!str2) return 0;
const strl = Math.max(str.length, 1);
if (str2.includes(str)) {
return strl / str2.length;
} else if (str2.toLowerCase().includes(str.toLowerCase())) {
return strl / str2.length / 1.2;
}
return 0;
}
return Math.max(similar(this.name), similar(this.id) / 1.5);
}
get guild(): Guild {
return this.owner;
}
+18
View File
@@ -60,6 +60,24 @@ class User extends SnowFlake {
return User.checkuser(userjson, owner);
}
}
compare(str: string) {
function similar(str2: string | null | undefined) {
if (!str2) return 0;
const strl = Math.max(str.length, 1);
if (str2.includes(str)) {
return strl / str2.length;
} else if (str2.toLowerCase().includes(str.toLowerCase())) {
return strl / str2.length / 1.2;
}
return 0;
}
return Math.max(
similar(this.name),
similar(this.nickname),
similar(this.username),
similar(this.id) / 1.5,
);
}
/**
* function is meant to check if userjson contains too much information IE non-public stuff
*