From b26ceff44d40421685ab42471a557f6a35112cfd Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sun, 7 Apr 2024 14:35:45 -0600 Subject: [PATCH] Add ability to search exports (#10850) * Add ability to search exports * Fix export saving --- web/src/components/card/ExportCard.tsx | 10 ++- web/src/components/overlay/ExportDialog.tsx | 11 +-- .../overlay/MobileReviewSettingsDrawer.tsx | 11 +-- web/src/pages/Export.tsx | 67 ++++++++++++++----- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/web/src/components/card/ExportCard.tsx b/web/src/components/card/ExportCard.tsx index 7431781ea..5ebd4be80 100644 --- a/web/src/components/card/ExportCard.tsx +++ b/web/src/components/card/ExportCard.tsx @@ -12,6 +12,7 @@ import { Input } from "../ui/input"; import useKeyboardListener from "@/hooks/use-keyboard-listener"; type ExportProps = { + className: string; file: { name: string; }; @@ -19,7 +20,12 @@ type ExportProps = { onDelete: (file: string) => void; }; -export default function ExportCard({ file, onRename, onDelete }: ExportProps) { +export default function ExportCard({ + className, + file, + onRename, + onDelete, +}: ExportProps) { const videoRef = useRef(null); const [hovered, setHovered] = useState(false); const [playing, setPlaying] = useState(false); @@ -94,7 +100,7 @@ export default function ExportCard({ file, onRename, onDelete }: ExportProps) {
setHovered(true) : undefined } diff --git a/web/src/components/overlay/ExportDialog.tsx b/web/src/components/overlay/ExportDialog.tsx index 6468c2d16..924de2ffa 100644 --- a/web/src/components/overlay/ExportDialog.tsx +++ b/web/src/components/overlay/ExportDialog.tsx @@ -64,10 +64,13 @@ export default function ExportDialog({ } axios - .post(`export/${camera}/start/${range.after}/end/${range.before}`, { - playback: "realtime", - name, - }) + .post( + `export/${camera}/start/${Math.round(range.after)}/end/${Math.round(range.before)}`, + { + playback: "realtime", + name, + }, + ) .then((response) => { if (response.status == 200) { toast.success( diff --git a/web/src/components/overlay/MobileReviewSettingsDrawer.tsx b/web/src/components/overlay/MobileReviewSettingsDrawer.tsx index 26c6d9bbc..da5c6ec6a 100644 --- a/web/src/components/overlay/MobileReviewSettingsDrawer.tsx +++ b/web/src/components/overlay/MobileReviewSettingsDrawer.tsx @@ -66,10 +66,13 @@ export default function MobileReviewSettingsDrawer({ } axios - .post(`export/${camera}/start/${range.after}/end/${range.before}`, { - playback: "realtime", - name, - }) + .post( + `export/${camera}/start/${Math.round(range.after)}/end/${Math.round(range.before)}`, + { + playback: "realtime", + name, + }, + ) .then((response) => { if (response.status == 200) { toast.success( diff --git a/web/src/pages/Export.tsx b/web/src/pages/Export.tsx index a5f775419..dfd524e44 100644 --- a/web/src/pages/Export.tsx +++ b/web/src/pages/Export.tsx @@ -10,8 +10,9 @@ import { AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; import axios from "axios"; -import { useCallback, useState } from "react"; +import { useCallback, useMemo, useState } from "react"; import useSWR from "swr"; type ExportItem = { @@ -19,24 +20,30 @@ type ExportItem = { }; function Export() { - const { data: exports, mutate } = useSWR( + const { data: allExports, mutate } = useSWR( "exports/", (url: string) => axios({ baseURL: baseUrl, url }).then((res) => res.data), ); - const [deleteClip, setDeleteClip] = useState(); + // Search - const onHandleRename = useCallback( - (original: string, update: string) => { - axios.patch(`export/${original}/${update}`).then((response) => { - if (response.status == 200) { - setDeleteClip(undefined); - mutate(); - } - }); - }, - [mutate], - ); + const [search, setSearch] = useState(""); + + const exports = useMemo(() => { + if (!search || !allExports) { + return allExports; + } + + return allExports.filter((exp) => + exp.name + .toLowerCase() + .includes(search.toLowerCase().replaceAll(" ", "_")), + ); + }, [allExports, search]); + + // Deleting + + const [deleteClip, setDeleteClip] = useState(); const onHandleDelete = useCallback(() => { if (!deleteClip) { @@ -51,8 +58,22 @@ function Export() { }); }, [deleteClip, mutate]); + // Renaming + + const onHandleRename = useCallback( + (original: string, update: string) => { + axios.patch(`export/${original}/${update}`).then((response) => { + if (response.status == 200) { + setDeleteClip(undefined); + mutate(); + } + }); + }, + [mutate], + ); + return ( -
+
setDeleteClip(undefined)} @@ -73,12 +94,24 @@ function Export() { +
+ setSearch(e.target.value)} + /> +
+
- {exports && ( + {allExports && exports && (
- {Object.values(exports).map((item) => ( + {Object.values(allExports).map((item) => ( setDeleteClip(file)}