mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-25 07:16:02 +00:00
add: ProjectPopover to wrap the dialog into it. this is to avoid mouse passthrough and stuff
This commit is contained in:
@@ -23,7 +23,6 @@ import { useRecordingTimer } from "./hooks/useRecordingTimer";
|
||||
import { useScreenRecorder } from "../../hooks/useScreenRecorder";
|
||||
import { useVideoDevices } from "../../hooks/useVideoDevices";
|
||||
import { useWebcamPreviewOverlay } from "./hooks/useWebcamPreviewOverlay";
|
||||
import ProjectBrowserDialog from "../video-editor/ProjectBrowserDialog";
|
||||
import {
|
||||
canToggleFloatingWebcamPreview,
|
||||
} from "./floatingWebcamPreview";
|
||||
@@ -31,6 +30,7 @@ import { LaunchPopoverCoordinatorProvider, useLaunchPopoverCoordinator } from ".
|
||||
import { CountdownPopover } from "./popovers/CountdownPopover";
|
||||
import { MicPopover } from "./popovers/MicPopover";
|
||||
import { MorePopover } from "./popovers/MorePopover";
|
||||
import { ProjectPopover } from "./popovers/ProjectPopover";
|
||||
import { SourcePopover } from "./popovers/SourcePopover";
|
||||
import { WebcamPopover } from "./popovers/WebcamPopover";
|
||||
import { HudInteractionContext } from "./contexts/HudInteractionContext";
|
||||
@@ -40,7 +40,7 @@ import styles from "./LaunchWindow.module.css";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Button } from "../ui/button";
|
||||
import { RecordingControls } from "./RecordingControls";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
const SHOW_DEV_UPDATE_PREVIEW = import.meta.env.DEV;
|
||||
|
||||
@@ -84,24 +84,17 @@ function LaunchWindowContent() {
|
||||
const hudContentRef = useRef<HTMLDivElement>(null);
|
||||
const hudBarRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const closeAllPopovers = useCallback(() => {
|
||||
if (openId) {
|
||||
requestClose(openId);
|
||||
}
|
||||
}, [openId, requestClose]);
|
||||
|
||||
const {
|
||||
selectedSource,
|
||||
hasSelectedSource,
|
||||
projectLibraryEntries,
|
||||
projectBrowserOpen,
|
||||
setProjectBrowserOpen,
|
||||
handleSourceSelect,
|
||||
openVideoFile,
|
||||
openProjectBrowser,
|
||||
openProjectFromLibrary,
|
||||
syncSelectedSource,
|
||||
} = useLaunchWindowActions({ closeAllPopovers });
|
||||
refreshProjectLibrary,
|
||||
} = useLaunchWindowActions();
|
||||
|
||||
const showWebcamControls = webcamEnabled && !recording;
|
||||
const { devices, selectedDeviceId, setSelectedDeviceId } = useMicrophoneDevices(
|
||||
@@ -176,8 +169,6 @@ function LaunchWindowContent() {
|
||||
|
||||
const { handleHudMouseEnter, handleHudMouseLeave, beginInteractiveHudAction } = useLaunchHudInteractionState({
|
||||
openId,
|
||||
projectBrowserOpen,
|
||||
setProjectBrowserOpen,
|
||||
isHudDraggingRef,
|
||||
isWebcamPreviewDraggingRef,
|
||||
webcamPreviewDragStartRef,
|
||||
@@ -338,7 +329,6 @@ function LaunchWindowContent() {
|
||||
}
|
||||
/>
|
||||
|
||||
<Separator orientation="vertical" className="mx-[5px] h-6" />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@@ -359,6 +349,14 @@ function LaunchWindowContent() {
|
||||
|
||||
<Separator orientation="vertical" className="mx-[5px] h-6" />
|
||||
|
||||
<div className="relative w-0 h-0">
|
||||
<ProjectPopover
|
||||
entries={projectLibraryEntries}
|
||||
onOpenProject={openProjectFromLibrary}
|
||||
trigger={<div className="absolute inset-0 pointer-events-none opacity-0" />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MorePopover
|
||||
supportsHudCaptureProtection={supportsHudCaptureProtection}
|
||||
hideHudFromCapture={hideHudFromCapture}
|
||||
@@ -372,11 +370,13 @@ function LaunchWindowContent() {
|
||||
void openVideoFile();
|
||||
}}
|
||||
onOpenProjectBrowser={() => {
|
||||
void openProjectBrowser();
|
||||
refreshProjectLibrary().then(() => {
|
||||
requestOpen("projects");
|
||||
});
|
||||
}}
|
||||
showDevUpdatePreview={SHOW_DEV_UPDATE_PREVIEW}
|
||||
onPreviewUpdateUi={() => {
|
||||
closeAllPopovers();
|
||||
if (openId) requestClose(openId);
|
||||
void window.electronAPI.previewUpdateToast().catch((error) => {
|
||||
console.warn("Failed to preview update toast:", error);
|
||||
});
|
||||
@@ -537,19 +537,6 @@ function LaunchWindowContent() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{projectBrowserOpen ? (
|
||||
<div className={`${styles.electronNoDrag} pointer-events-auto`}>
|
||||
<ProjectBrowserDialog
|
||||
open={projectBrowserOpen}
|
||||
onOpenChange={setProjectBrowserOpen}
|
||||
entries={projectLibraryEntries}
|
||||
renderMode="inline"
|
||||
onOpenProject={(projectPath) => {
|
||||
void openProjectFromLibrary(projectPath);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</HudInteractionContext.Provider>
|
||||
|
||||
@@ -2,21 +2,16 @@ import { useCallback, useEffect, useRef, type MouseEvent, type RefObject } from
|
||||
|
||||
export function useLaunchHudInteractionState({
|
||||
openId,
|
||||
projectBrowserOpen,
|
||||
setProjectBrowserOpen,
|
||||
isHudDraggingRef,
|
||||
isWebcamPreviewDraggingRef,
|
||||
webcamPreviewDragStartRef,
|
||||
}: {
|
||||
openId: string | null;
|
||||
projectBrowserOpen: boolean;
|
||||
setProjectBrowserOpen: (open: boolean) => void;
|
||||
isHudDraggingRef: RefObject<boolean>;
|
||||
isWebcamPreviewDraggingRef: RefObject<boolean>;
|
||||
webcamPreviewDragStartRef: RefObject<unknown>;
|
||||
}) {
|
||||
const anyPopoverOpenRef = useRef(false);
|
||||
const projectBrowserOpenRef = useRef(false);
|
||||
const isMouseOverHudRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -33,21 +28,10 @@ export function useLaunchHudInteractionState({
|
||||
}
|
||||
}, [openId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!openId) return;
|
||||
setProjectBrowserOpen(false);
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(false);
|
||||
}, [openId, setProjectBrowserOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
projectBrowserOpenRef.current = projectBrowserOpen;
|
||||
}, [projectBrowserOpen]);
|
||||
|
||||
const beginInteractiveHudAction = useCallback(() => {
|
||||
setProjectBrowserOpen(false);
|
||||
isMouseOverHudRef.current = true;
|
||||
window.electronAPI?.hudOverlaySetIgnoreMouse?.(false);
|
||||
}, [setProjectBrowserOpen]);
|
||||
}, []);
|
||||
|
||||
const handleHudMouseEnter = useCallback(() => {
|
||||
isMouseOverHudRef.current = true;
|
||||
@@ -72,7 +56,6 @@ export function useLaunchHudInteractionState({
|
||||
!isHudDraggingRef.current &&
|
||||
!isWebcamPreviewDraggingRef.current &&
|
||||
!webcamPreviewDragStartRef.current &&
|
||||
!projectBrowserOpenRef.current &&
|
||||
!isMouseOverHudRef.current &&
|
||||
!anyPopoverOpenRef.current
|
||||
) {
|
||||
|
||||
@@ -2,15 +2,10 @@ import { useCallback, useState } from "react";
|
||||
import type { ProjectLibraryEntry } from "@/components/video-editor/ProjectBrowserDialog";
|
||||
import type { DesktopSource } from "../popovers/launchPopoverTypes";
|
||||
|
||||
export function useLaunchWindowActions({
|
||||
closeAllPopovers,
|
||||
}: {
|
||||
closeAllPopovers: () => void;
|
||||
}) {
|
||||
export function useLaunchWindowActions() {
|
||||
const [selectedSource, setSelectedSource] = useState("Screen");
|
||||
const [hasSelectedSource, setHasSelectedSource] = useState(false);
|
||||
const [projectLibraryEntries, setProjectLibraryEntries] = useState<ProjectLibraryEntry[]>([]);
|
||||
const [projectBrowserOpen, setProjectBrowserOpen] = useState(false);
|
||||
|
||||
const handleSourceSelect = useCallback(async (source: DesktopSource) => {
|
||||
await window.electronAPI.selectSource(source);
|
||||
@@ -41,24 +36,12 @@ export function useLaunchWindowActions({
|
||||
console.error("Failed to load project library:", error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const openProjectBrowser = useCallback(async () => {
|
||||
if (projectBrowserOpen) {
|
||||
setProjectBrowserOpen(false);
|
||||
return;
|
||||
}
|
||||
closeAllPopovers();
|
||||
await refreshProjectLibrary();
|
||||
setProjectBrowserOpen(true);
|
||||
}, [closeAllPopovers, projectBrowserOpen, refreshProjectLibrary]);
|
||||
|
||||
const openProjectFromLibrary = useCallback(async (projectPath: string) => {
|
||||
try {
|
||||
const result = await window.electronAPI.openProjectFileAtPath(projectPath);
|
||||
if (result.canceled || !result.success) {
|
||||
return;
|
||||
}
|
||||
setProjectBrowserOpen(false);
|
||||
await window.electronAPI.switchToEditor();
|
||||
} catch (error) {
|
||||
console.error("Failed to open project from library:", error);
|
||||
@@ -79,12 +62,10 @@ export function useLaunchWindowActions({
|
||||
selectedSource,
|
||||
hasSelectedSource,
|
||||
projectLibraryEntries,
|
||||
projectBrowserOpen,
|
||||
setProjectBrowserOpen,
|
||||
handleSourceSelect,
|
||||
openVideoFile,
|
||||
openProjectBrowser,
|
||||
openProjectFromLibrary,
|
||||
syncSelectedSource,
|
||||
refreshProjectLibrary,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { ReactElement } from "react";
|
||||
import { useLaunchPopoverCoordinator } from "./LaunchPopoverCoordinator";
|
||||
import { HudPopover } from "./PopoverScaffold";
|
||||
import ProjectBrowserDialog from "../../video-editor/ProjectBrowserDialog";
|
||||
import type { ProjectLibraryEntry } from "../../video-editor/ProjectBrowserDialog";
|
||||
|
||||
const POPOVER_ID = "projects";
|
||||
|
||||
export function ProjectPopover({
|
||||
trigger,
|
||||
entries,
|
||||
onOpenProject,
|
||||
}: {
|
||||
trigger: ReactElement;
|
||||
entries: ProjectLibraryEntry[];
|
||||
onOpenProject: (projectPath: string) => void;
|
||||
}) {
|
||||
const { isOpen, requestOpen, requestClose } = useLaunchPopoverCoordinator();
|
||||
const open = isOpen(POPOVER_ID);
|
||||
|
||||
return (
|
||||
<HudPopover
|
||||
open={open}
|
||||
onOpenChange={(nextOpen) => {
|
||||
if (!nextOpen) {
|
||||
requestClose(POPOVER_ID);
|
||||
return;
|
||||
}
|
||||
requestOpen(POPOVER_ID);
|
||||
}}
|
||||
trigger={trigger}
|
||||
align="center"
|
||||
>
|
||||
<ProjectBrowserDialog
|
||||
open={open}
|
||||
onOpenChange={(nextOpen) => {
|
||||
if (!nextOpen) requestClose(POPOVER_ID);
|
||||
}}
|
||||
entries={entries}
|
||||
renderMode="inline"
|
||||
onOpenProject={(path) => {
|
||||
onOpenProject(path);
|
||||
requestClose(POPOVER_ID);
|
||||
}}
|
||||
/>
|
||||
</HudPopover>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user