// - Import firebase component import firebase, { firebaseRef } from 'app/firebase/' // - Import utility components import moment from 'moment' // - Import action types import * as types from 'actionTypes' // - Import actions import * as globalActions from 'globalActions' import * as postActions from 'postActions' import * as userActions from 'userActions' import * as notifyActions from 'notifyActions' /* _____________ CRUD DB _____________ */ /** * Add a circle * @param {string} circleName */ export var dbAddCircle = (circleName) => { return (dispatch, getState) => { let uid = getState().authorize.uid let circle = { creationDate: moment().unix(), name: circleName, users: {} } let circleRef = firebaseRef.child(`userCircles/${uid}/circles`).push(circle) return circleRef.then(() => { dispatch(addCircle(uid, { ...circle, id: circleRef.key })) }, (error) => dispatch(globalActions.showErrorMessage(error.message))) } } /** * Add a user in a circle * @param {string} cid is circle identifier * @param {object} userFollowing is the user for following */ export var dbAddFollowingUser = (cid, userFollowing) => { return (dispatch, getState) => { let uid = getState().authorize.uid let user = getState().user.info[uid] let userCircle = { creationDate: moment().unix(), fullName: userFollowing.fullName, avatar: userFollowing.avatar || '' } let userFollower = { creationDate: moment().unix(), fullName: user.fullName, avatar: user.avatar || '', approved: false } let updates = {} updates[`userCircles/${uid}/circles/${cid}/users/${userFollowing.userId}`] = userCircle updates[`userCircles/${userFollowing.userId}/circles/-Followers/users/${uid}`] = userFollower return firebaseRef.update(updates).then((result) => { dispatch(addFollowingUser(uid, cid, userFollowing.userId, { ...userCircle })) dispatch(notifyActions.dbAddNotify( { description: `${user.fullName} follow you.`, url: `/${uid}`, notifyRecieverUserId: userFollowing.userId, notifierUserId: uid })) }, (error) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Add a user in a circle * @param {string} cid is circle identifier * @param {string} followingId following user identifier */ export var dbDeleteFollowingUser = (cid, followingId) => { return (dispatch, getState) => { let uid = getState().authorize.uid let updates = {} updates[`userCircles/${uid}/circles/${cid}/users/${followingId}`] = null updates[`userCircles/${followingId}/circles/-Followers/users/${uid}`] = null return firebaseRef.update(updates).then((result) => { dispatch(deleteFollowingUser(uid, cid, followingId)) }, (error) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Update a circle from database * @param {object} newCircle */ export const dbUpdateCircle = (newCircle) => { return (dispatch, getState) => { // Get current user id var uid = getState().authorize.uid // Write the new data simultaneously in the list let updates = {} let circle = getState().circle.userCircles[uid][newCircle.id] let updatedCircle = { name: newCircle.name || circle.name, users: newCircle.users ? newCircle.users : (circle.users || []) } updates[`userCircles/${uid}/circles/${newCircle.id}`] = updatedCircle return firebaseRef.update(updates).then((result) => { dispatch(updateCircle(uid, { id: newCircle.id, ...updatedCircle })) }, (error) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Delete a circle from database * @param {string} id is circle identifier */ export const dbDeleteCircle = (id) => { return (dispatch, getState) => { // Get current user id var uid = getState().authorize.uid // Write the new data simultaneously in the list var updates = {}; updates[`userCircles/${uid}/circles/${id}`] = null; return firebaseRef.update(updates).then((result) => { dispatch(deleteCircle(uid, id)) }, (error) => { dispatch(globalActions.showErrorMessage(error.message)) }); } } /** * Get all user circles from data base */ export const dbGetCircles = () => { return (dispatch, getState) => { var uid = getState().authorize.uid if (uid) { var circlesRef = firebaseRef.child(`userCircles/${uid}/circles`); return circlesRef.once('value').then((snapshot) => { var circles = snapshot.val() || {}; var parsedCircles = {}; Object.keys(circles).forEach((circleId) => { if (circleId !== '-Followers' && circles[circleId].users) { Object.keys(circles[circleId].users).filter((v, i, a) => a.indexOf(v) === i).forEach((userId) => { dispatch(postActions.dbGetPostsByUserId(userId)) dispatch(userActions.dbGetUserInfoByUserId(userId)) }) } parsedCircles[circleId] = { id: circleId, ...circles[circleId] } }) dispatch(addCircles(uid, parsedCircles)); }); } } } /** * Get all user circles from data base by user id */ export const dbGetCirclesByUserId = (uid) => { return (dispatch, getState) => { if (uid) { var circlesRef = firebaseRef.child(`userCircles/${uid}/circles`); return circlesRef.once('value').then((snapshot) => { var circles = snapshot.val() || {}; var parsedCircles = {}; Object.keys(circles).forEach((circleId) => { parsedCircles[circleId] = { id: circleId, ...circles[circleId] } }) dispatch(addCircles(uid, parsedCircles)); }) } } } /* _____________ CRUD State _____________ */ /** * Add a normal circle * @param {string} uid is user identifier * @param {object} circle */ export const addCircle = (uid, circle) => { return { type: types.ADD_CIRCLE, payload: { uid, circle } } } /** * Update a circle * @param {string} uid is user identifier * @param {object} circle */ export const updateCircle = (uid, circle) => { return { type: types.UPDATE_CIRCLE, payload: { uid, circle } } } /** * Delete a circle * @param {string} uid is user identifier * @param {string} id is circle identifier */ export const deleteCircle = (uid, id) => { return { type: types.DELETE_CIRCLE, payload: { uid, id } } } /** * Add a list of circle * @param {string} uid * @param {[object]} circles */ export const addCircles = (uid, circles) => { return { type: types.ADD_LIST_CIRCLE, payload: { uid, circles } } } /** * Clea all data in circle store */ export const clearAllCircles = () => { return { type: types.CLEAR_ALL_CIRCLES } } /** * Open circle settings */ export const openCircleSettings = (uid, id) => { return { type: types.OPEN_CIRCLE_SETTINGS, payload: { uid, id } } } /** * Close open circle settings */ export const closeCircleSettings = (uid, id) => { return { type: types.CLOSE_CIRCLE_SETTINGS, payload: { uid, id } } } /** * Add following user in a circle * @param {string} uid user identifire who want to follow the following user * @param {string} cid circle identifier that following user should be added in * @param {string} followingId following user identifier * @param {object} userCircle information about following user */ export const addFollowingUser = (uid, cid, followingId, userCircle) => { return { type: types.ADD_FOLLOWING_USER, payload: { uid, cid, followingId, userCircle } } } /** * Delete following user from a circle * @param {string} uid user identifire who want to follow the following user * @param {string} cid circle identifier that following user should be added in * @param {string} followingId following user identifier */ export const deleteFollowingUser = (uid, cid, followingId) => { return { type: types.DELETE_FOLLOWING_USER, payload: { uid, cid, followingId } } }