import View from "../View" ; import { doNavbarItemsAnimation } from "./ItemsAnimationHelpers" ; import { doViewsSlideAnimation , doViewsOverlayAnimation , doViewsFadeAnimation } from "./ViewsFXHelpers" ; import { NavbarProp } from "../SceneRenderer" ; import { AnimationType } from "../Airr" ; import Scene from "../Scene" ; import { ViewProps } from "../ViewRenderer" ; function invokeViewsAfterEffects ( newViewComp , oldViewComp ) { if ( newViewComp && typeof newViewComp . viewAfterActivation === "function" ) { newViewComp . viewAfterActivation ( ) ; } if ( oldViewComp && typeof oldViewComp . viewAfterDeactivation === "function" ) { oldViewComp . viewAfterDeactivation ( ) ; } } interface DoViewsAnimationConfig { newViewComp : View < ViewProps > ; oldViewComp : View < ViewProps > ; newViewIndex : number ; oldViewIndex : number ; navbar : NavbarProp ; animationTime : number ; animation : AnimationType ; stackMode : boolean ; ctnDOM : HTMLElement ; sceneWidth : number ; mockTitle ? : HTMLElement ; titleNode ? : HTMLElement ; backDOM ? : HTMLElement ; } function doViewsAnimation ( { newViewComp , oldViewComp , newViewIndex , oldViewIndex , navbar , mockTitle , titleNode , backDOM , animation , animationTime , stackMode , ctnDOM , sceneWidth } ) { return new Promise ( ( resolve ) : void => { const oldViewName = oldViewComp . props . name ; const newViewDOM = newViewComp . refDOM . current ; const oldViewDOM = oldViewComp . refDOM . current ; const direction = newViewIndex > oldViewIndex ? 1 : - 1 ; if ( ! newViewDOM ) { throw new Error ( "new view DOM refference was not found" ) ; } if ( navbar ) { doNavbarItemsAnimation ( { newViewIndex , oldViewIndex , direction , mockTitle , titleNode , backDOM , animationTime } ) ; } if ( animation === "slide" && oldViewName ) { doViewsSlideAnimation ( newViewDOM , sceneWidth , ctnDOM , direction , animationTime ) . then ( resolve ) ; } else if ( animation === "overlay" && oldViewName ) { doViewsOverlayAnimation ( { newViewDOM , oldViewDOM , direction , animationTime , ctnWidth : ctnDOM . clientWidth , ctnHeight : ctnDOM . clientHeight , stackMode } ) . then ( resolve ) ; } else if ( animation === "fade" || ! oldViewName ) { doViewsFadeAnimation ( newViewDOM , animationTime ) . then ( resolve ) ; } } ) ; } interface PerformViewsTransitionConfig extends DoViewsAnimationConfig { animEndCallback : ( ) => void ; } export function performViewsTransition ( { newViewComp , oldViewComp , newViewIndex , oldViewIndex , navbar , mockTitle , titleNode , backDOM , animation , animationTime , stackMode , ctnDOM , sceneWidth , animEndCallback } ) { if ( newViewComp && typeof newViewComp . viewBeforeActivation === "function" ) { newViewComp . viewBeforeActivation ( ) ; } if ( oldViewComp && typeof oldViewComp . viewBeforeDeactivation === "function" ) { oldViewComp . viewBeforeDeactivation ( ) ; } if ( animation ) { doViewsAnimation ( { newViewComp , oldViewComp , newViewIndex , oldViewIndex , navbar , mockTitle , titleNode , backDOM , animation , animationTime , stackMode , ctnDOM , sceneWidth } ) . then ( ( ) : void => { animEndCallback ( ) ; } ) ; } else { animEndCallback ( ) ; } } function scenePreAnimEndStateChange ( scene , newViewName ) { return new Promise ( resolve => { scene . setState ( { activeViewName : newViewName , GUIDisabled : false , mockTitleName : null } , resolve ) ; } ) ; } export function getViewsTransitionConfig ( newViewName , scene , callback ) { const oldViewName = scene . state . activeViewName ; const newViewComp = scene . refsCOMPViews [ newViewName ] . current ; const oldViewComp = scene . refsCOMPViews [ oldViewName ] . current ; const newViewIndex = scene . getViewIndex ( newViewName ) ; const oldViewIndex = scene . getViewIndex ( oldViewName ) ; return { newViewComp , oldViewComp , newViewIndex , oldViewIndex , navbar : scene . state . navbar , titleNode : scene . refDOMNavbar . current && ( scene . refDOMNavbar . current . querySelector ( ".title" ) as HTMLElement ) , mockTitle : scene . refDOMNavbar . current && ( scene . refDOMNavbar . current . querySelector ( ".mock-title" ) as HTMLElement ) , animation : scene . state . animation , animationTime : scene . state . animationTime , sceneWidth : scene . refDOM . current . clientWidth , ctnDOM : scene . refDOMContainer . current , stackMode : scene . state . stackMode , backDOM : scene . state . backButton && ! scene . state . backButtonOnFirstView ? ( scene . refDOMNavbar . current . querySelector ( ".back" ) as HTMLElement ) : null , animEndCallback : ( ) => { scenePreAnimEndStateChange ( scene , newViewName ) . then ( ( ) => { scene . viewChangeInProgress = false ; invokeViewsAfterEffects ( newViewComp , oldViewComp ) ; if ( typeof scene . viewsAnimationEnd === "function" ) { scene . viewsAnimationEnd ( oldViewName , newViewName ) ; } callback ( ) ; } ) ; } } ; }