import { assertExists } from '@ulangi/assert' ; import { SQLiteDatabase , Transaction } from '@ulangi/sqlite-adapter' ; import { ActionType , createAction } from '@ulangi/ulangi-action' ; import { currentComparableCommonVersion } from '@ulangi/ulangi-common' ; import { DownloadSpecificSetsRequest } from '@ulangi/ulangi-common/interfaces' ; import { DownloadSpecificSetsResponseResolver , SetResolver , } from '@ulangi/ulangi-common/resolvers' ; import { IncompatibleSetModel , SessionModel , SetModel , } from '@ulangi/ulangi-local-database' ; import axios , { AxiosResponse } from 'axios' ; import * as _ from 'lodash' ; import { call , delay , put } from 'redux-saga/effects' ; import { PromiseType } from 'utility-types' ; import { errorConverter } from '../converters/ErrorConverter' ; import { createRequest } from '../utils/createRequest' ; export class DownloadIncompatibleSetSaga { private setResolver = new SetResolver ( ) ; private downloadSpecificSetsResponseResolver = new DownloadSpecificSetsResponseResolver ( ) ; private userDb : SQLiteDatabase ; private sharedDb : SQLiteDatabase ; private sessionModel : SessionModel ; private setModel : SetModel ; private incompatibleSetModel : IncompatibleSetModel ; public constructor ( userDb , sharedDb , sessionModel , setModel , incompatibleSetModel ) { this . userDb = userDb ; this . sharedDb = sharedDb ; this . sessionModel = sessionModel ; this . setModel = setModel ; this . incompatibleSetModel = incompatibleSetModel ; } public * downloadIncompatibleSets ( apiUrl , downloadLimit , delayBetweenTransactions ) { let success , noMore ; try { yield put ( createAction ( ActionType . SET__DOWNLOADING_INCOMPATIBLE_SETS , null ) ) ; const accessToken = yield call ( [ this . sessionModel , 'getAccessToken' ] , this . sharedDb ) ; const latestSyncedTime = yield call ( [ this . setModel , 'getLatestSyncTime' ] , this . userDb ) ; const { setIds : existingIncompatibleSetIds , } = yield call ( [ this . incompatibleSetModel , 'getIncompatibleSetIdsForRedownload' ] , this . userDb , currentComparableCommonVersion , downloadLimit , true ) ; noMore = existingIncompatibleSetIds . length === 0 ; if ( noMore === false ) { const response = yield call ( [ axios , 'request' ] , createRequest < DownloadSpecificSetsRequest > ( 'post' , apiUrl , '/download-specific-sets' , null , { setIds : existingIncompatibleSetIds , } , { accessToken : assertExists ( accessToken ) } ) ) ; const { setList : downloadedSetList , } = this . downloadSpecificSetsResponseResolver . resolve ( response . data , true ) ; const setList = downloadedSetList . filter ( ( set ) : boolean => { return ( set . lastSyncedAt !== null && latestSyncedTime !== null && set . lastSyncedAt <= latestSyncedTime ) ; } ) ; const existedSetIds = yield call ( [ this . setModel , 'setIdsExist' ] , this . userDb , setList . map ( ( set ) : string => set . setId ) ) ; for ( const set of setList ) { yield call ( [ this . userDb , 'transaction' ] , ( tx ) : void => { ! _ . includes ( existedSetIds , set . setId ) ? this . setModel . insertSet ( tx , set , 'remote' ) : this . setModel . updateSet ( tx , set , 'remote' ) , ! this . setResolver . isValid ( set , false ) ? this . incompatibleSetModel . upsertIncompatibleSet ( tx , set . setId , currentComparableCommonVersion ) : this . incompatibleSetModel . deleteIncompatibleSet ( tx , set . setId ) ; } ) ; yield delay ( delayBetweenTransactions ) ; } yield put ( createAction ( ActionType . SET__DOWNLOAD_INCOMPATIBLE_SETS_SUCCEEDED , { setList , } ) ) ; } else { yield put ( createAction ( ActionType . SET__DOWNLOAD_INCOMPATIBLE_SETS_SUCCEEDED , { setList : [ ] , } ) ) ; } success = true ; } catch ( error ) { yield put ( createAction ( ActionType . SET__DOWNLOAD_INCOMPATIBLE_SETS_FAILED , { errorCode : errorConverter . getErrorCode ( error ) , error , } ) ) ; success = false ; } return { success , noMore } ; } }