Skip to content

Commit 6b1523d

Browse files
authored
Merge pull request #13 from varun-raj/feat-smart-merge
Feat: Smart Merge
2 parents 87f7bc4 + 82510b8 commit 6b1523d

37 files changed

+1108
-167
lines changed

.env.sample

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
IMMICH_URL="" # Immich URL
22
IMMICH_API_KEY="" # Immich API Key
33
DB_USERNAME="" # Postgress Database Username
4-
DB_PASSWORD = "" # Postgres Database Password
5-
DB_HOST = "" # Postgres Host (IP address or hostname of the database)
6-
DB_PORT = "" # Postgres Port number (Default: 5432)
7-
DB_DATABASE_NAME = "" # Name of the database
4+
DB_PASSWORD="" # Postgres Database Password
5+
DB_HOST="" # Postgres Host (IP address or hostname of the database)
6+
DB_PORT="" # Postgres Port number (Default: 5432)
7+
DB_DATABASE_NAME="" # Name of the database

src/components/albums/potential-albums/PotentialAlbumsAssets.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export default function PotentialAlbumsAssets() {
3737
isSelected: selectedIds.includes(p.id),
3838
}));
3939
}, [assets, selectedIds]);
40-
console.log(images)
4140

4241
const slides = useMemo(
4342
() =>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import "yet-another-react-lightbox/styles.css";
2+
import { usePotentialAlbumContext } from "@/contexts/PotentialAlbumContext";
3+
import { listPotentialAlbumsAssets } from "@/handlers/api/album.handler";
4+
import { IAsset } from "@/types/asset";
5+
import React, { useEffect, useMemo, useState } from "react";
6+
import { Gallery } from "react-grid-gallery";
7+
import Lightbox from "yet-another-react-lightbox";
8+
import Captions from "yet-another-react-lightbox/plugins/captions";
9+
import { CalendarArrowDown, CalendarArrowUp, Hourglass } from "lucide-react";
10+
import { useMissingLocationContext } from "@/contexts/MissingLocationContext";
11+
import { listMissingLocationAssets } from "@/handlers/api/asset.handler";
12+
import { formatDate, parseDate } from "@/helpers/date.helper";
13+
import { addDays } from "date-fns";
14+
15+
export default function MissingLocationAssets() {
16+
const { startDate, selectedIds, assets, updateContext } = useMissingLocationContext();
17+
18+
const [loading, setLoading] = useState(false);
19+
const [errorMessage, setErrorMessage] = useState<string | null>(null);
20+
21+
const [index, setIndex] = useState(-1);
22+
23+
const fetchAssets = async () => {
24+
if (!startDate) return;
25+
setLoading(true);
26+
updateContext({
27+
assets: [],
28+
})
29+
return listMissingLocationAssets({ startDate })
30+
.then((assets) => updateContext({ assets }))
31+
.catch(setErrorMessage)
32+
.finally(() => setLoading(false));
33+
};
34+
35+
const images = useMemo(() => {
36+
return assets.map((p) => ({
37+
...p,
38+
src: p.url as string,
39+
original: p.previewUrl as string,
40+
width: p.exifImageWidth as number,
41+
height: p.exifImageHeight as number,
42+
isSelected: selectedIds.includes(p.id),
43+
}));
44+
}, [assets, selectedIds]);
45+
46+
const slides = useMemo(
47+
() =>
48+
images.map(({ original, width, height }) => ({
49+
src: original,
50+
width,
51+
height,
52+
})),
53+
[images]
54+
);
55+
56+
const handleClick = (idx: number) => setIndex(idx);
57+
58+
const handleSelect = (_idx: number, asset: IAsset) => {
59+
const isPresent =selectedIds.includes(asset.id)
60+
if(isPresent){
61+
updateContext({selectedIds:selectedIds.filter((id)=>id!==asset.id)})
62+
}
63+
else{
64+
updateContext({selectedIds:[...selectedIds,asset.id]})
65+
}
66+
67+
};
68+
69+
useEffect(() => {
70+
if (startDate) fetchAssets();
71+
}, [startDate]);
72+
73+
if (loading) return (
74+
<div className="flex flex-col gap-2 h-full justify-center items-center w-full">
75+
<Hourglass />
76+
<p className="text-lg">Loading...</p>
77+
</div>
78+
)
79+
80+
if (!startDate) return (
81+
<div className="flex flex-col gap-2 h-full justify-center items-center w-full">
82+
<CalendarArrowUp />
83+
<p className="text-lg">Please select a date</p>
84+
<p className="text-sm">
85+
When you select a date from the left, you will see all the orphan assets captured on that date
86+
</p>
87+
</div>
88+
)
89+
return (
90+
<>
91+
<Lightbox
92+
slides={slides}
93+
plugins={[Captions]}
94+
open={index >= 0}
95+
index={index}
96+
close={() => setIndex(-1)}
97+
/>
98+
<div className="w-full overflow-y-auto max-h-[calc(100vh-60px)]">
99+
<Gallery
100+
images={images}
101+
onClick={handleClick}
102+
enableImageSelection={true}
103+
onSelect={handleSelect}
104+
105+
/>
106+
</div>
107+
</>
108+
);
109+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useMissingLocationContext } from "@/contexts/MissingLocationContext";
2+
3+
import { IMissingLocationDatesResponse } from "@/handlers/api/asset.handler";
4+
import { cn } from "@/lib/utils";
5+
import React from "react";
6+
7+
interface IProps {
8+
record: IMissingLocationDatesResponse;
9+
onSelect: (date: string) => void;
10+
}
11+
export default function MissingLocationDateItem({ record, onSelect }: IProps) {
12+
const { startDate } = useMissingLocationContext()
13+
return (
14+
<div
15+
role="button"
16+
onClick={() => onSelect(record.date)}
17+
key={record.date}
18+
className={
19+
cn("flex gap-1 flex-col p-2 py-1 rounded-lg hover:dark:bg-zinc-800 border border-transparent hover:bg-zinc-100 px-4",
20+
startDate === record.date ? "bg-zinc-100 dark:bg-zinc-800 border-gray-300 dark:border-zinc-700" : "")
21+
}
22+
>
23+
<p className="font-mono text-sm">{record.date}</p>
24+
<p className="text-xs">{record.asset_count} W/O Location</p>
25+
</div>
26+
);
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { use, useEffect, useState } from "react";
2+
import { usePotentialAlbumContext } from "@/contexts/PotentialAlbumContext";
3+
import { IMissingLocationDatesResponse, listMissingLocationDates } from "@/handlers/api/asset.handler";
4+
import MissingLocationDateItem from "./MissingLocationDateItem";
5+
import { useMissingLocationContext } from "@/contexts/MissingLocationContext";
6+
7+
export default function MissingLocationDates() {
8+
const { updateContext } = useMissingLocationContext();
9+
const [dateRecords, setDateRecords] = React.useState<
10+
IMissingLocationDatesResponse[]
11+
>([]);
12+
13+
const [loading, setLoading] = useState(false);
14+
15+
const [errorMessage, setErrorMessage] = useState<string | null>(null);
16+
17+
const fetchData = async () => {
18+
return listMissingLocationDates({})
19+
.then(setDateRecords)
20+
.catch(setErrorMessage)
21+
.finally(() => setLoading(false));
22+
};
23+
24+
const handleSelect = (date: string) => {
25+
updateContext({ startDate: date });
26+
};
27+
28+
useEffect(() => {
29+
fetchData();
30+
}, []);
31+
32+
return (
33+
<div className="overflow-y-auto min-w-[170px] py-4 max-h-[calc(100vh-60px)] min-h-[calc(100vh-60px)] dark:bg-zinc-900 bg-gray-200 flex flex-col gap-2 px-2">
34+
{dateRecords.map((record) => (
35+
<MissingLocationDateItem
36+
key={record.date}
37+
record={record}
38+
onSelect={handleSelect}
39+
/>
40+
))}
41+
</div>
42+
);
43+
}

src/components/people/PeopleList.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export default function PeopleList() {
3838

3939
const handleRemove = (person: IPerson) => {
4040
setPeople((prev) => prev.filter((p) => {
41-
console.log(p.id, person.id, p.id !== person.id);
4241
return p.id !== person.id
4342
}));
4443
}
@@ -48,7 +47,6 @@ export default function PeopleList() {
4847
fetchData();
4948
}, [filters]);
5049

51-
console.log(people.length);
5250

5351
const renderContent = () => {
5452
if (loading) return <Loader />;

0 commit comments

Comments
 (0)