Files
discord.js/packages/voice/src/receive/SpeakingMap.ts

65 lines
1.5 KiB
TypeScript

/* eslint-disable @typescript-eslint/unified-signatures */
import { EventEmitter } from 'node:events';
export interface SpeakingMap extends EventEmitter {
/**
* Emitted when a user starts speaking.
*
* @eventProperty
*/
on(event: 'start', listener: (userId: string) => void): this;
/**
* Emitted when a user ends speaking.
*
* @eventProperty
*/
on(event: 'end', listener: (userId: string) => void): this;
}
/**
* Tracks the speaking states of users in a voice channel.
*/
export class SpeakingMap extends EventEmitter {
/**
* 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),
);
}
}