import PouchDB from 'pouchdb'
import { put, take, takeLatest, all } from 'redux-saga/effects'
import * as types from '../constants/actionTypes';
import PouchDBFind from 'pouchdb-find';
import Immutable from 'immutable';
import APIClient from '../APIClient';
import config from '../config';
PouchDB.debug.disable();
PouchDB.plugin(PouchDBFind);
const sessionsDB = new PouchDB('sessions');
const notesDB = new PouchDB('notes');
notesDB.createIndex({
index: { fields: ['session'] }
});
const client = new APIClient(config.apiRootUrl);
// ---
export function* loadSessions() {
const response = yield sessionsDB.allDocs({ include_docs: true })
const sessions = response.rows.map(row => row.doc)
yield put({ type: types.LOAD_SESSIONS, sessions: Immutable.List(sessions) })
}
export function* watchLoadSessions() {
yield takeLatest(types.LOAD_SESSIONS_ASYNC, loadSessions)
}
// ---
export function* createSession(action) {
const response = yield sessionsDB.put(action.session);
// TODO Error control
const session = Object.assign({}, action.session, { rev: response.rev });
yield put({ type: types.CREATE_SESSION, session: session })
}
export function* watchCreateSession() {
yield takeLatest(types.CREATE_SESSION_ASYNC, createSession)
}
// ---
export function* updateSession(action) {
const { _id } = action.session;
let session;
const doc = yield sessionsDB.get(_id);
session = Object.assign({}, doc, action.values);
const response = yield sessionsDB.put(session);
yield put({
type: types.UPDATE_SESSION,
session: Object.assign({}, session, { rev: response.rev })
})
}
export function* watchUpdateSession() {
yield takeLatest(types.UPDATE_SESSION_ASYNC, updateSession)
}
// ---
export function* addNote(action) {
const response = yield notesDB.put(action.note);
// TODO Error control
const note = Object.assign({}, action.note, { rev: response.rev });
yield put({ type: types.ADD_NOTE, note: note })
}
export function* watchAddNote() {
yield takeLatest(types.ADD_NOTE_ASYNC, addNote)
}
// ---
export function* loadNotesBySession(action) {
const result = yield notesDB.find({
selector: { session: action.session._id },
// sort: ['name']
});
yield put({ type: types.LOAD_NOTES_BY_SESSION, notes: Immutable.List(result.docs) })
}
export function* watchLoadNotesBySession() {
yield takeLatest(types.LOAD_NOTES_BY_SESSION_ASYNC, loadNotesBySession)
}
// ---
export function* watchLoginSubmit() {
while (true) {
const { username, password } = yield take(types.AUTH_LOGIN_SUBMIT);
yield put({ type: types.AUTH_LOGIN_REQUEST, username, password });
}
}
function* watchLoginRequest() {
while (true) {
try {
const { username, password } = yield take(types.AUTH_LOGIN_REQUEST);
const response = yield client.post('/api/auth/login/', { username, password });
localStorage.setItem('currentUser', JSON.stringify(response.user));
localStorage.setItem('token', response.token);
const actions = [{
type: types.AUTH_LOGIN_SUCCESS,
user: response.user,
token: response.token,
meta: {
transition: (prevState, nextState, action) => ({
pathname: '/sessions',
}),
},
}, {
type: types.AUTH_STORE_TOKEN_ASYNC,
token: response.token,
}];
yield actions.map(action => put(action))
} catch(e) {
yield put({ type: types.AUTH_LOGIN_ERROR, error: e });
}
}
}
function* watchStoreToken() {
while (true) {
const { token } = yield take(types.AUTH_STORE_TOKEN_ASYNC);
yield put({ type: types.AUTH_STORE_TOKEN, token });
}
}
function* watchUpdateSettings() {
while (true) {
const { username, firstname, lastname } = yield take(types.USER_UPDATE_SETTINGS_ASYNC);
try {
yield client.put('/api/auth/user/', {
username,
first_name: firstname,
last_name: lastname
});
yield put({ type: types.USER_UPDATE_SETTINGS, firstname, lastname });
} catch (e) {
}
}
}
// ---
export default function* rootSaga() {
yield all([
watchLoadSessions(),
watchLoadNotesBySession(),
watchAddNote(),
watchCreateSession(),
watchUpdateSession(),
watchLoginSubmit(),
watchLoginRequest(),
watchStoreToken(),
watchUpdateSettings(),
])
}