From f66a562824176d1415c60243d1b859bbd1649793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81bastien=20Beaury?= Date: Tue, 26 Nov 2024 15:32:41 -0500 Subject: [PATCH] [wip] feat: add delete prev recording feat in settings --- apps/desktop/src-tauri/src/lib.rs | 25 ++++++ .../(window-chrome)/settings/recordings.tsx | 89 ++++++++++++------- apps/desktop/src/utils/tauri.ts | 6 ++ 3 files changed, 90 insertions(+), 30 deletions(-) diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index f3eaf78b6..eb52e38e9 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -244,6 +244,11 @@ pub struct RecordingStopped { path: PathBuf, } +#[derive(Deserialize, specta::Type, Serialize, tauri_specta::Event, Debug, Clone)] +pub struct RecordingDeleted { + path: PathBuf, +} + #[derive(Deserialize, specta::Type, Serialize, tauri_specta::Event, Debug, Clone)] pub struct RequestStartRecording; @@ -680,6 +685,24 @@ async fn open_file_path(_app: AppHandle, path: PathBuf) -> Result<(), String> { Ok(()) } + +#[tauri::command] +#[specta::specta] +async fn delete_file(_app: AppHandle, path: PathBuf) -> Result<(), String> { + let path_str = path.to_str().ok_or("Invalid path")?; + + #[cfg(target_os = "macos")] + { + Command::new("rm") + .arg("-r") + .arg(path_str) + .spawn() + .map_err(|e| format!("Failed to delete folder: {}", e))?; + } + + Ok(()) +} + #[derive(Deserialize, specta::Type, tauri_specta::Event, Debug, Clone)] struct RenderFrameEvent { frame_number: u32, @@ -1694,6 +1717,7 @@ pub async fn run() { copy_video_to_clipboard, copy_screenshot_to_clipboard, open_file_path, + delete_file, get_video_metadata, create_editor_instance, start_playback, @@ -1735,6 +1759,7 @@ pub async fn run() { RecordingMetaChanged, RecordingStarted, RecordingStopped, + RecordingDeleted, RequestStartRecording, RequestRestartRecording, RequestStopRecording, diff --git a/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx b/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx index f61416f95..dd11928a5 100644 --- a/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx +++ b/apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx @@ -3,6 +3,7 @@ import { For, Show, Suspense, createSignal } from "solid-js"; import { convertFileSrc } from "@tauri-apps/api/core"; import { commands, events } from "~/utils/tauri"; +import { createQueryInvalidate } from "~/utils/events"; type MediaEntry = { id: string; @@ -13,38 +14,52 @@ type MediaEntry = { }; export default function Recordings() { - const fetchRecordings = createQuery(() => ({ - queryKey: ["recordings"], - queryFn: async () => { - const result = await commands - .listRecordings() - .catch( - () => - Promise.resolve([]) as ReturnType + function fetchRecordingsQuery() { + const fetchRecordings = createQuery(() => ({ + queryKey: ["recordings"], + queryFn: async () => { + const result = await commands + .listRecordings() + .catch( + () => + Promise.resolve([]) as ReturnType + ); + + const recordings = await Promise.all( + result.map(async (file) => { + const [id, path, meta] = file; + const thumbnailPath = `${path}/screenshots/display.jpg`; + + return { + id, + path, + prettyName: meta.pretty_name, + isNew: false, + thumbnailPath, + }; + }) ); + return recordings; + }, + staleTime: 0, + })); - const recordings = await Promise.all( - result.map(async (file) => { - const [id, path, meta] = file; - const thumbnailPath = `${path}/screenshots/display.jpg`; + createQueryInvalidate(fetchRecordings, "recordingDeleted"); - return { - id, - path, - prettyName: meta.pretty_name, - isNew: false, - thumbnailPath, - }; - }) - ); - return recordings; - }, - })); + return fetchRecordings; + } - const handleRecordingClick = (recording: MediaEntry) => { + const recordings = fetchRecordingsQuery(); + + const handleOpenRecording = (recording: MediaEntry) => { events.newRecordingAdded.emit({ path: recording.path }); }; + const handleDeleteRecording = (path: string) => { + commands.deleteFile(path); + events.recordingDeleted.emit({ path }); + }; + const handleOpenFolder = (path: string) => { commands.openFilePath(path); }; @@ -60,18 +75,21 @@ export default function Recordings() {
    0} + when={recordings.data && recordings.data.length > 0} fallback={

    No recordings found

    } > - + {(recording) => ( handleRecordingClick(recording)} onOpenFolder={() => handleOpenFolder(recording.path)} onOpenEditor={() => handleOpenEditor(recording.path)} + onOpenRecording={() => handleOpenRecording(recording)} + onDeleteRecording={() => + handleDeleteRecording(recording.path) + } /> )} @@ -84,9 +102,10 @@ export default function Recordings() { function RecordingItem(props: { recording: MediaEntry; - onClick: () => void; onOpenFolder: () => void; onOpenEditor: () => void; + onOpenRecording: () => void; + onDeleteRecording: () => void; }) { const [imageExists, setImageExists] = createSignal(true); @@ -133,12 +152,22 @@ function RecordingItem(props: { type="button" onClick={(e) => { e.stopPropagation(); - props.onClick(); + props.onOpenRecording(); }} class="p-2 hover:bg-gray-200 rounded-full" > +
); diff --git a/apps/desktop/src/utils/tauri.ts b/apps/desktop/src/utils/tauri.ts index 75fac8e70..6ba47b1e4 100644 --- a/apps/desktop/src/utils/tauri.ts +++ b/apps/desktop/src/utils/tauri.ts @@ -68,6 +68,9 @@ async copyScreenshotToClipboard(path: string) : Promise { async openFilePath(path: string) : Promise { return await TAURI_INVOKE("open_file_path", { path }); }, +async deleteFile(path: string) : Promise { + return await TAURI_INVOKE("delete_file", { path }); +}, async getVideoMetadata(videoId: string, videoType: VideoType | null) : Promise<[number, number]> { return await TAURI_INVOKE("get_video_metadata", { videoId, videoType }); }, @@ -171,6 +174,7 @@ editorStateChanged: EditorStateChanged, newNotification: NewNotification, newRecordingAdded: NewRecordingAdded, newScreenshotAdded: NewScreenshotAdded, +recordingDeleted: RecordingDeleted, recordingMetaChanged: RecordingMetaChanged, recordingOptionsChanged: RecordingOptionsChanged, recordingStarted: RecordingStarted, @@ -190,6 +194,7 @@ editorStateChanged: "editor-state-changed", newNotification: "new-notification", newRecordingAdded: "new-recording-added", newScreenshotAdded: "new-screenshot-added", +recordingDeleted: "recording-deleted", recordingMetaChanged: "recording-meta-changed", recordingOptionsChanged: "recording-options-changed", recordingStarted: "recording-started", @@ -252,6 +257,7 @@ export type Plan = { upgraded: boolean; last_checked: number } export type PreCreatedVideo = { id: string; link: string; config: S3UploadMeta } export type ProjectConfiguration = { aspectRatio: AspectRatio | null; background: BackgroundConfiguration; camera: Camera; audio: AudioConfiguration; cursor: CursorConfiguration; hotkeys: HotkeysConfiguration; timeline?: TimelineConfiguration | null; motionBlur: number | null } export type ProjectRecordings = { segments: SegmentRecordings[] } +export type RecordingDeleted = { path: string } export type RecordingInfo = { captureTarget: ScreenCaptureTarget } export type RecordingMeta = ({ segment: SingleSegment } | { inner: MultipleSegments }) & { pretty_name: string; sharing?: SharingMeta | null } export type RecordingMetaChanged = { id: string }