|
271 | 271 | </div> |
272 | 272 | } |
273 | 273 |
|
| 274 | + @if (fiestaPairingString != null) |
| 275 | + { |
| 276 | + <div class="tunnel-url"> |
| 277 | + <label>Pairing string:</label> |
| 278 | + <code class="token-value @(showFiestaPairingString ? "" : "blurred")">@fiestaPairingString</code> |
| 279 | + <button class="copy-btn" @onclick="() => showFiestaPairingString = !showFiestaPairingString" |
| 280 | + title="@(showFiestaPairingString ? "Hide" : "Reveal")"> |
| 281 | + @if (showFiestaPairingString) |
| 282 | + { |
| 283 | + <svg class="icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg> |
| 284 | + } |
| 285 | + else |
| 286 | + { |
| 287 | + <svg class="icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> |
| 288 | + } |
| 289 | + </button> |
| 290 | + <button class="copy-btn" @onclick="CopyFiestaPairingString" title="Copy to clipboard"> |
| 291 | + <svg class="icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg> |
| 292 | + </button> |
| 293 | + </div> |
| 294 | + <p class="hint">Paste this string into the hub machine's Settings → Fiesta Workers → "Paste pairing string" field.</p> |
| 295 | + } |
| 296 | + |
274 | 297 | @if (!string.IsNullOrEmpty(directQrCodeDataUri)) |
275 | 298 | { |
276 | 299 | <div class="qr-code"> |
|
1126 | 1149 | string? url = null; |
1127 | 1150 | try |
1128 | 1151 | { |
1129 | | - var doc = System.Text.Json.JsonDocument.Parse(result); |
| 1152 | + using var doc = System.Text.Json.JsonDocument.Parse(result); |
1130 | 1153 | if (doc.RootElement.TryGetProperty("url", out var urlProp)) |
1131 | 1154 | url = urlProp.GetString(); |
1132 | 1155 | if (doc.RootElement.TryGetProperty("token", out var tokenProp)) |
|
1155 | 1178 | settings.RemoteUrl = url; |
1156 | 1179 |
|
1157 | 1180 | ShowStatus("QR code scanned!", "success"); |
| 1181 | + StateHasChanged(); |
1158 | 1182 | } |
1159 | 1183 |
|
1160 | 1184 | private async Task TunnelLogin() |
|
1351 | 1375 |
|
1352 | 1376 | private void TryGenerateFiestaPairingString() |
1353 | 1377 | { |
1354 | | - try { fiestaPairingString = FiestaService.GeneratePairingString(); } |
1355 | | - catch { fiestaPairingString = null; } |
| 1378 | + try |
| 1379 | + { |
| 1380 | + fiestaPairingString = FiestaService.GeneratePairingString(); |
| 1381 | + } |
| 1382 | + catch (Exception ex) |
| 1383 | + { |
| 1384 | + fiestaPairingString = null; |
| 1385 | + Console.WriteLine($"[Settings] Failed to generate pairing string: {ex.Message}"); |
| 1386 | + ShowStatus($"Could not generate pairing string: {ex.Message}", "error", 8000); |
| 1387 | + } |
1356 | 1388 | } |
1357 | 1389 |
|
1358 | 1390 | private async Task CopyFiestaPairingString() |
|
1564 | 1596 | WsBridgeServer.ServerPassword = settings.ServerPassword; |
1565 | 1597 | WsBridgeServer.SetCopilotService(CopilotService); |
1566 | 1598 | WsBridgeServer.Start(DevTunnelService.BridgePort, settings.Port); |
| 1599 | + if (!WsBridgeServer.IsRunning) |
| 1600 | + { |
| 1601 | + ShowStatus($"Failed to start bridge server on port {DevTunnelService.BridgePort} — the port may already be in use.", "error", 10000); |
| 1602 | + return; |
| 1603 | + } |
1567 | 1604 | settings.DirectSharingEnabled = true; |
1568 | 1605 | settings.Save(); |
1569 | 1606 | GenerateDirectQrCode(); |
|
0 commit comments