33 IJGISStoryMap ,
44 IJupyterGISModel ,
55} from '@jupytergis/schema' ;
6- import React , { useEffect , useMemo , useState } from 'react' ;
6+ import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
77import Markdown from 'react-markdown' ;
88
99import StoryNavBar from './StoryNavBar' ;
@@ -46,6 +46,26 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
4646 return storyData ?. landmarks ?. [ currentIndexDisplayed ] ;
4747 } , [ storyData , currentIndexDisplayed ] ) ;
4848
49+ const zoomToCurrentLayer = ( ) => {
50+ if ( currentLandmarkId ) {
51+ model . centerOnPosition ( currentLandmarkId ) ;
52+ }
53+ } ;
54+
55+ const setSelectedLayerByIndex = useCallback (
56+ ( index : number ) => {
57+ const landmarkId = storyData ?. landmarks ?. [ index ] ;
58+ if ( landmarkId ) {
59+ model . selected = {
60+ [ landmarkId ] : {
61+ type : 'layer' ,
62+ } ,
63+ } ;
64+ }
65+ } ,
66+ [ storyData , model ] ,
67+ ) ;
68+
4969 useEffect ( ( ) => {
5070 const updateStory = ( ) => {
5171 const { story } = model . getSelectedStory ( ) ;
@@ -70,6 +90,13 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
7090 }
7191 } , [ currentLandmarkId , model ] ) ;
7292
93+ // Set selected layer on initial render and when story data changes
94+ useEffect ( ( ) => {
95+ if ( storyData ?. landmarks && currentIndexDisplayed >= 0 ) {
96+ setSelectedLayerByIndex ( currentIndexDisplayed ) ;
97+ }
98+ } , [ storyData , currentIndexDisplayed , setSelectedLayerByIndex ] ) ;
99+
73100 // Listen for layer selection changes in unguided mode
74101 useEffect ( ( ) => {
75102 // ! TODO this logic (getting a single selected layer) is also in the processing index.ts, move to tools
@@ -113,21 +140,17 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
113140 } ;
114141 } , [ model , storyData ] ) ;
115142
116- const zoomToCurrentLayer = ( ) => {
117- if ( currentLandmarkId ) {
118- model . centerOnPosition ( currentLandmarkId ) ;
119- }
120- } ;
121-
122143 const handlePrev = ( ) => {
123144 if ( currentIndexDisplayed > 0 ) {
124- setCurrentIndexDisplayed ( currentIndexDisplayed - 1 ) ;
145+ const newIndex = currentIndexDisplayed - 1 ;
146+ setCurrentIndexDisplayed ( newIndex ) ;
125147 }
126148 } ;
127149
128150 const handleNext = ( ) => {
129151 if ( currentIndexDisplayed < landmarks . length - 1 ) {
130- setCurrentIndexDisplayed ( currentIndexDisplayed + 1 ) ;
152+ const newIndex = currentIndexDisplayed + 1 ;
153+ setCurrentIndexDisplayed ( newIndex ) ;
131154 }
132155 } ;
133156
@@ -140,51 +163,21 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
140163 }
141164
142165 return (
143- < div className = "jgis-story-viewer-panel" style = { { overflow : 'hidden' } } >
166+ < div className = "jgis-story-viewer-panel" >
144167 { /* Image container with title overlay */ }
145168 { activeSlide ?. content ?. image ? (
146- < div style = { { position : 'relative' , width : '100%' , height : '30%' } } >
169+ < div className = "jgis-story-viewer-image-container" >
147170 < img
148171 src = { activeSlide . content . image }
149172 alt = { activeSlide . content . title || 'Story map image' }
150- style = { {
151- width : '100%' ,
152- height : '100%' ,
153- maxHeight : '240px' ,
154- objectFit : 'cover' ,
155- display : 'block' ,
156- } }
173+ className = "jgis-story-viewer-image"
157174 />
158- < h1
159- style = { {
160- position : 'absolute' ,
161- top : 0 ,
162- left : 0 ,
163- width : '100%' ,
164- marginTop : 0 ,
165- marginBottom : 0 ,
166- marginLeft : 'auto' ,
167- marginRight : 'auto' ,
168- paddingTop : '1rem' ,
169- paddingBottom : '1rem' ,
170- color : 'white' ,
171- textShadow : '2px 2px 4px rgba(0, 0, 0, 0.8)' ,
172- backgroundColor : 'rgba(0, 0, 0, 0.3)' ,
173- textAlign : 'center' ,
174- } }
175- >
175+ < h1 className = "jgis-story-viewer-image-title" >
176176 { `Slide ${ currentIndexDisplayed + 1 } - ${ layerName ? layerName : 'Landmark Name' } ` }
177177 </ h1 >
178178 { /* if guided -> nav buttons */ }
179179 { storyData . storyType === 'guided' && (
180- < div
181- style = { {
182- position : 'absolute' ,
183- bottom : 0 ,
184- left : 0 ,
185- width : '100%' ,
186- } }
187- >
180+ < div className = "jgis-story-viewer-nav-container" >
188181 < StoryNavBar
189182 onPrev = { handlePrev }
190183 onNext = { handleNext }
@@ -196,7 +189,7 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
196189 </ div >
197190 ) : (
198191 < >
199- < h1 style = { { textAlign : 'center' } } > { storyData . title } </ h1 >
192+ < h1 className = "jgis-story-viewer-title" > { storyData . title } </ h1 >
200193 { /* if guided -> nav buttons */ }
201194 { storyData . storyType === 'guided' && (
202195 < StoryNavBar
@@ -208,13 +201,13 @@ function StoryViewerPanel({ model }: IStoryViewerPanelProps) {
208201 ) }
209202 </ >
210203 ) }
211- < h2 style = { { textAlign : 'center' } } >
204+ < h2 className = "jgis-story-viewer-subtitle" >
212205 { activeSlide ?. content ?. title
213206 ? activeSlide . content . title
214207 : 'Slide Title' }
215208 </ h2 >
216209 { activeSlide ?. content ?. markdown && (
217- < div className = "jgis-story-viewer-content" style = { { paddingLeft : 16 } } >
210+ < div className = "jgis-story-viewer-content" >
218211 < Markdown > { activeSlide . content . markdown } </ Markdown >
219212 </ div >
220213 ) }
0 commit comments