diff --git a/web/src/components/card/SearchThumbnailFooter.tsx b/web/src/components/card/SearchThumbnailFooter.tsx index f4b3474ea..b21361b18 100644 --- a/web/src/components/card/SearchThumbnailFooter.tsx +++ b/web/src/components/card/SearchThumbnailFooter.tsx @@ -33,9 +33,11 @@ import { toast } from "sonner"; import { MdImageSearch } from "react-icons/md"; import { isMobileOnly } from "react-device-detect"; import { buttonVariants } from "../ui/button"; +import { cn } from "@/lib/utils"; type SearchThumbnailProps = { searchResult: SearchResult; + columns: number; findSimilar: () => void; refreshResults: () => void; showObjectLifecycle: () => void; @@ -43,6 +45,7 @@ type SearchThumbnailProps = { export default function SearchThumbnailFooter({ searchResult, + columns, findSimilar, refreshResults, showObjectLifecycle, @@ -114,104 +117,112 @@ export default function SearchThumbnailFooter({ }} /> -
- {searchResult.end_time ? ( - - ) : ( -
- -
+
4 && + "items-start sm:flex-col sm:gap-2 lg:flex-row lg:items-center lg:gap-1", )} - {formattedDate} -
-
- {!isMobileOnly && - config?.plus?.enabled && - searchResult.has_snapshot && - searchResult.end_time && - !searchResult.plus_id && ( + > +
+ {searchResult.end_time ? ( + + ) : ( +
+ +
+ )} + {formattedDate} +
+
+ {!isMobileOnly && + config?.plus?.enabled && + searchResult.has_snapshot && + searchResult.end_time && + !searchResult.plus_id && ( + + + setShowFrigatePlus(true)} + /> + + Submit to Frigate+ + + )} + + {config?.semantic_search?.enabled && ( - setShowFrigatePlus(true)} + onClick={findSimilar} /> - Submit to Frigate+ + Find similar )} - {config?.semantic_search?.enabled && ( - - - - - Find similar - - )} - - - - - - - {searchResult.has_clip && ( - - - - Download video - - - )} - {searchResult.has_snapshot && ( - - - - Download snapshot - - - )} - - - View object lifecycle - - - {isMobileOnly && - config?.plus?.enabled && - searchResult.has_snapshot && - searchResult.end_time && - !searchResult.plus_id && ( - setShowFrigatePlus(true)} - > - - Submit to Frigate+ + + + + + + {searchResult.has_clip && ( + + + + Download video + )} - setDeleteDialogOpen(true)} - > - - Delete - - - + {searchResult.has_snapshot && ( + + + + Download snapshot + + + )} + + + View object lifecycle + + + {isMobileOnly && + config?.plus?.enabled && + searchResult.has_snapshot && + searchResult.end_time && + !searchResult.plus_id && ( + setShowFrigatePlus(true)} + > + + Submit to Frigate+ + + )} + setDeleteDialogOpen(true)} + > + + Delete + + + +
); diff --git a/web/src/components/settings/SearchSettings.tsx b/web/src/components/settings/SearchSettings.tsx index cce43db7f..b3a1e89d3 100644 --- a/web/src/components/settings/SearchSettings.tsx +++ b/web/src/components/settings/SearchSettings.tsx @@ -1,6 +1,6 @@ import { Button } from "../ui/button"; import { useState } from "react"; -import { isDesktop } from "react-device-detect"; +import { isDesktop, isMobileOnly } from "react-device-detect"; import { cn } from "@/lib/utils"; import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog"; import { FaCog } from "react-icons/fa"; @@ -68,26 +68,32 @@ export default function SearchSettings({
- -
-
-
Grid Columns
-
- Select the number of columns in the grid view. + {!isMobileOnly && ( + <> + +
+
+
Grid Columns
+
+ Select the number of columns in the grid view. +
+
+
+ setColumns(value)} + max={6} + min={2} + step={1} + className="flex-grow" + /> + + {columns} + +
-
-
- setColumns(value)} - max={6} - min={2} - step={1} - className="flex-grow" - /> - {columns} -
-
+ + )}
); diff --git a/web/src/pages/Explore.tsx b/web/src/pages/Explore.tsx index 42100d5da..202b079a6 100644 --- a/web/src/pages/Explore.tsx +++ b/web/src/pages/Explore.tsx @@ -14,6 +14,7 @@ import { ModelState } from "@/types/ws"; import { formatSecondsToDuration } from "@/utils/dateUtil"; import SearchView from "@/views/search/SearchView"; import { useCallback, useEffect, useMemo, useState } from "react"; +import { isMobileOnly } from "react-device-detect"; import { LuCheck, LuExternalLink, LuX } from "react-icons/lu"; import { TbExclamationCircle } from "react-icons/tb"; import { Link } from "react-router-dom"; @@ -32,7 +33,12 @@ export default function Explore() { // grid const [columnCount, setColumnCount] = usePersistence("exploreGridColumns", 4); - const gridColumns = useMemo(() => columnCount ?? 4, [columnCount]); + const gridColumns = useMemo(() => { + if (isMobileOnly) { + return 2; + } + return columnCount ?? 4; + }, [columnCount]); // default layout diff --git a/web/src/views/search/SearchView.tsx b/web/src/views/search/SearchView.tsx index c403012c7..665f7a4fd 100644 --- a/web/src/views/search/SearchView.tsx +++ b/web/src/views/search/SearchView.tsx @@ -387,7 +387,7 @@ export default function SearchView({ key={value.id} ref={(item) => (itemRefs.current[index] = item)} data-start={value.start_time} - className="review-item relative rounded-lg" + className="review-item relative flex flex-col rounded-lg" >
-
+
{ if (config?.semantic_search.enabled) { setSimilaritySearch(value);