diff --git a/tanco/app.py b/tanco/app.py index 6810eff..d602329 100644 --- a/tanco/app.py +++ b/tanco/app.py @@ -89,6 +89,18 @@ async def notify(code, data, wrap=True): await o.put(data) +async def notify_client_state(code): + data = dict(name="client", status='connected') + if not clients.get(code): + data['status'] = 'disconnected' + + html = await quart.render_template_string(''' + {% import 'websocket.html' as ws %} + {{ ws.ws(**data) }} + ''', data=data) + await notify(code, html, wrap=False) + + async def notify_state(code, state, focus): data = dict(state=state, focus=focus, code=code) html = await quart.render_template('state.html', data=data) @@ -232,7 +244,7 @@ async def attempt_live(code): global observers observers.setdefault(code, []).append(q) try: - await ws.send('') + await notify_client_state(code) while True: html = await q.get() await ws.send(html) @@ -249,6 +261,7 @@ async def attempt_share(code): global clients clients[code] = q await ws.send('hello') + await notify_client_state(code) try: while True: cmd = await q.get() @@ -259,6 +272,7 @@ async def attempt_share(code): await notify(code, f'
{ws_res}
', wrap=False) except asyncio.CancelledError: clients.pop(code) + await notify_client_state(code) @app.route('/a//shell', methods=['POST']) diff --git a/tanco/runner.py b/tanco/runner.py index 5e85c11..b55982b 100644 --- a/tanco/runner.py +++ b/tanco/runner.py @@ -73,6 +73,7 @@ def load_config() -> Config: class NoTestPlanError(Exception): pass + class StopTesting(Exception): pass diff --git a/tanco/static/style.css b/tanco/static/style.css index 7f8af08..c15ad65 100644 --- a/tanco/static/style.css +++ b/tanco/static/style.css @@ -33,10 +33,15 @@ a:hover { color: #0162c2ff; background: #f3f0e5; } #whoami { position:absolute; top: 20px; left: var(--top-info-left); } -#ws { position:absolute; top: 30px; right: 10px; +.ws { position:absolute; top: 30px; width: 10px; height: 10px; border-radius: 10px; border: solid #333 1px; background: #999; } -#ws .tooltip { position: relative; left: -100px; width: 100px; } +.ws .tooltip { position: relative; left: -100px; width: 100px; } +.ws.connected { background-color: limegreen; } +.ws.disconnected { background-color: tomato; } +#browser-ws { right: 10px; } +#client-ws { right: 30px; } + .has-tooltip:hover .tooltip { visibility: visible; transition-delay: 500ms; diff --git a/tanco/templates/attempt.html b/tanco/templates/attempt.html index 78481b7..156d3ab 100644 --- a/tanco/templates/attempt.html +++ b/tanco/templates/attempt.html @@ -9,20 +9,22 @@ -
-
websocket: waiting to connect
-
+{% import "websocket.html" as ws %} +{{ ws.ws("client", "waiting") }} +{{ ws.ws("browser","waiting", 'hx-ext=ws ws-connect=live') }} diff --git a/tanco/templates/websocket.html b/tanco/templates/websocket.html new file mode 100644 index 0000000..560bb43 --- /dev/null +++ b/tanco/templates/websocket.html @@ -0,0 +1,8 @@ +{% macro ws(name, status, attrs='') %} +
+
{{ name }} websocket: + {{ status }} +
+
+{% endmacro %} \ No newline at end of file