mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 01:53:30 +01:00
63 lines
1.4 KiB
TypeScript
63 lines
1.4 KiB
TypeScript
import { TypedEmitter } from 'tiny-typed-emitter';
|
|
import type { Awaited } from '../util/util';
|
|
|
|
/**
|
|
* The events that a SpeakingMap can emit.
|
|
*/
|
|
export interface SpeakingMapEvents {
|
|
/**
|
|
* Emitted when a user starts speaking.
|
|
*/
|
|
start: (userId: string) => Awaited<void>;
|
|
|
|
/**
|
|
* Emitted when a user stops speaking.
|
|
*/
|
|
end: (userId: string) => Awaited<void>;
|
|
}
|
|
|
|
/**
|
|
* Tracks the speaking states of users in a voice channel.
|
|
*/
|
|
export class SpeakingMap extends TypedEmitter<SpeakingMapEvents> {
|
|
/**
|
|
* The delay after a packet is received from a user until they're marked as not speaking anymore.
|
|
*/
|
|
public static readonly DELAY = 100;
|
|
|
|
/**
|
|
* The currently speaking users, mapped to the milliseconds since UNIX epoch at which they started speaking.
|
|
*/
|
|
public readonly users: Map<string, number>;
|
|
|
|
private readonly speakingTimeouts: Map<string, NodeJS.Timeout>;
|
|
|
|
public constructor() {
|
|
super();
|
|
this.users = new Map();
|
|
this.speakingTimeouts = new Map();
|
|
}
|
|
|
|
public onPacket(userId: string) {
|
|
const timeout = this.speakingTimeouts.get(userId);
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
} else {
|
|
this.users.set(userId, Date.now());
|
|
this.emit('start', userId);
|
|
}
|
|
this.startTimeout(userId);
|
|
}
|
|
|
|
private startTimeout(userId: string) {
|
|
this.speakingTimeouts.set(
|
|
userId,
|
|
setTimeout(() => {
|
|
this.emit('end', userId);
|
|
this.speakingTimeouts.delete(userId);
|
|
this.users.delete(userId);
|
|
}, SpeakingMap.DELAY),
|
|
);
|
|
}
|
|
}
|