Bluesky app fork with some witchin' additions 馃挮
at fbd1138d97dda2df66bee13ad3ca6e83d55ebc25 84 lines 2.1 kB view raw
1import React from 'react' 2import {nanoid} from 'nanoid/non-secure' 3 4import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' 5import {type ImageSource} from '#/view/com/lightbox/ImageViewing/@types' 6 7export type Lightbox = { 8 id: string 9 images: ImageSource[] 10 index: number 11} 12 13const LightboxContext = React.createContext<{ 14 activeLightbox: Lightbox | null 15}>({ 16 activeLightbox: null, 17}) 18LightboxContext.displayName = 'LightboxContext' 19 20const LightboxControlContext = React.createContext<{ 21 openLightbox: (lightbox: Omit<Lightbox, 'id'>) => void 22 closeLightbox: () => boolean 23}>({ 24 openLightbox: () => {}, 25 closeLightbox: () => false, 26}) 27LightboxControlContext.displayName = 'LightboxControlContext' 28 29export function Provider({children}: React.PropsWithChildren<{}>) { 30 const [activeLightbox, setActiveLightbox] = React.useState<Lightbox | null>( 31 null, 32 ) 33 34 const openLightbox = useNonReactiveCallback( 35 (lightbox: Omit<Lightbox, 'id'>) => { 36 setActiveLightbox(prevLightbox => { 37 if (prevLightbox) { 38 // Ignore duplicate open requests. If it's already open, 39 // the user has to explicitly close the previous one first. 40 return prevLightbox 41 } else { 42 return {...lightbox, id: nanoid()} 43 } 44 }) 45 }, 46 ) 47 48 const closeLightbox = useNonReactiveCallback(() => { 49 let wasActive = !!activeLightbox 50 setActiveLightbox(null) 51 return wasActive 52 }) 53 54 const state = React.useMemo( 55 () => ({ 56 activeLightbox, 57 }), 58 [activeLightbox], 59 ) 60 61 const methods = React.useMemo( 62 () => ({ 63 openLightbox, 64 closeLightbox, 65 }), 66 [openLightbox, closeLightbox], 67 ) 68 69 return ( 70 <LightboxContext.Provider value={state}> 71 <LightboxControlContext.Provider value={methods}> 72 {children} 73 </LightboxControlContext.Provider> 74 </LightboxContext.Provider> 75 ) 76} 77 78export function useLightbox() { 79 return React.useContext(LightboxContext) 80} 81 82export function useLightboxControls() { 83 return React.useContext(LightboxControlContext) 84}