diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index c5a1269..7b16f2f 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -3,7 +3,7 @@ import { createRequire } from "node:module"; import os from "node:os"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; - +import type { DesktopCapturerSource } from "electron"; import { app, BrowserWindow, @@ -14,7 +14,6 @@ import { shell, systemPreferences, } from "electron"; -import type { DesktopCapturerSource } from "electron"; import { normalizeProjectMedia, normalizeRecordingSession, @@ -410,46 +409,6 @@ function setCurrentRecordingSessionState(session: RecordingSession | null) { currentVideoPath = session?.screenVideoPath ?? null; } -async function storeRecordedSessionFiles(payload: StoreRecordedSessionInput) { - const createdAt = - typeof payload.createdAt === "number" && Number.isFinite(payload.createdAt) - ? payload.createdAt - : Date.now(); - const screenVideoPath = resolveRecordingOutputPath(payload.screen.fileName); - await fs.writeFile(screenVideoPath, Buffer.from(payload.screen.videoData)); - - let webcamVideoPath: string | undefined; - if (payload.webcam) { - webcamVideoPath = resolveRecordingOutputPath(payload.webcam.fileName); - await fs.writeFile(webcamVideoPath, Buffer.from(payload.webcam.videoData)); - } - - const session: RecordingSession = webcamVideoPath - ? { screenVideoPath, webcamVideoPath, createdAt } - : { screenVideoPath, createdAt }; - setCurrentRecordingSessionState(session); - 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; - - const sessionManifestPath = path.join( - RECORDINGS_DIR, - `${path.parse(payload.screen.fileName).name}${RECORDING_SESSION_SUFFIX}`, - ); - await fs.writeFile(sessionManifestPath, JSON.stringify(session, null, 2), "utf-8"); - - return { - success: true, - path: screenVideoPath, - session, - message: "Recording session stored successfully", - }; -} - export function registerIpcHandlers( createEditorWindow: () => void, createSourceSelectorWindow: () => BrowserWindow, @@ -612,12 +571,12 @@ export function registerIpcHandlers( typeof payload.createdAt === "number" && Number.isFinite(payload.createdAt) ? payload.createdAt : Date.now(); - const screenVideoPath = path.join(RECORDINGS_DIR, payload.screen.fileName); + const screenVideoPath = resolveRecordingOutputPath(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); + webcamVideoPath = resolveRecordingOutputPath(payload.webcam.fileName); await fs.writeFile(webcamVideoPath, Buffer.from(payload.webcam.videoData)); } @@ -625,7 +584,6 @@ export function registerIpcHandlers( ? { screenVideoPath, webcamVideoPath, createdAt } : { screenVideoPath, createdAt }; setCurrentRecordingSessionState(session); - currentVideoPath = screenVideoPath; currentProjectPath = null; const telemetryPath = `${screenVideoPath}.cursor.json`; @@ -638,6 +596,12 @@ export function registerIpcHandlers( } pendingCursorRecordingData = null; + const sessionManifestPath = path.join( + RECORDINGS_DIR, + `${path.parse(payload.screen.fileName).name}${RECORDING_SESSION_SUFFIX}`, + ); + await fs.writeFile(sessionManifestPath, JSON.stringify(session, null, 2), "utf-8"); + return { success: true, path: screenVideoPath, @@ -1010,18 +974,7 @@ export function registerIpcHandlers( const content = await fs.readFile(filePath, "utf-8"); const project = JSON.parse(content); currentProjectPath = filePath; - if (project && typeof project === "object") { - const rawProject = project as { media?: unknown; videoPath?: unknown }; - const media = - normalizeProjectMedia(rawProject.media) ?? - (typeof rawProject.videoPath === "string" - ? { - screenVideoPath: - normalizeVideoSourcePath(rawProject.videoPath) ?? rawProject.videoPath, - } - : null); - setCurrentRecordingSessionState(media ? { ...media, createdAt: Date.now() } : null); - } + setCurrentRecordingSessionState(await getApprovedProjectSession(project, filePath)); return { success: true, @@ -1050,18 +1003,7 @@ export function registerIpcHandlers( const content = await fs.readFile(currentProjectPath, "utf-8"); const project = JSON.parse(content); - if (project && typeof project === "object") { - const rawProject = project as { media?: unknown; videoPath?: unknown }; - const media = - normalizeProjectMedia(rawProject.media) ?? - (typeof rawProject.videoPath === "string" - ? { - screenVideoPath: - normalizeVideoSourcePath(rawProject.videoPath) ?? rawProject.videoPath, - } - : null); - setCurrentRecordingSessionState(media ? { ...media, createdAt: Date.now() } : null); - } + setCurrentRecordingSessionState(await getApprovedProjectSession(project, currentProjectPath)); return { success: true, path: currentProjectPath, diff --git a/src/assets/cursors/Cursor=App-Starting.svg b/src/assets/cursors/Cursor=App-Starting.svg new file mode 100644 index 0000000..7a10d40 --- /dev/null +++ b/src/assets/cursors/Cursor=App-Starting.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/cursors/Cursor=Help.svg b/src/assets/cursors/Cursor=Help.svg new file mode 100644 index 0000000..d187c52 --- /dev/null +++ b/src/assets/cursors/Cursor=Help.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/cursors/Cursor=Not-Allowed.svg b/src/assets/cursors/Cursor=Not-Allowed.svg new file mode 100644 index 0000000..8b2c3f8 --- /dev/null +++ b/src/assets/cursors/Cursor=Not-Allowed.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/cursors/Cursor=Up-Arrow.svg b/src/assets/cursors/Cursor=Up-Arrow.svg new file mode 100644 index 0000000..b742e70 --- /dev/null +++ b/src/assets/cursors/Cursor=Up-Arrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/cursors/Cursor=Wait.svg b/src/assets/cursors/Cursor=Wait.svg new file mode 100644 index 0000000..2b56934 --- /dev/null +++ b/src/assets/cursors/Cursor=Wait.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/lib/cursor/nativeCursor.ts b/src/lib/cursor/nativeCursor.ts index d6ae220..30f7a46 100644 --- a/src/lib/cursor/nativeCursor.ts +++ b/src/lib/cursor/nativeCursor.ts @@ -1,14 +1,18 @@ import { type Container, Point } from "pixi.js"; +import appStartingUrl from "@/assets/cursors/Cursor=App-Starting.svg"; import crosshairUrl from "@/assets/cursors/Cursor=Cross.svg"; import arrowUrl from "@/assets/cursors/Cursor=Default.svg"; import pointerUrl from "@/assets/cursors/Cursor=Hand-(Pointing).svg"; -import notAllowedUrl from "@/assets/cursors/Cursor=Menu.svg"; +import helpUrl from "@/assets/cursors/Cursor=Help.svg"; import moveUrl from "@/assets/cursors/Cursor=Move.svg"; +import notAllowedUrl from "@/assets/cursors/Cursor=Not-Allowed.svg"; import resizeNeswUrl from "@/assets/cursors/Cursor=Resize-North-East-South-West.svg"; import resizeNsUrl from "@/assets/cursors/Cursor=Resize-North-South.svg"; import resizeNwseUrl from "@/assets/cursors/Cursor=Resize-North-West-South-East.svg"; import resizeEwUrl from "@/assets/cursors/Cursor=Resize-West-East.svg"; import textUrl from "@/assets/cursors/Cursor=Text-Cursor.svg"; +import upArrowUrl from "@/assets/cursors/Cursor=Up-Arrow.svg"; +import waitUrl from "@/assets/cursors/Cursor=Wait.svg"; import type { CropRegion } from "@/components/video-editor/types"; import type { CursorRecordingData, @@ -113,6 +117,34 @@ const PRETTY_NATIVE_CURSOR_ASSETS: Partial