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);