Make video a per-server toggle instead of an env-wide setting

VIDEO_ENABLED is now permission rather than behaviour: it decides whether
the feature exists at all, while turning it on for a server is a toggle in
the panel or !video in chat, off by default. Video costs real CPU for
every playing channel, so that should be a deliberate choice rather than
something a config flag switches on everywhere.

With the env flag off the panel renders no toggle at all and !video says
so, and the switch applies from the next track — swapping tracks mid-play
would cut the current one.

The loop button no longer reads "выкл" either: it sat next to the video
button showing the same word, so the two states were indistinguishable.
Both now name what they do and rely on highlighting for state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-09-09 02:13:08 +03:00
co-authored by Claude Opus 5
parent e06c42f60c
commit a9b680c418
11 changed files with 92 additions and 13 deletions
+23 -1
View File
@@ -260,6 +260,26 @@ export const commands: Command[] = [
await ctx.reply(`🔁 Повтор: ${loopLabel(nextMode)}`);
},
},
{
name: "video",
aliases: ["видео"],
usage: "video [on|off]",
description: "Показывать клип как демонстрацию экрана",
async run(ctx) {
if (!config.VIDEO_ENABLED) {
throw new UserFacingError("Видео выключено в настройках бота (VIDEO_ENABLED)");
}
const raw = (ctx.args[0] ?? "").toLowerCase();
const current = ctx.manager.snapshot(ctx.serverId).videoEnabled;
const next = raw ? ["on", "вкл", "true", "1", "да"].includes(raw) : !current;
await ctx.manager.setVideo(ctx.serverId, ctx.actor.id, next);
await ctx.reply(
next
? "📺 Клип будет показан как демонстрация экрана — со следующего трека."
: "🔇 Видео выключено, играю только звук.",
);
},
},
{
name: "shuffle",
aliases: ["sh", "перемешай"],
@@ -348,7 +368,9 @@ export const commands: Command[] = [
usage: "help",
description: "Показать список команд",
async run(ctx) {
const lines = commands.map(
const lines = commands
.filter((command) => command.name !== "video" || config.VIDEO_ENABLED)
.map(
(command) => `\`${config.COMMAND_PREFIX}${command.usage}\`${command.description}`,
);
await ctx.reply(