@@ -114,20 +114,56 @@ function CarouselOverflow ({ originalSrc, rel }) {
114
114
export function CarouselProvider ( { children } ) {
115
115
const media = useRef ( new Map ( ) )
116
116
const showModal = useShowModal ( )
117
+ const modalCloseRef = useRef ( null )
118
+ const [ confirmedCount , setConfirmedCount ] = useState ( 0 )
117
119
118
120
const showCarousel = useCallback ( ( { src } ) => {
119
121
// only show confirmed entries
120
122
const confirmedEntries = Array . from ( media . current . entries ( ) )
121
123
. filter ( ( [ , entry ] ) => entry . confirmed )
122
124
123
125
showModal ( ( close , setOptions ) => {
126
+ modalCloseRef . current = close
124
127
return < Carousel close = { close } mediaArr = { confirmedEntries } src = { src } setOptions = { setOptions } />
125
128
} , {
126
129
fullScreen : true ,
127
- overflow : < CarouselOverflow { ...media . current . get ( src ) } />
130
+ overflow : < CarouselOverflow { ...media . current . get ( src ) } /> ,
131
+ hash : 'carousel' ,
132
+ onClose : ( ) => {
133
+ modalCloseRef . current = null
134
+ }
128
135
} )
129
136
} , [ showModal ] )
130
137
138
+ // Handle initial hash-based carousel opening with proper SSR safety
139
+ useEffect ( ( ) => {
140
+ // Ensure we're in browser environment
141
+ if ( typeof window === 'undefined' ) return
142
+
143
+ const handleHashCarousel = ( ) => {
144
+ if ( window . location . hash === '#carousel' ) {
145
+ const confirmedEntries = Array . from ( media . current . entries ( ) )
146
+ . filter ( ( [ , entry ] ) => entry . confirmed )
147
+
148
+ if ( confirmedEntries . length > 0 ) {
149
+ showCarousel ( { src : confirmedEntries [ 0 ] [ 0 ] } )
150
+ } else {
151
+ // Remove hash if no confirmed media exists
152
+ window . history . replaceState (
153
+ window . history . state ,
154
+ '' ,
155
+ window . location . pathname + window . location . search
156
+ )
157
+ }
158
+ }
159
+ }
160
+
161
+ // Only run on mount if hash is present
162
+ if ( window . location . hash === '#carousel' ) {
163
+ handleHashCarousel ( )
164
+ }
165
+ } , [ showCarousel , confirmedCount ] )
166
+
131
167
const addMedia = useCallback ( ( { src, originalSrc, rel } ) => {
132
168
media . current . set ( src , { src, originalSrc, rel, confirmed : false } )
133
169
} , [ ] )
@@ -137,11 +173,29 @@ export function CarouselProvider ({ children }) {
137
173
if ( mediaItem ) {
138
174
mediaItem . confirmed = true
139
175
media . current . set ( src , mediaItem )
176
+
177
+ const newConfirmedCount = Array . from ( media . current . values ( ) )
178
+ . filter ( entry => entry . confirmed ) . length
179
+ setConfirmedCount ( newConfirmedCount )
180
+
181
+ // Handle hash-based carousel opening when first media is confirmed
182
+ if ( typeof window !== 'undefined' && window . location . hash === '#carousel' ) {
183
+ if ( newConfirmedCount === 1 ) {
184
+ showCarousel ( { src } )
185
+ }
186
+ }
140
187
}
141
- } , [ ] )
188
+ } , [ showCarousel ] )
142
189
143
190
const removeMedia = useCallback ( ( src ) => {
191
+ const wasConfirmed = media . current . get ( src ) ?. confirmed
144
192
media . current . delete ( src )
193
+
194
+ if ( wasConfirmed ) {
195
+ const newConfirmedCount = Array . from ( media . current . values ( ) )
196
+ . filter ( entry => entry . confirmed ) . length
197
+ setConfirmedCount ( newConfirmedCount )
198
+ }
145
199
} , [ ] )
146
200
147
201
const value = useMemo (
0 commit comments