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 = () => {