feat: network config dialog for TCP tunnels

- TCP Tunnel Sink/Source now open a dialog asking for host:port
- TCP Network Server uses configurable port (shown in dropdown)
- Host defaults to 127.0.0.1, port defaults to 4713
- Config persists across clicks (netHost/netPort state)
This commit is contained in:
joren
2026-03-30 00:19:43 +02:00
parent b3c7955340
commit 6d3ad50764

View File

@@ -40,6 +40,9 @@
let showProfileDialog = $state(false); let showProfileDialog = $state(false);
let showRuleDialog = $state(false); let showRuleDialog = $state(false);
let showVirtualMenu = $state(false); let showVirtualMenu = $state(false);
let showNetworkDialog = $state<{ type: string } | null>(null);
let netHost = $state('127.0.0.1');
let netPort = $state('4713');
let newHideRule = $state(''); let newHideRule = $state('');
let newMergeRule = $state(''); let newMergeRule = $state('');
let newProfileName = $state(''); let newProfileName = $state('');
@@ -467,9 +470,37 @@
<button onclick={async () => { showVirtualMenu = false; await createNullSink('pwweb-null-' + Date.now().toString(36)); }}>Null Sink (Virtual Output)</button> <button onclick={async () => { showVirtualMenu = false; await createNullSink('pwweb-null-' + Date.now().toString(36)); }}>Null Sink (Virtual Output)</button>
<button onclick={async () => { showVirtualMenu = false; await createLoopback('pwweb-loop-' + Date.now().toString(36)); }}>Loopback Device</button> <button onclick={async () => { showVirtualMenu = false; await createLoopback('pwweb-loop-' + Date.now().toString(36)); }}>Loopback Device</button>
<div class="virt-sep"></div> <div class="virt-sep"></div>
<button onclick={async () => { showVirtualMenu = false; await loadModule('module-native-protocol-tcp', 'auth-anonymous=1 port=4713'); }}>TCP Network Server</button> <button onclick={async () => { showVirtualMenu = false; await loadModule('module-native-protocol-tcp', 'auth-anonymous=1 port=' + netPort); }}>TCP Network Server (port {netPort})</button>
<button onclick={async () => { showVirtualMenu = false; await loadModule('module-tunnel-sink', 'server=tcp:127.0.0.1:4713'); }}>TCP Tunnel Sink</button> <button onclick={async () => { showVirtualMenu = false; showNetworkDialog = { type: 'tunnel-sink' }; }}>TCP Tunnel Sink...</button>
<button onclick={async () => { showVirtualMenu = false; await loadModule('module-tunnel-source', 'server=tcp:127.0.0.1:4713'); }}>TCP Tunnel Source</button> <button onclick={async () => { showVirtualMenu = false; showNetworkDialog = { type: 'tunnel-source' }; }}>TCP Tunnel Source...</button>
</div>
{/if}
<!-- Network config dialog -->
{#if showNetworkDialog}
<div class="dialog" style="right:auto;left:50%;top:50%;transform:translate(-50%,-50%);width:300px">
<div class="dialog-header">
<span>{showNetworkDialog.type === 'tunnel-sink' ? 'TCP Tunnel Sink' : 'TCP Tunnel Source'}</span>
<button class="close" onclick={() => { showNetworkDialog = null; }}>X</button>
</div>
<div class="dialog-body">
<div class="input-row">
<span style="font-size:10px;color:#888;width:50px">Host:</span>
<input class="dlg-input" bind:value={netHost} placeholder="127.0.0.1" />
</div>
<div class="input-row">
<span style="font-size:10px;color:#888;width:50px">Port:</span>
<input class="dlg-input" bind:value={netPort} placeholder="4713" />
</div>
<div class="input-row" style="justify-content:flex-end">
<button onclick={() => { showNetworkDialog = null; }}>Cancel</button>
<button onclick={async () => {
const mod = showNetworkDialog!.type === 'tunnel-sink' ? 'module-tunnel-sink' : 'module-tunnel-source';
await loadModule(mod, 'server=tcp:' + netHost + ':' + netPort);
showNetworkDialog = null;
}}>Connect</button>
</div>
</div>
</div> </div>
{/if} {/if}