grain.social is a photo sharing platform built on atproto. grain.social
atproto photography appview
50
fork

Configure Feed

Select the types of activity you want to include in your feed.

at f2930131d5335ecd8a8711c4d1b8701e8a692852 88 lines 3.2 kB view raw
1import { GalleryView } from "$lexicon/types/social/grain/gallery/defs.ts"; 2import { isPhotoView } from "$lexicon/types/social/grain/photo/defs.ts"; 3import { AtUri } from "@atproto/syntax"; 4import { ModerationDecsion } from "../lib/moderation.ts"; 5import { CommentsButton } from "../modules/comments.tsx"; 6import { EditGalleryButton } from "./EditGalleryDialog.tsx"; 7import { FavoriteButton } from "./FavoriteButton.tsx"; 8import { GalleryInfo } from "./GalleryInfo.tsx"; 9import { GalleryLayout } from "./GalleryLayout.tsx"; 10import { ModerationWrapper } from "./ModerationWrapper.tsx"; 11import { ShareGalleryDialogButton } from "./ShareGalleryDialog.tsx"; 12 13export function GalleryPage({ 14 gallery, 15 currentUserDid, 16 modDecision, 17}: Readonly<{ 18 gallery: GalleryView; 19 currentUserDid?: string; 20 modDecision?: ModerationDecsion; 21}>) { 22 const isCreator = currentUserDid === gallery.creator.did; 23 const isLoggedIn = !!currentUserDid; 24 const galleryItems = gallery.items?.filter(isPhotoView) ?? []; 25 return ( 26 <div class="px-4" id="gallery-page"> 27 <div id="dialog-target" /> 28 <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between mt-4 mb-2"> 29 <GalleryInfo gallery={gallery} /> 30 {isLoggedIn && isCreator 31 ? ( 32 <div class="flex self-start gap-2 w-full flex-col sm:flex-row sm:justify-end"> 33 <EditGalleryButton gallery={gallery} /> 34 <div class="flex flex-row gap-2 w-full sm:w-fit"> 35 <FavoriteButton class="flex-1" gallery={gallery} /> 36 <CommentsButton class="flex-1" gallery={gallery} /> 37 <ShareGalleryDialogButton class="flex-1" gallery={gallery} /> 38 </div> 39 </div> 40 ) 41 : null} 42 {!isCreator 43 ? ( 44 <div class="flex self-start gap-2 flex-row w-full sm:w-fit"> 45 <FavoriteButton gallery={gallery} /> 46 <CommentsButton class="flex-1" gallery={gallery} /> 47 <ShareGalleryDialogButton class="flex-1" gallery={gallery} /> 48 </div> 49 ) 50 : null} 51 </div> 52 {isLoggedIn && isCreator && gallery.items?.length === 0 53 ? ( 54 <div 55 hx-get={`/dialogs/gallery/${new AtUri(gallery.uri).rkey}/photos`} 56 hx-trigger="load" 57 hx-target="#dialog-target" 58 hx-swap="innerHTML" 59 /> 60 ) 61 : null} 62 { 63 <ModerationWrapper moderationDecision={modDecision} class="mb-2"> 64 <GalleryLayout 65 layoutButtons={ 66 <> 67 <GalleryLayout.ModeButton mode="justified" /> 68 <GalleryLayout.ModeButton mode="masonry" /> 69 </> 70 } 71 > 72 <GalleryLayout.Container> 73 {galleryItems?.length 74 ? galleryItems.map((photo) => ( 75 <GalleryLayout.Item 76 key={photo.cid} 77 photo={photo} 78 gallery={gallery} 79 /> 80 )) 81 : null} 82 </GalleryLayout.Container> 83 </GalleryLayout> 84 </ModerationWrapper> 85 } 86 </div> 87 ); 88}