Initial git
This commit is contained in:
138
app/actions/authorizeActions.jsx
Normal file
138
app/actions/authorizeActions.jsx
Normal file
@@ -0,0 +1,138 @@
|
||||
// - Import react components
|
||||
import {firebaseRef, firebaseAuth} from 'app/firebase/'
|
||||
import moment from 'moment'
|
||||
import {push} from 'react-router-redux'
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
/**
|
||||
* Log in user in server
|
||||
* @param {string} email
|
||||
* @param {string} password
|
||||
*/
|
||||
export var dbLogin = (email, password) => {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(globalActions.showNotificationRequest())
|
||||
|
||||
return firebaseAuth().signInWithEmailAndPassword(email, password).then((result) => {
|
||||
dispatch(globalActions.showNotificationSuccess())
|
||||
dispatch(login(result.uid))
|
||||
dispatch(push('/'))
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.code)))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out user in server
|
||||
*/
|
||||
export var dbLogout = () => {
|
||||
return (dispatch, getState) => {
|
||||
return firebaseAuth().signOut().then((result) => {
|
||||
dispatch(logout())
|
||||
dispatch(push('/login'))
|
||||
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.code)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user in database
|
||||
* @param {object} user
|
||||
*/
|
||||
export var dbSignup = (user) => {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(globalActions.showNotificationRequest())
|
||||
return firebaseAuth().createUserWithEmailAndPassword(user.email, user.password).then((signupResult) => {
|
||||
firebaseRef.child(`users/${signupResult.uid}/info`).set({
|
||||
...user
|
||||
}).then((result) => {
|
||||
|
||||
dispatch(globalActions.showNotificationSuccess())
|
||||
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.code)))
|
||||
|
||||
dispatch(signup({
|
||||
uid: signupResult.uid,
|
||||
...user
|
||||
}))
|
||||
dispatch(push('/'))
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.code)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change user's password
|
||||
* @param {string} newPassword
|
||||
*/
|
||||
export const dbUpdatePassword = (newPassword) => {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(globalActions.showNotificationRequest())
|
||||
firebaseAuth().onAuthStateChanged((user) => {
|
||||
if (user) {
|
||||
|
||||
user.updatePassword(newPassword).then(() => {
|
||||
// Update successful.
|
||||
dispatch(globalActions.showNotificationSuccess())
|
||||
dispatch(updatePassword())
|
||||
dispatch(push('/'))
|
||||
}, (error) => {
|
||||
// An error happened.
|
||||
switch (error.code) {
|
||||
case 'auth/requires-recent-login':
|
||||
dispatch(globalActions.showErrorMessage(error.code))
|
||||
dispatch(dbLogout())
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
/**
|
||||
* Loing user
|
||||
* @param {string} uid
|
||||
*/
|
||||
export var login = (uid) => {
|
||||
return {type: types.LOGIN, authed: true, uid}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout user
|
||||
*/
|
||||
export var logout = () => {
|
||||
return {type: types.LOGOUT}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user
|
||||
* @param {object} user
|
||||
*/
|
||||
export var signup = (user) => {
|
||||
return {
|
||||
type: types.SIGNUP,
|
||||
...user
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user's password
|
||||
*/
|
||||
export const updatePassword = () => {
|
||||
return {type: types.UPDATE_PASSWORD}
|
||||
}
|
||||
|
||||
337
app/actions/circleActions.jsx
Normal file
337
app/actions/circleActions.jsx
Normal file
@@ -0,0 +1,337 @@
|
||||
// - 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 }
|
||||
}
|
||||
|
||||
}
|
||||
231
app/actions/commentActions.jsx
Normal file
231
app/actions/commentActions.jsx
Normal file
@@ -0,0 +1,231 @@
|
||||
// - Import react components
|
||||
import moment from 'moment'
|
||||
import { firebaseRef } from 'app/firebase/'
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
import * as notifyActions from 'notifyActions'
|
||||
|
||||
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
/**
|
||||
* Add comment to database
|
||||
* @param {object} newComment user comment
|
||||
* @param {function} callBack will be fired when server responsed
|
||||
*/
|
||||
export const dbAddComment = (newComment, callBack) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var comment = {
|
||||
postId: newComment.postId,
|
||||
score: 0,
|
||||
text: newComment.text,
|
||||
creationDate: moment().unix(),
|
||||
userDisplayName: getState().user.info[uid].fullName,
|
||||
userAvatar: getState().user.info[uid].avatar,
|
||||
userId: uid
|
||||
}
|
||||
|
||||
var commentRef = firebaseRef.child(`postComments/${newComment.postId}`).push(comment)
|
||||
return commentRef.then(() => {
|
||||
dispatch(addComment(
|
||||
{
|
||||
comment,
|
||||
postId: newComment.postId,
|
||||
id: commentRef.key,
|
||||
editorStatus: false
|
||||
}))
|
||||
callBack()
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
if (newComment.ownerPostUserId !== uid)
|
||||
dispatch(notifyActions.dbAddNotify(
|
||||
{
|
||||
description: 'Add comment on your post.',
|
||||
url: `/${newComment.ownerPostUserId}/posts/${newComment.postId}`,
|
||||
notifyRecieverUserId: newComment.ownerPostUserId, notifierUserId: uid
|
||||
}))
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all comments from database
|
||||
*/
|
||||
export const dbGetComments = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var commentsRef = firebaseRef.child(`postComments`);
|
||||
|
||||
return commentsRef.on('value', (snapshot) => {
|
||||
var comments = snapshot.val() || {};
|
||||
dispatch(addCommentList(comments))
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a comment from database
|
||||
* @param {string} id of comment
|
||||
* @param {string} postId is the identifier of the post which comment belong to
|
||||
*/
|
||||
export const dbUpdateComment = (id, postId, text) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
let comment = getState().comment.postComments[postId][id]
|
||||
updates[`postComments/${postId}/${id}`] = {
|
||||
postId: postId,
|
||||
score: comment.score,
|
||||
text: text,
|
||||
creationDate: comment.creationDate,
|
||||
userDisplayName: comment.userDisplayName,
|
||||
userAvatar: comment.userAvatar,
|
||||
userId: uid
|
||||
}
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(updateComment({ id, postId, text, editorStatus: false }))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a comment from database
|
||||
* @param {string} id of comment
|
||||
* @param {string} postId is the identifier of the post which comment belong to
|
||||
*/
|
||||
export const dbDeleteComment = (id, postId) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
updates[`postComments/${postId}/${id}`] = null;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(deleteComment(id, postId))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
|
||||
/**
|
||||
* Add comment
|
||||
* @param {object} data
|
||||
*/
|
||||
export const addComment = (data) => {
|
||||
|
||||
return {
|
||||
type: types.ADD_COMMENT,
|
||||
payload: data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update comment
|
||||
* @param {object} data
|
||||
*/
|
||||
export const updateComment = (data) => {
|
||||
|
||||
return {
|
||||
type: types.UPDATE_COMMENT,
|
||||
payload: data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add comment list
|
||||
* @param {[object]} postComments an array of comments
|
||||
*/
|
||||
export const addCommentList = (postComments) => {
|
||||
|
||||
return {
|
||||
type: types.ADD_COMMENT_LIST,
|
||||
payload: postComments
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Delete a comment
|
||||
* @param {string} id of comment
|
||||
* @param {string} postId is the identifier of the post which comment belong to
|
||||
*/
|
||||
export const deleteComment = (id, postId) => {
|
||||
return { type: types.DELETE_COMMENT, payload: { id, postId } }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data
|
||||
*/
|
||||
export const clearAllData = () => {
|
||||
return {
|
||||
type: types.CLEAR_ALL_DATA_COMMENT
|
||||
}
|
||||
}
|
||||
|
||||
export const openCommentEditor = (comment) => {
|
||||
|
||||
return {
|
||||
type: types.OPEN_COMMENT_EDITOR,
|
||||
payload: comment
|
||||
}
|
||||
}
|
||||
|
||||
export const closeCommentEditor = (comment) => {
|
||||
|
||||
return {
|
||||
type: types.CLOSE_COMMENT_EDITOR,
|
||||
payload: comment
|
||||
}
|
||||
}
|
||||
|
||||
52
app/actions/fileActions.jsx
Normal file
52
app/actions/fileActions.jsx
Normal file
@@ -0,0 +1,52 @@
|
||||
// - Import react components
|
||||
import moment from 'moment'
|
||||
|
||||
// - Import image gallery action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as imageGalleryActions from 'imageGalleryActions'
|
||||
|
||||
// - Import firebase
|
||||
import {storageRef,firebaseRef} from 'app/firebase/'
|
||||
|
||||
|
||||
// - Upload file start
|
||||
export const uploadFile = (file) => {
|
||||
return (dispatch,getState) => {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// - Upload file error
|
||||
export const uploadError = (error) => {
|
||||
return{
|
||||
type: types.UPLOAD_FILE_ERROR,
|
||||
error
|
||||
}
|
||||
}
|
||||
|
||||
// - Uplaod file complete
|
||||
export const uploadComplete = (result) => {
|
||||
return{
|
||||
type: types.UPLOAD_FILE_COMPLETE,
|
||||
result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// - Download file
|
||||
export const downloadFile = (fileName) => {
|
||||
return {
|
||||
type: types.DOWNLOAD_FILE,
|
||||
fileName
|
||||
}
|
||||
}
|
||||
218
app/actions/globalActions.jsx
Normal file
218
app/actions/globalActions.jsx
Normal file
@@ -0,0 +1,218 @@
|
||||
// - Import image gallery action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as postActions from 'postActions'
|
||||
import * as commentActions from 'commentActions'
|
||||
import * as userActions from 'userActions'
|
||||
|
||||
/**
|
||||
* Progress change
|
||||
* @param {string} percent
|
||||
* @param {boolean} visible
|
||||
*/
|
||||
export const progressChange = (percent, visible) => {
|
||||
return {
|
||||
type: types.PROGRESS_CHANGE,
|
||||
payload: {percent, visible}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Default data loaded status will be true
|
||||
* @param {boolean} status
|
||||
*/
|
||||
export const defaultDataEnable = (status) => {
|
||||
return{
|
||||
type: types.DEFAULT_DATA_ENABLE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default data loaded status will be false
|
||||
* @param {boolean} status
|
||||
*/
|
||||
export const defaultDataDisable = (status) => {
|
||||
return{
|
||||
type: types.DEFAULT_DATA_DISABLE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Show notification normally
|
||||
* @param {string} message
|
||||
*/
|
||||
export const showNotificationNormal = (message) => {
|
||||
return (dispatch,getState) => {
|
||||
dispatch(showNormalMessage(message))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// - Show global normal message
|
||||
export const showNormalMessage = (message) => {
|
||||
return{
|
||||
type: types.SHOW_NORMAL_MESSAGE_GLOBAL,
|
||||
message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// - Show notification of request
|
||||
export const showNotificationRequest = () => {
|
||||
return (dispatch,getState) => {
|
||||
dispatch(showSendRequestMessage())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// - Show global request sent message
|
||||
export const showSendRequestMessage = () => {
|
||||
return{
|
||||
type: types.SHOW_SEND_REQUEST_MESSAGE_GLOBAL
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// - Show notification of success
|
||||
export const showNotificationSuccess = () => {
|
||||
return (dispatch,getState) => {
|
||||
dispatch(showRequestSuccessMessage())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// - Show global request successful message
|
||||
export const showRequestSuccessMessage = () => {
|
||||
return{
|
||||
type: types.SHOW_REQUEST_SUCCESS_MESSAGE_GLOBAL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide global message
|
||||
*/
|
||||
export const hideMessage = () => {
|
||||
return{
|
||||
type: types.HIDE_MESSAGE_GLOBAL
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show error message
|
||||
* @param {string} message
|
||||
*/
|
||||
export const showErrorMessage = (message) => {
|
||||
return {
|
||||
type: types.SHOW_ERROR_MESSAGE_GLOBAL,
|
||||
payload: message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set header title
|
||||
*/
|
||||
export const setHeaderTitleOpt = (opt,payload) => {
|
||||
return (dispatch,getState) => {
|
||||
switch (opt) {
|
||||
case 'profile':
|
||||
const userName = getState().user.info && getState().user.info[payload] ? getState().user.info[payload].fullName : ''
|
||||
dispatch(setHeaderTitle(userName))
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set header title
|
||||
*/
|
||||
export const setHeaderTitle = (text) => {
|
||||
return{
|
||||
type: types.SET_HEADER_TITLE,
|
||||
payload: text
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open post write
|
||||
*/
|
||||
export const openPostWrite = () => {
|
||||
return{
|
||||
type: types.OPEN_POST_WRITE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Close post write
|
||||
*/
|
||||
export const closePostWrite = () => {
|
||||
return{
|
||||
type: types.CLOSE_POST_WRITE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show top loading
|
||||
*/
|
||||
export const showTopLoading = () => {
|
||||
return{
|
||||
type: types.SHOW_TOP_LOADING
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide top loading
|
||||
*/
|
||||
export const hideTopLoading = () => {
|
||||
return{
|
||||
type: types.HIDE_TOP_LOADING
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Store temp data
|
||||
*/
|
||||
export const temp = (data) => {
|
||||
return{
|
||||
type: types.TEMP,
|
||||
payload: data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// - Load data for guest
|
||||
export const loadDataGuest = () => {
|
||||
return (dispatch,getState) => {
|
||||
var userString = "{\"avatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"contact\":\"amir.gholzam@live.com\",\"email\":\"amir.gholzam@live.com\",\"fullName\":\"React Social Blog\",\"password\":\"123qwe\",\"summary\":\" The React Social Blog (RSB) Application is a diary app blog\"}"
|
||||
var postString = '[{"id":"-KkauHBOZXlALsHIrNsvsq","body":"The React Social Blog (RSB) Application is a diary app blog based on Semantic ui React for UI, Redux with react-redux for managing states and React for managing DOM .It is an open source project as a portfolio.\\n\\nI will be really grateful to receive any issue: \\nhttps://github.com/Qolzam/react-blog/issues\\n\\n \\n","commentCounter":0,"creationDate":1495301432,"deletationDate":"","deleted":false,"image":"http://www.freeimageslive.com/galleries/nature/abstract/preview/frosty_grass.jpg","lastEditDate":"","ownerAvatar":"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg","ownerDisplayName":"React Social Blog","ownerUserId":"5flWuB1RieZR7GIAwHYMPYaI5o33","postTypeId":1,"score":0,"video":"","viewCount":0},{"id":"-KkauHBOZXlALsHIrNIq","body":"It is a demo website","commentCounter":0,"creationDate":1495301432,"deletationDate":"","deleted":false,"image":"http://www.freeimageslive.com/galleries/nature/environment/pics/eaten%20_flower0905.jpg","lastEditDate":"","ownerAvatar":"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg","ownerDisplayName":"React Social Blog","ownerUserId":"5flWuB1RieZR7GIAwHYMPYaI5o33","postTypeId":1,"score":0,"video":"","viewCount":0},{"id":"-KkauHBOZXlsLsHIrNIq","body":"This is an open source project","commentCounter":0,"creationDate":1495301432,"deletationDate":"","deleted":false,"image":"http://www.freeimageslive.com/galleries/nature/environment/pics/eaten%20_flower0905.jpg","lastEditDate":"","ownerAvatar":"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg","ownerDisplayName":"React Social Blog","ownerUserId":"5flWuB1RieZR7GIAwHYMPYaI5o33","postTypeId":1,"score":0,"video":"","viewCount":0},{"id":"-KkaurBOZXlALsHIrNIq","body":"I have documentaion, testing, add some features DEBUG in my todo list","commentCounter":0,"creationDate":1495301432,"deletationDate":"","deleted":false,"image":"http://www.freeimageslive.com/galleries/nature/environment/pics/eaten%20_flower0905.jpg","lastEditDate":"","ownerAvatar":"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg","ownerDisplayName":"React Social Blog","ownerUserId":"5flWuB1RieZR7GIAwHYMPYaI5o33","postTypeId":1,"score":0,"video":"","viewCount":0}]'
|
||||
var postCommentString = "{\"postComments\":{\"-KkauHBOZXlALsHIrNIq\":{\"-KkaxkH1WmfcQaidsNHK3R\":{\"creationDate\":1495302341,\"postId\":\"-KkauHBOZXlALsHIrNIq\",\"score\":0,\"text\":\"On developing :)\",\"userAvatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"userDisplayName\":\"React Social Blog\",\"userId\":\"5flWuB1RieZR7GIAwHYMPYaI5o33\"},\"-KkafsdfxkH1WmfcQaiNHK3R\":{\"creationDate\":1495302341,\"postId\":\"-KkauHBOZXlALsHIrNIq\",\"score\":0,\"text\":\"This is a good project for lorem if you want to learn more and deeply about react and ui frameworkes. I'm preparing a good document for lorem :)\",\"userAvatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"userDisplayName\":\"React Social Blog\",\"userId\":\"5flWuB1RieZR7GIAwHYMPYaI5o33\"},\"-KkaxkH1WfrmfcQaiNHK3R\":{\"creationDate\":1495302341,\"postId\":\"-KkauHBOZXlALsHIrNIq\",\"score\":0,\"text\":\"On I'm so happy now that I have you react-blog so far I was looking for you oh it's just lorem so don't make it serious :)\",\"userAvatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"userDisplayName\":\"React Social Blog\",\"userId\":\"5flWuB1RieZR7GIAwHYMPYaI5o33\"},\"-KkaxkH1WmfcQakeiNHK3R\":{\"creationDate\":1495302341,\"postId\":\"-KkauHBOZXlALsHIrNIq\",\"score\":0,\"text\":\"On developing :)\",\"userAvatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"userDisplayName\":\"React Social Blog\",\"userId\":\"5flWuB1RieZR7GIAwHYMPYaI5o33\"},\"-KkaxkH1WmfcQpraiNHK3R\":{\"creationDate\":1495302341,\"postId\":\"-KkauHBOZXlALsHIrNIq\",\"score\":0,\"text\":\"On developing :)\",\"userAvatar\":\"http://www.freeimageslive.com/galleries/nature/abstract/preview/frostyleaves00406.jpg\",\"userDisplayName\":\"React Social Blog\",\"userId\":\"5flWuB1RieZR7GIAwHYMPYaI5o33\"}}}}"
|
||||
var user = JSON.parse(userString)
|
||||
dispatch(userActions.addUserInfo(user))
|
||||
var post = JSON.parse(postString)
|
||||
dispatch(postActions.addPosts(post))
|
||||
var postComment = JSON.parse(postCommentString)
|
||||
dispatch(commentActions.addCommentList(postComment.postComments))
|
||||
}
|
||||
|
||||
}
|
||||
248
app/actions/imageGalleryActions.jsx
Normal file
248
app/actions/imageGalleryActions.jsx
Normal file
@@ -0,0 +1,248 @@
|
||||
// - Import react componetns
|
||||
import moment from 'moment'
|
||||
import { firebaseRef, firebaseAuth, storageRef } from 'app/firebase/'
|
||||
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
|
||||
// - Import app API
|
||||
import FileAPI from 'FileAPI'
|
||||
|
||||
/* _____________ UI Actions _____________ */
|
||||
|
||||
|
||||
/**
|
||||
* Clear selected data
|
||||
*/
|
||||
export const clearSelectData = () => {
|
||||
return { type: types.CLEARS_SELECT_IMAGE_GALLERY }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data in image gallery store
|
||||
*/
|
||||
export const clearAllData = () => {
|
||||
return {
|
||||
type: types.CLEAT_ALL_DATA_IMAGE_GALLERY
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Download images for image gallery
|
||||
*/
|
||||
export const downloadForImageGallery = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var imagesRef = firebaseRef.child(`userFiles/${uid}/files/images`);
|
||||
|
||||
return imagesRef.once('value').then((snapshot) => {
|
||||
var images = snapshot.val() || {};
|
||||
var parsedImages = []
|
||||
Object.keys(images).forEach((imageId) => {
|
||||
parsedImages.push({
|
||||
id: imageId,
|
||||
...images[imageId]
|
||||
})
|
||||
})
|
||||
dispatch(addImageList(parsedImages));
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* _____________ CRUD Database_____________ */
|
||||
|
||||
/**
|
||||
* Save image in the server
|
||||
* @param {string} imageName is the name of image
|
||||
*/
|
||||
export const dbSaveImage = (imageName) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var image = {
|
||||
creationDate: moment().unix(),
|
||||
deletationDate: '',
|
||||
name: imageName,
|
||||
ownerUserId: uid,
|
||||
lastEditDate: '',
|
||||
deleted: false
|
||||
}
|
||||
|
||||
var imageRef = firebaseRef.child(`userFiles/${uid}/files/images`).push(image)
|
||||
return imageRef.then(() => {
|
||||
dispatch(addImage({
|
||||
...image,
|
||||
id: imageRef.key
|
||||
}))
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image from database
|
||||
* @param {string} id of image
|
||||
*/
|
||||
export const dbDeleteImage = (id) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
updates[`userFiles/${uid}/files/images/${id}`] = null;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(deleteImage(id))
|
||||
console.log('image removed: ', id);
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload image on the server
|
||||
* @param {file} file
|
||||
* @param {string} fileName
|
||||
*/
|
||||
export const dbUploadImage = (file, fileName) => {
|
||||
return (dispatch, getState) => {
|
||||
// Create a storage refrence
|
||||
var storegeFile = storageRef.child(`images/${fileName}`)
|
||||
|
||||
// Upload file
|
||||
var task = storegeFile.put(file)
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
// Upload storage bar
|
||||
task.on('state_changed', (snapshot) => {
|
||||
var percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
|
||||
dispatch(globalActions.progressChange(percentage, true))
|
||||
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.code))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
}, (complete) => {
|
||||
dispatch(globalActions.progressChange(100, false))
|
||||
dispatch(dbSaveImage(fileName))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download image from server
|
||||
* @param {string} fileName
|
||||
*/
|
||||
export const dbDownloadImage = (fileName) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
if (getState().imageGallery.imageURLList[fileName] && fileName !== '')
|
||||
return
|
||||
|
||||
if(getState().imageGallery.imageRequests.indexOf(fileName) > -1)
|
||||
return
|
||||
dispatch(sendImageRequest(fileName))
|
||||
|
||||
// Create a reference to the file we want to download
|
||||
var starsRef = storageRef.child(`images/${fileName}`);
|
||||
|
||||
// Get the download URL
|
||||
starsRef.getDownloadURL().then((url) => {
|
||||
// Insert url into an <img> tag to "download"
|
||||
if (!getState().imageGallery.imageURLList[fileName] || fileName === '')
|
||||
dispatch(setImageURL(fileName, url))
|
||||
}).catch((error) => {
|
||||
|
||||
// A full list of error codes is available at
|
||||
// https://firebase.google.com/docs/storage/web/handle-errors
|
||||
switch (error.code) {
|
||||
case 'storage/object_not_found':
|
||||
// File doesn't exist
|
||||
dispatch(globalActions.showErrorMessage('storage/object_not_found'))
|
||||
break;
|
||||
|
||||
case 'storage/unauthorized':
|
||||
// User doesn't have permission to access the object
|
||||
dispatch(globalActions.showErrorMessage('storage/unauthorized'))
|
||||
break;
|
||||
|
||||
case 'storage/canceled':
|
||||
// User canceled the upload
|
||||
dispatch(globalActions.showErrorMessage('storage/canceled'))
|
||||
break;
|
||||
|
||||
case 'storage/unknown':
|
||||
// Unknown error occurred, inspect the server response
|
||||
dispatch(globalActions.showErrorMessage('storage/unknown'))
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
/**
|
||||
* Add image list to image gallery
|
||||
* @param {[object]} images is an array of images
|
||||
*/
|
||||
export const addImageList = (images) => {
|
||||
return { type: types.ADD_IMAGE_LIST_GALLERY, images }
|
||||
}
|
||||
|
||||
/**
|
||||
* Add image to image gallery
|
||||
* @param {object} image
|
||||
*/
|
||||
export const addImage = (image) => {
|
||||
return { type: types.ADD_IMAGE_GALLERY, image }
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image
|
||||
* @param {string} id is an image identifier
|
||||
*/
|
||||
export const deleteImage = (id) => {
|
||||
return { type: types.DELETE_IMAGE, id }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image
|
||||
*/
|
||||
export const setImageURL = (name, url) => {
|
||||
return {
|
||||
type: types.SET_IMAGE_URL,
|
||||
payload: { name, url }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send image request
|
||||
*/
|
||||
export const sendImageRequest = (name) => {
|
||||
return {
|
||||
type: types.SEND_IMAGE_REQUEST,
|
||||
payload: name
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
20
app/actions/imageUploaderActions.jsx
Normal file
20
app/actions/imageUploaderActions.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
// - Import image uploader action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
|
||||
// - Image uploader actions
|
||||
|
||||
export const openImageUploader = (status)=> {
|
||||
return {
|
||||
type: types.OPEN_IMAGE_UPLOADER,
|
||||
status
|
||||
}
|
||||
}
|
||||
|
||||
export const openImageEditor = (editStatus) =>{
|
||||
return{
|
||||
type: types.OPEN_IMAGE_EDITOR,
|
||||
editStatus
|
||||
|
||||
}
|
||||
}
|
||||
168
app/actions/notifyActions.jsx
Normal file
168
app/actions/notifyActions.jsx
Normal file
@@ -0,0 +1,168 @@
|
||||
// - Import react components
|
||||
import moment from 'moment'
|
||||
import { firebaseRef } from 'app/firebase/'
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
import * as userActions from 'userActions'
|
||||
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
/**
|
||||
* Add notificaition to database
|
||||
* @param {object} newNotify user notificaition
|
||||
*/
|
||||
export const dbAddNotify = (newNotify) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var notify = {
|
||||
description: newNotify.description,
|
||||
url: newNotify.url,
|
||||
notifierUserId: newNotify.notifierUserId,
|
||||
isSeen: false
|
||||
}
|
||||
|
||||
var notifyRef = firebaseRef.child(`userNotifies/${newNotify.notifyRecieverUserId}`).push(notify)
|
||||
return notifyRef.then(() => {
|
||||
dispatch(addNotify())
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all notificaitions from database
|
||||
*/
|
||||
export const dbGetNotifies = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var notifiesRef = firebaseRef.child(`userNotifies/${uid}`);
|
||||
|
||||
return notifiesRef.on('value', (snapshot) => {
|
||||
var notifies = snapshot.val() || {};
|
||||
|
||||
Object.keys(notifies).forEach((key => {
|
||||
if (!getState().user.info[notifies[key].notifierUserId]) {
|
||||
dispatch(userActions.dbGetUserInfoByUserId(notifies[key].notifierUserId))
|
||||
|
||||
}
|
||||
}))
|
||||
dispatch(addNotifyList(notifies))
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a notificaition from database
|
||||
* @param {string} id of notificaition
|
||||
*/
|
||||
export const dbDeleteNotify = (id) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
updates[`userNotifies/${uid}/${id}`] = null;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(deleteNotify(id))
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make seen a notificaition from database
|
||||
* @param {string} id of notificaition
|
||||
*/
|
||||
export const dbSeenNotify = (id) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
let notify = getState().notify.userNotifies[id]
|
||||
let updatedNotify = {
|
||||
description: notify.description,
|
||||
url: notify.url,
|
||||
notifierUserId: notify.notifierUserId,
|
||||
isSeen: true
|
||||
}
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
updates[`userNotifies/${uid}/${id}`] = updatedNotify;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(seenNotify(id))
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
|
||||
/**
|
||||
* Add notificaition
|
||||
* @param {object} data
|
||||
*/
|
||||
export const addNotify = () => {
|
||||
|
||||
return {
|
||||
type: types.ADD_NOTIFY
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add notificaition list
|
||||
* @param {[object]} userNotifies an array of notificaitions
|
||||
*/
|
||||
export const addNotifyList = (userNotifies) => {
|
||||
|
||||
return {
|
||||
type: types.ADD_NOTIFY_LIST,
|
||||
payload: userNotifies
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a notificaition
|
||||
* @param {string} id of notificaition
|
||||
*/
|
||||
export const deleteNotify = (id) => {
|
||||
return { type: types.DELETE_NOTIFY, payload: id }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change notificaition to has seen status
|
||||
* @param {string} id of notificaition
|
||||
*/
|
||||
export const seenNotify = (id) => {
|
||||
return { type: types.SEEN_NOTIFY, payload: id }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data
|
||||
*/
|
||||
export const clearAllNotifications = () => {
|
||||
return {
|
||||
type: types.CLEAR_ALL_DATA_NOTIFY
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
339
app/actions/postActions.jsx
Normal file
339
app/actions/postActions.jsx
Normal file
@@ -0,0 +1,339 @@
|
||||
// - 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'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
/**
|
||||
* Add a normal post
|
||||
* @param {object} newPost
|
||||
* @param {function} callBack
|
||||
*/
|
||||
export var dbAddPost = (newPost,callBack) => {
|
||||
return(dispatch,getState) => {
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var post = {
|
||||
postTypeId: 0,
|
||||
creationDate: moment().unix(),
|
||||
deletationDate: '',
|
||||
score: 0,
|
||||
viewCount: 0,
|
||||
body: newPost.body,
|
||||
ownerUserId: uid,
|
||||
ownerDisplayName: newPost.name,
|
||||
ownerAvatar: newPost.avatar,
|
||||
lastEditDate: '',
|
||||
tags: newPost.tags || [],
|
||||
commentCounter: 0,
|
||||
image:'',
|
||||
video:'',
|
||||
disableComments: newPost.disableComments,
|
||||
disableSharing: newPost.disableSharing,
|
||||
deleted:false
|
||||
}
|
||||
|
||||
|
||||
var postRef = firebaseRef.child(`userPosts/${uid}/posts`).push(post)
|
||||
return postRef.then(()=>{
|
||||
dispatch(addPost(uid,{
|
||||
...post,
|
||||
id: postRef.key
|
||||
}))
|
||||
callBack()
|
||||
},(error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a post with image
|
||||
* @param {object} newPost
|
||||
* @param {function} callBack
|
||||
*/
|
||||
export const dbAddImagePost = (newPost,callBack) => {
|
||||
return(dispatch,getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var post = {
|
||||
postTypeId: 1,
|
||||
creationDate: moment().unix(),
|
||||
deletationDate: '',
|
||||
score: 0,
|
||||
viewCount: 0,
|
||||
body: newPost.body,
|
||||
ownerUserId: uid,
|
||||
ownerDisplayName: newPost.name,
|
||||
ownerAvatar: newPost.avatar,
|
||||
lastEditDate: '',
|
||||
tags: newPost.tags || [],
|
||||
commentCounter: 0,
|
||||
image: newPost.image || '',
|
||||
video:'',
|
||||
disableComments: newPost.disableComments ? newPost.disableComments : false,
|
||||
disableSharing: newPost.disableSharing ? newPost.disableSharing : false,
|
||||
deleted:false
|
||||
}
|
||||
|
||||
|
||||
var postRef = firebaseRef.child(`userPosts/${uid}/posts`).push(post)
|
||||
return postRef.then(()=>{
|
||||
dispatch(addPost(uid,{
|
||||
...post,
|
||||
id: postRef.key
|
||||
}))
|
||||
callBack()
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a post from database
|
||||
* @param {object} newPost
|
||||
* @param {func} callBack //TODO: anti pattern should change to parent state or move state to redux
|
||||
*/
|
||||
export const dbUpdatePost = (newPost,callBack) => {
|
||||
console.log(newPost)
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
let updates = {};
|
||||
let post = getState().post.userPosts[uid][newPost.id]
|
||||
let updatedPost = {
|
||||
postTypeId: post.postTypeId,
|
||||
creationDate: post.creationDate,
|
||||
deletationDate: '',
|
||||
score: post.score,
|
||||
viewCount: post.viewCount,
|
||||
body: newPost.body ? newPost.body : post.body || '',
|
||||
ownerUserId: uid,
|
||||
ownerDisplayName: post.ownerDisplayName,
|
||||
ownerAvatar: post.ownerAvatar,
|
||||
lastEditDate: moment().unix(),
|
||||
tags: newPost.tags ? newPost.tags : (post.tags || []),
|
||||
commentCounter: post.commentCounter,
|
||||
image: newPost.image ? newPost.image : post.image,
|
||||
video:'',
|
||||
disableComments: newPost.disableComments !== undefined ? newPost.disableComments : (post.disableComments ? post.disableComments : false),
|
||||
disableSharing: newPost.disableSharing !== undefined ? newPost.disableSharing : (post.disableSharing ? post.disableSharing : false),
|
||||
deleted:false
|
||||
}
|
||||
updates[`userPosts/${uid}/posts/${newPost.id}`] = updatedPost
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
|
||||
dispatch(updatePost(uid,{id:newPost.id, ...updatedPost}))
|
||||
callBack()
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a post from database
|
||||
* @param {string} id is post identifier
|
||||
*/
|
||||
export const dbDeletePost = (id) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch(globalActions.showTopLoading())
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
updates[`userPosts/${uid}/posts/${id}`] = null;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(deletePost(uid,id))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
dispatch(globalActions.hideTopLoading())
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all user posts from data base
|
||||
*/
|
||||
export const dbGetPosts = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var postsRef = firebaseRef.child(`userPosts/${uid}/posts`);
|
||||
|
||||
return postsRef.once('value').then((snapshot) => {
|
||||
var posts = snapshot.val() || {};
|
||||
var parsedPosts = {};
|
||||
Object.keys(posts).forEach((postId) => {
|
||||
parsedPosts[postId]={
|
||||
id: postId,
|
||||
...posts[postId]
|
||||
};
|
||||
});
|
||||
|
||||
dispatch(addPosts(uid,parsedPosts));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all user posts from data base
|
||||
*/
|
||||
export const dbGetPostById = (uid,postId) => {
|
||||
return (dispatch, getState) => {
|
||||
if (uid) {
|
||||
var postsRef = firebaseRef.child(`userPosts/${uid}/posts/${postId}`);
|
||||
|
||||
return postsRef.once('value').then((snapshot) => {
|
||||
const newPost = snapshot.val() || {};
|
||||
const post = {
|
||||
id : postId,
|
||||
...newPost
|
||||
}
|
||||
dispatch(addPost(uid,post));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all user posts from data base by user id
|
||||
*/
|
||||
export const dbGetPostsByUserId = (uid) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
if (uid) {
|
||||
var postsRef = firebaseRef.child(`userPosts/${uid}/posts`);
|
||||
|
||||
return postsRef.once('value').then((snapshot) => {
|
||||
var posts = snapshot.val() || {};
|
||||
var parsedPosts = {};
|
||||
Object.keys(posts).forEach((postId) => {
|
||||
parsedPosts[postId]={
|
||||
id: postId,
|
||||
...posts[postId]
|
||||
};
|
||||
});
|
||||
|
||||
dispatch(addPosts(uid,parsedPosts));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
/**
|
||||
* Add a normal post
|
||||
* @param {string} uid is user identifier
|
||||
* @param {object} post
|
||||
*/
|
||||
export const addPost = (uid,post) => {
|
||||
return{
|
||||
type: types.ADD_POST,
|
||||
payload: {uid,post}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a post
|
||||
* @param {string} uid is user identifier
|
||||
* @param {object} post
|
||||
*/
|
||||
export const updatePost = (uid,post) => {
|
||||
return{
|
||||
type: types.UPDATE_POST,
|
||||
payload: {uid,post}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a post
|
||||
* @param {string} uid is user identifier
|
||||
* @param {string} id is post identifier
|
||||
*/
|
||||
export const deletePost = (uid,id) => {
|
||||
return{
|
||||
type: types.DELETE_POST,
|
||||
payload: {uid,id}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a list of post
|
||||
* @param {string} uid
|
||||
* @param {[object]} posts
|
||||
*/
|
||||
export const addPosts = (uid,posts) => {
|
||||
return {
|
||||
type: types.ADD_LIST_POST,
|
||||
payload: {uid,posts}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clea all data in post store
|
||||
*/
|
||||
export const clearAllData = () => {
|
||||
return{
|
||||
type: types.CLEAR_ALL_DATA_POST
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a post with image
|
||||
* @param {object} post
|
||||
*/
|
||||
export const addImagePost = (uid,post) => {
|
||||
return{
|
||||
type: types.ADD_IMAGE_POST,
|
||||
payload: {uid,post}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
192
app/actions/userActions.jsx
Normal file
192
app/actions/userActions.jsx
Normal file
@@ -0,0 +1,192 @@
|
||||
// - Import react components
|
||||
import {firebaseRef} from 'app/firebase/'
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
import * as userActions from 'userActions'
|
||||
|
||||
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
|
||||
/**
|
||||
* Get user info from database
|
||||
*/
|
||||
export const dbGetUserInfo = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var userInfoRef = firebaseRef.child(`users/${uid}/info`);
|
||||
|
||||
return userInfoRef.once('value').then((snapshot) => {
|
||||
var userInfo = snapshot.val() || {};
|
||||
dispatch(addUserInfo(uid,userInfo))
|
||||
},error => console.log(error));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user info from database
|
||||
* @param {string} uid
|
||||
*/
|
||||
export const dbGetUserInfoByUserId = (uid,sw) => {
|
||||
return (dispatch, getState) => {
|
||||
if (uid) {
|
||||
var userInfoRef = firebaseRef.child(`users/${uid}/info`);
|
||||
|
||||
return userInfoRef.once('value').then((snapshot) => {
|
||||
var userInfo = snapshot.val() || {};
|
||||
dispatch(addUserInfo(uid,userInfo))
|
||||
switch (sw) {
|
||||
case 'header':
|
||||
dispatch(globalActions.setHeaderTitle(userInfo.fullName))
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},error => console.log(error));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updata user information
|
||||
* @param {object} newInfo
|
||||
*/
|
||||
export const dbUpdateUserInfo = (newInfo) => {
|
||||
return (dispatch,getState) => {
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
let updates = {};
|
||||
let info = getState().user.info[uid]
|
||||
let updatedInfo = {
|
||||
avatar: newInfo.avatar || info.avatar || '',
|
||||
banner:newInfo.banner || info.banner || '',
|
||||
email: newInfo.email || info.email || '',
|
||||
fullName: newInfo.fullName || info.fullName || '',
|
||||
tagLine: newInfo.tagLine || info.tagLine || ''
|
||||
}
|
||||
updates[`users/${uid}/info`] = updatedInfo
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
|
||||
dispatch(updateUserInfo(uid,updatedInfo))
|
||||
dispatch(closeEditProfile())
|
||||
}, (error) => {
|
||||
dispatch(globalActions.showErrorMessage(error.message))
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// - Get people info from database
|
||||
export const dbGetPeopleInfo = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var peopleRef = firebaseRef.child(`users`);
|
||||
|
||||
return peopleRef.once('value').then((snapshot) => {
|
||||
let people = snapshot.val() || {};
|
||||
|
||||
let parsedPeople = {};
|
||||
Object.keys(people).forEach((userId) => {
|
||||
if(userId !== uid){
|
||||
parsedPeople[userId]={
|
||||
...people[userId].info
|
||||
}}
|
||||
|
||||
})
|
||||
dispatch(addPeopleInfo(parsedPeople))
|
||||
},error => console.log(error));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _____________ CRUD State _____________ */
|
||||
|
||||
|
||||
/**
|
||||
* Add user information
|
||||
* @param {string} uid is the user identifier
|
||||
* @param {object} info is the information about user
|
||||
*/
|
||||
export const addUserInfo = (uid,info) => {
|
||||
return{
|
||||
type: types.ADD_USER_INFO,
|
||||
payload: {uid,info}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add people information
|
||||
* @param {[object]} infoList is the lst of information about users
|
||||
*/
|
||||
export const addPeopleInfo = (infoList) => {
|
||||
return{
|
||||
type: types.ADD_PEOPLE_INFO,
|
||||
payload: infoList
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user information
|
||||
* @param {string} uid is the user identifier
|
||||
* @param {object} info is the information about user
|
||||
*/
|
||||
export const updateUserInfo = (uid,info) => {
|
||||
return{
|
||||
type: types.UPDATE_USER_INFO,
|
||||
payload: {uid,info}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User info
|
||||
* @param {object} info
|
||||
*/
|
||||
export const userInfo = (info) => {
|
||||
return{
|
||||
type: types.USER_INFO,
|
||||
info
|
||||
}
|
||||
}
|
||||
|
||||
export const clearAllData = () => {
|
||||
return {
|
||||
type: types.CLEAR_ALL_DATA_USER
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open edit profile
|
||||
*/
|
||||
export const openEditProfile = () => {
|
||||
return{
|
||||
type: types.OPEN_EDIT_PROFILE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Close edit profile
|
||||
*/
|
||||
export const closeEditProfile = () => {
|
||||
return{
|
||||
type: types.CLOSE_EDIT_PROFILE
|
||||
}
|
||||
|
||||
}
|
||||
130
app/actions/voteActions.jsx
Normal file
130
app/actions/voteActions.jsx
Normal file
@@ -0,0 +1,130 @@
|
||||
// - Import react components
|
||||
import {createAction as action} from 'redux-actions'
|
||||
import moment from 'moment'
|
||||
import { firebaseRef } from 'app/firebase/'
|
||||
|
||||
// - Import action types
|
||||
import * as types from 'actionTypes'
|
||||
|
||||
// - Import actions
|
||||
import * as globalActions from 'globalActions'
|
||||
import * as notifyActions from 'notifyActions'
|
||||
|
||||
|
||||
/* _____________ CRUD DB _____________ */
|
||||
|
||||
/**
|
||||
* Add vote to database
|
||||
* @param {string} postId is the identifier of the post which user vote
|
||||
*/
|
||||
export const dbAddVote = (postId,ownerPostUserId) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
var uid = getState().authorize.uid
|
||||
var vote = {
|
||||
postId: postId,
|
||||
creationDate: moment().unix(),
|
||||
userDisplayName: getState().user.info[uid].fullName,
|
||||
userAvatar: getState().user.info[uid].avatar,
|
||||
userId: uid
|
||||
}
|
||||
|
||||
var voteRef = firebaseRef.child(`postVotes/${postId}`).push(vote)
|
||||
return voteRef.then(() => {
|
||||
dispatch(addVote(
|
||||
{
|
||||
vote,
|
||||
postId: postId,
|
||||
id: voteRef.key
|
||||
}))
|
||||
if(uid !== ownerPostUserId)
|
||||
dispatch(notifyActions.dbAddNotify(
|
||||
{
|
||||
description:'Vote on your post.',
|
||||
url:`/${ownerPostUserId}/posts/${postId}`,
|
||||
notifyRecieverUserId:ownerPostUserId,notifierUserId:uid
|
||||
}))
|
||||
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all votes from database
|
||||
*/
|
||||
export const dbGetVotes = () => {
|
||||
return (dispatch, getState) => {
|
||||
var uid = getState().authorize.uid
|
||||
if (uid) {
|
||||
var votesRef = firebaseRef.child(`postVotes`);
|
||||
|
||||
return votesRef.on('value',(snapshot) => {
|
||||
var votes = snapshot.val() || {};
|
||||
dispatch(addVoteList(votes))
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a vote from database
|
||||
* @param {string} id of vote
|
||||
* @param {string} postId is the identifier of the post which vote belong to
|
||||
*/
|
||||
export const dbDeleteVote = (postId) => {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
// Get current user id
|
||||
var uid = getState().authorize.uid
|
||||
|
||||
// Write the new data simultaneously in the list
|
||||
var updates = {};
|
||||
let votes = getState().vote.postVotes[postId]
|
||||
let id = Object.keys(votes).filter((key)=> votes[key].userId === uid)[0]
|
||||
console.log(' Id : ',id)
|
||||
|
||||
updates[`postVotes/${postId}/${id}`] = null;
|
||||
|
||||
return firebaseRef.update(updates).then((result) => {
|
||||
dispatch(deleteVote({id, postId}))
|
||||
}, (error) => dispatch(globalActions.showErrorMessage(error.message)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a vote
|
||||
* @param {object} data
|
||||
*/
|
||||
export const addVote = (data) => {
|
||||
return { type: types.ADD_VOTE, payload: data }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a vote
|
||||
* @param {object} data
|
||||
*/
|
||||
export const deleteVote = (data) => {
|
||||
return { type: types.DELETE_VOTE, payload: data }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ad a list of vote
|
||||
* @param {object} data
|
||||
*/
|
||||
export const addVoteList = (data) => {
|
||||
return { type: types.ADD_VOTE_LIST, payload: data }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data
|
||||
*/
|
||||
export const clearAllvotes = () => {
|
||||
return { type: types.CLEAR_ALL_DATA_VOTE }
|
||||
}
|
||||
Reference in New Issue
Block a user