Clear the search list after a pick, and stop double-announcing tracks
Two bits of clutter visible in one screenshot: the results list stayed in the channel after a track was chosen, still wearing its reactions, and every track produced two lines — the command's own reply and the player's "now playing" notice. Picking now spends the session and deletes the list, so a second reaction does nothing and the message goes away. The player announces a track only when it started one by itself; when a command started it, that command has already said so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
bf2d04d579
commit
a63db8c957
+11
-2
@@ -81,13 +81,22 @@ function activeSession(messageId: string | undefined): SearchSession | null {
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolves a reaction on a results message into the track it stands for. */
|
/**
|
||||||
|
* Resolves a reaction on a results message into the track it stands for, and
|
||||||
|
* spends the session: the list is answered once, so a second reaction on the
|
||||||
|
* same message does nothing and the message itself can go away.
|
||||||
|
*/
|
||||||
export function trackForReaction(messageId: string, userId: string, emoji: string): Track | null {
|
export function trackForReaction(messageId: string, userId: string, emoji: string): Track | null {
|
||||||
const session = activeSession(messageId);
|
const session = activeSession(messageId);
|
||||||
// Only the person who searched picks; otherwise anyone could hijack the list.
|
// Only the person who searched picks; otherwise anyone could hijack the list.
|
||||||
if (!session || session.userId !== userId) return null;
|
if (!session || session.userId !== userId) return null;
|
||||||
const index = CHOICE_EMOJI.indexOf(emoji);
|
const index = CHOICE_EMOJI.indexOf(emoji);
|
||||||
return index === -1 ? null : (session.tracks[index] ?? null);
|
const track = index === -1 ? null : (session.tracks[index] ?? null);
|
||||||
|
if (track) {
|
||||||
|
sessionsByMessage.delete(messageId);
|
||||||
|
latestByUser.delete(`${session.channelId}:${session.userId}`);
|
||||||
|
}
|
||||||
|
return track;
|
||||||
}
|
}
|
||||||
|
|
||||||
function added(track: Track, startedNow: boolean, position: number): string {
|
function added(track: Track, startedNow: boolean, position: number): string {
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ async function handleChoice(
|
|||||||
const username = message.server?.getMember(userId)?.nickname ?? track.requestedBy.username;
|
const username = message.server?.getMember(userId)?.nickname ?? track.requestedBy.username;
|
||||||
try {
|
try {
|
||||||
const text = await enqueueChoice(manager, serverId, message.channelId, { id: userId, username }, track);
|
const text = await enqueueChoice(manager, serverId, message.channelId, { id: userId, username }, track);
|
||||||
|
// The list has served its purpose; leaving it behind only clutters the channel.
|
||||||
|
await message.delete().catch((err: unknown) => {
|
||||||
|
log.debug({ err }, "could not delete the search results message");
|
||||||
|
});
|
||||||
await message.channel?.sendMessage(text);
|
await message.channel?.sendMessage(text);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof UserFacingError) {
|
if (err instanceof UserFacingError) {
|
||||||
|
|||||||
+7
-5
@@ -306,7 +306,7 @@ export class GuildPlayer extends EventEmitter<GuildPlayerEvents> {
|
|||||||
/** Starts playback if nothing is currently playing. */
|
/** Starts playback if nothing is currently playing. */
|
||||||
async ensurePlaying(): Promise<void> {
|
async ensurePlaying(): Promise<void> {
|
||||||
if (this.current || this.status === "buffering" || this.status === "connecting") return;
|
if (this.current || this.status === "buffering" || this.status === "connecting") return;
|
||||||
await this.advance(false);
|
await this.advance(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async startPlayback(track: Track, seekSeconds = 0): Promise<void> {
|
private async startPlayback(track: Track, seekSeconds = 0): Promise<void> {
|
||||||
@@ -425,7 +425,7 @@ export class GuildPlayer extends EventEmitter<GuildPlayerEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Moves to the next track. `skipLoop` ignores per-track looping (used by skip). */
|
/** Moves to the next track. `skipLoop` ignores per-track looping (used by skip). */
|
||||||
private async advance(skipLoop: boolean): Promise<void> {
|
private async advance(skipLoop: boolean, announce = true): Promise<void> {
|
||||||
const finished = this.current;
|
const finished = this.current;
|
||||||
this.current = null;
|
this.current = null;
|
||||||
// The track has to go with the sound: a published video track keeps showing
|
// The track has to go with the sound: a published video track keeps showing
|
||||||
@@ -452,14 +452,16 @@ export class GuildPlayer extends EventEmitter<GuildPlayerEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.startPlayback(next);
|
await this.startPlayback(next);
|
||||||
this.notify(`▶️ Сейчас играет: **${next.title}**`);
|
// A command that started this track has already said so; announcing again
|
||||||
|
// would double every line in the channel.
|
||||||
|
if (announce) this.notify(`▶️ Сейчас играет: **${next.title}**`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async skip(count = 1): Promise<Track | null> {
|
async skip(count = 1): Promise<Track | null> {
|
||||||
if (!this.current && this.queue.length === 0) throw new UserFacingError("Нечего пропускать");
|
if (!this.current && this.queue.length === 0) throw new UserFacingError("Нечего пропускать");
|
||||||
for (let i = 1; i < count; i += 1) this.queue.shift();
|
for (let i = 1; i < count; i += 1) this.queue.shift();
|
||||||
this.teardownPlayback();
|
this.teardownPlayback();
|
||||||
await this.advance(true);
|
await this.advance(true, false);
|
||||||
return this.current;
|
return this.current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +560,7 @@ export class GuildPlayer extends EventEmitter<GuildPlayerEvents> {
|
|||||||
if (tracks.length === 0) return;
|
if (tracks.length === 0) return;
|
||||||
this.queue.unshift(...tracks);
|
this.queue.unshift(...tracks);
|
||||||
this.teardownPlayback();
|
this.teardownPlayback();
|
||||||
await this.advance(true);
|
await this.advance(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------- housekeeping ---
|
// ---------------------------------------------------------- housekeeping ---
|
||||||
|
|||||||
Reference in New Issue
Block a user