(filePath)
| 13387 | |
| 13388 | function formatPwnPhaseLabel(phase) { |
| 13389 | if (!phase) { |
| 13390 | return 'Idle'; |
| 13391 | } |
| 13392 | return phase.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase()); |
| 13393 | } |
| 13394 | |
| 13395 | async function handlePwnInstallClick() { |
| 13396 | if (pwnStatus.installing) { |
| 13397 | addConsoleMessage('Pwnagotchi installer already running', 'warning'); |
| 13398 | return; |
| 13399 | } |
| 13400 | |
| 13401 | const installBtn = document.getElementById('pwn-install-btn'); |
| 13402 | if (installBtn) { |
| 13403 | installBtn.disabled = true; |
| 13404 | installBtn.textContent = 'Starting installer...'; |
| 13405 | installBtn.classList.add('opacity-70', 'cursor-not-allowed'); |
| 13406 | } |
| 13407 | |
| 13408 | resetPwnLogState('Installer requested. Waiting for output...'); |
| 13409 | startPwnLogStreaming({ initial: true }); |
| 13410 | |
| 13411 | try { |
| 13412 | const result = await postPwnAPI('/api/pwnagotchi/install', {}); |
| 13413 | addConsoleMessage('Pwnagotchi installer started', 'success'); |
| 13414 | if (result && result.status) { |
| 13415 | updatePwnagotchiUI(result.status); |
| 13416 | } else { |
| 13417 | refreshPwnagotchiStatus({ silent: true }); |
| 13418 | } |
| 13419 | } catch (error) { |
| 13420 | console.error('Failed to start Pwnagotchi installer:', error); |
| 13421 | addConsoleMessage(`Install failed: ${error.message}`, 'error'); |
| 13422 | stopPwnLogStreaming(); |
| 13423 | setPwnLogEmptyMessage('Installer failed to start. Check Ragnar logs for details.'); |
| 13424 | } finally { |
| 13425 | updatePwnButtons(); |
| 13426 | } |
| 13427 | } |
| 13428 | |
| 13429 | async function handlePwnSwap(targetMode) { |
| 13430 | const normalized = targetMode === 'pwnagotchi' ? 'pwnagotchi' : 'ragnar'; |
| 13431 | |
| 13432 | if (normalized === 'pwnagotchi' && !pwnStatus.installed) { |
| 13433 | addConsoleMessage('Install Pwnagotchi before swapping', 'warning'); |
| 13434 | return; |
| 13435 | } |
| 13436 | |
| 13437 | const buttonId = normalized === 'pwnagotchi' ? 'pwn-swap-to-pwn-btn' : 'pwn-swap-to-ragnar-btn'; |
| 13438 | const button = document.getElementById(buttonId); |
| 13439 | if (button) { |
| 13440 | button.disabled = true; |
| 13441 | button.textContent = 'Scheduling switch...'; |
| 13442 | button.classList.add('opacity-60', 'cursor-not-allowed'); |
| 13443 | } |
| 13444 | |
| 13445 | try { |
| 13446 | const result = await postPwnAPI('/api/pwnagotchi/swap', { target: normalized }); |
nothing calls this directly
no test coverage detected