11import React , { PureComponent } from "react" ;
22import PropTypes from "prop-types" ;
3- import {
4- TransitionGroup as ReactTransitionGroup ,
5- CSSTransition
6- } from "react-transition-group" ;
7- import { Swipeable } from "react-swipeable" ;
83import includes from "lodash/includes" ;
4+ import debounce from "lodash/debounce" ;
95import ResourceSlide from "frontend/components/resource-slide" ;
106import { resourceCollectionsAPI , requests } from "api" ;
117import { entityStoreActions } from "actions" ;
@@ -53,6 +49,9 @@ class ResourceSlideshow extends PureComponent {
5349 props . pagination
5450 ) ;
5551 this . state . totalCount = props . pagination . totalCount || 0 ;
52+
53+ this . sliderRef = React . createRef ( null ) ;
54+ this . debouncedScroll = debounce ( this . bindScroll , 100 ) ;
5655 }
5756
5857 static getDerivedStateFromProps ( nextProps , prevState ) {
@@ -73,16 +72,36 @@ class ResourceSlideshow extends PureComponent {
7372
7473 componentDidMount ( ) {
7574 document . addEventListener ( "keyup" , this . bindKeyboard , false ) ;
75+
76+ if ( this . sliderRef . current ) {
77+ this . sliderRef . current . addEventListener ( "scroll" , this . debouncedScroll ) ;
78+ }
7679 }
7780
78- componentDidUpdate ( prevProps ) {
81+ componentDidUpdate ( prevProps , prevState ) {
7982 if ( this . props . collectionResources !== prevProps . collectionResources ) {
8083 this . updateMap ( this . props . collectionResources , this . props . pagination ) ;
8184 }
85+
86+ if ( prevState . position !== this . state . position && this . sliderRef . current ) {
87+ const clientWidth = this . sliderRef . current . clientWidth ;
88+
89+ this . sliderRef . current . scrollTo ( {
90+ left : ( this . state . position - 1 ) * clientWidth ,
91+ top : 0
92+ } ) ;
93+ }
8294 }
8395
8496 componentWillUnmount ( ) {
8597 document . removeEventListener ( "keyup" , this . bindKeyboard , false ) ;
98+
99+ if ( this . sliderRef . current ) {
100+ this . sliderRef . current . removeEventListener (
101+ "scroll" ,
102+ this . debouncedScroll
103+ ) ;
104+ }
86105 }
87106
88107 getFigureByType ( resource ) {
@@ -109,6 +128,18 @@ class ResourceSlideshow extends PureComponent {
109128 }
110129 } ;
111130
131+ bindScroll = event => {
132+ const boundary = event . target . getBoundingClientRect ( ) ;
133+ const scrollLeft = Math . round ( event . target . scrollLeft ) ;
134+ const width = Math . round ( boundary . width ) ;
135+ const activeCalc = Math . round ( scrollLeft / width ) ;
136+ const active = scrollLeft === 0 || activeCalc < 0 ? 0 : activeCalc ;
137+
138+ if ( active + 1 !== this . state . position ) {
139+ this . updatePosition ( active + 1 ) ;
140+ }
141+ } ;
142+
112143 handleUnloadedSlide = position => {
113144 const page = this . positionToPage ( position , this . props . pagination . perPage ) ;
114145 if ( ! this . isPageLoaded ( page ) ) {
@@ -167,10 +198,11 @@ class ResourceSlideshow extends PureComponent {
167198 this . setState ( { map } ) ;
168199 }
169200
170- updatePosition ( newPosition ) {
201+ async updatePosition ( newPosition ) {
171202 if ( ! this . isLoaded ( newPosition ) ) {
172203 this . handleUnloadedSlide ( newPosition ) ;
173204 }
205+
174206 this . setState ( { position : newPosition } ) ;
175207 }
176208
@@ -183,40 +215,33 @@ class ResourceSlideshow extends PureComponent {
183215 return { ...this . state . map , ...updates } ;
184216 }
185217
186- renderSlideShow ( ) {
218+ renderSlideShow ( slides ) {
187219 const position = this . state . position ;
188- const collectionResource = this . state . map [ position ] ;
189220
190- return (
191- < CSSTransition
192- key = { position }
193- classNames = { this . state . slideDirection }
194- timeout = { { enter : 500 , exit : 500 } }
221+ return slides . map ( ( slide , index ) => (
222+ < Styled . Slide
223+ key = { slide . id }
224+ id = { slide . id }
225+ data-active = { index === position - 1 }
226+ style = { {
227+ viewTimeline : `--slide-${ slide . id } x` ,
228+ animationTimeline : `--slide-${ slide . id } `
229+ } }
195230 >
196- < Styled . Slide >
197- { this . isLoaded ( position ) ? (
198- this . getFigureByType ( collectionResource )
199- ) : (
200- < ResourceSlide . SlideLoading />
201- ) }
202- </ Styled . Slide >
203- </ CSSTransition >
204- ) ;
231+ { this . isLoaded ( position ) ? (
232+ this . getFigureByType ( slide )
233+ ) : (
234+ < ResourceSlide . SlideLoading />
235+ ) }
236+ </ Styled . Slide >
237+ ) ) ;
205238 }
206239
207240 renderPlaceholder ( ) {
208241 return (
209- < CSSTransition
210- key = "placeholder"
211- classNames = { this . state . slideDirection }
212- timeout = { { enter : 500 , exit : 500 } }
213- >
214- < div >
215- < Styled . Slide >
216- < ResourceSlide . SlidePlaceholder />
217- </ Styled . Slide >
218- </ div >
219- </ CSSTransition >
242+ < Styled . Slide data-active >
243+ < ResourceSlide . SlidePlaceholder />
244+ </ Styled . Slide >
220245 ) ;
221246 }
222247
@@ -226,21 +251,19 @@ class ResourceSlideshow extends PureComponent {
226251 const collectionResource = this . state . map [ position ] ;
227252 const collectionResourcesCount = this . props . collectionResources . length ;
228253 const t = this . props . t ;
254+ const slides = Object . values ( this . state . map ) ;
229255
230256 return (
231- < Styled . SlideShow >
232- < Swipeable
233- onSwipedLeft = { this . handleSlideNext }
234- onSwipedRight = { this . handleSlidePrev }
235- >
236- < Styled . SlidesWrapper >
237- < ReactTransitionGroup >
238- { collectionResourcesCount > 0
239- ? this . renderSlideShow ( )
240- : this . renderPlaceholder ( ) }
241- </ ReactTransitionGroup >
242- </ Styled . SlidesWrapper >
243- </ Swipeable >
257+ < Styled . SlideShow
258+ style = { {
259+ timelineScope : slides . map ( slide => `--slide-${ slide . id } ` ) . join ( "," )
260+ } }
261+ >
262+ < Styled . SlidesWrapper ref = { this . sliderRef } >
263+ { collectionResourcesCount > 0
264+ ? this . renderSlideShow ( slides )
265+ : this . renderPlaceholder ( ) }
266+ </ Styled . SlidesWrapper >
244267 < Styled . Footer >
245268 { this . isLoaded ( position ) ? (
246269 < ResourceSlide . Caption
0 commit comments