grain.social is a photo sharing platform built on atproto.
1import { PhotoView } from "$lexicon/types/social/grain/photo/defs.ts";
2import { $Typed } from "$lexicon/util.ts";
3import { Button } from "./Button.tsx";
4import { Dialog } from "./Dialog.tsx";
5import { LibaryPhotoSelectDialogButton } from "./LibraryPhotoSelectDialog.tsx";
6import { PhotoSelectButton } from "./PhotoSelectButton.tsx";
7
8export function GalleryEditPhotosDialog({
9 galleryUri,
10 photos,
11}: Readonly<{
12 galleryUri: string;
13 photos: $Typed<PhotoView>[];
14}>) {
15 return (
16 <Dialog id="photo-select-dialog">
17 <Dialog.Content class="flex flex-col gap-4">
18 <Dialog.X class="fill-zinc-950 dark:fill-zinc-50" />
19 <Dialog.Title>Edit photos</Dialog.Title>
20 <div class="flex flex-col gap-4">
21 <form
22 class="w-full flex flex-col gap-4"
23 hx-encoding="multipart/form-data"
24 _="on change from #file-input call Grain.galleryPhotosDialog.uploadPhotos(me)"
25 >
26 <input hidden name="page" value="gallery" />
27 <input hidden name="galleryUri" value={galleryUri} />
28 <Button variant="primary" class="w-full" asChild>
29 <label>
30 <i class="fa-solid fa-cloud-arrow-up mr-2" />
31 Upload photos
32 <input
33 id="file-input"
34 class="hidden"
35 type="file"
36 name="files"
37 multiple
38 accept="image/*"
39 />
40 </label>
41 </Button>
42
43 <label class="block gap-2">
44 <input
45 id="parse-exif"
46 type="checkbox"
47 name="parseExif"
48 class="mr-2 accent-sky-600"
49 checked
50 />
51 Include image metadata (EXIF)
52 <button
53 type="button"
54 hx-get="/dialogs/exif-info"
55 hx-target="#layout"
56 hx-swap="afterbegin"
57 class="cursor-pointer"
58 >
59 <i class="fa fa-info-circle ml-1" />
60 </button>
61 </label>
62 </form>
63 <LibaryPhotoSelectDialogButton galleryUri={galleryUri} />
64 </div>
65 <div class="flex-1 overflow-y-auto">
66 <div id="image-preview" class="grid grid-cols-3 gap-2">
67 {photos.length
68 ? (
69 photos.map((photo) => (
70 <PhotoSelectButton
71 key={photo.cid}
72 galleryUri={galleryUri}
73 photo={photo}
74 />
75 ))
76 )
77 : null}
78 </div>
79 </div>
80 <Dialog.Close variant="secondary" class="w-full">Close</Dialog.Close>
81 </Dialog.Content>
82 </Dialog>
83 );
84}