// - Import domain import { User } from 'domain/users' import { Circle, UserFollower } from 'domain/circles' import { SocialError } from 'domain/common' // - Import utility components import moment from 'moment' // - Import action types import { CircleActionType } from 'constants/circleActionType' // - Import actions import * as globalActions from 'actions/globalActions' import * as postActions from 'actions/postActions' import * as userActions from 'actions/userActions' import * as notifyActions from 'actions/notifyActions' import { IServiceProvider,ServiceProvide } from 'factories' import { ICircleService } from 'services/circles' const serviceProvider: IServiceProvider = new ServiceProvide() const circleService: ICircleService = serviceProvider.createCircleService() /* _____________ CRUD DB _____________ */ /** * Add a circle * @param {string} circleName */ export let dbAddCircle = (circleName: string) => { return (dispatch: any, getState: Function) => { let uid: string = getState().authorize.uid let circle: Circle = { creationDate: moment().unix(), name: circleName, users: {} } return circleService.addCircle(uid,circle).then((circleKey: string) => { circle.id = circleKey circle.ownerId = uid dispatch(addCircle(circle)) }, (error: SocialError) => dispatch(globalActions.showErrorMessage(error.message))) } } /** * Add a user in a circle * @param {string} cid is circle identifier * @param {User} userFollowing is the user for following */ export let dbAddFollowingUser = (cid: string, userFollowing: User) => { return (dispatch: any, getState: Function) => { let uid: string = getState().authorize.uid let user: User = getState().user.info[uid] let userCircle: User = { creationDate: moment().unix(), fullName: userFollowing.fullName, avatar: userFollowing.avatar || '' } let userFollower: UserFollower = { creationDate: moment().unix(), fullName: user.fullName, avatar: user.avatar || '', approved: false } return circleService.addFollowingUser(uid,cid,userCircle,userFollower,userFollowing.userId as string) .then(() => { dispatch(addFollowingUser(uid, cid, userFollowing.userId as string, { ...userCircle } as User)) dispatch(notifyActions.dbAddNotification( { description: `${user.fullName} follow you.`, url: `/${uid}`, notifyRecieverUserId: userFollowing.userId as string, notifierUserId: uid, isSeen: false })) }, (error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Delete a user from a circle * @param {string} cid is circle identifier * @param {string} userFollowingId following user identifier */ export let dbDeleteFollowingUser = (cid: string, userFollowingId: string) => { return (dispatch: any, getState: Function) => { let uid: string = getState().authorize.uid return circleService.deleteFollowingUser(uid,cid,userFollowingId) .then(() => { dispatch(deleteFollowingUser(uid, cid, userFollowingId)) }, (error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Update a circle from database * @param {Circle} newCircle */ export const dbUpdateCircle = (newCircle: Circle) => { return (dispatch: any, getState: Function) => { // Get current user id let uid: string = getState().authorize.uid // Write the new data simultaneously in the list let circle: Circle = getState().circle.userCircles[uid][newCircle.id!] let updatedCircle: Circle = { name: newCircle.name || circle.name, users: newCircle.users ? newCircle.users : (circle.users || []) } return circleService.updateCircle(uid,newCircle.id!,circle) .then(() => { dispatch(updateCircle(uid,{ id: newCircle.id, ...updatedCircle })) }, (error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Delete a circle from database * @param {string} id is circle identifier */ export const dbDeleteCircle = (id: string) => { return (dispatch: any, getState: Function) => { // Get current user id let uid: string = getState().authorize.uid return circleService.deleteCircle(uid,id) .then(() => { dispatch(deleteCircle(uid, id)) }, (error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } /** * Get all user circles from data base */ export const dbGetCircles = () => { return (dispatch: any, getState: Function) => { let uid: string = getState().authorize.uid if (uid) { return circleService.getCircles(uid) .then((circles: { [circleId: string]: Circle }) => { 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, '')) }) } }) dispatch(addCircles(uid, circles)) }) .catch((error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } } /** * Get all user circles from data base by user id * @param uid user identifier */ export const dbGetCirclesByUserId = (uid: string) => { return (dispatch: any, getState: Function) => { if (uid) { return circleService.getCircles(uid) .then((circles: { [circleId: string]: Circle }) => { dispatch(addCircles(uid, circles)) }) .catch((error: SocialError) => { dispatch(globalActions.showErrorMessage(error.message)) }) } } } /* _____________ CRUD State _____________ */ /** * Add a normal circle * @param {string} uid is user identifier * @param {Circle} circle */ export const addCircle = (circle: Circle) => { return { type: CircleActionType.ADD_CIRCLE, payload: { circle } } } /** * Update a circle * @param {string} uid is user identifier * @param {Circle} circle */ export const updateCircle = (uid: string, circle: Circle) => { return { type: CircleActionType.UPDATE_CIRCLE, payload: { uid, circle } } } /** * Delete a circle * @param {string} uid is user identifier * @param {string} id is circle identifier */ export const deleteCircle = (uid: string, id: string) => { return { type: CircleActionType.DELETE_CIRCLE, payload: { uid, id } } } /** * Add a list of circle * @param {string} uid * @param {circleId: string]: Circle} circles */ export const addCircles = (uid: string, circles: { [circleId: string]: Circle }) => { return { type: CircleActionType.ADD_LIST_CIRCLE, payload: { uid, circles } } } /** * Clea all data in circle store */ export const clearAllCircles = () => { return { type: CircleActionType.CLEAR_ALL_CIRCLES } } /** * Open circle settings * @param uid user idenifier * @param id circle identifier */ export const openCircleSettings = (uid: string, id: string) => { return { type: CircleActionType.OPEN_CIRCLE_SETTINGS, payload: { uid, id } } } /** * Close open circle settings * @param uid user identifier * @param id circle identifier */ export const closeCircleSettings = (uid: string, id: string) => { return { type: CircleActionType.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 {User} userCircle information about following user */ export const addFollowingUser = (uid: string, cid: string, followingId: string, userCircle: User) => { return { type: CircleActionType.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: string, cid: string, followingId: string) => { return { type: CircleActionType.DELETE_FOLLOWING_USER, payload: { uid, cid, followingId } } }