File indexing completed on 2024-12-22 05:35:28
0001 import React, { useState } from 'react'; 0002 import ReactDOM from 'react-dom'; 0003 import {isMobile} from 'react-device-detect'; 0004 import VideoPlayerWrapper from './components/video-player'; 0005 import BookReaderWrapper from './components/book-reader'; 0006 import MusicPlayerWrapper from './components/music-player'; 0007 import ComicsReaderWrapper from './components/comics-reader'; 0008 0009 import {GenerateGalleryArray, CheckForMultipleAudioFiles, GroupAudioFilesInGallery} from './product-media-slider-helpers'; 0010 0011 function ProductMediaSlider(){ 0012 0013 /* Component */ 0014 0015 const [ product, setProduct ] = useState(window.product); 0016 let galleryArray = GenerateGalleryArray(product); 0017 const audioFileIndex = galleryArray.findIndex(gf => gf.type === "audio"); 0018 if (audioFileIndex > -1) galleryArray = GroupAudioFilesInGallery(galleryArray); 0019 const [ gallery, setGallery ] = useState(galleryArray); 0020 const [ disableGallery, setDisableGallery ] = useState(gallery.length > 1 ? false : true) 0021 const parentContainerElement = document.getElementById('product-title-div'); 0022 const [ containerWidth, setContainerWidth ] = useState(parentContainerElement.offsetWidth); 0023 const [ currentSlide, setCurrentSlide ] = useState(0); 0024 const [ sliderHeight, setSliderHeight ] = useState(360); 0025 const [ cinemaMode, setCinemaMode ] = useState(false); 0026 const [ isFullScreen, setIsFullScreen] = useState(false) 0027 const [ showPlaylist, setShowPlaylist ] = useState(false); 0028 const [ showSliderArrows, setShowSliderArrows ] = useState(isMobile === true ? true : false); 0029 const [ sliderFadeControlsMode, setSliderFadeControlsMode ] = useState(true); 0030 0031 let sliderFadeControlTimeOut; 0032 0033 // use effects 0034 React.useEffect(() => { 0035 initProductMediaSlider(currentSlide); 0036 if (gallery[currentSlide].type === "book") setShowSliderArrows(false) 0037 else setShowSliderArrows(true) 0038 },[currentSlide]) 0039 React.useEffect((event) => { updateDimensions(event,currentSlide) },[currentSlide, cinemaMode]) 0040 React.useEffect(() => { handleMouseMovementEventListener(showPlaylist,isFullScreen) },[showPlaylist,isFullScreen]) 0041 0042 // init product media slider 0043 function initProductMediaSlider(currentSlide){ 0044 window.addEventListener("resize", function(event){updateDimensions(event,currentSlide)}); 0045 window.addEventListener("orientationchange", function(event){updateDimensions(event,currentSlide)}); 0046 } 0047 0048 // handle mouse movement event listener 0049 function handleMouseMovementEventListener(showPlaylist,isFullScreen){ 0050 window.removeEventListener("mousemove",function(event){ onMouseMovement(event,showPlaylist,isFullScreen)}) 0051 window.removeEventListener("mousedown",function(event){ onMouseMovement(event,showPlaylist,isFullScreen)}) 0052 window.addEventListener("mousemove",function(event){ onMouseMovement(event,showPlaylist,isFullScreen) }); 0053 window.addEventListener("mousedown",function(event){ onMouseMovement(event,showPlaylist,isFullScreen) }); 0054 } 0055 0056 // update dimensions 0057 function updateDimensions(){ 0058 const newContainerWidth = parentContainerElement.offsetWidth; 0059 setContainerWidth(newContainerWidth) 0060 document.getElementById('product-page-content').removeEventListener("DOMNodeRemoved", updateDimensions); 0061 document.getElementById('product-page-content').removeEventListener("DOMNodeInserted", updateDimensions); 0062 if (cinemaMode === false) setSliderHeight(360) 0063 } 0064 0065 // on mouse movement 0066 function onMouseMovement(event,showPlaylist,isFullScreen){ 0067 const mediaSliderOffest = $('#media-slider').offset() 0068 const mediaSliderLeft = mediaSliderOffest.left; 0069 const mediaSliderRight = mediaSliderLeft + $('#media-slider').width(); 0070 const mediaSliderTop = mediaSliderOffest.top - window.pageYOffset; 0071 let mediaSliderBottom = mediaSliderTop + $('#media-slider').height(); 0072 if (showPlaylist) mediaSliderBottom += 110; 0073 else mediaSliderBottom += 30; 0074 let mouseIn = false; 0075 if (event.clientX > mediaSliderLeft && event.clientX < mediaSliderRight && event.clientY > mediaSliderTop && event.clientY < mediaSliderBottom ){ mouseIn = true; } 0076 if (isFullScreen) mouseIn = true; 0077 if (mouseIn) { 0078 setSliderFadeControlsMode(false) 0079 clearTimeout(sliderFadeControlTimeOut); 0080 sliderFadeControlTimeOut = setTimeout(function(){ 0081 setSliderFadeControlsMode(true) 0082 }, 2000); 0083 } else { 0084 setSliderFadeControlsMode(true) 0085 clearTimeout(sliderFadeControlTimeOut); 0086 } 0087 } 0088 0089 // toggle cinema mode 0090 function toggleCinemaMode(){ 0091 document.getElementById('product-page-content').addEventListener("DOMNodeRemoved", updateDimensions); 0092 document.getElementById('product-page-content').addEventListener("DOMNodeInserted", updateDimensions); 0093 const newCinemaMode = cinemaMode === true ? false : true; 0094 const targetParentElement = cinemaMode === true ? $('#product-main') : $('#product-page-content'); 0095 const targetChildPrependedElement = cinemaMode === true ? $('#product-title-div') : $('#product-media-slider-container'); 0096 $('#product-main-img-container').prependTo(targetParentElement); 0097 $(targetChildPrependedElement).prependTo('#product-main-img'); 0098 $("#product-media-slider-container").toggleClass("imgsmall"); 0099 $("#product-media-slider-container").toggleClass("imgfull"); 0100 setCinemaMode(newCinemaMode) 0101 } 0102 0103 // toggle show playlist 0104 function toggleShowPlaylist(){ 0105 const newShowPlaylistValue = showPlaylist === true ? false : true; 0106 setShowPlaylist(newShowPlaylistValue) 0107 } 0108 0109 //handle full screen toggle 0110 function hanleFullScreenToggle(val){ 0111 setIsFullScreen(val); 0112 const newSliderHeight = val === true ? window.innerHeight : 360; 0113 setSliderHeight(newSliderHeight); 0114 const parentContainerElement = document.getElementById('product-title-div'); 0115 const newContainerWidth = val === true ? window.offsetWidth : parentContainerElement; 0116 setContainerWidth(newContainerWidth); 0117 } 0118 0119 // on finish slides render 0120 function onFinishedSlidesRender(){ 0121 let swiperHasComics = false; 0122 const comicsItem = gallery.find((g,index) => g.type === "comics"); 0123 if (comicsItem) swiperHasComics = true 0124 if (!swiperHasComics){ 0125 0126 } 0127 0128 $(document).ready(function() { 0129 window.mySwiper = new Swiper('.swiper-container', { 0130 speed: 400, 0131 initialSlide: 0, 0132 observer: true, 0133 observeParents: true, 0134 preloadImages: true, 0135 updateOnImagesReady: true, 0136 pagination: '.swiper-pagination', 0137 paginationClickable: '.swiper-pagination', 0138 threshold:50, 0139 onSlideChangeStart: function(swiper){ 0140 setCurrentSlide(swiper.activeIndex); 0141 } 0142 }); 0143 window.mySwiper.update() 0144 // if (isMobile) setShowPlaylist(true) 0145 }); 0146 } 0147 0148 // on finished thumbs render 0149 function onfinishedThumbsRender(){ 0150 $(document).ready(function() { 0151 let slidesPerView = Math.ceil(containerWidth / 200); 0152 if (isMobile) slidesPerView = 2; 0153 window.galleryThumbs = new Swiper('.gallery-thumbs', { 0154 slidesPerView:slidesPerView, 0155 initialSlide: currentSlide, 0156 spaceBetween:10, 0157 freeMode: true, 0158 watchSlidesVisibility: true, 0159 watchSlidesProgress: true, 0160 activeIndex:currentSlide, 0161 scrollbar:'.swiper-scrollbar' 0162 }); 0163 window.galleryThumbs.update() 0164 }); 0165 } 0166 0167 // on thumb item click 0168 function onThumbItemClick(slideIndex){ 0169 window.mySwiper.slideTo(slideIndex) 0170 } 0171 0172 // go next 0173 function goNext(){ 0174 let nextSlide = window.mySwiper.activeIndex + 1; 0175 if (nextSlide > gallery.length - 1) nextSlide = 0; 0176 window.mySwiper.slideTo(nextSlide) 0177 } 0178 0179 // go prev 0180 function goPrev(){ 0181 let prevSlide = window.mySwiper.activeIndex - 1; 0182 if (prevSlide < 0 ) prevSlide = gallery.length - 1; 0183 window.mySwiper.slideTo(prevSlide) 0184 } 0185 0186 0187 /* Render */ 0188 0189 // media slider css class 0190 let mediaSliderCssClass = ""; 0191 if (disableGallery === true) mediaSliderCssClass += "disable-gallery "; 0192 if (cinemaMode === true) mediaSliderCssClass += "cinema-mode "; 0193 // if (showSliderArrows === false) mediaSliderCssClass += "hide-arrows "; 0194 if (showPlaylist === false) mediaSliderCssClass += "hide-playlist "; 0195 if (sliderFadeControlsMode === true) mediaSliderCssClass += "fade-controls "; 0196 if (isMobile === true) mediaSliderCssClass += "is-mobile "; 0197 if (showSliderArrows === false) mediaSliderCssClass += "hide-controls "; 0198 if (isFullScreen === true) mediaSliderCssClass += "is-full-screen" 0199 0200 // slides display 0201 const slidesDisplay = gallery.map((s,index) => ( 0202 <SlideItem 0203 key={index} 0204 slideIndex={index} 0205 slide={s} 0206 currentSlide={currentSlide} 0207 containerWidth={containerWidth} 0208 sliderHeight={sliderHeight} 0209 cinemaMode={cinemaMode} 0210 gallery={gallery} 0211 product={product} 0212 disableGallery={disableGallery} 0213 onFinishedSlidesRender={onFinishedSlidesRender} 0214 onCinemaModeClick={toggleCinemaMode} 0215 onSetSliderHeight={height => setSliderHeight(height)} 0216 onUpdateDimensions={updateDimensions} 0217 onFullScreenToggle={hanleFullScreenToggle} 0218 isFullScreen={isFullScreen} 0219 onNextSlideClick={goNext} 0220 /> 0221 )); 0222 0223 let thumbnailNavigationDisplay; 0224 if (showPlaylist && gallery.length > 1){ 0225 // thumbnail navigation 0226 const slidesThumbnailNavigationDisplay = gallery.map((g, index) => ( 0227 <ThumbNavigationItem 0228 key={index} 0229 slideIndex={index} 0230 currentSlide={currentSlide} 0231 gallery={gallery} 0232 item={g} 0233 onFinishedSlidesRender={onFinishedSlidesRender} 0234 containerWidth={containerWidth} 0235 onfinishedThumbsRender={onfinishedThumbsRender} 0236 onThumbItemClick={(slideIndex) => onThumbItemClick(slideIndex)} 0237 /> 0238 )) 0239 0240 let thumbnailNavigationCss; 0241 if (containerWidth > (gallery.length * 200)){ 0242 thumbnailNavigationCss = { 0243 paddingLeft: (containerWidth - (gallery.length * 200)) / 2 0244 } 0245 } 0246 0247 thumbnailNavigationDisplay = ( 0248 <div id="slide-navigation" className="swiper-container gallery-thumbs" > 0249 <div className="thumbnail-navigation swiper-wrapper" style={thumbnailNavigationCss}>{slidesThumbnailNavigationDisplay}</div> 0250 <div className="swiper-scrollbar"></div> 0251 </div> 0252 ) 0253 } 0254 0255 return ( 0256 <main id="media-slider" 0257 style={{height:sliderHeight}} 0258 className={mediaSliderCssClass} 0259 > 0260 <div id="slider-container" className="swiper-container"> 0261 <div className="swiper-wrapper"> 0262 {slidesDisplay} 0263 </div> 0264 <div className="swiper-pagination"></div> 0265 <a className="carousel-control carousel-control-left left" onClick={goPrev}> 0266 <span className="visible-container"> 0267 <span className="glyphicon glyphicon-chevron-left"></span> 0268 </span> 0269 </a> 0270 <a className="carousel-control carousel-control-right right" onClick={goNext}> 0271 <span className="visible-container"> 0272 <span className="glyphicon glyphicon-chevron-right"></span> 0273 </span> 0274 </a> 0275 </div> 0276 {thumbnailNavigationDisplay} 0277 <a className="slider-navigation-toggle" onClick={toggleShowPlaylist} style={{top:(sliderHeight) - 75}}></a> 0278 </main> 0279 ) 0280 } 0281 0282 function SlideItem(props){ 0283 0284 const [ mediaStyle, setMediaStyle ] = useState(); 0285 const [ itemSetHeight, setItemSetHeight ] = useState(); 0286 0287 React.useEffect(() => { 0288 if (props.gallery && props.gallery.length === props.slideIndex + 1) props.onFinishedSlidesRender(); 0289 }, [props.gallery]) 0290 React.useEffect(() => { getSlideContentHeight(props.cinemaMode) },[props.currentSlide, props.cinemaMode]); 0291 React.useEffect(() => { 0292 const newItemSetHeight = props.sliderHeight; 0293 setItemSetHeight(newItemSetHeight); 0294 },[props.isFullScreen,props.sliderHeight]); 0295 0296 function getSlideContentHeight(cinemaMode){ 0297 if (props.currentSlide === props.slideIndex){ 0298 if (props.isFullScreen === false){ 0299 if (props.slide.type === "image"){ 0300 const imageEl = document.getElementById('slide-img-'+props.slideIndex); 0301 if ( cinemaMode === true ){ 0302 let imageHeight = imageEl.naturalHeight; 0303 if (imageEl.naturalWidth > window.innerWidth){ 0304 let dimensionsPercentage = window.innerWidth / imageEl.naturalWidth; 0305 imageHeight = imageEl.naturalHeight * dimensionsPercentage; 0306 } 0307 setMediaStyle({height:imageHeight}) 0308 props.onSetSliderHeight(imageHeight); 0309 } else { 0310 if (props.disableGallery) setMediaStyle({maxHeight:360}) 0311 } 0312 } 0313 else if (props.slide.type === "embed"){ 0314 if (cinemaMode === true) props.onSetSliderHeight(315) 0315 } 0316 else if (props.slide.type === "video"){ 0317 if (cinemaMode === true) props.onSetSliderHeight(screen.height * 0.7); 0318 else props.onSetSliderHeight(360) 0319 } else if (props.slide.type === "book" || "comics"){ 0320 props.onSetSliderHeight(360) 0321 } else if ( props.slide.type === "audio"){ 0322 props.onSetSliderHeight(360) 0323 } 0324 } 0325 } 0326 } 0327 0328 function onCinemaModeClick(){ 0329 let cinemaMode = props.cinemaMode === true ? false : true; 0330 getSlideContentHeight(cinemaMode); 0331 props.onCinemaModeClick() 0332 } 0333 0334 let slideContentDisplay; 0335 if (props.slide.type === "embed"){ 0336 slideContentDisplay = ( 0337 <div id="iframe-container"> 0338 <div dangerouslySetInnerHTML={{__html: props.slide.url}} /> 0339 </div> 0340 ) 0341 } 0342 else if (props.slide.type === "image") { 0343 slideContentDisplay = ( 0344 <img 0345 onClick={props.onCinemaModeClick} 0346 id={"slide-img-"+props.slideIndex} 0347 src={props.slide.url} 0348 style={mediaStyle} 0349 /> 0350 ) 0351 } 0352 else if (props.slide.type === "video") { 0353 slideContentDisplay = ( 0354 <VideoPlayerWrapper 0355 height={props.sliderHeight} 0356 width={props.containerWidth} 0357 cinemaMode={props.cinemaMode} 0358 onCinemaModeClick={onCinemaModeClick} 0359 slide={props.slide} 0360 playVideo={props.currentSlide === props.slideIndex} 0361 onUpdateDimensions={props.onUpdateDimensions} 0362 onFullScreenToggle={props.onFullScreenToggle} 0363 onNextSlideClick={props.onNextSlideClick} 0364 /> 0365 ) 0366 } 0367 else if (props.slide.type === "audio"){ 0368 0369 slideContentDisplay = ( 0370 <MusicPlayerWrapper 0371 height={props.sliderHeight} 0372 width={props.containerWidth} 0373 cinemaMode={props.cinemaMode} 0374 onCinemaModeClick={onCinemaModeClick} 0375 slide={props.slide} 0376 playAudio={props.currentSlide === props.slideIndex} 0377 product={props.product} 0378 onUpdateDimensions={props.onUpdateDimensions} 0379 onFullScreenToggle={props.onFullScreenToggle} 0380 /> 0381 ) 0382 } 0383 else if (props.slide.type === "book"){ 0384 slideContentDisplay = ( 0385 <BookReaderWrapper 0386 height={props.sliderHeight} 0387 width={props.containerWidth} 0388 onCinemaModeClick={props.onCinemaModeClick} 0389 slide={props.slide} 0390 product={props.product} 0391 cinemaMode={props.cinemaMode} 0392 playVideo={props.currentSlide === props.slideIndex} 0393 onUpdateDimensions={props.onUpdateDimensions} 0394 onFullScreenToggle={props.onFullScreenToggle} 0395 /> 0396 ) 0397 } 0398 else if (props.slide.type === "comics"){ 0399 slideContentDisplay = ( 0400 <ComicsReaderWrapper 0401 height={props.sliderHeight} 0402 width={props.containerWidth} 0403 onCinemaModeClick={props.onCinemaModeClick} 0404 slide={props.slide} 0405 slideIndex={props.slideIndex} 0406 currentSlide={props.currentSlide} 0407 cinemaMode={props.cinemaMode} 0408 containerWidth={props.containerWidth} 0409 sliderHeight={props.sliderHeight} 0410 playVideo={props.currentSlide === props.slideIndex} 0411 onUpdateDimensions={props.onUpdateDimensions} 0412 onFullScreenToggle={props.onFullScreenToggle} 0413 isFullScreen={props.isFullScreen} 0414 /> 0415 ) 0416 0417 } 0418 0419 return ( 0420 <div 0421 id={"slide-"+props.slideIndex} 0422 className={props.currentSlide === props.slideIndex ? "active slide-item swiper-slide " + props.slide.type : "slide-item swiper-slide " + props.slide.type } 0423 style={ { width:props.containerWidth, height:props.sliderHeight }}> 0424 {slideContentDisplay} 0425 </div> 0426 ) 0427 } 0428 0429 function ThumbNavigationItem(props){ 0430 0431 React.useEffect(() => { if (props.gallery && props.gallery.length === props.slideIndex + 1){ props.onfinishedThumbsRender() } }, [props.gallery]) 0432 React.useEffect(() => { 0433 if (window.galleryThumbs) window.galleryThumbs.slideTo(props.currentSlide); 0434 },[props.currentSlide]) 0435 0436 let previewImageContainer; 0437 if (props.item.type === "book"){ 0438 previewImageContainer = ( 0439 <div className="pages preview-image"> 0440 <div className="page"> 0441 {props.item.title} 0442 </div> 0443 </div> 0444 ) 0445 } else { 0446 let bgImage; 0447 if (props.item.type === "image"){ 0448 bgImage = props.item.url.split('/img')[0] + "/cache/120x80-1/img" + props.item.url.split('/img')[1]; 0449 } else if (props.item.type === "video"){ 0450 bgImage = props.item.url_thumb; 0451 } 0452 previewImageContainer = <div className="preview-image" style={{"backgroundImage":"url("+bgImage+")"}}></div> 0453 } 0454 0455 return ( 0456 <div className={props.currentSlide === (props.slideIndex) ? " swiper-slide active " + props.item.type : " swiper-slide " + props.item.type } 0457 onClick={() => props.onThumbItemClick(props.slideIndex)} 0458 onTouchEnd={() => props.onThumbItemClick(props.slideIndex)}> 0459 {previewImageContainer} 0460 </div> 0461 ) 0462 } 0463 0464 const rootElement = document.getElementById("product-media-slider-container"); 0465 ReactDOM.render(<ProductMediaSlider />, rootElement);