mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 08:15:42 +00:00
fix(hud): persist capture hiding review fixes
This commit is contained in:
@@ -85,7 +85,8 @@ export function LaunchWindow() {
|
||||
const [selectedSource, setSelectedSource] = useState("Screen");
|
||||
const [hasSelectedSource, setHasSelectedSource] = useState(false);
|
||||
const [recordingsDirectory, setRecordingsDirectory] = useState<string | null>(null);
|
||||
const [hideHudFromCapture, setHideHudFromCapture] = useState(false);
|
||||
const [hideHudFromCapture, setHideHudFromCapture] = useState(true);
|
||||
const [platform, setPlatform] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const checkSelectedSource = async () => {
|
||||
@@ -106,6 +107,27 @@ export function LaunchWindow() {
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
const loadPlatform = async () => {
|
||||
try {
|
||||
const nextPlatform = await window.electronAPI.getPlatform();
|
||||
if (!cancelled) {
|
||||
setPlatform(nextPlatform);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load platform:", error);
|
||||
}
|
||||
};
|
||||
|
||||
void loadPlatform();
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
@@ -204,6 +226,7 @@ export function LaunchWindow() {
|
||||
? recordingsDirectory.split(/[\\/]/).filter(Boolean).pop() || recordingsDirectory
|
||||
: "recordings";
|
||||
const dividerClass = "mx-1 h-5 w-px shrink-0 bg-white/35";
|
||||
const supportsHudCaptureProtection = platform !== "linux";
|
||||
|
||||
const toggleMicrophone = () => {
|
||||
if (!recording) {
|
||||
@@ -266,21 +289,25 @@ export function LaunchWindow() {
|
||||
<div className={dividerClass} />
|
||||
|
||||
<div className={`flex items-center gap-1 ${styles.electronNoDrag}`}>
|
||||
<Button
|
||||
variant="link"
|
||||
size="icon"
|
||||
onClick={() => void toggleHudCaptureProtection()}
|
||||
title={
|
||||
hideHudFromCapture ? t("recording.showHudInVideo") : t("recording.hideHudFromVideo")
|
||||
}
|
||||
className="text-white/80 hover:bg-transparent"
|
||||
>
|
||||
{hideHudFromCapture ? (
|
||||
<EyeOff size={16} className="text-[#2563EB]" />
|
||||
) : (
|
||||
<Eye size={16} className="text-white/35" />
|
||||
)}
|
||||
</Button>
|
||||
{supportsHudCaptureProtection && (
|
||||
<Button
|
||||
variant="link"
|
||||
size="icon"
|
||||
onClick={() => void toggleHudCaptureProtection()}
|
||||
title={
|
||||
hideHudFromCapture
|
||||
? t("recording.showHudInVideo")
|
||||
: t("recording.hideHudFromVideo")
|
||||
}
|
||||
className="text-white/80 hover:bg-transparent"
|
||||
>
|
||||
{hideHudFromCapture ? (
|
||||
<EyeOff size={16} className="text-white/35" />
|
||||
) : (
|
||||
<Eye size={16} className="text-[#2563EB]" />
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="link"
|
||||
size="icon"
|
||||
|
||||
Vendored
-208
@@ -1,210 +1,2 @@
|
||||
/// <reference types="vite/client" />
|
||||
/// <reference types="../electron/electron-env" />
|
||||
|
||||
interface ProcessedDesktopSource {
|
||||
id: string;
|
||||
name: string;
|
||||
display_id: string;
|
||||
thumbnail: string | null;
|
||||
appIcon: string | null;
|
||||
originalName?: string;
|
||||
sourceType?: "screen" | "window";
|
||||
appName?: string;
|
||||
windowTitle?: string;
|
||||
}
|
||||
|
||||
interface CursorTelemetryPoint {
|
||||
timeMs: number;
|
||||
cx: number;
|
||||
cy: number;
|
||||
interactionType?: "move" | "click" | "double-click" | "right-click" | "middle-click" | "mouseup";
|
||||
cursorType?:
|
||||
| "arrow"
|
||||
| "text"
|
||||
| "pointer"
|
||||
| "crosshair"
|
||||
| "open-hand"
|
||||
| "closed-hand"
|
||||
| "resize-ew"
|
||||
| "resize-ns"
|
||||
| "not-allowed";
|
||||
}
|
||||
|
||||
interface SystemCursorAsset {
|
||||
dataUrl: string;
|
||||
hotspotX: number;
|
||||
hotspotY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface Window {
|
||||
electronAPI: {
|
||||
hudOverlayHide: () => void;
|
||||
hudOverlayClose: () => void;
|
||||
getHudOverlayCaptureProtection: () => Promise<{ success: boolean; enabled: boolean }>;
|
||||
setHudOverlayCaptureProtection: (
|
||||
enabled: boolean,
|
||||
) => Promise<{ success: boolean; enabled: boolean }>;
|
||||
getSources: (opts: Electron.SourcesOptions) => Promise<ProcessedDesktopSource[]>;
|
||||
switchToEditor: () => Promise<void>;
|
||||
openSourceSelector: () => Promise<void>;
|
||||
selectSource: (source: any) => Promise<any>;
|
||||
getSelectedSource: () => Promise<any>;
|
||||
startNativeScreenRecording: (
|
||||
source: any,
|
||||
options?: {
|
||||
capturesSystemAudio?: boolean;
|
||||
capturesMicrophone?: boolean;
|
||||
microphoneDeviceId?: string;
|
||||
microphoneLabel?: string;
|
||||
},
|
||||
) => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
stopNativeScreenRecording: () => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
startFfmpegRecording: (source: any) => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
stopFfmpegRecording: () => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
storeRecordedVideo: (
|
||||
videoData: ArrayBuffer,
|
||||
fileName: string,
|
||||
) => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message: string;
|
||||
error?: string;
|
||||
}>;
|
||||
getRecordedVideoPath: () => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
readLocalFile: (filePath: string) => Promise<{
|
||||
success: boolean;
|
||||
data?: Uint8Array;
|
||||
error?: string;
|
||||
}>;
|
||||
getAssetBasePath: () => Promise<string | null>;
|
||||
setRecordingState: (recording: boolean) => Promise<void>;
|
||||
getCursorTelemetry: (videoPath?: string) => Promise<{
|
||||
success: boolean;
|
||||
samples: CursorTelemetryPoint[];
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
getSystemCursorAssets: () => Promise<{
|
||||
success: boolean;
|
||||
cursors: Record<string, SystemCursorAsset>;
|
||||
error?: string;
|
||||
}>;
|
||||
onStopRecordingFromTray: (callback: () => void) => () => void;
|
||||
onRecordingStateChanged: (
|
||||
callback: (state: { recording: boolean; sourceName: string }) => void,
|
||||
) => () => void;
|
||||
onRecordingInterrupted: (
|
||||
callback: (state: { reason: string; message: string }) => void,
|
||||
) => () => void;
|
||||
onCursorStateChanged: (
|
||||
callback: (state: { cursorType: CursorTelemetryPoint["cursorType"] }) => void,
|
||||
) => () => void;
|
||||
openExternalUrl: (url: string) => Promise<{ success: boolean; error?: string }>;
|
||||
getAccessibilityPermissionStatus: () => Promise<{
|
||||
success: boolean;
|
||||
trusted: boolean;
|
||||
prompted: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
requestAccessibilityPermission: () => Promise<{
|
||||
success: boolean;
|
||||
trusted: boolean;
|
||||
prompted: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
getScreenRecordingPermissionStatus: () => Promise<{
|
||||
success: boolean;
|
||||
status: string;
|
||||
error?: string;
|
||||
}>;
|
||||
openScreenRecordingPreferences: () => Promise<{ success: boolean; error?: string }>;
|
||||
openAccessibilityPreferences: () => Promise<{ success: boolean; error?: string }>;
|
||||
saveExportedVideo: (
|
||||
videoData: ArrayBuffer,
|
||||
fileName: string,
|
||||
) => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
canceled?: boolean;
|
||||
}>;
|
||||
openVideoFilePicker: () => Promise<{ success: boolean; path?: string; canceled?: boolean }>;
|
||||
setCurrentVideoPath: (path: string) => Promise<{ success: boolean }>;
|
||||
getCurrentVideoPath: () => Promise<{ success: boolean; path?: string }>;
|
||||
clearCurrentVideoPath: () => Promise<{ success: boolean }>;
|
||||
saveProjectFile: (
|
||||
projectData: unknown,
|
||||
suggestedName?: string,
|
||||
existingProjectPath?: string,
|
||||
) => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
message?: string;
|
||||
canceled?: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
loadProjectFile: () => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
project?: unknown;
|
||||
message?: string;
|
||||
canceled?: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
loadCurrentProjectFile: () => Promise<{
|
||||
success: boolean;
|
||||
path?: string;
|
||||
project?: unknown;
|
||||
message?: string;
|
||||
canceled?: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
onMenuLoadProject: (callback: () => void) => () => void;
|
||||
onMenuSaveProject: (callback: () => void) => () => void;
|
||||
onMenuSaveProjectAs: (callback: () => void) => () => void;
|
||||
hideOsCursor: () => Promise<{ success: boolean }>;
|
||||
setHasUnsavedChanges: (hasChanges: boolean) => void;
|
||||
onRequestSaveBeforeClose: (callback: () => Promise<void>) => () => void;
|
||||
getRecordingsDirectory: () => Promise<{
|
||||
success: boolean;
|
||||
path: string;
|
||||
isDefault: boolean;
|
||||
error?: string;
|
||||
}>;
|
||||
chooseRecordingsDirectory: () => Promise<{
|
||||
success: boolean;
|
||||
canceled?: boolean;
|
||||
path?: string;
|
||||
isDefault?: boolean;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user