import { SQLiteDatabase } from '@ulangi/sqlite-adapter' ; import { Action , ActionType , createAction } from '@ulangi/ulangi-action' ; import { CategorySortType } from '@ulangi/ulangi-common/enums' ; import { CategoryFilterCondition } from '@ulangi/ulangi-common/types' ; import { CategoryModel , SpacedRepetitionModel , WritingModel , } from '@ulangi/ulangi-local-database' ; import * as _ from 'lodash' ; import { Task } from 'redux-saga' ; import { call , cancel , fork , put , take } from 'redux-saga/effects' ; import { PromiseType } from 'utility-types' ; import { errorConverter } from '../converters/ErrorConverter' ; import { SagaConfig } from '../interfaces/SagaConfig' ; import { SagaEnv } from '../interfaces/SagaEnv' ; import { ProtectedSaga } from './ProtectedSaga' ; export class ManageSaga extends ProtectedSaga { private fetchCategoryTask ? : Task ; private userDb : SQLiteDatabase ; private categoryModel : CategoryModel ; private spacedRepetitionModel : SpacedRepetitionModel ; private writingModel : WritingModel ; public constructor ( userDb , categoryModel , spacedRepetitionModel , writingModel ) { super ( ) ; this . userDb = userDb ; this . categoryModel = categoryModel ; this . spacedRepetitionModel = spacedRepetitionModel ; this . writingModel = writingModel ; } public * run ( _ , config ) { yield fork ( [ this , this . allowPrepareAndClearFetchCategory ] , config . manage . fetchCategoryLimit ) ; yield fork ( [ this , this . allowFetchSpacedRepetitionDueAndNewCounts ] , config . spacedRepetition . maxLevel ) ; yield fork ( [ this , this . allowFetchWritingDueAndNewCounts ] , config . spacedRepetition . maxLevel ) ; } public * allowPrepareAndClearFetchCategory ( limit ) { this . fetchCategoryTask = yield fork ( [ this , this . allowPrepareFetchCategory ] , limit ) ; yield fork ( [ this , this . allowClearFetchCategory ] , limit ) ; } private * allowClearFetchCategory ( limit ) { while ( true ) { yield take ( ActionType . MANAGE__CLEAR_FETCH_CATEGORY ) ; if ( typeof this . fetchCategoryTask !== 'undefined' ) { yield cancel ( this . fetchCategoryTask ) ; } this . fetchCategoryTask = yield fork ( [ this , this . allowPrepareFetchCategory ] , limit ) ; } } private * allowPrepareFetchCategory ( limit ) { try { const action = yield take ( ActionType . MANAGE__PREPARE_FETCH_CATEGORY ) ; yield put ( createAction ( ActionType . MANAGE__PREPARING_FETCH_CATEGORY , null ) ) ; yield fork ( [ this , this . allowFetchCategory ] , action . payload . filterCondition , action . payload . sortType , limit ) ; yield put ( createAction ( ActionType . MANAGE__PREPARE_FETCH_CATEGORY_SUCCEEDED , null ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . MANAGE__PREPARE_FETCH_CATEGORY_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } private * allowFetchCategory ( filterCondition , sortType , limit ) { let offset = 0 ; while ( true ) { yield take ( ActionType . MANAGE__FETCH_CATEGORY ) ; try { yield put ( createAction ( ActionType . MANAGE__FETCHING_CATEGORY , null ) ) ; const { setId , vocabularyStatus } = filterCondition ; const { categoryList , } = yield call ( [ this . categoryModel , 'getCategoryListByVocabularyStatus' ] , this . userDb , setId , vocabularyStatus , sortType , limit , offset ) ; const noMore = categoryList . length === 0 ? true : false ; offset += limit ; yield put ( createAction ( ActionType . MANAGE__FETCH_CATEGORY_SUCCEEDED , { categoryList , noMore , } ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . MANAGE__FETCH_CATEGORY_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } } public * allowFetchSpacedRepetitionDueAndNewCounts ( maxLevel ) { while ( true ) { const action = yield take ( ActionType . MANAGE__FETCH_SPACED_REPETITION_DUE_AND_NEW_COUNTS ) ; const { setId , initialInterval , categoryNames } = action . payload ; yield fork ( [ this , this . fetchSpacedRepetitionDueAndNewCounts ] , setId , maxLevel , initialInterval , categoryNames ) ; } } public * fetchSpacedRepetitionDueAndNewCounts ( setId , maxLevel , initialInterval , categoryNames ) { try { yield put ( createAction ( ActionType . MANAGE__FETCHING_SPACED_REPETITION_DUE_AND_NEW_COUNTS , null ) ) ; const newCount = yield call ( [ this . spacedRepetitionModel , 'getNewCountByCategoryNames' ] , this . userDb , setId , categoryNames ) ; const dueCount = yield call ( [ this . spacedRepetitionModel , 'getDueCountByCategoryNames' ] , this . userDb , setId , initialInterval , maxLevel , categoryNames ) ; yield put ( createAction ( ActionType . MANAGE__FETCH_SPACED_REPETITION_DUE_AND_NEW_COUNTS_SUCCEEDED , _ . fromPairs ( categoryNames . map ( ( categoryName ) : [ string , { due : number ; new : number ; } ] => { return [ categoryName , { due : dueCount [ categoryName ] || 0 , new : newCount [ categoryName ] || 0 , } , ] ; } ) ) ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . MANAGE__FETCH_SPACED_REPETITION_DUE_AND_NEW_COUNTS_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } public * allowFetchWritingDueAndNewCounts ( maxLevel ) { while ( true ) { const action = yield take ( ActionType . MANAGE__FETCH_WRITING_DUE_AND_NEW_COUNTS ) ; const { setId , initialInterval , categoryNames } = action . payload ; yield fork ( [ this , this . fetchWritingDueAndNewCounts ] , setId , maxLevel , initialInterval , categoryNames ) ; } } public * fetchWritingDueAndNewCounts ( setId , maxLevel , initialInterval , categoryNames ) { try { yield put ( createAction ( ActionType . MANAGE__FETCHING_WRITING_DUE_AND_NEW_COUNTS , null ) ) ; const newCount = yield call ( [ this . writingModel , 'getNewCountByCategoryNames' ] , this . userDb , setId , categoryNames ) ; const dueCount = yield call ( [ this . writingModel , 'getDueCountByCategoryNames' ] , this . userDb , setId , initialInterval , maxLevel , categoryNames ) ; yield put ( createAction ( ActionType . MANAGE__FETCH_WRITING_DUE_AND_NEW_COUNTS_SUCCEEDED , _ . fromPairs ( categoryNames . map ( ( categoryName ) : [ string , { due : number ; new : number ; } ] => { return [ categoryName , { due : dueCount [ categoryName ] || 0 , new : newCount [ categoryName ] || 0 , } , ] ; } ) ) ) ) ; } catch ( error ) { yield put ( createAction ( ActionType . MANAGE__FETCH_WRITING_DUE_AND_NEW_COUNTS_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; } } }