app: add slash commands
This commit is contained in:
@@ -115,6 +115,7 @@ class StatusBar(Static):
|
||||
connected = reactive(False)
|
||||
reconnecting = reactive(False)
|
||||
self_deaf = reactive(False)
|
||||
self_mute = reactive(False)
|
||||
server_info = reactive("")
|
||||
output_vol = reactive(100)
|
||||
input_vol = reactive(100)
|
||||
@@ -148,11 +149,14 @@ class StatusBar(Static):
|
||||
|
||||
deaf_sym = "[#f7768e]\u2298[/]" if self.self_deaf else ""
|
||||
deaf_full = "[#f7768e]\u2298[/] deaf" if self.self_deaf else ""
|
||||
mute_sym = "[#e0af68]\u2715[/]" if self.self_mute else ""
|
||||
mute_full = "[#e0af68]\u2715[/] mute" if self.self_mute else ""
|
||||
|
||||
if w < 40:
|
||||
return f" {conn_sym} {deaf_sym}{ptt_sym}"
|
||||
return f" {conn_sym} {deaf_sym}{mute_sym}{ptt_sym}"
|
||||
if w < 60:
|
||||
return f" {conn_full} {deaf_full}{' ' if deaf_full else ''}{ptt_full}"
|
||||
flags = f"{deaf_full}{' ' if deaf_full else ''}{mute_full}{' ' if mute_full else ''}"
|
||||
return f" {conn_full} {flags}{ptt_full}"
|
||||
|
||||
vol = (
|
||||
f" [dim]out[/]{self._vol_bar(self.output_vol)}"
|
||||
@@ -164,8 +168,8 @@ class StatusBar(Static):
|
||||
else:
|
||||
pitch_str = ""
|
||||
info = f" [dim]{self.server_info}[/]" if self.server_info else ""
|
||||
deaf = f"{deaf_full} " if deaf_full else ""
|
||||
return f" {conn_full} {deaf}{ptt_full}{vol}{pitch_str}{info}"
|
||||
flags = f"{deaf_full}{' ' if deaf_full else ''}{mute_full}{' ' if mute_full else ''}"
|
||||
return f" {conn_full} {flags}{ptt_full}{vol}{pitch_str}{info}"
|
||||
|
||||
|
||||
class ChannelTree(Static):
|
||||
@@ -450,6 +454,7 @@ class TuimbleApp(App):
|
||||
on_failure=self._reconnect_on_failure,
|
||||
on_exhausted=self._reconnect_on_exhausted,
|
||||
)
|
||||
self._muted: bool = False
|
||||
self._intentional_disconnect: bool = False
|
||||
|
||||
def _make_client(self, srv=None) -> MumbleClient:
|
||||
@@ -585,10 +590,12 @@ class TuimbleApp(App):
|
||||
|
||||
def on_server_connected(self, _msg: ServerConnected) -> None:
|
||||
self._intentional_disconnect = False
|
||||
self._muted = False
|
||||
|
||||
status = self.query_one("#status", StatusBar)
|
||||
status.reconnecting = False
|
||||
status.connected = True
|
||||
status.self_mute = False
|
||||
srv = self._config.server
|
||||
status.server_info = f"{srv.host}:{srv.port}"
|
||||
|
||||
@@ -651,6 +658,10 @@ class TuimbleApp(App):
|
||||
event.input.clear()
|
||||
self._history.push(text)
|
||||
|
||||
if text.startswith("/"):
|
||||
self._dispatch_command(text)
|
||||
return
|
||||
|
||||
if not self._client.connected:
|
||||
self._show_error("not connected")
|
||||
return
|
||||
@@ -659,6 +670,50 @@ class TuimbleApp(App):
|
||||
chatlog = self.query_one("#chatlog", ChatLog)
|
||||
chatlog.write(f"[#e0af68]{self._config.server.username}[/] {text}")
|
||||
|
||||
def _dispatch_command(self, text: str) -> None:
|
||||
"""Handle slash commands."""
|
||||
cmd = text.split()[0].lower()
|
||||
chatlog = self.query_one("#chatlog", ChatLog)
|
||||
|
||||
if cmd == "/help":
|
||||
chatlog.write("[dim]/deafen toggle self-deafen[/dim]")
|
||||
chatlog.write("[dim]/mute toggle self-mute[/dim]")
|
||||
chatlog.write("[dim]/unmute unmute yourself[/dim]")
|
||||
chatlog.write("[dim]/register register on server[/dim]")
|
||||
elif cmd == "/deafen":
|
||||
self.action_toggle_deaf()
|
||||
elif cmd == "/mute":
|
||||
if self._muted:
|
||||
chatlog.write("[dim]already muted[/dim]")
|
||||
return
|
||||
self._muted = True
|
||||
self._audio.capturing = False
|
||||
self._client.set_self_mute(True)
|
||||
status = self.query_one("#status", StatusBar)
|
||||
status.self_mute = True
|
||||
status.ptt_active = False
|
||||
chatlog.write("[#e0af68]\u2715 muted[/]")
|
||||
elif cmd == "/unmute":
|
||||
if not self._muted:
|
||||
chatlog.write("[dim]already unmuted[/dim]")
|
||||
return
|
||||
self._muted = False
|
||||
self._client.set_self_mute(False)
|
||||
status = self.query_one("#status", StatusBar)
|
||||
status.self_mute = False
|
||||
chatlog.write("[#9ece6a]\u2713 unmuted[/]")
|
||||
elif cmd == "/register":
|
||||
if not self._client.connected:
|
||||
self._show_error("not connected")
|
||||
return
|
||||
try:
|
||||
self._client.register_self()
|
||||
chatlog.write("[#9ece6a]\u2713 registration requested[/]")
|
||||
except Exception as exc:
|
||||
self._show_error(f"register failed: {exc}")
|
||||
else:
|
||||
self._show_error(f"unknown command: {cmd}")
|
||||
|
||||
# -- audio ---------------------------------------------------------------
|
||||
|
||||
def _on_device_change(self) -> None:
|
||||
@@ -978,6 +1033,8 @@ class TuimbleApp(App):
|
||||
self._ptt.key_down()
|
||||
|
||||
def _on_ptt_change(self, transmitting: bool) -> None:
|
||||
if self._muted:
|
||||
transmitting = False
|
||||
self._audio.capturing = transmitting
|
||||
status = self.query_one("#status", StatusBar)
|
||||
status.ptt_active = transmitting
|
||||
|
||||
@@ -256,6 +256,39 @@ async def test_statusbar_deaf():
|
||||
assert "\u2298" in rendered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_statusbar_muted():
|
||||
app = StatusBarApp()
|
||||
async with app.run_test(size=(80, 5)) as _pilot:
|
||||
bar = app.query_one("#status", StatusBar)
|
||||
bar.self_mute = True
|
||||
rendered = bar.render()
|
||||
assert "\u2715" in rendered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_statusbar_muted_compact():
|
||||
app = StatusBarApp()
|
||||
async with app.run_test(size=(30, 5)) as pilot:
|
||||
bar = app.query_one("#status", StatusBar)
|
||||
bar.self_mute = True
|
||||
await pilot.resize_terminal(30, 5)
|
||||
await pilot.pause()
|
||||
rendered = bar.render()
|
||||
assert "\u2715" in rendered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_statusbar_muted_medium():
|
||||
app = StatusBarApp()
|
||||
async with app.run_test(size=(50, 5)) as _pilot:
|
||||
bar = app.query_one("#status", StatusBar)
|
||||
bar.self_mute = True
|
||||
rendered = bar.render()
|
||||
assert "\u2715" in rendered
|
||||
assert "mute" in rendered
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_statusbar_reconnecting():
|
||||
app = StatusBarApp()
|
||||
|
||||
Reference in New Issue
Block a user