import playerSagas from './sagas' ; import { findInstant } from './utils' ; import { ActionTypes as AppActionTypes } from '../actionTypes' ; import { ActionTypes } from "./actionTypes" ; import { AppAction , AppStore , AppStoreReplay } from "../store" ; import { Bundle } from "../linker" ; import { CodecastRecord } from "../recorder/save_screen" ; import { QuickalgoLibraryCall } from "../stepper/api" ; export interface PlayerResetPayload { sliceName : string ; state : unknown ; } export interface PlayerResetAction extends AppAction { type : ActionTypes . PlayerReset ; payload : PlayerResetPayload ; } export const playerReset = ( payload ) : PlayerResetAction => ( { type : ActionTypes . PlayerReset , payload , } ) ; export default function ( bundle ) { bundle . include ( playerSagas ) ; bundle . addReducer ( AppActionTypes . AppInit , ( state , { payload : { environment } } ) => { state . environment = environment ? environment : 'main' ; state . player = { ... initialStatePlayer } ; playerClear ( state ) ; } ) ; bundle . defineAction ( ActionTypes . PlayerClear ) ; bundle . addReducer ( ActionTypes . PlayerClear , ( state ) => { playerClear ( state ) ; } ) ; bundle . defineAction ( ActionTypes . PlayerPreparing ) ; bundle . addReducer ( ActionTypes . PlayerPreparing , ( state ) => { state . player . isReady = false ; } ) ; bundle . defineAction ( ActionTypes . PlayerPrepareProgress ) ; bundle . addReducer ( ActionTypes . PlayerPrepareProgress , ( state , { payload : { progress } } ) => { state . player . progress = progress ; } ) ; bundle . defineAction ( ActionTypes . PlayerPrepareFailure ) ; bundle . addReducer ( ActionTypes . PlayerPrepareFailure , ( state , { payload : { message } } ) => { state . player . error = { source : 'prepare' , message , details : '' } ; } ) ; bundle . defineAction ( ActionTypes . PlayerReady ) ; bundle . addReducer ( ActionTypes . PlayerReady , ( state , { payload : { duration , data , instants } } ) => { state . player . audioTime = 0 ; state . player . duration = duration ; state . player . data = data ; state . player . instants = instants ; state . player . current = instants . length ? instants [ 0 ] : null ; if ( state . player . data && state . player . duration ) { state . player . isReady = true ; } } ) ; bundle . defineAction ( ActionTypes . PlayerStarted ) ; bundle . addReducer ( ActionTypes . PlayerStarted , ( state ) => { state . player . isPlaying = true ; } ) ; bundle . defineAction ( ActionTypes . PlayerPaused ) ; bundle . addReducer ( ActionTypes . PlayerPaused , ( state ) => { state . player . isPlaying = false ; } ) ; bundle . defineAction ( ActionTypes . PlayerTick ) ; bundle . addReducer ( ActionTypes . PlayerTick , ( state , { payload : { audioTime } } ) => { const instants = state . player . instants ; state . player . current = findInstant ( instants , audioTime ) ; state . player . audioTime = audioTime ; } ) ; bundle . defineAction ( ActionTypes . PlayerVolumeChanged ) ; bundle . addReducer ( ActionTypes . PlayerVolumeChanged , ( state , { payload : { volume } } ) => { const audio = state . player . audio ; audio . volume = volume ; state . player . volume = audio . volume ; } ) ; bundle . defineAction ( ActionTypes . PlayerMutedChanged ) ; bundle . addReducer ( ActionTypes . PlayerMutedChanged , ( state , { payload : { isMuted } } ) => { const audio = state . player . audio ; state . player . isMuted = isMuted ; audio . muted = state . player . isMuted || state . editor . isMuted ; } ) ; bundle . defineAction ( ActionTypes . PlayerEditorMutedChanged ) ; bundle . addReducer ( ActionTypes . PlayerEditorMutedChanged , ( state , { payload : { isMuted } } ) => { const audio = state . player . audio ; state . editor . isMuted = isMuted ; audio . muted = state . player . isMuted || state . editor . isMuted ; } ) ; bundle . defineAction ( ActionTypes . PlayerSeek ) ; bundle . defineAction ( ActionTypes . PlayerSeeked ) ; bundle . defineAction ( ActionTypes . PlayerReset ) ; bundle . addReducer ( ActionTypes . PlayerReset , ( state , { payload : { sliceName , state : newState , partial } } ) => { if ( partial ) { state [ sliceName ] = { ... state [ sliceName ] , ... newState } ; } else { state [ sliceName ] = newState ; } } ) ; bundle . defineAction ( ActionTypes . PlayerResetFull ) ; bundle . addReducer ( ActionTypes . PlayerResetFull , ( state , { payload : { newState } } ) => { console . log ( 'DO FULL RESET WITH' , newState ) ; return newState ; } ) ; } ; export interface PlayerInstant { isEnd ? : boolean ; t : number ; pos : number ; event : any [ ] ; range ? : any ; state : AppStoreReplay ; sagas : any [ ] ; quickalgoLibraryCalls : QuickalgoLibraryCall [ ] ; jump ? : boolean ; mute ? : boolean ; } export type PlayerError = { message : string ; source : string ; details : string ; } ; export const initialStatePlayer = { audio : null as HTMLVideoElement , volume : 100 , isMuted : false , progress : 0 , audioTime : 0 , duration : 0 , data : null as CodecastRecord , instants : null as PlayerInstant [ ] , current : null as PlayerInstant , isReady : false , isPlaying : false , error : null as PlayerError } ; function playerClear ( state ) { const audio = document . createElement ( 'video' ) ; state . player . audio = audio ; state . player . audioTime = 0 ; state . player . volume = audio . volume ; state . player . isMuted = audio . muted ; state . player . progress = 0 ; }