fix: restore cursor pipeline build after rebase
This commit is contained in:
@@ -43,3 +43,6 @@ __screenshots__/
|
||||
result
|
||||
result-*
|
||||
.direnv/
|
||||
|
||||
#kilocode
|
||||
.kilo/
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user