diff --git a/src/components/shared/AssetGrid.tsx b/src/components/shared/AssetGrid.tsx index 065cf07..fbcd366 100644 --- a/src/components/shared/AssetGrid.tsx +++ b/src/components/shared/AssetGrid.tsx @@ -1,12 +1,13 @@ import "yet-another-react-lightbox/styles.css"; import { IAsset } from '@/types/asset'; -import React, { useEffect, useMemo, useState } from 'react' +import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react' import Lightbox from 'yet-another-react-lightbox'; import { Gallery } from "react-grid-gallery"; import LazyGridImage from "../ui/lazy-grid-image"; import Download from "yet-another-react-lightbox/plugins/download"; import Video from "yet-another-react-lightbox/plugins/video"; +import { usePhotoSelectionContext } from '@/contexts/PhotoSelectionContext'; interface AssetGridProps { @@ -16,10 +17,31 @@ interface AssetGridProps { onSelectionChange?: (ids: string[]) => void; } -export default function AssetGrid({ assets, isInternal = true, selectable = false, onSelectionChange }: AssetGridProps) { +interface AssetGridRef { + getSelectedIds: () => string[]; + selectAll: () => void; + unselectAll: () => void; +} + +const AssetGrid = forwardRef(({ assets, isInternal = true, selectable = false, onSelectionChange }, ref) => { const [index, setIndex] = useState(-1); - const [selectedIds, setSelectedIds] = useState([]); const [lastSelectedIndex, setLastSelectedIndex] = useState(-1); + + // Use context for selection state + const { selectedIds, updateContext } = usePhotoSelectionContext(); + + useImperativeHandle(ref, () => ({ + getSelectedIds: () => selectedIds, + selectAll: () => { + const allIds = assets.map((asset) => asset.id); + updateContext({ selectedIds: allIds }); + onSelectionChange?.(allIds); + }, + unselectAll: () => { + updateContext({ selectedIds: [] }); + onSelectionChange?.([]); + }, + }), [assets, selectedIds, updateContext]); const handleClick = (index: number, asset: IAsset, event: React.MouseEvent) => { @@ -35,8 +57,9 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals event.stopPropagation(); const isPresent = selectedIds.includes(asset.id); if (isPresent) { - setSelectedIds(selectedIds.filter((id) => id !== asset.id)); - onSelectionChange?.(selectedIds.filter((id) => id !== asset.id)); + const newSelectedIds = selectedIds.filter((id) => id !== asset.id); + updateContext({ selectedIds: newSelectedIds }); + onSelectionChange?.(newSelectedIds); } else { const clickedIndex = images.findIndex((image) => { return image.id === asset.id; @@ -44,14 +67,15 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals if (event.shiftKey) { const startIndex = Math.min(clickedIndex, lastSelectedIndex); const endIndex = Math.max(clickedIndex, lastSelectedIndex); - const newSelectedIds = images.slice(startIndex, endIndex + 1).map((image) => image.id); - const allSelectedIds = [...selectedIds, ...newSelectedIds]; + const rangeSelectedIds = images.slice(startIndex, endIndex + 1).map((image) => image.id); + const allSelectedIds = [...selectedIds, ...rangeSelectedIds]; const uniqueSelectedIds = [...new Set(allSelectedIds)]; - setSelectedIds(uniqueSelectedIds); + updateContext({ selectedIds: uniqueSelectedIds }); onSelectionChange?.(uniqueSelectedIds); } else { - setSelectedIds([...selectedIds, asset.id]); - onSelectionChange?.([...selectedIds, asset.id]); + const newSelectedIds = [...selectedIds, asset.id]; + updateContext({ selectedIds: newSelectedIds }); + onSelectionChange?.(newSelectedIds); } setLastSelectedIndex(clickedIndex); } @@ -93,7 +117,7 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals const handleEsc = (event: KeyboardEvent) => { if (event.key === "Escape") { - setSelectedIds([]); + updateContext({ selectedIds: [] }); onSelectionChange?.([]); } }; @@ -122,4 +146,6 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals /> ); -} +}) +AssetGrid.displayName = "AssetGrid"; +export default AssetGrid; diff --git a/src/handlers/api/asset.handler.ts b/src/handlers/api/asset.handler.ts index 7b86638..85667a5 100644 --- a/src/handlers/api/asset.handler.ts +++ b/src/handlers/api/asset.handler.ts @@ -73,7 +73,7 @@ export const getAssetGeoHeatmap = async (filters: IHeatMapParams) => { } export const deleteAssets = async (ids: string[]) => { - return API.delete(UPDATE_ASSETS_PATH, { ids }); + return API.delete(UPDATE_ASSETS_PATH, { ids, force: true }); } export interface IEmptyVideosParams { diff --git a/src/pages/albums/potential-albums.tsx b/src/pages/albums/potential-albums.tsx index 322559a..98fe253 100644 --- a/src/pages/albums/potential-albums.tsx +++ b/src/pages/albums/potential-albums.tsx @@ -150,6 +150,7 @@ export default function PotentialAlbums() { {contextState.selectedIds.length} Selected

+ {contextState.selectedIds.length === contextState.assets.length ? ( - - + )}
diff --git a/src/pages/assets/empty-videos.tsx b/src/pages/assets/empty-videos.tsx index 5daae3b..e0b1e6b 100644 --- a/src/pages/assets/empty-videos.tsx +++ b/src/pages/assets/empty-videos.tsx @@ -22,6 +22,7 @@ export default function EmptyVideosPage() { const [assets, setAssets] = useState([]) const [loading, setLoading] = useState(false) const [errorMessage, setErrorMessage] = useState('') + // Initialize filters from URL params or defaults const getInitialFilters = () => {