@@ -2,6 +2,15 @@ import React, { useState } from 'react';
22import videos from '../data/videos.json' ;
33
44const VideoGallery = ( ) => {
5+ const [ fullscreenGif , setFullscreenGif ] = useState ( null ) ;
6+
7+ const openFullscreen = ( gifUrl , title ) => {
8+ setFullscreenGif ( { url : gifUrl , title } ) ;
9+ } ;
10+
11+ const closeFullscreen = ( ) => {
12+ setFullscreenGif ( null ) ;
13+ } ;
514 // Group videos by repository
615 const videosByRepo = videos . reduce ( ( acc , video ) => {
716 if ( ! acc [ video . repository ] ) {
@@ -68,12 +77,41 @@ const VideoGallery = () => {
6877 }
6978
7079 return (
71- < div >
80+ < div style = { { position : 'relative' } } >
7281 < img
7382 src = { gifUrl }
7483 alt = { video . fileName || 'Video' }
7584 style = { { width : '100%' , maxHeight : '200px' , borderRadius : '4px' , objectFit : 'contain' , backgroundColor : '#f5f5f5' } }
7685 />
86+ < button
87+ onClick = { ( ) => openFullscreen ( gifUrl , video . fileName || 'Video' ) }
88+ style = { {
89+ position : 'absolute' ,
90+ top : '8px' ,
91+ right : '8px' ,
92+ backgroundColor : 'rgba(0, 0, 0, 0.6)' ,
93+ color : 'white' ,
94+ border : 'none' ,
95+ borderRadius : '4px' ,
96+ padding : '8px 12px' ,
97+ cursor : 'pointer' ,
98+ fontSize : '0.875rem' ,
99+ fontWeight : 'bold' ,
100+ display : 'flex' ,
101+ alignItems : 'center' ,
102+ gap : '4px' ,
103+ transition : 'background-color 0.2s'
104+ } }
105+ onMouseEnter = { ( e ) => e . target . style . backgroundColor = 'rgba(0, 0, 0, 0.8)' }
106+ onMouseLeave = { ( e ) => e . target . style . backgroundColor = 'rgba(0, 0, 0, 0.6)' }
107+ aria-label = "View fullscreen"
108+ title = "View fullscreen"
109+ >
110+ < svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "currentColor" >
111+ < path d = "M1.5 1a.5.5 0 0 0-.5.5v4a.5.5 0 0 1-1 0v-4A1.5 1.5 0 0 1 1.5 0h4a.5.5 0 0 1 0 1h-4zM10 .5a.5.5 0 0 1 .5-.5h4A1.5 1.5 0 0 1 16 1.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 0-.5-.5h-4a.5.5 0 0 1-.5-.5zM.5 10a.5.5 0 0 1 .5.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 1 0 1h-4A1.5 1.5 0 0 1 0 14.5v-4a.5.5 0 0 1 .5-.5zm15 0a.5.5 0 0 1 .5.5v4a1.5 1.5 0 0 1-1.5 1.5h-4a.5.5 0 0 1 0-1h4a.5.5 0 0 0 .5-.5v-4a.5.5 0 0 1 .5-.5z" />
112+ </ svg >
113+ Fullscreen
114+ </ button >
77115 </ div >
78116 ) ;
79117 } else {
@@ -328,6 +366,84 @@ const VideoGallery = () => {
328366 ) ) }
329367 </ div >
330368 ) }
369+
370+ { /* Fullscreen Modal for GIFs */ }
371+ { fullscreenGif && (
372+ < div
373+ style = { {
374+ position : 'fixed' ,
375+ top : 0 ,
376+ left : 0 ,
377+ right : 0 ,
378+ bottom : 0 ,
379+ backgroundColor : 'rgba(0, 0, 0, 0.95)' ,
380+ zIndex : 9999 ,
381+ display : 'flex' ,
382+ flexDirection : 'column' ,
383+ alignItems : 'center' ,
384+ justifyContent : 'center' ,
385+ padding : '2rem'
386+ } }
387+ onClick = { closeFullscreen }
388+ >
389+ < div style = { {
390+ position : 'relative' ,
391+ maxWidth : '90vw' ,
392+ maxHeight : '90vh' ,
393+ display : 'flex' ,
394+ flexDirection : 'column' ,
395+ alignItems : 'center'
396+ } }
397+ onClick = { ( e ) => e . stopPropagation ( ) }
398+ >
399+ < div style = { {
400+ display : 'flex' ,
401+ justifyContent : 'space-between' ,
402+ alignItems : 'center' ,
403+ width : '100%' ,
404+ marginBottom : '1rem' ,
405+ color : 'white'
406+ } } >
407+ < h3 style = { { margin : 0 , fontSize : '1.25rem' } } > { fullscreenGif . title } </ h3 >
408+ < button
409+ onClick = { closeFullscreen }
410+ style = { {
411+ backgroundColor : 'transparent' ,
412+ color : 'white' ,
413+ border : '2px solid white' ,
414+ borderRadius : '4px' ,
415+ padding : '8px 16px' ,
416+ cursor : 'pointer' ,
417+ fontSize : '1rem' ,
418+ fontWeight : 'bold' ,
419+ transition : 'all 0.2s'
420+ } }
421+ onMouseEnter = { ( e ) => {
422+ e . target . style . backgroundColor = 'white' ;
423+ e . target . style . color = 'black' ;
424+ } }
425+ onMouseLeave = { ( e ) => {
426+ e . target . style . backgroundColor = 'transparent' ;
427+ e . target . style . color = 'white' ;
428+ } }
429+ aria-label = "Close fullscreen"
430+ >
431+ ✕ Close
432+ </ button >
433+ </ div >
434+ < img
435+ src = { fullscreenGif . url }
436+ alt = { fullscreenGif . title }
437+ style = { {
438+ maxWidth : '100%' ,
439+ maxHeight : 'calc(90vh - 4rem)' ,
440+ objectFit : 'contain' ,
441+ borderRadius : '4px'
442+ } }
443+ />
444+ </ div >
445+ </ div >
446+ ) }
331447 </ div >
332448 ) ;
333449} ;
0 commit comments