export function updateTunnelUIElements(extension, isRunning, isStarting) { void isRunning; void isStarting; const elements = extension.tunnelElements || {}; const status = (extension.tunnelStatus?.status || "stopped").toLowerCase(); const tunnelButtonColorClasses = ["tunnel-button--enable", "tunnel-button--disable"]; const tunnelStatusColorClasses = ["tunnel-status--enable", "tunnel-status--disable"]; if (elements.button) { elements.button.disabled = status === "starting" || status === "stopping"; elements.button.classList.remove(...tunnelButtonColorClasses); if (status === "starting") { elements.button.innerHTML = ` Starting...`; elements.button.classList.add("tunnel-button--enable"); } else if (status === "stopping") { elements.button.innerHTML = ` Stopping...`; elements.button.classList.add("tunnel-button--disable"); } else if (status === "running") { elements.button.textContent = "Disable Cloudflare Tunnel"; elements.button.classList.add("tunnel-button--disable"); } else if (status === "error") { elements.button.textContent = "Retry Cloudflare Tunnel"; elements.button.classList.add("tunnel-button--disable"); } else { elements.button.textContent = "Enable Cloudflare Tunnel"; elements.button.classList.add("tunnel-button--enable"); } } if (elements.status) { elements.status.textContent = status.toUpperCase(); elements.status.classList.remove(...tunnelStatusColorClasses); if (status === "running" || status === "error" || status === "stopping") { elements.status.classList.add("tunnel-status--disable"); } else { elements.status.classList.add("tunnel-status--enable"); } } if (elements.url) { const url = extension.tunnelStatus?.public_url; if (url) { elements.url.innerHTML = `${url}`; } else { elements.url.textContent = status === "starting" ? "Requesting public URL..." : "No tunnel active"; } } if (elements.copyBtn) { const hasUrl = Boolean(extension.tunnelStatus?.public_url); elements.copyBtn.disabled = !hasUrl; elements.copyBtn.style.opacity = hasUrl ? "1" : "0.5"; } } export async function refreshTunnelStatus(extension) { try { const data = await extension.api.getTunnelStatus(); extension.tunnelStatus = data.tunnel || { status: "stopped" }; if (data.master_host !== undefined) { extension._applyMasterHost(data.master_host); } return extension.tunnelStatus; } catch (error) { extension.tunnelStatus = { status: "error", last_error: error.message }; extension.log("Failed to fetch tunnel status: " + error.message, "error"); return extension.tunnelStatus; } finally { updateTunnelUIElements(extension); } } export async function handleTunnelToggle(extension, button) { const currentStatus = (extension.tunnelStatus?.status || "stopped").toLowerCase(); if (currentStatus === "starting" || currentStatus === "stopping") { return; } const setStatus = (status) => { extension.tunnelStatus = { ...(extension.tunnelStatus || {}), status }; updateTunnelUIElements(extension); }; if (currentStatus === "running") { setStatus("stopping"); try { if (button) { button.innerHTML = ` Stopping...`; button.disabled = true; } const data = await extension.api.stopTunnel(); extension.tunnelStatus = data.tunnel || { status: "stopped" }; if (data.master_host !== undefined) { extension._applyMasterHost(data.master_host); } updateTunnelUIElements(extension); extension.ui.showToast(extension.app, "info", "Cloudflare Tunnel Disabled", "Master address restored", 4000); } catch (error) { extension.tunnelStatus = { status: "error", last_error: error.message }; updateTunnelUIElements(extension); extension.ui.showToast(extension.app, "error", "Failed to stop tunnel", error.message, 5000); } finally { if (button) { button.disabled = false; } } return; } // Start tunnel setStatus("starting"); if (button) { button.innerHTML = ` Starting...`; button.disabled = true; } try { const data = await extension.api.startTunnel(); extension.tunnelStatus = data.tunnel || { status: "running" }; if (data.master_host !== undefined) { extension._applyMasterHost(data.master_host); } updateTunnelUIElements(extension); const url = data.tunnel?.public_url || data.master_host; extension.ui.showToast(extension.app, "success", "Cloudflare Tunnel Ready", url || "Public URL created", 4500); } catch (error) { extension.tunnelStatus = { status: "error", last_error: error.message }; updateTunnelUIElements(extension); extension.ui.showToast(extension.app, "error", "Failed to start tunnel", error.message, 5000); } finally { if (button) { button.disabled = false; } } }