fix: restore cursor pipeline build after rebase

This commit is contained in:
EtienneLescot
2026-05-03 16:53:04 +02:00
parent e9650225ba
commit 28ff0fb7bf
8 changed files with 60 additions and 10 deletions
+3
View File
@@ -43,3 +43,6 @@ __screenshots__/
result
result-*
.direnv/
#kilocode
.kilo/
+43 -1
View File
@@ -451,9 +451,12 @@ async function storeRecordedSessionFiles(payload: StoreRecordedSessionInput) {
export function registerIpcHandlers(
createEditorWindow: () => void,
createSourceSelectorWindow: () => BrowserWindow,
_createCountdownOverlayWindow: () => BrowserWindow,
getMainWindow: () => BrowserWindow | null,
getSourceSelectorWindow: () => BrowserWindow | null,
_getCountdownOverlayWindow?: () => BrowserWindow | null,
onRecordingStateChange?: (recording: boolean, sourceName: string) => void,
_switchToHud?: () => void,
) {
ipcMain.handle("get-sources", async (_, opts) => {
const sources = await desktopCapturer.getSources(opts);
@@ -472,7 +475,7 @@ export function registerIpcHandlers(
// Reuse the exact source object returned during enumeration to avoid
// Windows window-source id mismatches across separate getSources() calls.
selectedDesktopSource =
typeof source.id === "string" ? lastEnumeratedSources.get(source.id) ?? null : null;
typeof source.id === "string" ? (lastEnumeratedSources.get(source.id) ?? null) : null;
if (!selectedDesktopSource && typeof source.id === "string") {
try {
@@ -602,6 +605,45 @@ export function registerIpcHandlers(
}
});
async function storeRecordedSessionFiles(payload: StoreRecordedSessionInput) {
const createdAt =
typeof payload.createdAt === "number" && Number.isFinite(payload.createdAt)
? payload.createdAt
: Date.now();
const screenVideoPath = path.join(RECORDINGS_DIR, payload.screen.fileName);
await fs.writeFile(screenVideoPath, Buffer.from(payload.screen.videoData));
let webcamVideoPath: string | undefined;
if (payload.webcam) {
webcamVideoPath = path.join(RECORDINGS_DIR, payload.webcam.fileName);
await fs.writeFile(webcamVideoPath, Buffer.from(payload.webcam.videoData));
}
const session: RecordingSession = webcamVideoPath
? { screenVideoPath, webcamVideoPath, createdAt }
: { screenVideoPath, createdAt };
setCurrentRecordingSessionState(session);
currentVideoPath = screenVideoPath;
currentProjectPath = null;
const telemetryPath = `${screenVideoPath}.cursor.json`;
if (pendingCursorRecordingData && pendingCursorRecordingData.samples.length > 0) {
await fs.writeFile(
telemetryPath,
JSON.stringify(pendingCursorRecordingData, null, 2),
"utf-8",
);
}
pendingCursorRecordingData = null;
return {
success: true,
path: screenVideoPath,
session,
message: "Recording session stored successfully",
};
}
ipcMain.handle("store-recorded-video", async (_, videoData: ArrayBuffer, fileName: string) => {
try {
return await storeRecordedSessionFiles({
+1
View File
@@ -1,4 +1,5 @@
import { contextBridge, ipcRenderer } from "electron";
import type { RecordingSession, StoreRecordedSessionInput } from "../src/lib/recordingSession";
import { NATIVE_BRIDGE_CHANNEL, type NativeBridgeRequest } from "../src/native/contracts";
// Asset base URL is passed from the main process via webPreferences.additionalArguments
@@ -435,8 +435,6 @@ export function SettingsPanel({
const [selectedColor, setSelectedColor] = useState("#ADADAD");
const [gradient, setGradient] = useState<string>(GRADIENTS[0]);
const [showCropModal, setShowCropModal] = useState(false);
const cropSnapshotRef = useRef<CropRegion | null>(null);
const [cropAspectLocked, setCropAspectLocked] = useState(false);
const [cropAspectRatio, setCropAspectRatio] = useState("");
const isPortraitCanvas = isPortraitAspectRatio(aspectRatio);
+8 -3
View File
@@ -38,12 +38,12 @@ import {
saveUserPreferences,
} from "@/lib/userPreferences";
import { BackgroundLoadError } from "@/lib/wallpaper";
import { nativeBridgeClient, useCursorRecordingData, useCursorTelemetry } from "@/native";
import {
getAspectRatioValue,
getNativeAspectRatioValue,
isPortraitAspectRatio,
} from "@/utils/aspectRatioUtils";
import { nativeBridgeClient, useCursorRecordingData, useCursorTelemetry } from "@/native";
import { ExportDialog } from "./ExportDialog";
import PlaybackControls from "./PlaybackControls";
import {
@@ -216,7 +216,12 @@ export default function VideoEditor() {
}
const project = candidate;
const sourcePath = project.videoPath;
const projectMedia = resolveProjectMedia(project);
if (!projectMedia) {
return false;
}
const sourcePath = projectMedia.screenVideoPath;
const webcamSourcePath = projectMedia.webcamVideoPath ?? null;
const normalizedEditor = normalizeProjectEditor(project.editor);
const inferredDurationMs = Math.max(
0,
@@ -405,7 +410,7 @@ export default function VideoEditor() {
setVideoPath(toFileUrl(result.path));
setCurrentProjectPath(null);
setLastSavedSnapshot(
createProjectSnapshot({ screenVideoPath: sourcePath }, INITIAL_EDITOR_STATE),
createProjectSnapshot({ screenVideoPath: result.path }, INITIAL_EDITOR_STATE),
);
} else {
setError("No video to load. Please record or select a video.");
@@ -25,14 +25,14 @@ import {
type WebcamLayoutPreset,
type WebcamSizePreset,
} from "@/lib/compositeLayout";
import { classifyWallpaper, DEFAULT_WALLPAPER, resolveImageWallpaperUrl } from "@/lib/wallpaper";
import { getCssClipPath } from "@/lib/webcamMaskShapes";
import {
getNativeCursorDisplayMetrics,
hasNativeCursorRecordingData,
projectNativeCursorToStage,
resolveInterpolatedNativeCursorFrame,
} from "@/lib/cursor/nativeCursor";
import { classifyWallpaper, DEFAULT_WALLPAPER, resolveImageWallpaperUrl } from "@/lib/wallpaper";
import { getCssClipPath } from "@/lib/webcamMaskShapes";
import type { CursorRecordingData } from "@/native/contracts";
import {
type AspectRatio,
+2 -1
View File
@@ -1,7 +1,8 @@
import { fixWebmDuration } from "@fix-webm-duration/fix";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { nativeBridgeClient } from "@/native";
import { useScopedT } from "@/contexts/I18nContext";
import { requestCameraAccess } from "@/lib/requestCameraAccess";
const TARGET_FRAME_RATE = 60;
const MIN_FRAME_RATE = 30;
+1 -1
View File
@@ -614,7 +614,7 @@ export class FrameRenderer {
return image;
}
private updateLayout(): void {
private updateLayout(webcamFrame?: VideoFrame | null): void {
if (!this.app || !this.videoSprite || !this.maskGraphics || !this.videoContainer) return;
const { width, height } = this.config;