diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-29 18:55:42 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-29 18:55:42 +0200 |
| commit | a2215bb071c4e1ce11c616d26df8fd4e7a8fdf57 (patch) | |
| tree | de2969394d8673194d219b22c4af0dd7faef2d10 /packages/meshbay-hub/src/meshbay_hub/static/app.js | |
| parent | c37fe3047367f401765351e5aca73f8f0ed6810c (diff) | |
| parent | 1f8a52484412b48205e5ff6aac506428e2fb77ed (diff) | |
| download | meshbay-a2215bb071c4e1ce11c616d26df8fd4e7a8fdf57.tar.gz | |
Merge remote-tracking branch 'origin/main'
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/app.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index 4aab150..c31653a 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -2373,6 +2373,9 @@ function NodePage({ token, username, userId, groups }) { const [rosterGroup, setRosterGroup] = useState(''); const [denylist, setDenylist] = useState(null); const [showDenylist, setShowDenylist] = useState(false); + const [nodeSettings, setNodeSettings] = useState(null); + const [editSettings, setEditSettings] = useState(null); + const [savingSettings, setSavingSettings] = useState(false); const [attachGroup_, setAttachGroup_] = useState(''); const [attachDir, setAttachDir] = useState(''); const [attachUpload, setAttachUpload] = useState(''); @@ -2434,6 +2437,7 @@ function NodePage({ token, username, userId, groups }) { transportRef.current = transport; setNodeGroups(result.groups || []); setOperatorPaired(!!result.operator_paired); + setNodeSettings(result.settings || null); setStatus('connected'); return; } catch (err) { @@ -2460,6 +2464,10 @@ function NodePage({ token, username, userId, groups }) { }; }, [connectAndFetch]); + useEffect(() => { + if (nodeSettings && !editSettings) setEditSettings({ ...nodeSettings }); + }, [nodeSettings]); + const refresh = useCallback(async () => { const transport = transportRef.current; if (!transport || !transport.connected) return; @@ -2467,6 +2475,7 @@ function NodePage({ token, username, userId, groups }) { const result = await transport.fetchNodeStatus(); setNodeGroups(result.groups || []); setOperatorPaired(!!result.operator_paired); + setNodeSettings(result.settings || null); } catch {} }, []); @@ -2673,6 +2682,22 @@ function NodePage({ token, username, userId, groups }) { } }, [refresh]); + const saveSettings = useCallback(async () => { + const transport = transportRef.current; + if (!transport || !transport.connected || !editSettings) return; + setSavingSettings(true); + setActionMsg(''); + try { + await transport.updateNodeSettings(editSettings); + setNodeSettings({ ...editSettings }); + setActionMsg(t('node.settings_saved')); + } catch (err) { + setActionMsg(err.message); + } finally { + setSavingSettings(false); + } + }, [editSettings]); + if (status === 'idle' || status === 'connecting') { return html`<div class="page-content"> <h2>${t('node.title')}</h2> @@ -2888,6 +2913,58 @@ function NodePage({ token, username, userId, groups }) { `} </div> + ${editSettings && html` + <div class="node-group"> + <span class="settings-heading">${t('node.settings')}</span> + <p class="node-hint">${t('node.settings_edit_hint')}</p> + <div class="node-settings-grid"> + <label class="node-setting"> + <span class="node-setting-label">${t('node.setting_invite_ttl')}</span> + <div class="node-setting-input"> + <input type="number" min="1" value=${editSettings.invite_ttl_hours} + onInput=${e => setEditSettings(s => ({...s, invite_ttl_hours: parseInt(e.target.value) || 1}))} /> + <span class="node-setting-unit">${t('node.setting_unit_hours')}</span> + </div> + </label> + <label class="node-setting"> + <span class="node-setting-label">${t('node.setting_pair_ttl')}</span> + <div class="node-setting-input"> + <input type="number" min="1" value=${editSettings.pair_ttl_hours} + onInput=${e => setEditSettings(s => ({...s, pair_ttl_hours: parseInt(e.target.value) || 1}))} /> + <span class="node-setting-unit">${t('node.setting_unit_hours')}</span> + </div> + </label> + <label class="node-setting"> + <span class="node-setting-label">${t('node.setting_device_ttl')}</span> + <div class="node-setting-input"> + <input type="number" min="1" value=${editSettings.device_request_ttl_minutes} + onInput=${e => setEditSettings(s => ({...s, device_request_ttl_minutes: parseInt(e.target.value) || 1}))} /> + <span class="node-setting-unit">${t('node.setting_unit_minutes')}</span> + </div> + </label> + <label class="node-setting"> + <span class="node-setting-label">${t('node.setting_max_streams')}</span> + <div class="node-setting-input"> + <input type="number" min="1" value=${editSettings.max_concurrent_streams} + onInput=${e => setEditSettings(s => ({...s, max_concurrent_streams: parseInt(e.target.value) || 1}))} /> + </div> + </label> + <label class="node-setting"> + <span class="node-setting-label">${t('node.setting_transcode')}</span> + <div class="node-setting-input"> + <input type="checkbox" checked=${editSettings.transcode_incompatible_video} + onChange=${e => setEditSettings(s => ({...s, transcode_incompatible_video: e.target.checked}))} /> + </div> + </label> + </div> + <div class="node-settings-actions"> + <button class="btn btn-primary btn-small" disabled=${savingSettings || busy} + onClick=${saveSettings}> + ${savingSettings ? t('node.settings_saving') : t('node.settings_save')}</button> + </div> + </div> + `} + ${/* In Electron, the Create Group wizard handles attaching. Keep for browser users who manage nodes via MNP. */ !platform.node.available && (() => { |