feat: support relative volume adjustment (+N/-N)
!volume +10 increases by 10, !volume -5 decreases by 5. Out-of-range results (below 0 or above 100) are rejected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -405,13 +405,14 @@ async def cmd_testtone(bot, message):
|
|||||||
await bot.reply(message, "Test tone complete")
|
await bot.reply(message, "Test tone complete")
|
||||||
|
|
||||||
|
|
||||||
@command("volume", help="Music: !volume [0-100]")
|
@command("volume", help="Music: !volume [0-100|+N|-N]")
|
||||||
async def cmd_volume(bot, message):
|
async def cmd_volume(bot, message):
|
||||||
"""Get or set playback volume.
|
"""Get or set playback volume.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
!volume Show current volume
|
!volume Show current volume
|
||||||
!volume <0-100> Set volume (takes effect immediately)
|
!volume <0-100> Set volume (takes effect immediately)
|
||||||
|
!volume +N/-N Adjust volume relatively
|
||||||
"""
|
"""
|
||||||
if not _is_mumble(bot):
|
if not _is_mumble(bot):
|
||||||
return
|
return
|
||||||
@@ -422,12 +423,18 @@ async def cmd_volume(bot, message):
|
|||||||
await bot.reply(message, f"Volume: {ps['volume']}%")
|
await bot.reply(message, f"Volume: {ps['volume']}%")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
arg = parts[1].strip()
|
||||||
|
relative = arg.startswith("+") or (arg.startswith("-") and arg != "-")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
val = int(parts[1])
|
val = int(arg)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await bot.reply(message, "Usage: !volume <0-100>")
|
await bot.reply(message, "Usage: !volume <0-100|+N|-N>")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if relative:
|
||||||
|
val = ps["volume"] + val
|
||||||
|
|
||||||
if val < 0 or val > 100:
|
if val < 0 or val > 100:
|
||||||
await bot.reply(message, "Volume must be 0-100")
|
await bot.reply(message, "Volume must be 0-100")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -319,8 +319,41 @@ class TestVolumeCommand:
|
|||||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
assert any("0-100" in r for r in bot.replied)
|
assert any("0-100" in r for r in bot.replied)
|
||||||
|
|
||||||
def test_volume_negative(self):
|
def test_volume_negative_absolute(self):
|
||||||
|
"""Bare negative that underflows clamps at 0-100 error."""
|
||||||
bot = _FakeBot()
|
bot = _FakeBot()
|
||||||
|
_mod._ps(bot)["volume"] = 5
|
||||||
|
msg = _Msg(text="!volume -10")
|
||||||
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
|
assert any("0-100" in r for r in bot.replied)
|
||||||
|
|
||||||
|
def test_volume_relative_up(self):
|
||||||
|
bot = _FakeBot()
|
||||||
|
msg = _Msg(text="!volume +15")
|
||||||
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
|
ps = _mod._ps(bot)
|
||||||
|
assert ps["volume"] == 65
|
||||||
|
assert any("65%" in r for r in bot.replied)
|
||||||
|
|
||||||
|
def test_volume_relative_down(self):
|
||||||
|
bot = _FakeBot()
|
||||||
|
_mod._ps(bot)["volume"] = 80
|
||||||
|
msg = _Msg(text="!volume -20")
|
||||||
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
|
ps = _mod._ps(bot)
|
||||||
|
assert ps["volume"] == 60
|
||||||
|
assert any("60%" in r for r in bot.replied)
|
||||||
|
|
||||||
|
def test_volume_relative_clamp_over(self):
|
||||||
|
bot = _FakeBot()
|
||||||
|
_mod._ps(bot)["volume"] = 95
|
||||||
|
msg = _Msg(text="!volume +10")
|
||||||
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
|
assert any("0-100" in r for r in bot.replied)
|
||||||
|
|
||||||
|
def test_volume_relative_clamp_under(self):
|
||||||
|
bot = _FakeBot()
|
||||||
|
_mod._ps(bot)["volume"] = 5
|
||||||
msg = _Msg(text="!volume -10")
|
msg = _Msg(text="!volume -10")
|
||||||
asyncio.run(_mod.cmd_volume(bot, msg))
|
asyncio.run(_mod.cmd_volume(bot, msg))
|
||||||
assert any("0-100" in r for r in bot.replied)
|
assert any("0-100" in r for r in bot.replied)
|
||||||
|
|||||||
Reference in New Issue
Block a user