diff --git a/src/components/launch/LaunchWindow.tsx b/src/components/launch/LaunchWindow.tsx index 032ecb4..2210276 100644 --- a/src/components/launch/LaunchWindow.tsx +++ b/src/components/launch/LaunchWindow.tsx @@ -97,7 +97,12 @@ export function LaunchWindow() { const showWebcamControls = webcamEnabled && !recording; const [isMicHovered, setIsMicHovered] = useState(false); + const [isMicFocused, setIsMicFocused] = useState(false); + const micExpanded = isMicHovered || isMicFocused; + const [isWebcamHovered, setIsWebcamHovered] = useState(false); + const [isWebcamFocused, setIsWebcamFocused] = useState(false); + const webcamExpanded = isWebcamHovered || isWebcamFocused; const { devices: micDevices, @@ -108,6 +113,8 @@ export function LaunchWindow() { devices: cameraDevices, selectedDeviceId: selectedCameraId, setSelectedDeviceId: setSelectedCameraId, + isLoading: isCameraDevicesLoading, + error: cameraDevicesError, } = useCameraDevices(webcamEnabled); const selectedMicLabel = @@ -257,46 +264,43 @@ export function LaunchWindow() { {/* Mic selector */} {showMicControls && (
setIsMicHovered(true)} onMouseLeave={() => setIsMicHovered(false)} - style={{ width: isMicHovered ? "240px" : "140px", transition: "width 300ms ease" }} + onFocus={() => setIsMicFocused(true)} + onBlur={() => setIsMicFocused(false)} + style={{ width: micExpanded ? "240px" : "140px", transition: "width 300ms ease" }} >
- {!isMicHovered ? ( + {!micExpanded && (
{selectedMicLabel}
- ) : ( - <> - - - + )} + + {micExpanded && ( + )}
)} @@ -304,43 +308,73 @@ export function LaunchWindow() { {/* Webcam selector */} {showWebcamControls && (
setIsWebcamHovered(true)} onMouseLeave={() => setIsWebcamHovered(false)} - style={{ width: isWebcamHovered ? "240px" : "140px", transition: "width 300ms ease" }} + onFocus={() => setIsWebcamFocused(true)} + onBlur={() => setIsWebcamFocused(false)} + style={{ width: webcamExpanded ? "240px" : "140px", transition: "width 300ms ease" }} >
- {!isWebcamHovered ? ( + {!webcamExpanded && (
{selectedCameraLabel}
- ) : cameraDevices.length > 0 ? ( - <> - - - - ) : ( - {t("webcam.searching")} + )} + {webcamExpanded && + (isCameraDevicesLoading ? ( + + {t("webcam.searching")} + + ) : cameraDevicesError ? ( + + {t("webcam.unavailable")} + + ) : cameraDevices.length === 0 ? ( + + {t("webcam.noneFound")} + + ) : ( + <> + + + + ))} + {!webcamExpanded && ( + )}
diff --git a/src/i18n/locales/en/launch.json b/src/i18n/locales/en/launch.json index f01e295..6e4a4ed 100644 --- a/src/i18n/locales/en/launch.json +++ b/src/i18n/locales/en/launch.json @@ -17,7 +17,9 @@ "enableWebcam": "Enable webcam", "disableWebcam": "Disable webcam", "defaultCamera": "Default Camera", - "searching": "Searching..." + "searching": "Searching...", + "noneFound": "No camera found", + "unavailable": "Camera unavailable" }, "sourceSelector": { "loading": "Loading sources...", diff --git a/src/i18n/locales/es/launch.json b/src/i18n/locales/es/launch.json index 4902404..b25ec3d 100644 --- a/src/i18n/locales/es/launch.json +++ b/src/i18n/locales/es/launch.json @@ -17,7 +17,9 @@ "enableWebcam": "Activar cámara web", "disableWebcam": "Desactivar cámara web", "defaultCamera": "Cámara predeterminada", - "searching": "Buscando..." + "searching": "Buscando...", + "noneFound": "No se encontró cámara", + "unavailable": "Cámara no disponible" }, "sourceSelector": { "loading": "Cargando fuentes...", diff --git a/src/i18n/locales/zh-CN/launch.json b/src/i18n/locales/zh-CN/launch.json index 48846a0..84fdcef 100644 --- a/src/i18n/locales/zh-CN/launch.json +++ b/src/i18n/locales/zh-CN/launch.json @@ -17,7 +17,9 @@ "enableWebcam": "启用摄像头", "disableWebcam": "禁用摄像头", "defaultCamera": "默认摄像头", - "searching": "正在搜索..." + "searching": "正在搜索...", + "noneFound": "未找到摄像头", + "unavailable": "摄像头不可用" }, "sourceSelector": { "loading": "正在加载源...",