Skip to content

Commit 4f94bcf

Browse files
authored
Merge pull request #136 from varun-raj/pre-release
Feb Release
2 parents c5ffba6 + d7d6458 commit 4f94bcf

27 files changed

+498
-222
lines changed

src/components/albums/list/AlbumThumbnail.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default function AlbumThumbnail({ album, onSelect, selected }: IAlbumThum
3636
}}
3737
/>
3838
<div className="absolute bottom-0 w-full bg-gray-800/70 text-white text-center text-xs font-bold py-1 group-hover:hidden">
39-
{formatDate(album.firstPhotoDate.toString(), 'MMM d, yyyy')} - {formatDate(album.lastPhotoDate.toString(), 'MMM d, yyyy')}
39+
{album.firstPhotoDate ? formatDate(album.firstPhotoDate?.toString(), 'MMM d, yyyy') : ''} - {album.lastPhotoDate ? formatDate(album.lastPhotoDate?.toString(), 'MMM d, yyyy') : ''}
4040
</div>
4141
<Checkbox
4242
defaultChecked={isSelected}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ArrowDown, ArrowUp, ArrowUpDownIcon, SortAsc, SortDesc } from "lucide-r
1212

1313
export default function PotentialAlbumsDates() {
1414
const router = useRouter();
15-
const { updateContext } = usePotentialAlbumContext();
15+
const { updateContext, minAssets } = usePotentialAlbumContext();
1616
const [dateRecords, setDateRecords] = React.useState<
1717
IPotentialAlbumsDatesResponse[]
1818
>([]);
@@ -26,6 +26,7 @@ export default function PotentialAlbumsDates() {
2626
return listPotentialAlbumsDates({
2727
sortBy: filters.sortBy,
2828
sortOrder: filters.sortOrder,
29+
minAssets,
2930
})
3031
.then(setDateRecords)
3132
.catch(setErrorMessage)
@@ -43,7 +44,7 @@ export default function PotentialAlbumsDates() {
4344

4445
useEffect(() => {
4546
fetchData();
46-
}, [filters]);
47+
}, [filters, minAssets]);
4748

4849
return (
4950
<div className="min-w-[200px] py-4 max-h-[calc(100vh-60px)] min-h-[calc(100vh-60px)] border-r border-gray-200 dark:border-zinc-800 flex flex-col gap-2 px-1">

src/components/assets/missing-location/MissingLocationAssets.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,15 @@ export default function MissingLocationAssets({ groupBy }: IProps) {
8181
[images]
8282
);
8383

84-
const handleClick = (idx: number) => setIndex(idx);
84+
const handleClick = (idx: number, asset: IAsset, event: MouseEvent<HTMLElement>) => {
85+
if (selectedIds.length > 0) {
86+
handleSelect(idx, asset, event);
87+
}
88+
else
89+
{
90+
setIndex(idx);
91+
}
92+
};
8593

8694
const handleSelect = (_idx: number, asset: IAsset, event: MouseEvent<HTMLElement>) => {
8795
event.stopPropagation();

src/components/assets/missing-location/MissingLocationDateItem.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,26 @@ import { useMissingLocationContext } from "@/contexts/MissingLocationContext";
33
import { IMissingLocationDatesResponse } from "@/handlers/api/asset.handler";
44
import { parseDate, formatDate } from "@/helpers/date.helper";
55
import { cn } from "@/lib/utils";
6-
import React, { useMemo } from "react";
6+
import React, { useEffect, useMemo, useRef } from "react";
77

88
interface IProps {
99
record: IMissingLocationDatesResponse;
1010
onSelect: (date: string) => void;
1111
groupBy: "date" | "album";
1212
}
13+
1314
export default function MissingLocationDateItem({ record, onSelect, groupBy }: IProps) {
15+
// Effect to handle scrolling after rendering
16+
useEffect(() => {
17+
if (startDate === record.label) {
18+
itemsRef.current?.scrollIntoView({
19+
behavior: "smooth", // Smooth scrolling
20+
block: "center", // Center the item in the view
21+
});
22+
}
23+
}, []);
24+
25+
const itemsRef = useRef<HTMLDivElement | null>(null);
1426
const { startDate } = useMissingLocationContext()
1527

1628
const dateLabel = useMemo(() => {
@@ -34,9 +46,10 @@ export default function MissingLocationDateItem({ record, onSelect, groupBy }: I
3446
cn("flex gap-1 flex-col p-1 rounded-lg hover:dark:bg-zinc-800 border border-transparent hover:bg-zinc-100",
3547
startDate === record.label ? "bg-zinc-100 dark:bg-zinc-800 border-gray-300 dark:border-zinc-700" : "")
3648
}
49+
ref={itemsRef}
3750
>
3851
<p className="text-sm truncate">{dateLabel}</p>
39-
<p className="text-xs text-foreground/50">{record.asset_count} Orphan Assets</p>
52+
<p className="text-xs text-foreground/50">{record.asset_count} Assets</p>
4053
</div>
4154
);
4255
}

src/components/assets/missing-location/MissingLocationDates.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,21 @@ interface IMissingLocationDatesProps {
1313

1414
}
1515
export default function MissingLocationDates({ groupBy }: IMissingLocationDatesProps) {
16-
const { updateContext } = useMissingLocationContext();
16+
const { dates, updateContext } = useMissingLocationContext();
1717
const router = useRouter();
18-
const [dateRecords, setDateRecords] = React.useState<
19-
IMissingLocationDatesResponse[]
20-
>([]);
2118
const [filters, setFilters] = useState<{ sortBy: string, sortOrder: string }>({ sortBy: "date", sortOrder: "desc" });
2219
const [loading, setLoading] = useState(false);
2320

2421
const [errorMessage, setErrorMessage] = useState<string | null>(null);
2522

2623
const fetchData = async () => {
2724
const func = groupBy === "album" ? listMissingLocationAlbums : listMissingLocationDates
28-
setDateRecords([])
25+
updateContext({ dates: [] })
2926
return func({
3027
sortBy: filters.sortBy,
3128
sortOrder: filters.sortOrder,
3229
})
33-
.then(setDateRecords)
30+
.then((r) => updateContext({ dates: r }))
3431
.catch(setErrorMessage)
3532
.finally(() => setLoading(false));
3633
};
@@ -96,7 +93,7 @@ export default function MissingLocationDates({ groupBy }: IMissingLocationDatesP
9693
</div>
9794
</div>
9895
<div className="overflow-y-auto flex flex-col gap-2">
99-
{dateRecords.map((record) => (
96+
{dates.map((record) => (
10097
<MissingLocationDateItem
10198
key={record.value}
10299
record={record}

src/components/assets/missing-location/TagMissingLocationDialog/TagMissingLocationDialog.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ export default function TagMissingLocationDialog({
4646
Tagging a location will add the location to the selected assets.
4747
</DialogDescription>
4848
</DialogHeader>
49-
<Tabs defaultValue="search" className="border rounded-lg">
49+
<Tabs defaultValue="searchOsm" className="border rounded-lg">
5050
<TabsList className="flex justify-between">
51-
<TabsTrigger value="search">Immich Search</TabsTrigger>
52-
<TabsTrigger value="searchOsm">OSM Search</TabsTrigger>
53-
<TabsTrigger value="latlong">Lat &amp; Long</TabsTrigger>
54-
<TabsTrigger value="maps">Map</TabsTrigger>
51+
<TabsTrigger value="searchOsm" className="w-full">Open Street Map</TabsTrigger>
52+
<TabsTrigger value="search" className="w-full">Immich Geo</TabsTrigger>
53+
<TabsTrigger value="latlong" className="w-full">Lat &amp; Long</TabsTrigger>
54+
<TabsTrigger value="maps" className="w-full">Map</TabsTrigger>
5555
</TabsList>
56-
<TabsContent value="search">
57-
<TagMissingLocationSearchAndAdd onSubmit={onSubmit} onOpenChange={setOpen} />
58-
</TabsContent>
5956
<TabsContent value="searchOsm">
6057
<TagMissingLocationOSMSearchAndAdd onSubmit={onSubmit} onOpenChange={setOpen} location={mapPosition} onLocationChange={setMapPosition} />
6158
</TabsContent>
59+
<TabsContent value="search">
60+
<TagMissingLocationSearchAndAdd onSubmit={onSubmit} onOpenChange={setOpen} />
61+
</TabsContent>
6262
<TabsContent value="latlong">
6363
<TagMissingLocationSearchLatLong onSubmit={onSubmit} onOpenChange={setOpen} location={mapPosition} onLocationChange={setMapPosition} />
6464
</TabsContent>

src/components/assets/missing-location/TagMissingLocationDialog/TagMissingLocationOSMSearchAndAdd.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ export default function TagMissingLocationOSMSearchAndAdd(
9696
setSelectedPlace(null);
9797
} else {
9898
setSelectedPlace(place);
99-
debugger;
10099
onLocationChange(place);
101100
}
102101
};
@@ -132,15 +131,12 @@ export default function TagMissingLocationOSMSearchAndAdd(
132131

133132
return (
134133
<div className="flex flex-col gap-4 py-4 px-2">
135-
<div className="flex flex-col gap-2">
136-
<Label>Search Location</Label>
137134
<Input
138135
placeholder="Search location"
139136
onChange={(e) => {
140137
handleSearch(e.target.value);
141138
}}
142139
/>
143-
</div>
144140
<div>
145141
{loading && <Loader />}
146142
{!loading && searchedPlaces && searchedPlaces.length === 0 && (
@@ -153,21 +149,21 @@ export default function TagMissingLocationOSMSearchAndAdd(
153149
key={place.name}
154150
onClick={() => handleSelect(place)}
155151
className={cn(
156-
"hover:bg-gray-300 flex justify-between items-center px-2 py-1 rounded-lg cursor-pointer",
152+
"hover:bg-gray-300 dark:hover:bg-gray-700 flex justify-between items-center px-2 py-1 rounded-lg cursor-pointer",
157153
{
158-
"bg-gray-300":
154+
"bg-gray-300 dark:bg-gray-700":
159155
selectedPlace && selectedPlace.name === place.name,
160156
}
161157
)}
162158
>
163159
<div>
164-
<p>{place.name}</p>
165-
<span className="text-xs text-gray-600">
160+
<p className="text-sm">{place.name}</p>
161+
<span className="text-xs text-gray-600 dark:text-gray-400">
166162
{place.latitude}, {place.longitude}
167163
</span>
168164
</div>
169165
{selectedPlace && selectedPlace.name === place.name && (
170-
<Check className="text-green-500" />
166+
<Check className="text-green-500 dark:text-green-400" />
171167
)}
172168
</div>
173169
))}
@@ -176,11 +172,11 @@ export default function TagMissingLocationOSMSearchAndAdd(
176172
</div>
177173
<div className="self-end">
178174
<Button
179-
variant="outline"
175+
variant="default"
180176
onClick={handleSubmit}
181177
disabled={!selectedPlace || submitting}
182178
>
183-
Add New Location
179+
Tag Location
184180
</Button>
185181
</div>
186182
</div>

src/components/assets/missing-location/TagMissingLocationDialog/TagMissingLocationSearchAndAdd.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ export default function TagMissingLocationSearchAndAdd(
9696
return (
9797
<div className="flex flex-col gap-4 py-4 px-2">
9898
<div className="flex flex-col gap-2">
99-
<Label>Search Location</Label>
10099
<Input
101100
placeholder="Search location"
102101
onChange={(e) => {
@@ -116,21 +115,21 @@ export default function TagMissingLocationSearchAndAdd(
116115
key={place.name}
117116
onClick={() => handleSelect(place)}
118117
className={cn(
119-
"hover:bg-zinc-900 flex justify-between items-center px-2 py-1 rounded-lg cursor-pointer",
118+
"hover:bg-zinc-200 dark:hover:bg-zinc-800 flex justify-between items-center px-2 py-1 rounded-lg cursor-pointer",
120119
{
121-
"bg-zinc-900":
120+
"bg-zinc-900 dark:bg-zinc-200":
122121
selectedPlace && selectedPlace.name === place.name,
123122
}
124123
)}
125124
>
126125
<div>
127126
<p>{place.name}</p>
128-
<span className="text-xs text-gray-600">
127+
<span className="text-xs text-gray-600 dark:text-gray-200">
129128
{place.latitude}, {place.longitude}
130129
</span>
131130
</div>
132131
{selectedPlace && selectedPlace.name === place.name && (
133-
<Check className="text-green-500" />
132+
<Check className="text-green-500 dark:text-green-400" />
134133
)}
135134
</div>
136135
))}
@@ -139,11 +138,11 @@ export default function TagMissingLocationSearchAndAdd(
139138
</div>
140139
<div className="self-end">
141140
<Button
142-
variant="outline"
141+
variant="default"
143142
onClick={handleSubmit}
144143
disabled={!selectedPlace || submitting}
145144
>
146-
Add New Location
145+
Tag Location
147146
</Button>
148147
</div>
149148
</div>

src/components/people/PeopleFilters.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,27 @@ import {
1515
import { Input } from "../ui/input";
1616
import { IPersonListFilters } from "@/handlers/api/people.handler";
1717
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select";
18+
import { removeNullOrUndefinedProperties } from "@/helpers/data.helper";
19+
import { ParsedUrlQueryInput } from "querystring";
1820

1921
export function PeopleFilters() {
2022
const router = useRouter();
21-
const { updateContext, page, maximumAssetCount, type = "all", query ="" } = usePeopleFilterContext();
23+
const { updateContext, page, maximumAssetCount, type = "all", query = "", visibility = "all" } = usePeopleFilterContext();
2224

2325
const handleChange = (data: Partial<IPersonListFilters>) => {
2426
updateContext(data);
2527
router.push({
2628
pathname: router.pathname,
27-
query: {
29+
query: {
2830
...router.query,
29-
...data,
31+
...data,
3032
page: data.page || undefined,
3133
type: data.type || undefined,
34+
visibility: data.visibility || undefined,
35+
query: data.query || undefined,
36+
maximumAssetCount: data.maximumAssetCount || undefined,
37+
sort: data.sort || undefined,
38+
sortOrder: data.sortOrder || undefined,
3239
},
3340
});
3441
}
@@ -73,6 +80,17 @@ export function PeopleFilters() {
7380
</SelectContent>
7481
</Select>
7582

83+
<Select value={visibility} onValueChange={(value) => handleChange({ visibility: value as "all" | "visible" | "hidden" })}>
84+
<SelectTrigger>
85+
<SelectValue placeholder="Visibility" />
86+
</SelectTrigger>
87+
<SelectContent>
88+
<SelectItem value="all">All</SelectItem>
89+
<SelectItem value="visible">Visible</SelectItem>
90+
<SelectItem value="hidden">Hidden</SelectItem>
91+
</SelectContent>
92+
</Select>
93+
7694
<Button
7795
disabled={prevPage < 1}
7896
onClick={() => handleChange({ page: prevPage })}

src/components/people/PersonItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export default function PersonItem({ person, onRemove }: IProps) {
107107
<Button variant="outline" className="!py-0.5 !px-2 text-xs h-7" onClick={() => {
108108
handleHide(!formData.isHidden);
109109
}}>
110-
Hide
110+
{formData.isHidden ? "Show" : "Hide"}
111111
</Button>
112112
<ShareAssetsTrigger filters={{ personIds: [person.id] }} buttonProps={{ variant: "outline", className: "!py-0.5 !px-2 text-xs h-7" }} />
113113
</div>

0 commit comments

Comments
 (0)