import { put, take, all, select, spawn, race, call, fork} from 'redux-saga/effects'
import { delay } from 'redux-saga';
import * as types from '../constants/actionTypes';
import { getLastSync } from '../selectors/syncSelectors';
import { getOnline } from '../selectors/authSelectors';
import moment from 'moment';
import { startSynchronize, endSynchronize, updateLastSync } from '../actions/syncActions';
import { forceSync } from '../actions/networkActions';
import { groupLoadAsync } from '../actions/groupActions';
import SessionSynchronizer from './SessionSyncronizer';
import NoteSynchronizer from './NoteSyncronizer';
import config from '../config';
function* doSync(context) {
const online = yield select(getOnline);
if(!online) {
yield put(endSynchronize());
return;
}
const lastSync = yield select(getLastSync);
yield put(startSynchronize());
const nextLastSync = moment().unix()
// TODO: manage errors
try {
const syncObjects = yield context.client.get('/api/notes/sync/', { modified_since: lastSync });
const sessionSynchronizer = new SessionSynchronizer(syncObjects.sessions, context.client);
yield sessionSynchronizer.syncObjects();
const noteSynchronizer = new NoteSynchronizer(syncObjects.notes, context.client);
yield noteSynchronizer.syncObjects();
yield put(updateLastSync(nextLastSync));
} finally {
yield put(endSynchronize());
}
}
function* doLoadGroup() {
yield put(groupLoadAsync());
}
function* watchDoSync(context) {
while (true) {
yield take(types.SYNC_DO_SYNC);
yield spawn(doSync, context); //we use spawn + take, because we do not want it to be interupted
yield fork(doLoadGroup);
yield take(types.SYNC_END_SYNC);
}
}
function* delayPutDoSync() {
yield put(forceSync());
yield call(delay, config.syncInterval);
}
function* loopDoSync() {
while(true) {
const online = yield select(getOnline);
if(!online) {
yield take(types.STATUS_ONLINE);
}
yield race({
delaySync: call(delayPutDoSync),
offline: take(types.STATUS_OFFLINE)
});
}
}
//--- The root saga
export default function* rootSaga(context) {
yield all([
watchDoSync(context),
loopDoSync()
]);
}