Skip to content

Commit

Permalink
[wip] feat: add delete prev recording feat in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
sbeaury committed Nov 26, 2024
1 parent aae824c commit f66a562
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 30 deletions.
25 changes: 25 additions & 0 deletions apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -1735,6 +1759,7 @@ pub async fn run() {
RecordingMetaChanged,
RecordingStarted,
RecordingStopped,
RecordingDeleted,
RequestStartRecording,
RequestRestartRecording,
RequestStopRecording,
Expand Down
89 changes: 59 additions & 30 deletions apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<typeof commands.listRecordings>
function fetchRecordingsQuery() {
const fetchRecordings = createQuery(() => ({
queryKey: ["recordings"],
queryFn: async () => {
const result = await commands
.listRecordings()
.catch(
() =>
Promise.resolve([]) as ReturnType<typeof commands.listRecordings>
);

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);
};
Expand All @@ -60,18 +75,21 @@ export default function Recordings() {
<div class="flex-1 overflow-y-auto">
<ul class="p-[0.625rem] flex flex-col gap-[0.5rem] w-full text-[--text-primary]">
<Show
when={fetchRecordings.data && fetchRecordings.data.length > 0}
when={recordings.data && recordings.data.length > 0}
fallback={
<p class="text-center text-[--text-tertiary]">No recordings found</p>
}
>
<For each={fetchRecordings.data}>
<For each={recordings.data}>
{(recording) => (
<RecordingItem
recording={recording}
onClick={() => handleRecordingClick(recording)}
onOpenFolder={() => handleOpenFolder(recording.path)}
onOpenEditor={() => handleOpenEditor(recording.path)}
onOpenRecording={() => handleOpenRecording(recording)}
onDeleteRecording={() =>
handleDeleteRecording(recording.path)
}
/>
)}
</For>
Expand All @@ -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);

Expand Down Expand Up @@ -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"
>
<IconLucideEye class="size-5" />
</button>
<button
type="button"
onClick={(e) => {
e.stopPropagation();
props.onDeleteRecording();
}}
class="p-2 hover:bg-gray-200 rounded-full"
>
<IconCapTrash class="size-5" />
</button>
</div>
</li>
);
Expand Down
6 changes: 6 additions & 0 deletions apps/desktop/src/utils/tauri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ async copyScreenshotToClipboard(path: string) : Promise<null> {
async openFilePath(path: string) : Promise<null> {
return await TAURI_INVOKE("open_file_path", { path });
},
async deleteFile(path: string) : Promise<null> {
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 });
},
Expand Down Expand Up @@ -171,6 +174,7 @@ editorStateChanged: EditorStateChanged,
newNotification: NewNotification,
newRecordingAdded: NewRecordingAdded,
newScreenshotAdded: NewScreenshotAdded,
recordingDeleted: RecordingDeleted,
recordingMetaChanged: RecordingMetaChanged,
recordingOptionsChanged: RecordingOptionsChanged,
recordingStarted: RecordingStarted,
Expand All @@ -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",
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit f66a562

Please sign in to comment.