diff --git a/src/Client.ts b/src/Client.ts index bf647983..d85266b7 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,7 +1,6 @@ import type { Accessor, Setter } from "solid-js"; import { batch, createSignal } from "solid-js"; -import { ReactiveMap } from "@solid-primitives/map"; import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter"; import { API } from "stoat-api"; import type { DataLogin, Error, RevoltConfig, Role } from "stoat-api"; @@ -28,7 +27,7 @@ import { EventClient, type EventClientOptions, } from "./events/EventClient.js"; -import { ProtocolV1, UserSlowmodes, handleEvent } from "./events/v1.js"; +import { ProtocolV1, handleEvent } from "./events/v1.js"; import type { HydratedChannel } from "./hydration/channel.js"; import type { HydratedEmoji } from "./hydration/emoji.js"; import type { HydratedMessage } from "./hydration/message.js"; @@ -183,7 +182,6 @@ export class Client extends AsyncEventEmitter { readonly serverMembers; readonly sessions; readonly users; - readonly userSlowmodes; readonly api: API; readonly options: ClientOptions; @@ -203,7 +201,6 @@ export class Client extends AsyncEventEmitter { readonly connectionFailureCount: Accessor; #setConnectionFailureCount: Setter; #reconnectTimeout: number | undefined; - #slowmodeTimers = new Map>(); /** * Create Stoat.js Client @@ -278,7 +275,6 @@ export class Client extends AsyncEventEmitter { this.serverMembers = new ServerMemberCollection(this); this.sessions = new SessionCollection(this); this.users = new UserCollection(this); - this.userSlowmodes = new ReactiveMap(); this.events = new EventClient(1, "json", this.options); this.events.on("error", (error) => this.emit("error", error)); @@ -611,21 +607,6 @@ export class Client extends AsyncEventEmitter { return data.id; } - setSlowmode(channelId: string, data: UserSlowmodes): void { - const existing = this.#slowmodeTimers.get(channelId); - if (existing) clearTimeout(existing); - - this.userSlowmodes.set(channelId, { ...data, receivedAt: Date.now() }); - - const timer = setTimeout(() => { - this.userSlowmodes.delete(channelId); - this.#slowmodeTimers.delete(channelId); - this.emit("userSlowmodes"); - }, data.retry_after * 1000); - - this.#slowmodeTimers.set(channelId, timer); - } - /** * Backend enforced limits for the logged in user */ diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 0cb10ab7..85cd327f 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -1,4 +1,4 @@ -import { batch } from "solid-js"; +import { Accessor, Setter, batch, createSignal } from "solid-js"; import { ReactiveMap } from "@solid-primitives/map"; import type { ReactiveSet } from "@solid-primitives/set"; @@ -17,6 +17,7 @@ import type { APIRoutes } from "stoat-api"; import { decodeTime, ulid } from "ulid"; import { ChannelCollection } from "../collections/index.js"; +import { UserSlowmodes } from "../events/v1.js"; import { hydrate } from "../hydration/index.js"; import { bitwiseAndEq, @@ -43,6 +44,10 @@ export class Channel { voiceParticipants = new ReactiveMap(); + readonly userSlowmode: Accessor; + readonly #setUserSlowmode: Setter; + #slowmodeTimeout: NodeJS.Timeout | undefined; + /** * Construct Channel * @param collection Collection @@ -51,6 +56,10 @@ export class Channel { constructor(collection: ChannelCollection, id: string) { this.#collection = collection; this.id = id; + + const [slowmode, setSlowmode] = createSignal(); + this.userSlowmode = slowmode; + this.#setUserSlowmode = setSlowmode; } /** @@ -874,4 +883,18 @@ export class Channel { return highest; } + + setUserSlowmode(slowmode: UserSlowmodes) { + if (this.#slowmodeTimeout) { + clearTimeout(this.#slowmodeTimeout); + } + + this.#setUserSlowmode({ ...slowmode, receivedAt: Date.now() }); + + this.#slowmodeTimeout = setTimeout(() => { + this.#setUserSlowmode(); + this.#slowmodeTimeout = undefined; + this.#collection.client.emit("userSlowmodes"); + }, slowmode.retry_after * 1000); + } } diff --git a/src/collections/AccountCollection.ts b/src/collections/AccountCollection.ts index 259d253e..e3777585 100644 --- a/src/collections/AccountCollection.ts +++ b/src/collections/AccountCollection.ts @@ -125,7 +125,7 @@ export class AccountCollection { email: newEmail, current_password: currentPassword, }, - ticket ? { headers: { "X-MFA-Ticket": ticket.token } } : undefined + ticket ? { headers: { "X-MFA-Ticket": ticket.token } } : undefined, ); } diff --git a/src/events/v1.ts b/src/events/v1.ts index dbaf7dfe..852142d1 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -1006,7 +1006,10 @@ export async function handleEvent( } case "UserSlowmodes": { for (const slowmode of event.slowmodes) { - client.setSlowmode(slowmode.channel_id, slowmode); + const channel = client.channels.getOrPartial(slowmode.channel_id); + if (channel) { + channel.setUserSlowmode(slowmode); + } } client.emit("userSlowmodes"); break;