/** * Root sagas can be exported from every file, and are all bundled together in one master saga. * This saga listens for requests to sync, as well as failure events. */ export default function* rootSaga() { yield fork(takeLatest, cacheManagerActionTypes.SYNC_ALL, startSync); yield fork(takeLatest, cacheManagerActionTypes.SYNC_FAILED, showSyncFailed); } /** * Sync everything (download/upload from the server), but halt if a SYNC_FAILED event occurs. * * `race` starts multiple effects at once and stops everything else as soon as one completes. * The object keys here ('sync' and 'cancelSync') are not being used. */ function* startSync() { yield race({ sync: call(syncAll), cancelSync: take(cacheManagerActionTypes.SYNC_FAILED), }); } /** * Sync everything, showing status messages to the user as it progresses. * * `select` gets a value from the global state; * `call` calls a function; * `put` dispatches an event; * `take` waits until an event occurs; * `fork` calls another saga asynchronously. */ function* syncAll() { const { syncInProgress } = yield select((state) => ({ syncInProgress: state.sync.syncInProgress, })); if (syncInProgress) return; try { yield call(Snackbar.show, 'Downloading...'); yield put(CacheManagerActions.syncStarted()); yield fork(syncWorkingState); // Wait until all downloads are done. yield take(cacheManagerActionTypes.SYNC_FINISHED); yield fork(syncUrlCache); yield call(Snackbar.show, 'Uploading...'); yield put(CacheManagerActions.syncStarted()); yield fork(syncCheckins); yield fork(syncCompletions); yield fork(syncAttachments); // Wait until all uploads are done. yield take(cacheManagerActionTypes.SYNC_FINISHED); yield call(Snackbar.show, 'Sync successful!'); } catch (error) { yield put(CacheManagerActions.syncFailed()); } } /** * Show an error message to the user, and clean up. */ function* showSyncFailed() { yield call(Snackbar.show, 'Sync failed!'); yield put(CacheManagerActions.syncFinished()); }