diff --git a/apps/desktop/src/components/network-health-indicator.tsx b/apps/desktop/src/components/network-health-indicator.tsx new file mode 100644 index 00000000000..b0450f2a4ba --- /dev/null +++ b/apps/desktop/src/components/network-health-indicator.tsx @@ -0,0 +1,146 @@ +import { cx } from "cva"; +import { Show } from "solid-js"; +import Tooltip from "~/components/Tooltip"; +import { + isRecordingInProgress, + networkHealth, + runSpeedTest, + runUploadHealthCheck, + speedTest, +} from "~/utils/network-health"; +import IconLucideAlertTriangle from "~icons/lucide/alert-triangle"; +import IconLucideRefreshCw from "~icons/lucide/refresh-cw"; +import IconLucideWifi from "~icons/lucide/wifi"; + +interface NetworkHealthIndicatorProps { + class?: string; +} + +export default function NetworkHealthIndicator( + props: NetworkHealthIndicatorProps, +) { + const isUnhealthy = () => networkHealth().status === "unhealthy"; + const isChecking = () => + networkHealth().status === "checking" || speedTest().status === "running"; + const isRecording = isRecordingInProgress; + + const handleRefresh = async (e: MouseEvent) => { + e.stopPropagation(); + if (isRecording() || isChecking()) return; + await runUploadHealthCheck(); + await runSpeedTest(); + }; + + const speedLabel = () => { + if (speedTest().status === "running") return "Testing..."; + if (speedTest().status === "error" && speedTest().speedMbps === null) + return "Failed"; + if (speedTest().speedMbps !== null) return `${speedTest().speedMbps} Mbps`; + if (networkHealth().status === "checking") return "Checking..."; + if (isUnhealthy()) return "Offline"; + return "Ready"; + }; + + const qualityLabel = () => { + const label = speedTest().recommendedLabel; + return label ? `${label}` : "1080p"; + }; + + const dotColor = () => { + if (isUnhealthy()) return "bg-red-9"; + if (speedTest().status === "running") return "bg-blue-9 animate-pulse"; + if (speedTest().status === "error" && speedTest().speedMbps === null) + return "bg-red-9"; + const speed = speedTest().speedMbps; + if (speed === null) return "bg-gray-8"; + if (speed >= 15) return "bg-green-9"; + if (speed >= 5) return "bg-blue-9"; + return "bg-amber-9"; + }; + + const tooltipContent = () => ( +