import { parseSync , stringifySync } from 'subtitle' ; import { call , put , select , takeLatest } from 'redux-saga/effects' ; import { readFileAsText } from '../common/utils' ; import { filterItems , getSubtitles , updateCurrentItem } from './utils' ; import { ActionTypes } from "./actionTypes" ; import { ActionTypes as EditorActionTypes } from "../editor/actionTypes" ; import { AppStore } from "../store" ; import { Bundle } from "../linker" ; import { getMessage } from "../lang" ; export default function ( bundle ) { bundle . defineAction ( ActionTypes . SubtitlesCleared ) ; bundle . addReducer ( ActionTypes . SubtitlesCleared , subtitlesClearedReducer ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadFromText ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadFromUrl ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadFromFile ) ; bundle . defineAction ( ActionTypes . SubtitlesReload ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadStarted ) ; bundle . addReducer ( ActionTypes . SubtitlesLoadStarted , subtitlesLoadStartedReducer ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadSucceeded ) ; bundle . addReducer ( ActionTypes . SubtitlesLoadSucceeded , subtitlesLoadSucceededReducer ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadFailed ) ; bundle . addReducer ( ActionTypes . SubtitlesLoadFailed , subtitlesLoadFailedReducer ) ; bundle . defineAction ( ActionTypes . SubtitlesLoadForTrimSucceeded ) ; bundle . addReducer ( ActionTypes . SubtitlesLoadForTrimSucceeded , subtitlesLoadForTrimSucceededReducer ) ; bundle . defineAction ( ActionTypes . SubtitlesTrimDone ) ; bundle . addReducer ( ActionTypes . SubtitlesTrimDone , subtitlesTrimDoneReducer ) ; bundle . addSaga ( subtitlesLoadSaga ) ; } function subtitlesClearedReducer ( state ) { state . subtitles . loaded = false ; state . subtitles . text = '' ; state . subtitles . items = [ ] ; state . subtitles . filteredItems = [ ] ; state . subtitles . currentIndex = 0 ; state . subtitles . loadedKey = 'none' ; } function subtitlesLoadStartedReducer ( state , { payload : { key } } ) { state . subtitles . loaded = false ; state . subtitles . loading = key ; state . subtitles . lastError = '' ; } function subtitlesLoadSucceededReducer ( state , { payload : { key , text , items } } ) { state . subtitles . loaded = true ; state . subtitles . loading = false ; state . subtitles . loadedKey = key ; state . subtitles . text = text ; state . subtitles . items = items ; state . subtitles . filteredItems = filterItems ( items , state . subtitles . filterRegexp ) ; updateCurrentItem ( state . subtitles ) ; } function subtitlesLoadFailedReducer ( state , { payload : { error } } ) { let errorText = getMessage ( 'SUBTITLES_FAILED_TO_LOAD' ) . s ; if ( error . res ) { errorText = `${ errorText } (${ error . res . statusCode })` ; } state . subtitles . loaded = false ; state . subtitles . loading = false ; state . subtitles . lastError = errorText ; state . subtitles . text = errorText ; state . subtitles . loadedKey = 'none' ; } function subtitlesLoadForTrimSucceededReducer ( state , { payload : { key , items } } ) { const index = state . subtitles . trim . loaded . findIndex ( element => element . key === key ) ; console . log ( 'load succeeded' , state . subtitles . trim . loaded , index ) ; if ( index !== - 1 ) { state . subtitles . trim . loaded [ index ] = { key , items } ; } else { state . subtitles . trim . loaded . push ( { key , items } ) ; } } function subtitlesTrimDoneReducer ( state , { payload : { subtitles : data } } ) { if ( data . length ) { for ( const { key , text } of data ) { state . subtitles . availableOptions [ key ] . text = text ; state . subtitles . availableOptions [ key ] . unsaved = true ; } } } function * subtitlesLoadSaga ( ) { yield takeLatest ( ActionTypes . SubtitlesLoadFromText , subtitlesLoadFromTextSaga ) ; yield takeLatest ( ActionTypes . SubtitlesLoadFromUrl , subtitlesLoadFromUrlSaga ) ; yield takeLatest ( ActionTypes . SubtitlesLoadFromFile , subtitlesLoadFromFileSaga ) ; yield takeLatest ( ActionTypes . SubtitlesReload , subtitlesReloadSaga ) ; yield takeLatest ( EditorActionTypes . EditorTrimEnter , subtitlesLoadForTrimSaga ) ; } function * subtitlesLoadFromTextSaga ( action ) { yield put ( { type : ActionTypes . SubtitlesLoadStarted , payload : { key : action . payload . key } } ) ; let items ; try { items = parseSync ( action . payload . text ) ; } catch ( ex ) { yield put ( { type : ActionTypes . SubtitlesLoadFailed , payload : { key : action . payload . key , error : ex } } ) ; return ; } yield put ( { type : ActionTypes . SubtitlesLoadSucceeded , payload : { key : action . payload . key , text : action . payload . text , items } } ) ; } function * subtitlesLoadFromUrlSaga ( action ) { const options = yield select ( state => state . options ) ; if ( options . data && options . data . subtitlesData && action . payload . key in options . data . subtitlesData ) { yield put ( { type : ActionTypes . SubtitlesLoadSucceeded , payload : { key : action . payload . key , text : action . payload . text , items : options . data . subtitlesData [ action . payload . key ] , } } ) ; return ; } yield put ( { type : ActionTypes . SubtitlesLoadStarted , payload : { key : action . payload . key } } ) ; try { const text = yield call ( getSubtitles , action . payload . url ) ; const items = parseSync ( text ) ; yield put ( { type : ActionTypes . SubtitlesLoadSucceeded , payload : { key : action . payload . key , text : action . payload . text , items } } ) ; } catch ( ex ) { yield put ( { type : ActionTypes . SubtitlesLoadFailed , payload : { key : action . payload . key , error : ex } } ) ; } } function * subtitlesLoadFromFileSaga ( action ) { try { const text = yield call ( readFileAsText , action . payload . file ) ; const items = parseSync ( text ) ; yield put ( { type : ActionTypes . SubtitlesLoadSucceeded , payload : { key : action . payload . key , text : action . payload . text , items } } ) ; } catch ( ex ) { yield put ( { type : ActionTypes . SubtitlesLoadFailed , payload : { key : action . payload . key , error : ex } } ) ; } } function * subtitlesReloadSaga ( _action ) { const state = yield select ( ) ; const { selectedKey : key , availableOptions } = state . subtitles ; if ( key ) { let text = ( availableOptions [ key ] . text || '' ) . trim ( ) ; if ( ! text ) { const data = state . player . data ; text = stringifySync ( [ { data : { start : 0 , end : data . events [ data . events . length - 1 ] [ 0 ] , text : '' } , type : 'cue' } ] , { format : 'SRT' } ) ; } yield put ( { type : ActionTypes . SubtitlesLoadFromText , payload : { key , text } } ) ; } } export function * subtitlesLoadForTrimSaga ( ) { const state = yield select ( ) ; const { availableOptions } = state . subtitles ; const availKeys = Object . keys ( availableOptions ) . sort ( ) ; for ( const key of availKeys ) { const { url } = availableOptions [ key ] ; let text = ( availableOptions [ key ] . text || '' ) . trim ( ) ; try { console . log ( 'here text' , { text } ) ; if ( ! text ) { text = yield call ( getSubtitles , url ) ; console . log ( 'get subtitles' ) ; } const items = parseSync ( text ) ; console . log ( 'rsult items' , { items } ) ; yield put ( { type : ActionTypes . SubtitlesLoadForTrimSucceeded , payload : { key , items } } ) ; } catch ( ex ) { } } }