import { TimePin } from "../../../animation/TimePin"; import { LinearGradient } from "../../../colors/Gradient"; import { HSLColor } from "../../../colors/HSLColor"; import { DateHelper } from "../../../date/DateHelper"; import { DateMath } from "../../../date/DateMath"; import { TimestampMessage } from "../../../messages/TimestampMessage"; import { RegExpUtility } from "../../../text/RegExpUtitlity"; import { ClassFlag } from "../../ClassFlag"; import { DOMHitTest } from "../../DOMHitTest"; import { DOMOrientation } from "../../DOMOrientation"; import { ElementAttribute } from "../../ElementAttribute"; import { ElementType } from "../../ElementType"; import { OnClick, OnMouseEnter, OnMouseMove, OnPause, OnPlay, OnTimeUpdate, OnTouchDrag, OnTouchEnd, OnTouchStart } from "../../EventListeners"; import { Fullscreen } from "../../Fullscreen"; import { Insight } from "../../Insight"; export class MediaGallery { static videoElements:HTMLElement[]; static activeVideoElement:HTMLElement; static attachedGlobalListeners = false; static insight:Insight; static readonly mediaVideo = new ElementType( "media-video" ); static readonly mediaImage = new ElementType( "media-image" ); static readonly activeFlag = new ClassFlag( "active-video" ); static readonly itemIndex = new ElementAttribute( "item-index" ); static readonly container = new ElementType ( "media-container" ); static readonly showPlayButton = new ClassFlag( "show-play-button" ); static readonly fullScreenButton = new ElementType( "fullscreen-button" ); static readonly progressIndicator = new ElementType( "progress-indicator" ); static applyOnDocument( insight:Insight ) { this.insight = insight; this.attachGlobalListener(); MediaGallery.videoElements = MediaGallery.mediaVideo.queryAll( document.body ) as HTMLElement[]; MediaGallery.videoElements.forEach( v => this.applyOnVideoElement( v ) ); } static attachGlobalListener() { if ( MediaGallery.attachedGlobalListeners ) { return; } MediaGallery.attachedGlobalListeners = true; // OnMouseMove.add( // document.body, // ( e )=> // { // if ( DOMOrientation.isPortrait ) // { // return; // } // if ( ! MediaGallery.activeVideoElement ) // { // return; // } // let isOver = DOMHitTest.isPointerOver( e, MediaGallery.activeVideoElement ); // if ( isOver ) // { // return; // } // MediaGallery.updateActiveVideo( null ); // } // ) } static applyOnVideoElement( element:Element ) { let videoElement = ElementType.video.query( element ); let fs = MediaGallery.fullScreenButton.query( element ); let pi = MediaGallery.progressIndicator.query( element ) as HTMLElement; OnClick.add( pi, ( e )=> { let relative = DOMHitTest.getNormalizedPointerPosition( e, pi ); let position = Math.round( videoElement.duration * relative.x ); videoElement.currentTime = position; e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); } ); let updateVideoTimeCode = ( text:string = null )=> { let textValue = text != null ? text : ( DateMath.formatToMinutesAndSeconds( videoElement.currentTime ) + " / " + DateMath.formatToMinutesAndSeconds( videoElement.duration ) ); pi.innerHTML = `${textValue}`; let percent = text != null ? 0 : (videoElement.currentTime / videoElement.duration) * 100; let leftColor = new HSLColor( 0, 0, 100, 0.3 ); let rightColor = new HSLColor( 0, 0, 100, 0.1 ); let linearBG = LinearGradient.createHorizontal( leftColor, rightColor, percent, 1 ); pi.style.background = linearBG + ", hsl(0,0%,0%,0.3)"; }; OnTimeUpdate.add( videoElement, () => { updateVideoTimeCode(); } ); OnClick.add( fs as HTMLElement, ()=> { Fullscreen.toggleFullscreen( element as HTMLElement, "auto" ); } ); updateVideoTimeCode( "--:--" ); // OnMouseEnter.add( element as HTMLElement, // ()=> // { // if ( DOMOrientation.isPortrait ) // { // return; // } // MediaGallery.updateActiveVideo( element ); // } // ); MediaGallery.showPlayButton.setAs( element, true ); OnClick.add( element as HTMLElement, ( me ) => { if ( DOMOrientation.isPortrait ) { return; } if ( videoElement.paused ) { this.updateActiveVideo( element ); MediaGallery.showPlayButton.setAs( element, false ); } else { videoElement.pause(); MediaGallery.showPlayButton.setAs( element, true ); } } ); OnTouchStart.add( element as HTMLElement, ( touchStartEvent )=> { if ( touchStartEvent.target == pi || DOMOrientation.isLandscape ) { return; } console.log( touchStartEvent ); let startPosition = DOMHitTest.getRelativeWindowPosition( touchStartEvent ); let moved = false; let treshold = 0.1; let onDrag = ( dragEvent:TouchEvent )=> { if ( moved ) { return; } let dragPosition = DOMHitTest.getRelativeWindowPosition( dragEvent ); moved = dragPosition.sub( startPosition ).length > treshold; } let onEnd = ()=> { OnTouchEnd.remove( element as HTMLElement, onEnd ); OnTouchDrag.remove( element as HTMLElement, onDrag ); if ( moved ) { return; } let videoElement = ElementType.video.query( element ); if ( videoElement.paused ) { this.updateActiveVideo( element ); MediaGallery.showPlayButton.setAs( element, false ); } else { videoElement.pause(); MediaGallery.showPlayButton.setAs( element, true ); } } OnTouchEnd.add( element as HTMLElement, onEnd ); OnTouchDrag.add( element as HTMLElement, onDrag ); } ) } static updateActiveVideo( e:Element ) { MediaGallery.activeVideoElement = e as HTMLElement; this.videoElements.forEach( ( v )=> { let isActive = MediaGallery.activeVideoElement === v; this.activeFlag.setAs( v, isActive ); let video = ElementType.video.query( v ); if ( ! video ) { return; } if ( video.paused === ! isActive ) { return; } if ( isActive ) { // video.currentTime = 0; video.play(); } else { video.pause(); MediaGallery.showPlayButton.setAs( v, true ); } } ) } }