mirror of
https://github.com/stoatchat/javascript-client-sdk.git
synced 2026-07-16 07:04:24 -04:00
feat: support for everyone/online/role mentions on messages
This commit is contained in:
+25
-1
@@ -11,12 +11,14 @@ import { decodeTime } from "ulid";
|
||||
|
||||
import type { Client } from "../Client.js";
|
||||
import type { MessageCollection } from "../collections/MessageCollection.js";
|
||||
import { MessageFlags } from "../hydration/message.js";
|
||||
|
||||
import type { Channel } from "./Channel.js";
|
||||
import { File } from "./File.js";
|
||||
import type { MessageEmbed } from "./MessageEmbed.js";
|
||||
import type { Server } from "./Server.js";
|
||||
import type { ServerMember } from "./ServerMember.js";
|
||||
import { ServerRole } from "./ServerRole.js";
|
||||
import type { SystemMessage } from "./SystemMessage.js";
|
||||
import type { User } from "./User.js";
|
||||
|
||||
@@ -177,11 +179,33 @@ export class Message {
|
||||
return this.#collection.getUnderlyingObject(this.id).mentionIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* IDs of roles this message mentions
|
||||
*/
|
||||
get roleMentionIds(): string[] | undefined {
|
||||
return this.#collection.getUnderlyingObject(this.id).roleMentionIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Roles this message mentions
|
||||
*/
|
||||
get roleMentions(): ServerRole[] | undefined {
|
||||
return this.roleMentionIds
|
||||
?.map((roleId) => this.server?.roles.get(roleId) as ServerRole)
|
||||
.filter((role) => role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this message mentions us
|
||||
*/
|
||||
get mentioned(): boolean {
|
||||
return this.mentionIds?.includes(this.#collection.client.user!.id) ?? false;
|
||||
return (
|
||||
!!(this.flags & MessageFlags.MentionsEveryone) ||
|
||||
!!(this.flags & MessageFlags.MentionsOnline) ||
|
||||
this.mentionIds?.includes(this.#collection.client.user!.id) ||
|
||||
this.roleMentions?.some((role) => role.assigned) ||
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { Role as APIRole, OverrideField } from "revolt-api";
|
||||
|
||||
import type { Client } from "../Client.js";
|
||||
|
||||
/**
|
||||
* Server Role
|
||||
*/
|
||||
export class ServerRole {
|
||||
protected client: Client;
|
||||
protected serverId: string;
|
||||
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly permissions: OverrideField;
|
||||
readonly colour?: string;
|
||||
readonly hoist: boolean;
|
||||
readonly rank: number;
|
||||
|
||||
/**
|
||||
* Construct server role
|
||||
* @param client Client
|
||||
* @param serverId Server ID
|
||||
* @param id Role ID
|
||||
* @param data Role data
|
||||
*/
|
||||
constructor(client: Client, serverId: string, id: string, data: APIRole) {
|
||||
this.client = client;
|
||||
this.serverId = serverId;
|
||||
|
||||
this.id = id;
|
||||
this.name = data.name;
|
||||
this.permissions = data.permissions;
|
||||
this.colour = data.colour ?? undefined;
|
||||
this.hoist = data.hoist || false;
|
||||
this.rank = data.rank ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this role is assigned to our server member
|
||||
*/
|
||||
get assigned() {
|
||||
return (
|
||||
this.client.servers.get(this.serverId)?.member?.roles.includes(this.id) ||
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export * from "./Message.js";
|
||||
export * from "./MessageEmbed.js";
|
||||
export * from "./PublicBot.js";
|
||||
export * from "./PublicInvite.js";
|
||||
export * from "./ServerRole.js";
|
||||
export * from "./Server.js";
|
||||
export * from "./ServerBan.js";
|
||||
export * from "./ServerMember.js";
|
||||
|
||||
@@ -23,11 +23,12 @@ export type HydratedMessage = {
|
||||
editedAt?: Date;
|
||||
embeds?: MessageEmbed[];
|
||||
mentionIds?: string[];
|
||||
roleMentionIds?: string[];
|
||||
replyIds?: string[];
|
||||
reactions: ReactiveMap<string, ReactiveSet<string>>;
|
||||
interactions?: Interactions;
|
||||
masquerade?: Masquerade;
|
||||
flags?: number;
|
||||
flags?: MessageFlags;
|
||||
};
|
||||
|
||||
export const messageHydration: Hydrate<Merge<Message>, HydratedMessage> = {
|
||||
@@ -58,6 +59,7 @@ export const messageHydration: Hydrate<Merge<Message>, HydratedMessage> = {
|
||||
embeds: (message, ctx) =>
|
||||
message.embeds!.map((embed) => MessageEmbed.from(ctx as Client, embed)),
|
||||
mentionIds: (message) => message.mentions!,
|
||||
roleMentionIds: (message) => message.role_mentions!,
|
||||
replyIds: (message) => message.replies!,
|
||||
reactions: (message) => {
|
||||
const map = new ReactiveMap<string, ReactiveSet<string>>();
|
||||
@@ -76,3 +78,22 @@ export const messageHydration: Hydrate<Merge<Message>, HydratedMessage> = {
|
||||
reactions: new ReactiveMap(),
|
||||
}),
|
||||
};
|
||||
|
||||
/**
|
||||
* Flags attributed to messages
|
||||
*/
|
||||
export enum MessageFlags {
|
||||
/**
|
||||
* Message will not send push / desktop notifications
|
||||
*/
|
||||
SuppressNotifications = 1,
|
||||
/**
|
||||
* Message will mention all users who can see the channel
|
||||
*/
|
||||
MentionsEveryone = 2,
|
||||
/**
|
||||
* Message will mention all users who are online and can see the channel.
|
||||
* This cannot be true if MentionsEveryone is true
|
||||
*/
|
||||
MentionsOnline = 3,
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import { ReactiveSet } from "@solid-primitives/set";
|
||||
import type {
|
||||
Server as APIServer,
|
||||
Category,
|
||||
Role,
|
||||
SystemMessageChannels,
|
||||
} from "revolt-api";
|
||||
|
||||
import type { Client } from "../Client.js";
|
||||
import { File } from "../classes/File.js";
|
||||
import { ServerRole } from "../classes/ServerRole.js";
|
||||
|
||||
import type { Hydrate } from "./index.js";
|
||||
|
||||
@@ -26,7 +26,7 @@ export type HydratedServer = {
|
||||
categories?: Category[];
|
||||
|
||||
systemMessages?: SystemMessageChannels;
|
||||
roles: ReactiveMap<string, Role>;
|
||||
roles: ReactiveMap<string, ServerRole>;
|
||||
defaultPermissions: number;
|
||||
|
||||
flags: ServerFlags;
|
||||
@@ -51,9 +51,12 @@ export const serverHydration: Hydrate<APIServer, HydratedServer> = {
|
||||
channelIds: (server) => new ReactiveSet(server.channels),
|
||||
categories: (server) => server.categories ?? [],
|
||||
systemMessages: (server) => server.system_messages ?? {},
|
||||
roles: (server) =>
|
||||
roles: (server, ctx) =>
|
||||
new ReactiveMap(
|
||||
Object.keys(server.roles!).map((id) => [id, server.roles![id]]),
|
||||
Object.keys(server.roles!).map((id) => [
|
||||
id,
|
||||
new ServerRole(ctx as Client, server._id, id, server.roles![id]),
|
||||
]),
|
||||
),
|
||||
defaultPermissions: (server) => server.default_permissions,
|
||||
icon: (server, ctx) => new File(ctx as Client, server.icon!),
|
||||
|
||||
Reference in New Issue
Block a user