Skip to content

Commit 8980d72

Browse files
Fix index error
1 parent 67d2434 commit 8980d72

6 files changed

Lines changed: 79 additions & 89 deletions

File tree

frontend/src/components/Media/ChronologicalGallery.tsx

Lines changed: 73 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { useMemo, useRef, useEffect, useCallback } from 'react';
2-
import { useDispatch } from 'react-redux';
2+
import { useDispatch, useSelector } from 'react-redux';
33
import { ImageCard } from '@/components/Media/ImageCard';
44
import { Image } from '@/types/Media';
55
import { groupImagesByYearMonthFromMetadata } from '@/utils/dateUtils';
66
import { setCurrentViewIndex } from '@/features/imageSlice';
7+
import { MediaView } from './MediaView';
8+
import { selectIsImageViewOpen } from '@/features/imageSelectors';
79

810
export type MonthMarker = {
911
offset: number;
@@ -31,6 +33,7 @@ export const ChronologicalGallery = ({
3133
const dispatch = useDispatch();
3234
const monthHeaderRefs = useRef<Map<string, HTMLDivElement | null>>(new Map());
3335
const galleryRef = useRef<HTMLDivElement>(null);
36+
const isImageViewOpen = useSelector(selectIsImageViewOpen);
3437

3538
// Optimized grouping with proper date handling
3639
const grouped = useMemo(
@@ -109,72 +112,76 @@ export const ChronologicalGallery = ({
109112
}, [recomputeMarkers, scrollContainerRef]);
110113

111114
return (
112-
<div ref={galleryRef} className={`space-y-0 ${className}`}>
113-
{/* Title */}
114-
{showTitle && (
115-
<div className="mb-6">
116-
<h1 className="mt-6 text-2xl font-bold">{title}</h1>
117-
</div>
118-
)}
119-
120-
{/* Gallery Content */}
121-
{sortedGrouped.map(({ year, months }) => (
122-
<div key={year} data-year={year}>
123-
{months.map(([month, imgs]) => {
124-
const monthName = new Date(
125-
Number(year),
126-
Number(month) - 1,
127-
).toLocaleString('default', { month: 'long' });
128-
129-
return (
130-
<div
131-
key={`${year}-${month}`}
132-
className="mb-8"
133-
data-timeline-month={`${year}-${month}`}
134-
id={`timeline-section-${year}-${month}`}
135-
ref={(el) => {
136-
const key = `${year}-${month}`;
137-
if (el) {
138-
monthHeaderRefs.current.set(key, el);
139-
} else {
140-
monthHeaderRefs.current.delete(key);
141-
}
142-
}}
143-
>
144-
{/* Sticky Month/Year Header */}
145-
<div className="bg-background sticky top-0 z-10 py-3 backdrop-blur-sm">
146-
<h3 className="flex items-center text-xl font-semibold text-gray-800 dark:text-gray-200">
147-
<div className="bg-primary mr-2 h-6 w-1"></div>
148-
{monthName} {year}
149-
<div className="mt-1 ml-2 text-sm font-normal text-gray-500">
150-
{imgs.length} {imgs.length === 1 ? 'image' : 'images'}
151-
</div>
152-
</h3>
153-
</div>
154-
155-
{/* Images Grid */}
156-
<div className="grid grid-cols-[repeat(auto-fill,_minmax(224px,_1fr))] gap-4 p-2">
157-
{imgs.map((img) => {
158-
const chronologicalIndex = imageIndexMap.get(img.id) ?? -1;
159-
160-
return (
161-
<div key={img.id} className="group relative">
162-
<ImageCard
163-
image={img}
164-
onClick={() =>
165-
dispatch(setCurrentViewIndex(chronologicalIndex))
166-
}
167-
className="w-full transition-transform duration-200 group-hover:scale-105"
168-
/>
115+
<>
116+
<div ref={galleryRef} className={`space-y-0 ${className}`}>
117+
{/* Title */}
118+
{showTitle && (
119+
<div className="mb-6">
120+
<h1 className="mt-6 text-2xl font-bold">{title}</h1>
121+
</div>
122+
)}
123+
124+
{/* Gallery Content */}
125+
{sortedGrouped.map(({ year, months }) => (
126+
<div key={year} data-year={year}>
127+
{months.map(([month, imgs]) => {
128+
const monthName = new Date(
129+
Number(year),
130+
Number(month) - 1,
131+
).toLocaleString('default', { month: 'long' });
132+
133+
return (
134+
<div
135+
key={`${year}-${month}`}
136+
className="mb-8"
137+
data-timeline-month={`${year}-${month}`}
138+
id={`timeline-section-${year}-${month}`}
139+
ref={(el) => {
140+
const key = `${year}-${month}`;
141+
if (el) {
142+
monthHeaderRefs.current.set(key, el);
143+
} else {
144+
monthHeaderRefs.current.delete(key);
145+
}
146+
}}
147+
>
148+
{/* Sticky Month/Year Header */}
149+
<div className="bg-background sticky top-0 z-10 py-3 backdrop-blur-sm">
150+
<h3 className="flex items-center text-xl font-semibold text-gray-800 dark:text-gray-200">
151+
<div className="bg-primary mr-2 h-6 w-1"></div>
152+
{monthName} {year}
153+
<div className="mt-1 ml-2 text-sm font-normal text-gray-500">
154+
{imgs.length} {imgs.length === 1 ? 'image' : 'images'}
169155
</div>
170-
);
171-
})}
156+
</h3>
157+
</div>
158+
159+
{/* Images Grid */}
160+
<div className="grid grid-cols-[repeat(auto-fill,_minmax(224px,_1fr))] gap-4 p-2">
161+
{imgs.map((img) => {
162+
const chronologicalIndex =
163+
imageIndexMap.get(img.id) ?? -1;
164+
165+
return (
166+
<div key={img.id} className="group relative">
167+
<ImageCard
168+
image={img}
169+
onClick={() =>
170+
dispatch(setCurrentViewIndex(chronologicalIndex))
171+
}
172+
className="w-full transition-transform duration-200 group-hover:scale-105"
173+
/>
174+
</div>
175+
);
176+
})}
177+
</div>
172178
</div>
173-
</div>
174-
);
175-
})}
176-
</div>
177-
))}
178-
</div>
179+
);
180+
})}
181+
</div>
182+
))}
183+
</div>
184+
{isImageViewOpen && <MediaView images={chronologicallySortedImages} />}
185+
</>
179186
);
180187
};

frontend/src/components/Media/MediaView.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { useState, useCallback, useMemo, useRef } from 'react';
22
import { useSelector, useDispatch } from 'react-redux';
33
import { revealItemInDir } from '@tauri-apps/plugin-opener';
44
import { MediaViewProps } from '@/types/Media';
5-
import {
6-
selectCurrentViewIndex,
7-
selectImages,
8-
} from '@/features/imageSelectors';
5+
import { selectCurrentViewIndex } from '@/features/imageSelectors';
96
import { setCurrentViewIndex, closeImageView } from '@/features/imageSlice';
107

118
// Modular components
@@ -23,11 +20,10 @@ import { useSlideshow } from '@/hooks/useSlideshow';
2320
import { useFavorites } from '@/hooks/useFavorites';
2421
import { useKeyboardNavigation } from '@/hooks/useKeyboardNavigation';
2522

26-
export function MediaView({ onClose, type = 'image' }: MediaViewProps) {
23+
export function MediaView({ onClose, type = 'image', images }: MediaViewProps) {
2724
const dispatch = useDispatch();
2825

2926
// Redux selectors
30-
const images = useSelector(selectImages);
3127
const currentViewIndex = useSelector(selectCurrentViewIndex);
3228
const totalImages = images.length;
3329

frontend/src/pages/AITagging/AITagging.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { useEffect, useRef, useState } from 'react';
22
import { useDispatch, useSelector } from 'react-redux';
3-
import { MediaView } from '@/components/Media/MediaView';
43
import { FaceCollections } from '@/components/FaceCollections';
54
import { Image } from '@/types/Media';
65
import { setImages } from '@/features/imageSlice';
76
import { showLoader, hideLoader } from '@/features/loaderSlice';
8-
import { selectIsImageViewOpen, selectImages } from '@/features/imageSelectors';
7+
import { selectImages } from '@/features/imageSelectors';
98
import { usePictoQuery } from '@/hooks/useQueryExtension';
109
import { fetchAllImages } from '@/api/api-functions';
1110
import {
@@ -17,7 +16,6 @@ import { EmptyAITaggingState } from '@/components/EmptyStates/EmptyAITaggingStat
1716

1817
export const AITagging = () => {
1918
const dispatch = useDispatch();
20-
const isImageViewOpen = useSelector(selectIsImageViewOpen);
2119
const scrollableRef = useRef<HTMLDivElement>(null);
2220
const [monthMarkers, setMonthMarkers] = useState<MonthMarker[]>([]);
2321
const taggedImages = useSelector(selectImages);
@@ -70,9 +68,6 @@ export const AITagging = () => {
7068
<EmptyAITaggingState />
7169
)}
7270
</div>
73-
74-
{/* Media Viewer Modal */}
75-
{isImageViewOpen && <MediaView />}
7671
</div>
7772
{monthMarkers.length > 0 && (
7873
<TimelineScrollbar

frontend/src/pages/Home/Home.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import {
55
MonthMarker,
66
} from '@/components/Media/ChronologicalGallery';
77
import TimelineScrollbar from '@/components/Timeline/TimelineScrollbar';
8-
import { MediaView } from '@/components/Media/MediaView';
98
import { Image } from '@/types/Media';
109
import { setImages } from '@/features/imageSlice';
1110
import { showLoader, hideLoader } from '@/features/loaderSlice';
12-
import { selectImages, selectIsImageViewOpen } from '@/features/imageSelectors';
11+
import { selectImages } from '@/features/imageSelectors';
1312
import { usePictoQuery } from '@/hooks/useQueryExtension';
1413
import { fetchAllImages } from '@/api/api-functions';
1514
import { RootState } from '@/app/store';
@@ -18,7 +17,6 @@ import { EmptyGalleryState } from '@/components/EmptyStates/EmptyGalleryState';
1817

1918
export const Home = () => {
2019
const dispatch = useDispatch();
21-
const isImageViewOpen = useSelector(selectIsImageViewOpen);
2220
const images = useSelector(selectImages);
2321
const scrollableRef = useRef<HTMLDivElement>(null);
2422
const [monthMarkers, setMonthMarkers] = useState<MonthMarker[]>([]);
@@ -53,10 +51,6 @@ export const Home = () => {
5351
}
5452
}, [data, isSuccess, isError, isLoading, dispatch, isSearchActive]);
5553

56-
const handleCloseMediaView = () => {
57-
// MediaView will handle closing via Redux
58-
};
59-
6054
const title =
6155
isSearchActive && images.length > 0
6256
? `Face Search Results (${images.length} found)`
@@ -90,9 +84,6 @@ export const Home = () => {
9084
className="absolute top-0 right-0 h-full w-4"
9185
/>
9286
)}
93-
94-
{/* Media viewer modal */}
95-
{isImageViewOpen && <MediaView onClose={handleCloseMediaView} />}
9687
</div>
9788
);
9889
};

frontend/src/pages/PersonImages/PersonImages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export const PersonImages = () => {
121121
</div>
122122

123123
{/* Media Viewer Modal */}
124-
{isImageViewOpen && <MediaView />}
124+
{isImageViewOpen && <MediaView images={images} />}
125125
</div>
126126
);
127127
};

frontend/src/types/Media.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface ImageGridProps {
3434
export interface MediaViewProps {
3535
onClose?: () => void;
3636
type?: string;
37+
images: Image[];
3738
}
3839

3940
export interface SortingControlsProps {

0 commit comments

Comments
 (0)