summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/ui/app.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-29 18:55:42 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-29 18:55:42 +0200
commita2215bb071c4e1ce11c616d26df8fd4e7a8fdf57 (patch)
treede2969394d8673194d219b22c4af0dd7faef2d10 /packages/meshbay-node/src/meshbay_node/ui/app.py
parentc37fe3047367f401765351e5aca73f8f0ed6810c (diff)
parent1f8a52484412b48205e5ff6aac506428e2fb77ed (diff)
downloadmeshbay-a2215bb071c4e1ce11c616d26df8fd4e7a8fdf57.tar.gz
Merge remote-tracking branch 'origin/main'
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/ui/app.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/ui/app.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/ui/app.py b/packages/meshbay-node/src/meshbay_node/ui/app.py
index 514a143..b25b36a 100644
--- a/packages/meshbay-node/src/meshbay_node/ui/app.py
+++ b/packages/meshbay-node/src/meshbay_node/ui/app.py
@@ -291,6 +291,13 @@ def create_ui_app(state: dict) -> FastAPI:
"quic_port": config.node.quic_port,
"ui_port": config.node.ui_port,
"data_dir": str(config.data_dir),
+ "settings": {
+ "invite_ttl_hours": config.node.invite_ttl_hours,
+ "pair_ttl_hours": config.node.pair_ttl_hours,
+ "device_request_ttl_minutes": config.node.device_request_ttl_minutes,
+ "max_concurrent_streams": config.node.max_concurrent_streams,
+ "transcode_incompatible_video": config.node.transcode_incompatible_video,
+ },
"groups": [
{
"id": g.id,
@@ -438,6 +445,12 @@ def create_ui_app(state: dict) -> FastAPI:
# seconds, on a real library) — see ops.start_reload for why.
return await _op(lambda: ops.start_reload(state))
+ # ── Node settings (operator only, localhost) ───────────────────────────
+
+ @app.put("/api/node-settings")
+ async def update_node_settings(payload: dict):
+ return await _op(lambda: ops.set_node_settings(state, payload))
+
# ── Chat endpoints ───────────────────────────────────────────────────────
_chat_subscribers: list[WebSocket] = []
@@ -521,6 +534,24 @@ def _fmt_size(n: int) -> str:
return f"{n / (1024 * 1024 * 1024):.2f} GB"
+def _render_node_settings(config) -> str:
+ if not config:
+ return ""
+ nd = config.node
+ transcode = "on" if nd.transcode_incompatible_video else "off"
+ return f"""
+ <table style="margin-top:10px">
+ <thead><tr><th>Setting</th><th>Value</th></tr></thead>
+ <tbody>
+ <tr><td>Invitation TTL</td><td>{nd.invite_ttl_hours} hours</td></tr>
+ <tr><td>Pairing code TTL</td><td>{nd.pair_ttl_hours} hours</td></tr>
+ <tr><td>Device request TTL</td><td>{nd.device_request_ttl_minutes} minutes</td></tr>
+ <tr><td>Max concurrent streams</td><td>{nd.max_concurrent_streams}</td></tr>
+ <tr><td>Transcode incompatible video</td><td>{transcode}</td></tr>
+ </tbody>
+ </table>"""
+
+
def _render_roster(roster_view: dict | None) -> str:
"""
Who this node recognises, and which keys are theirs.
@@ -766,6 +797,7 @@ def _render_page(state: dict, roster_view: dict | None = None,
<p><b>Hub:</b> {state.get("hub_url", "—")}</p>
<p><b>QUIC port:</b> {state.get("quic_port", "—")}</p>
<p><b>Node ID:</b> <code>{state.get("endpoint_hint") or "—"}</code></p>
+ {_render_node_settings(config)}
</div>
<h2>Maintenance</h2>