[Refactoring][Breaking Changes]
- Move `reducers` and `actions` folders to `store` folder. - Move pages container components to `containers` folder.
This commit is contained in:
48
src/store/reducers/authorize/AuthorizeState.ts
Normal file
48
src/store/reducers/authorize/AuthorizeState.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Post state
|
||||
*
|
||||
* @export
|
||||
* @class AuthorizeState
|
||||
*/
|
||||
export class AuthorizeState {
|
||||
|
||||
/**
|
||||
* Authorized user identifier
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AuthorizeState
|
||||
*/
|
||||
uid: number = 0
|
||||
|
||||
/**
|
||||
* If user is authed {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof AuthorizeState
|
||||
*/
|
||||
authed: Boolean = false
|
||||
|
||||
/**
|
||||
* If user is verifide {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof AuthorizeState
|
||||
*/
|
||||
isVerifide: Boolean = false
|
||||
|
||||
/**
|
||||
* If user password is updated {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof AuthorizeState
|
||||
*/
|
||||
updatePassword: Boolean = false
|
||||
|
||||
/**
|
||||
* If the user is guest {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof AuthorizeState
|
||||
*/
|
||||
guest: Boolean = false
|
||||
}
|
||||
14
src/store/reducers/authorize/IAuthorizeAction.ts
Normal file
14
src/store/reducers/authorize/IAuthorizeAction.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// - Import action types
|
||||
import { AuthorizeActionType } from 'constants/authorizeActionType'
|
||||
|
||||
/**
|
||||
* Authorize action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IAuthorizeAction
|
||||
*/
|
||||
export interface IAuthorizeAction {
|
||||
payload: any
|
||||
type: AuthorizeActionType
|
||||
|
||||
}
|
||||
49
src/store/reducers/authorize/authorizeReducer.ts
Normal file
49
src/store/reducers/authorize/authorizeReducer.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
// - Import react components
|
||||
import { Reducer, Action } from 'redux'
|
||||
|
||||
// - Import action types
|
||||
import { AuthorizeActionType } from 'constants/authorizeActionType'
|
||||
|
||||
import { IAuthorizeAction } from './IAuthorizeAction'
|
||||
import { AuthorizeState } from './AuthorizeState'
|
||||
|
||||
/**
|
||||
* Authorize reducer
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export let authorizeReducer = (state: AuthorizeState = new AuthorizeState(), action: IAuthorizeAction) => {
|
||||
const { payload } = action
|
||||
switch (action.type) {
|
||||
case AuthorizeActionType.LOGIN:
|
||||
return{
|
||||
...state,
|
||||
uid: payload.uid,
|
||||
authed: true,
|
||||
guest: false,
|
||||
isVerifide: payload.isVerifide
|
||||
}
|
||||
case AuthorizeActionType.LOGOUT:
|
||||
return{
|
||||
...state,
|
||||
uid: 0,
|
||||
authed: false,
|
||||
guest: true
|
||||
}
|
||||
|
||||
case AuthorizeActionType.SIGNUP:
|
||||
return{
|
||||
...state,
|
||||
uid: payload.userId
|
||||
}
|
||||
case AuthorizeActionType.UPDATE_PASSWORD:
|
||||
return{
|
||||
...state,
|
||||
updatePassword: payload.updatePassword
|
||||
}
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
5
src/store/reducers/authorize/authorizeSelector.ts
Normal file
5
src/store/reducers/authorize/authorizeSelector.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
const getCurrentUser = (state: any) => (state.user.info && state.authorize.uid) ? state.user.info[state.authorize.uid] : null
|
||||
|
||||
export const authorizeSelector = {
|
||||
getCurrentUser
|
||||
}
|
||||
6
src/store/reducers/authorize/index.ts
Normal file
6
src/store/reducers/authorize/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { authorizeReducer } from './authorizeReducer'
|
||||
import {authorizeSelector} from './authorizeSelector'
|
||||
export {
|
||||
authorizeReducer,
|
||||
authorizeSelector
|
||||
}
|
||||
60
src/store/reducers/circles/CircleState.ts
Normal file
60
src/store/reducers/circles/CircleState.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Circle, UserTie } from 'src/core/domain/circles'
|
||||
|
||||
/**
|
||||
* Circle state
|
||||
*
|
||||
* @export
|
||||
* @class CircleState
|
||||
*/
|
||||
export class CircleState {
|
||||
/**
|
||||
* The list of users belong to users circle
|
||||
*
|
||||
* @memberof CircleState
|
||||
*/
|
||||
userTies: { [userId: string]: UserTie } = {}
|
||||
|
||||
/**
|
||||
* The list of users belong to users circle
|
||||
*
|
||||
* @memberof CircleState
|
||||
*/
|
||||
userTieds: { [userId: string]: UserTie } = {}
|
||||
|
||||
/**
|
||||
* The list of circle of current user
|
||||
*/
|
||||
circleList: { [circleId: string]: Circle }
|
||||
|
||||
/**
|
||||
* Whether select circle box is open for the selected user
|
||||
*/
|
||||
selectCircleStatus: { [userId: string]: boolean }
|
||||
|
||||
/**
|
||||
* Whether following loading is shown for the selected user
|
||||
*/
|
||||
followingLoadingStatus: { [userId: string]: boolean }
|
||||
|
||||
/**
|
||||
* Keep selected circles for refere user
|
||||
*/
|
||||
selectedCircles: { [userId: string]: string[] }
|
||||
|
||||
/**
|
||||
* Whether the select circles box for referer user is open
|
||||
*/
|
||||
openSelecteCircles: { [userId: string]: boolean }
|
||||
|
||||
/**
|
||||
* If user circles are loaded {true} or not {false}
|
||||
*
|
||||
* @memberof CircleState
|
||||
*/
|
||||
loaded: boolean = false
|
||||
|
||||
/**
|
||||
* Circle stting state
|
||||
*/
|
||||
openSetting: {[circleId: string]: boolean }
|
||||
}
|
||||
14
src/store/reducers/circles/ICircleAction.ts
Normal file
14
src/store/reducers/circles/ICircleAction.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
import { CircleActionType } from 'constants/circleActionType'
|
||||
|
||||
/**
|
||||
* Circle action interface
|
||||
*
|
||||
* @export
|
||||
* @interface ICircleAction
|
||||
*/
|
||||
export interface ICircleAction {
|
||||
payload: any,
|
||||
type: CircleActionType
|
||||
|
||||
}
|
||||
274
src/store/reducers/circles/circleReducer.ts
Normal file
274
src/store/reducers/circles/circleReducer.ts
Normal file
@@ -0,0 +1,274 @@
|
||||
// - Import react components
|
||||
import moment from 'moment/moment'
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import domain
|
||||
import { User } from 'src/core/domain/users'
|
||||
import { Circle, UserTie } from 'src/core/domain/circles'
|
||||
|
||||
// - Import action types
|
||||
import { CircleActionType } from 'constants/circleActionType'
|
||||
|
||||
import { CircleState } from './CircleState'
|
||||
import { ICircleAction } from './ICircleAction'
|
||||
|
||||
/**
|
||||
* Circle reducer
|
||||
* @param state
|
||||
* @param action
|
||||
*/
|
||||
export let circleReducer = (state: CircleState = new CircleState(), action: ICircleAction) => {
|
||||
const { payload } = action
|
||||
switch (action.type) {
|
||||
case CircleActionType.CLEAR_ALL_CIRCLES:
|
||||
return new CircleState()
|
||||
|
||||
case CircleActionType.ADD_CIRCLE:
|
||||
return {
|
||||
...state,
|
||||
circleList: {
|
||||
...state.circleList,
|
||||
[payload.circle.id]: {
|
||||
...payload.circle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.UPDATE_CIRCLE:
|
||||
return {
|
||||
...state,
|
||||
openSetting: {
|
||||
...state.openSetting,
|
||||
[payload.circle.id]: false
|
||||
},
|
||||
circleList: {
|
||||
...state.circleList,
|
||||
[payload.circle.id]: {
|
||||
...payload.circle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.DELETE_CIRCLE:
|
||||
let filteredDeleteCircles = {}
|
||||
Object.keys(state.circleList).map((key) => {
|
||||
if (key !== payload.circleId) {
|
||||
return _.merge(filteredDeleteCircles, { [key]: { ...state.circleList![key] } })
|
||||
}
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
circleList: {
|
||||
...state.circleList,
|
||||
...filteredDeleteCircles
|
||||
}
|
||||
}
|
||||
case CircleActionType.ADD_LIST_CIRCLE:
|
||||
return {
|
||||
...state,
|
||||
circleList: {
|
||||
...state.circleList,
|
||||
...payload.circleList
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
|
||||
case CircleActionType.ADD_FOLLOWING_USER:
|
||||
return {
|
||||
...state,
|
||||
userTies: {
|
||||
...state.userTies,
|
||||
[payload.userTie.userId]: {
|
||||
...payload.userTie
|
||||
}
|
||||
},
|
||||
selectedCircles: {
|
||||
...state.selectedCircles,
|
||||
[payload.userTie.userId]: payload.userTie.circleIdList
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.UPDATE_USER_TIE:
|
||||
return {
|
||||
...state,
|
||||
userTies: {
|
||||
...state.userTies,
|
||||
[payload.userTie.user.userId]: {
|
||||
...payload.userTie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.ADD_USER_TIE_LIST:
|
||||
return {
|
||||
...state,
|
||||
userTies: {
|
||||
...state.userTies,
|
||||
...payload.userTies
|
||||
},
|
||||
selectedCircles : getSelectedCircles(payload.userTies)
|
||||
}
|
||||
|
||||
case CircleActionType.ADD_USER_TIED_LIST:
|
||||
return {
|
||||
...state,
|
||||
userTieds: {
|
||||
...state.userTieds,
|
||||
...payload.userTieds
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.DELETE_USER_FROM_CIRCLE:
|
||||
let filteredCircles: string[] = []
|
||||
Object.keys(state.userTies[payload.userId].circleIdList!).forEach((circleId) => {
|
||||
if (circleId !== payload.circleId) {
|
||||
filteredCircles.push(circleId)
|
||||
}
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
userTies: {
|
||||
...state.userTies,
|
||||
[payload.userTie.user.userId]: {
|
||||
...payload.userTie,
|
||||
circleIdList: filteredCircles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.DELETE_FOLLOWING_USER:
|
||||
let filteredUserTies: {[userId: string]: UserTie } = {}
|
||||
|
||||
Object.keys(state.userTies).forEach((userId) => {
|
||||
if (userId !== payload.userId) {
|
||||
return _.merge(filteredUserTies, { [userId]: { ...state.userTies[userId] } })
|
||||
}
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
userTies: {
|
||||
...filteredUserTies
|
||||
},
|
||||
selectedCircles : getSelectedCircles(filteredUserTies)
|
||||
}
|
||||
|
||||
/**
|
||||
* User interface stuffs
|
||||
*/
|
||||
|
||||
case CircleActionType.CLOSE_CIRCLE_SETTINGS:
|
||||
return {
|
||||
...state,
|
||||
openSetting: {
|
||||
...state.openSetting,
|
||||
[payload.circleId]: false
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.OPEN_CIRCLE_SETTINGS:
|
||||
return {
|
||||
...state,
|
||||
openSetting: {
|
||||
...state.openSetting,
|
||||
[payload.circleId]: true
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.SHOW_SELECT_CIRCLE_BOX:
|
||||
return {
|
||||
...state,
|
||||
selectCircleStatus: {
|
||||
...state.selectCircleStatus,
|
||||
[payload.userId]: true
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.HIDE_SELECT_CIRCLE_BOX:
|
||||
return {
|
||||
...state,
|
||||
selectCircleStatus: {
|
||||
...state.selectCircleStatus,
|
||||
[payload.userId]: false
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.SHOW_FOLLOWING_USER_LOADING:
|
||||
return {
|
||||
...state,
|
||||
followingLoadingStatus: {
|
||||
...state.followingLoadingStatus,
|
||||
[payload.userId]: true
|
||||
}
|
||||
}
|
||||
|
||||
case CircleActionType.HIDE_FOLLOWING_USER_LOADING:
|
||||
return {
|
||||
...state,
|
||||
followingLoadingStatus: {
|
||||
...state.followingLoadingStatus,
|
||||
[payload.userId]: false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User box component
|
||||
*/
|
||||
case CircleActionType.SET_SELECTED_CIRCLES_USER_BOX_COMPONENT:
|
||||
return {
|
||||
...state,
|
||||
selectedCircles: {
|
||||
...state.selectedCircles,
|
||||
[payload.userId]: payload.circleList
|
||||
}
|
||||
}
|
||||
/**
|
||||
* User box component
|
||||
*/
|
||||
case CircleActionType.REMOVE_SELECTED_CIRCLES_USER_BOX_COMPONENT:
|
||||
return {
|
||||
...state,
|
||||
selectedCircles: {
|
||||
...state.selectedCircles,
|
||||
[payload.userId]: []
|
||||
}
|
||||
}
|
||||
/**
|
||||
* User box component
|
||||
*/
|
||||
case CircleActionType.OPEN_SELECT_CIRCLES_USER_BOX_COMPONENT:
|
||||
return {
|
||||
...state,
|
||||
openSelecteCircles: {
|
||||
...state.openSelecteCircles,
|
||||
[payload.userId]: true
|
||||
}
|
||||
}
|
||||
case CircleActionType.CLOSE_SELECT_CIRCLES_USER_BOX_COMPONENT:
|
||||
return {
|
||||
...state,
|
||||
openSelecteCircles: {
|
||||
...state.openSelecteCircles,
|
||||
[payload.userId]: false
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map user ties selected to selected circles
|
||||
*/
|
||||
const getSelectedCircles = (userTies: {[userId: string]: UserTie }) => {
|
||||
let selectedCircles: {[userId: string]: string[]} = {}
|
||||
Object.keys(userTies).forEach((userId: string) => {
|
||||
const userTie = (userTies as {[userId: string]: UserTie })[userId]
|
||||
selectedCircles = {
|
||||
...selectedCircles,
|
||||
[userTie.userId!]: userTie.circleIdList!
|
||||
}
|
||||
})
|
||||
|
||||
return selectedCircles
|
||||
}
|
||||
3
src/store/reducers/circles/index.ts
Normal file
3
src/store/reducers/circles/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { circleReducer } from './circleReducer'
|
||||
|
||||
export {circleReducer}
|
||||
32
src/store/reducers/comments/CommentState.ts
Normal file
32
src/store/reducers/comments/CommentState.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
import { Comment } from 'src/core/domain/comments'
|
||||
|
||||
/**
|
||||
* Comment state
|
||||
*
|
||||
* @export
|
||||
* @class CommentState
|
||||
*/
|
||||
export class CommentState {
|
||||
|
||||
/**
|
||||
* The list of comments on the posts
|
||||
*
|
||||
* @type {({[postId: string]: {[commentId: string]: Comment}} | null)}
|
||||
* @memberof CommentState
|
||||
*/
|
||||
postComments: {[postId: string]: {[commentId: string]: Comment}} = {}
|
||||
|
||||
/**
|
||||
* Whether comment editor is open
|
||||
*/
|
||||
editorStatus: {[postId: string]: {[commentId: string]: boolean}} = {}
|
||||
|
||||
/**
|
||||
* If the comments are loaded {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof CommentState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
}
|
||||
14
src/store/reducers/comments/ICommentAction.ts
Normal file
14
src/store/reducers/comments/ICommentAction.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
import {CommentActionType} from 'constants/commentActionType'
|
||||
|
||||
/**
|
||||
* Comment action interface
|
||||
*
|
||||
* @export
|
||||
* @interface ICommentAction
|
||||
*/
|
||||
export interface ICommentAction {
|
||||
payload: any
|
||||
type: CommentActionType
|
||||
|
||||
}
|
||||
115
src/store/reducers/comments/commentReducer.ts
Normal file
115
src/store/reducers/comments/commentReducer.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
// - Import react components
|
||||
import moment from 'moment/moment'
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import domain
|
||||
import { User } from 'src/core/domain/users'
|
||||
import { Comment } from 'src/core/domain/comments'
|
||||
|
||||
// - Import action types
|
||||
import { CommentActionType } from 'constants/commentActionType'
|
||||
|
||||
import { CommentState } from './CommentState'
|
||||
import { ICommentAction } from './ICommentAction'
|
||||
|
||||
/**
|
||||
* Comment reducer
|
||||
* @param state
|
||||
* @param action
|
||||
*/
|
||||
export let commentReducer = (state: CommentState = new CommentState(), action: ICommentAction) => {
|
||||
let { payload } = action
|
||||
switch (action.type) {
|
||||
|
||||
/* _____________ CRUD _____________ */
|
||||
case CommentActionType.ADD_COMMENT:
|
||||
return {
|
||||
...state,
|
||||
postComments: {
|
||||
...state.postComments,
|
||||
[payload.postId]: {
|
||||
...state.postComments![payload.postId],
|
||||
[payload.id]: {
|
||||
...payload,
|
||||
editorStatus: false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
case CommentActionType.ADD_COMMENT_LIST:
|
||||
return {
|
||||
...state,
|
||||
postComments: {
|
||||
...state.postComments,
|
||||
...payload
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
case CommentActionType.UPDATE_COMMENT:
|
||||
const {comment} = payload
|
||||
return {
|
||||
...state,
|
||||
postComments: {
|
||||
...state.postComments,
|
||||
[comment.postId]: {
|
||||
...state.postComments![comment.postId],
|
||||
[comment.id]: {
|
||||
...state.postComments![comment.postId][comment.id],
|
||||
text: comment.text,
|
||||
editorStatus: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case CommentActionType.DELETE_COMMENT:
|
||||
if (!state.postComments![payload.postId]) {
|
||||
return state
|
||||
}
|
||||
let parsedComments = {}
|
||||
Object.keys(state.postComments![payload.postId]).map((id) => {
|
||||
if (id !== payload.id) {
|
||||
_.merge(parsedComments, { [id]: { ...state.postComments![payload.postId][id] } })
|
||||
}
|
||||
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
postComments: {
|
||||
...state.postComments,
|
||||
[payload.postId]: {
|
||||
...parsedComments
|
||||
}
|
||||
}
|
||||
}
|
||||
case CommentActionType.CLOSE_COMMENT_EDITOR:
|
||||
return {
|
||||
...state,
|
||||
editorStatus: {
|
||||
...state.editorStatus,
|
||||
[payload.postId]: {
|
||||
...state.editorStatus![payload.postId],
|
||||
[payload.id]: false
|
||||
}
|
||||
}
|
||||
}
|
||||
case CommentActionType.OPEN_COMMENT_EDITOR:
|
||||
return {
|
||||
...state,
|
||||
editorStatus: {
|
||||
...state.editorStatus,
|
||||
[payload.postId]: {
|
||||
...state.editorStatus![payload.postId],
|
||||
[payload.id]: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case CommentActionType.CLEAR_ALL_DATA_COMMENT:
|
||||
return new CommentState()
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
3
src/store/reducers/comments/index.ts
Normal file
3
src/store/reducers/comments/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { commentReducer } from './commentReducer'
|
||||
|
||||
export {commentReducer}
|
||||
128
src/store/reducers/global/GlobalState.ts
Normal file
128
src/store/reducers/global/GlobalState.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Global state
|
||||
*
|
||||
* @export
|
||||
* @class GlobalState
|
||||
*/
|
||||
export class GlobalState {
|
||||
|
||||
/**
|
||||
* Set percent of loading progress and visibility for Master component
|
||||
*
|
||||
* @type {{
|
||||
* percent: number,
|
||||
* visible: boolean
|
||||
* }}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
progress: {
|
||||
percent: number
|
||||
visible: boolean
|
||||
} = {
|
||||
percent: 0,
|
||||
visible: false
|
||||
}
|
||||
|
||||
/**
|
||||
* If loading is enabled {true} or not false
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
loadingStatus: boolean = true
|
||||
|
||||
/**
|
||||
* Whether send feedback is diplayed
|
||||
*/
|
||||
sendFeedbackStatus: boolean = false
|
||||
|
||||
/**
|
||||
* If user date is loaded {true} or not {false}
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
defaultLoadDataStatus: boolean = false
|
||||
|
||||
/**
|
||||
* If message popup is open {true} or not {false}
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
messageOpen: boolean = false
|
||||
|
||||
/**
|
||||
* The text of popup global message
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
message: string = ''
|
||||
|
||||
/**
|
||||
* Window size
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
windowWidth: number = 0
|
||||
|
||||
/**
|
||||
* Window height
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
windowHeight: number = 0
|
||||
|
||||
/**
|
||||
* The text of website header
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
headerTitle: string = ''
|
||||
|
||||
/**
|
||||
* Top loading is visible {true} or not {false}
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
showTopLoading: boolean = false
|
||||
|
||||
/**
|
||||
* Top loading message queue
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
topLoadingQueue: number = 0
|
||||
|
||||
/**
|
||||
* Master loading is visible {true} or not {false}
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
showMasterLoading: boolean = true
|
||||
|
||||
/**
|
||||
* Master loading message queue
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
masterLoadingQueue: number = 0
|
||||
|
||||
/**
|
||||
* Temp date storage
|
||||
*
|
||||
* @type {*}
|
||||
* @memberof IGlobalState
|
||||
*/
|
||||
temp: any = {
|
||||
caller: []
|
||||
}
|
||||
}
|
||||
13
src/store/reducers/global/IGlobalAction.ts
Normal file
13
src/store/reducers/global/IGlobalAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { GlobalActionType } from 'constants/globalActionType'
|
||||
|
||||
/**
|
||||
* Global action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IGlobalAction
|
||||
*/
|
||||
export interface IGlobalAction {
|
||||
payload: any,
|
||||
type: GlobalActionType
|
||||
|
||||
}
|
||||
117
src/store/reducers/global/globalReducer.ts
Normal file
117
src/store/reducers/global/globalReducer.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
// - Import action types
|
||||
import { GlobalActionType } from 'constants/globalActionType'
|
||||
|
||||
import { GlobalState } from './GlobalState'
|
||||
import { IGlobalAction } from './IGlobalAction'
|
||||
|
||||
/**
|
||||
* Global reducer
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export const globalReducer = (state: GlobalState = new GlobalState(), action: IGlobalAction) => {
|
||||
const { payload } = action
|
||||
switch (action.type) {
|
||||
case GlobalActionType.PROGRESS_CHANGE:
|
||||
return {
|
||||
...state,
|
||||
progress: {
|
||||
...state.progress,
|
||||
percent: payload.percent,
|
||||
visible: payload.visible
|
||||
}
|
||||
}
|
||||
case GlobalActionType.DEFAULT_DATA_DISABLE:
|
||||
return {
|
||||
...state,
|
||||
defaultLoadDataStatus: false
|
||||
}
|
||||
case GlobalActionType.DEFAULT_DATA_ENABLE:
|
||||
return {
|
||||
...state,
|
||||
defaultLoadDataStatus: true
|
||||
}
|
||||
case GlobalActionType.SHOW_MESSAGE_GLOBAL:
|
||||
return {
|
||||
...state,
|
||||
message: action.payload,
|
||||
messageOpen: true
|
||||
}
|
||||
case GlobalActionType.SHOW_NORMAL_MESSAGE_GLOBAL:
|
||||
return {
|
||||
...state,
|
||||
message: action.payload,
|
||||
messageOpen: true
|
||||
}
|
||||
case GlobalActionType.HIDE_MESSAGE_GLOBAL:
|
||||
return {
|
||||
...state,
|
||||
message: '',
|
||||
messageOpen: false,
|
||||
messageColor: ''
|
||||
}
|
||||
case GlobalActionType.SET_HEADER_TITLE:
|
||||
return {
|
||||
...state,
|
||||
headerTitle: action.payload
|
||||
}
|
||||
case GlobalActionType.SHOW_SEND_FEEDBACK:
|
||||
return {
|
||||
...state,
|
||||
sendFeedbackStatus: true
|
||||
}
|
||||
case GlobalActionType.HIDE_SEND_FEEDBACK:
|
||||
return {
|
||||
...state,
|
||||
sendFeedbackStatus: false
|
||||
}
|
||||
case GlobalActionType.HIDE_TOP_LOADING:
|
||||
const queueTopLoading = state.topLoadingQueue > 0 ? (state.topLoadingQueue - 1) : 0
|
||||
return {
|
||||
...state,
|
||||
topLoadingQueue: queueTopLoading,
|
||||
showTopLoading: (queueTopLoading > 0 ? true : false)
|
||||
|
||||
}
|
||||
case GlobalActionType.SHOW_TOP_LOADING:
|
||||
return {
|
||||
...state,
|
||||
topLoadingQueue: (state.topLoadingQueue + 1),
|
||||
showTopLoading: true
|
||||
}
|
||||
case GlobalActionType.HIDE_MASTER_LOADING:
|
||||
const queueMasterLoading = state.masterLoadingQueue > 0 ? (state.masterLoadingQueue - 1) : 0
|
||||
return {
|
||||
...state,
|
||||
masterLoadingQueue: queueMasterLoading,
|
||||
showMasterLoading: (queueMasterLoading > 0 ? true : false)
|
||||
|
||||
}
|
||||
case GlobalActionType.SHOW_MASTER_LOADING:
|
||||
return {
|
||||
...state,
|
||||
masterLoadingQueue: (state.masterLoadingQueue + 1),
|
||||
showMasterLoading: true
|
||||
}
|
||||
case GlobalActionType.TEMP:
|
||||
return {
|
||||
...state,
|
||||
temp: {
|
||||
...state.temp,
|
||||
caller: [
|
||||
...state.temp.caller,
|
||||
payload.caller
|
||||
]
|
||||
}
|
||||
}
|
||||
case GlobalActionType.CLEAR_ALL_GLOBAL:
|
||||
return {
|
||||
...state,
|
||||
sendFeedbackStatus: false,
|
||||
}
|
||||
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
||||
}
|
||||
3
src/store/reducers/global/index.ts
Normal file
3
src/store/reducers/global/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { globalReducer } from './globalReducer'
|
||||
|
||||
export {globalReducer}
|
||||
13
src/store/reducers/imageGallery/IImageGalleryAction.ts
Normal file
13
src/store/reducers/imageGallery/IImageGalleryAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { ImageGalleryActionType } from 'constants/imageGalleryActionType'
|
||||
|
||||
/**
|
||||
* ImageGallery action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IImageGalleryAction
|
||||
*/
|
||||
export interface IImageGalleryAction {
|
||||
payload: any,
|
||||
type: ImageGalleryActionType
|
||||
|
||||
}
|
||||
67
src/store/reducers/imageGallery/ImageGalleryState.ts
Normal file
67
src/store/reducers/imageGallery/ImageGalleryState.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Image } from 'src/core/domain/imageGallery'
|
||||
|
||||
/**
|
||||
* ImageGallery state
|
||||
*
|
||||
* @export
|
||||
* @class ImageGalleryState
|
||||
*/
|
||||
export class ImageGalleryState {
|
||||
|
||||
/**
|
||||
* Image gallery is open {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
status: Boolean = false
|
||||
|
||||
/**
|
||||
* The list of image
|
||||
*
|
||||
* @type {(Image[] | null)}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
images: Image[] = []
|
||||
|
||||
/**
|
||||
* Selected image name
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
selectImage: string = ''
|
||||
|
||||
/**
|
||||
* Selected image address
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
selectURL: string = ''
|
||||
|
||||
/**
|
||||
* If image gallery is loaded {true} or not false
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
|
||||
/**
|
||||
* Images address list
|
||||
*
|
||||
* @type {*}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
imageURLList: any = {}
|
||||
|
||||
/**
|
||||
* Store image requested
|
||||
*
|
||||
* @type {*}
|
||||
* @memberof ImageGalleryState
|
||||
*/
|
||||
imageRequests: any = {}
|
||||
|
||||
}
|
||||
67
src/store/reducers/imageGallery/imageGalleryReducer.ts
Normal file
67
src/store/reducers/imageGallery/imageGalleryReducer.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
// - Import react components
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import domain
|
||||
import { User } from 'src/core/domain/users'
|
||||
import { Image } from 'src/core/domain/imageGallery'
|
||||
|
||||
// - Import image gallery action types
|
||||
import { ImageGalleryActionType } from 'constants/imageGalleryActionType'
|
||||
|
||||
import { IImageGalleryAction } from './IImageGalleryAction'
|
||||
import { ImageGalleryState } from './ImageGalleryState'
|
||||
|
||||
/**
|
||||
* Image gallery reducer
|
||||
*/
|
||||
export let imageGalleryReducer = (state: ImageGalleryState = new ImageGalleryState(), action: IImageGalleryAction) => {
|
||||
const { payload } = action
|
||||
|
||||
switch (action.type) {
|
||||
/* ----------------- CRUD ----------------- */
|
||||
case ImageGalleryActionType.ADD_IMAGE_GALLERY:
|
||||
return {
|
||||
...state,
|
||||
images: [...state.images!, payload]
|
||||
}
|
||||
case ImageGalleryActionType.ADD_IMAGE_LIST_GALLERY:
|
||||
return {
|
||||
...state,
|
||||
images: [...payload],
|
||||
loaded: true
|
||||
}
|
||||
|
||||
case ImageGalleryActionType.DELETE_IMAGE:
|
||||
return {
|
||||
...state,
|
||||
images: [
|
||||
...state.images!.filter((item: Image) => {
|
||||
return item.id !== payload
|
||||
})
|
||||
]
|
||||
}
|
||||
case ImageGalleryActionType.SET_IMAGE_URL:
|
||||
return {
|
||||
...state,
|
||||
imageURLList: {
|
||||
...state.imageURLList,
|
||||
[payload.name]: payload.url
|
||||
}
|
||||
}
|
||||
|
||||
case ImageGalleryActionType.SEND_IMAGE_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
imageRequests: [
|
||||
...state.imageRequests,
|
||||
payload
|
||||
]
|
||||
}
|
||||
|
||||
case ImageGalleryActionType.CLEAT_ALL_DATA_IMAGE_GALLERY:
|
||||
return new ImageGalleryState()
|
||||
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
3
src/store/reducers/imageGallery/index.ts
Normal file
3
src/store/reducers/imageGallery/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { imageGalleryReducer } from './imageGalleryReducer'
|
||||
|
||||
export {imageGalleryReducer}
|
||||
5
src/store/reducers/index.ts
Normal file
5
src/store/reducers/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import {rootReducer} from './rootReducer'
|
||||
|
||||
export {
|
||||
rootReducer
|
||||
}
|
||||
198
src/store/reducers/locale/langugeType.ts
Normal file
198
src/store/reducers/locale/langugeType.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* ISO 639-1 defines abbreviations for languages.
|
||||
* Reference for country codes
|
||||
* https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
*/
|
||||
export enum LanguageType {
|
||||
Abkhazian = 'ab',
|
||||
Afar = 'aa',
|
||||
Afrikaans = 'af',
|
||||
Akan = 'ak',
|
||||
Albanian = 'sq',
|
||||
Amharic = 'am',
|
||||
Arabic = 'ar',
|
||||
Aragonese = 'an',
|
||||
Armenian = 'hy',
|
||||
Assamese = 'as',
|
||||
Avaric = 'av',
|
||||
Avestan = 'ae',
|
||||
Aymara = 'ay',
|
||||
Azerbaijani = 'az',
|
||||
Bambara = 'bm',
|
||||
Bashkir = 'ba',
|
||||
Basque = 'eu',
|
||||
Belarusian = 'be',
|
||||
BengaliBangla = 'bn',
|
||||
Bihari = 'bh',
|
||||
Bislama = 'bi',
|
||||
Bosnian = 'bs',
|
||||
Breton= 'br',
|
||||
Bulgarian = 'bg',
|
||||
Burmese = 'my',
|
||||
Catalan = 'ca',
|
||||
Chamorro = 'ch',
|
||||
Chechen = 'ce',
|
||||
ChichewaChewaNyanja = 'ny',
|
||||
Chinese = 'zh',
|
||||
ChineseSimplified = 'zh-Hans',
|
||||
ChineseTraditional = 'zh-Hant',
|
||||
Chuvash = 'cv',
|
||||
Cornish = 'kw',
|
||||
Corsican = 'co',
|
||||
Cree = 'cr',
|
||||
Croatian = 'hr',
|
||||
Czech = 'cs',
|
||||
Danish = 'da',
|
||||
DivehiDhivehiMaldivian = 'dv',
|
||||
Dutch = 'nl',
|
||||
Dzongkha = 'dz',
|
||||
English = 'en',
|
||||
Esperanto = 'eo',
|
||||
Estonian = 'et',
|
||||
Ewe = 'ee',
|
||||
Faroese = 'fo',
|
||||
Fijian = 'fj',
|
||||
Finnish = 'fi',
|
||||
French = 'fr',
|
||||
FulaFulahPulaarPular = 'ff',
|
||||
Galician = 'gl',
|
||||
GaelicScottish = 'gd',
|
||||
GaelicManx = 'gv',
|
||||
Georgian = 'ka',
|
||||
German = 'de',
|
||||
Greek = 'el',
|
||||
Greenlandic = 'kl',
|
||||
Guarani = 'gn',
|
||||
Gujarati = 'gu',
|
||||
HaitianCreole = 'ht',
|
||||
Hausa = 'ha',
|
||||
Hebrew = 'he',
|
||||
Herero = 'hz',
|
||||
Hindi = 'hi',
|
||||
HiriMotu = 'ho',
|
||||
Hungarian = 'hu',
|
||||
Icelandic = 'is',
|
||||
Ido = 'io',
|
||||
Igbo = 'ig',
|
||||
Indonesian = 'in',
|
||||
Interlingua = 'ia',
|
||||
Interlingue = 'ie',
|
||||
Inuktitut = 'iu',
|
||||
Inupiak = 'ik',
|
||||
Irish = 'ga',
|
||||
Italian = 'it',
|
||||
Japanese = 'ja',
|
||||
Javanese = 'jv',
|
||||
KalaallisutGreenlandic = 'kl',
|
||||
Kannada = 'kn',
|
||||
Kanuri = 'kr',
|
||||
Kashmiri = 'ks',
|
||||
Kazakh = 'kk',
|
||||
Khmer = 'km',
|
||||
Kikuyu = 'ki',
|
||||
KinyarwandaRwanda = 'rw',
|
||||
Kirundi = 'rn',
|
||||
Kyrgyz = 'ky',
|
||||
Komi = 'kv',
|
||||
Kongo = 'kg',
|
||||
Korean = 'ko',
|
||||
Kurdish = 'ku',
|
||||
Kwanyama = 'kj',
|
||||
Lao = 'lo',
|
||||
Latin = 'la',
|
||||
LatvianLettish = 'lv',
|
||||
LimburgishLimburger = 'li',
|
||||
Lingala = 'ln',
|
||||
Lithuanian = 'lt',
|
||||
LugaKatanga = 'lu',
|
||||
LugandaGanda = 'lg',
|
||||
Luxembourgish = 'lb',
|
||||
Manx = 'gv',
|
||||
Macedonian = 'mk',
|
||||
Malagasy = 'mg',
|
||||
Malay = 'ms',
|
||||
Malayalam = 'ml',
|
||||
Maltese = 'mt',
|
||||
Maori = 'mi',
|
||||
Marathi = 'mr',
|
||||
Marshallese = 'mh',
|
||||
Moldavian = 'mo',
|
||||
Mongolian = 'mn',
|
||||
Nauru = 'na',
|
||||
Navajo = 'nv',
|
||||
Ndonga = 'ng',
|
||||
NorthernNdebele = 'nd',
|
||||
Nepali = 'ne',
|
||||
Norwegian = 'no',
|
||||
Norwegianbokmål = 'nb',
|
||||
NorwegianNynorsk = 'nn',
|
||||
Nuosu = 'ii',
|
||||
Occitan = 'oc',
|
||||
Ojibwe = 'oj',
|
||||
OldChurchSlavonicOldBulgarian = 'cu',
|
||||
Oriya = 'or',
|
||||
OromoAfaanOromo = 'om',
|
||||
Ossetian = 'os',
|
||||
Pāli = 'pi',
|
||||
PashtoPushto = 'ps',
|
||||
PersianFarsi = 'fa',
|
||||
Polish = 'pl',
|
||||
Portuguese = 'pt',
|
||||
PunjabiEastern = 'pa',
|
||||
Quechua = 'qu',
|
||||
Romansh = 'rm',
|
||||
Romanian = 'ro',
|
||||
Russian = 'ru',
|
||||
Sami = 'se',
|
||||
Samoan = 'sm',
|
||||
Sango = 'sg',
|
||||
Sanskrit = 'sa',
|
||||
Serbian = 'sr',
|
||||
SerboCroatian = 'sh',
|
||||
Sesotho = 'st',
|
||||
Setswana = 'tn',
|
||||
Shona = 'sn',
|
||||
SichuanYi = 'ii',
|
||||
Sindhi = 'sd',
|
||||
Sinhalese = 'si',
|
||||
Siswati = 'ss',
|
||||
Slovak = 'sk',
|
||||
Slovenian = 'sl',
|
||||
Somali = 'so',
|
||||
SouthernNdebele = 'nr',
|
||||
Spanish = 'es',
|
||||
Sundanese = 'su',
|
||||
SwahiliKiswahili = 'sw',
|
||||
Swati = 'ss',
|
||||
Swedish = 'sv',
|
||||
Tagalog = 'tl',
|
||||
Tahitian = 'ty',
|
||||
Tajik = 'tg',
|
||||
Tamil = 'ta',
|
||||
Tatar = 'tt',
|
||||
Telugu = 'te',
|
||||
Thai = 'th',
|
||||
Tibetan = 'bo',
|
||||
Tigrinya = 'ti',
|
||||
Tonga = 'to',
|
||||
Tsonga = 'ts',
|
||||
Turkish = 'tr',
|
||||
Turkmen = 'tk',
|
||||
Twi = 'tw',
|
||||
Uyghur = 'ug',
|
||||
Ukrainian = 'uk',
|
||||
Urdu = 'ur',
|
||||
Uzbek = 'uz',
|
||||
Venda = 've',
|
||||
Vietnamese = 'vi',
|
||||
Volapük = 'vo',
|
||||
Wallon = 'wa',
|
||||
Welsh = 'cy',
|
||||
Wolof = 'wo',
|
||||
WesternFrisian = 'fy',
|
||||
Xhosa = 'xh',
|
||||
Yiddish = 'yi',
|
||||
Yoruba = 'yo',
|
||||
ZhuangChuang = 'za',
|
||||
Zulu = 'zu',
|
||||
}
|
||||
14
src/store/reducers/notifications/INotificationAction.ts
Normal file
14
src/store/reducers/notifications/INotificationAction.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {NotificationActionType} from 'constants/notificationActionType'
|
||||
|
||||
/**
|
||||
* Notification action interface
|
||||
*
|
||||
* @export
|
||||
* @interface INotificationAction
|
||||
*/
|
||||
export interface INotificationAction {
|
||||
payload: any,
|
||||
type: NotificationActionType
|
||||
|
||||
}
|
||||
|
||||
26
src/store/reducers/notifications/NotificationState.ts
Normal file
26
src/store/reducers/notifications/NotificationState.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Notification } from 'src/core/domain/notifications'
|
||||
|
||||
/**
|
||||
* Notification state
|
||||
*
|
||||
* @export
|
||||
* @class NotificationState
|
||||
*/
|
||||
export class NotificationState {
|
||||
|
||||
/**
|
||||
* The list of users notification
|
||||
*
|
||||
* @type {({[userId: string]: {[notificationId: string]: Notification}} | null)}
|
||||
* @memberof NotificationState
|
||||
*/
|
||||
userNotifies: {[userId: string]: {[notificationId: string]: Notification}} = {}
|
||||
|
||||
/**
|
||||
* If user notifications are loaded {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof NotificationState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
}
|
||||
3
src/store/reducers/notifications/index.ts
Normal file
3
src/store/reducers/notifications/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { notificationReducer } from './notificationReducer'
|
||||
|
||||
export {notificationReducer}
|
||||
72
src/store/reducers/notifications/notificationReducer.ts
Normal file
72
src/store/reducers/notifications/notificationReducer.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
// - Import react components
|
||||
import moment from 'moment/moment'
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import domain
|
||||
import { Notification } from 'src/core/domain/notifications'
|
||||
|
||||
// - Import action types
|
||||
import { NotificationActionType } from 'constants/notificationActionType'
|
||||
|
||||
import { NotificationState } from './NotificationState'
|
||||
import { INotificationAction } from './INotificationAction'
|
||||
|
||||
/**
|
||||
* Notify actions
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export let notificationReducer = (state: NotificationState = new NotificationState(), action: INotificationAction) => {
|
||||
let { payload } = action
|
||||
switch (action.type) {
|
||||
|
||||
/* _____________ CRUD _____________ */
|
||||
case NotificationActionType.ADD_NOTIFY:
|
||||
return state
|
||||
|
||||
case NotificationActionType.ADD_NOTIFY_LIST:
|
||||
return {
|
||||
...state,
|
||||
userNotifies: {
|
||||
...payload
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
|
||||
case NotificationActionType.SEEN_NOTIFY:
|
||||
return {
|
||||
...state,
|
||||
userNotifies: {
|
||||
...state.userNotifies,
|
||||
[payload]: {
|
||||
...state.userNotifies![payload],
|
||||
isSeen: true
|
||||
}
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
|
||||
case NotificationActionType.DELETE_NOTIFY:
|
||||
let parsedNotifies = {}
|
||||
Object.keys(state.userNotifies!).map((id) => {
|
||||
if (id !== payload) {
|
||||
_.merge(parsedNotifies, { [id]: { ...state.userNotifies![id] } })
|
||||
}
|
||||
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
userNotifies: {
|
||||
...parsedNotifies
|
||||
}
|
||||
}
|
||||
|
||||
case NotificationActionType.CLEAR_ALL_DATA_NOTIFY:
|
||||
return new NotificationState()
|
||||
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
13
src/store/reducers/posts/IPostAction.ts
Normal file
13
src/store/reducers/posts/IPostAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { PostActionType } from 'constants/postActionType'
|
||||
|
||||
/**
|
||||
* Post action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IPostAction
|
||||
*/
|
||||
export interface IPostAction {
|
||||
payload: any,
|
||||
type: PostActionType
|
||||
|
||||
}
|
||||
38
src/store/reducers/posts/PostState.ts
Normal file
38
src/store/reducers/posts/PostState.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Post } from 'src/core/domain/posts'
|
||||
|
||||
/**
|
||||
* Post state
|
||||
*
|
||||
* @export
|
||||
* @class PostState
|
||||
*/
|
||||
export class PostState {
|
||||
|
||||
/**
|
||||
* The list of user posts
|
||||
*
|
||||
* @type {*}
|
||||
* @memberof PostState
|
||||
*/
|
||||
userPosts: any = {}
|
||||
|
||||
/**
|
||||
* If user posts are loaded {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof PostState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
|
||||
/**
|
||||
* Stream data storage
|
||||
*/
|
||||
stream?: {hasMoreData: boolean, lastPageRequest: number, lastPostId: string} =
|
||||
{hasMoreData: true, lastPageRequest: -1, lastPostId: ''}
|
||||
|
||||
/**
|
||||
* Profile posts data storage
|
||||
*/
|
||||
profile?: {[userId: string]: {hasMoreData: boolean, lastPageRequest: number, lastPostId: string}} =
|
||||
{}
|
||||
}
|
||||
7
src/store/reducers/posts/index.ts
Normal file
7
src/store/reducers/posts/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { postReducer } from './postReducer'
|
||||
import { postSelector } from './postSelector'
|
||||
|
||||
export {
|
||||
postReducer,
|
||||
postSelector
|
||||
}
|
||||
179
src/store/reducers/posts/postReducer.ts
Normal file
179
src/store/reducers/posts/postReducer.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
// - Import react components
|
||||
import moment from 'moment/moment'
|
||||
import _ from 'lodash'
|
||||
import { Reducer, Action } from 'redux'
|
||||
|
||||
// - Import action types
|
||||
import { PostActionType } from 'constants/postActionType'
|
||||
|
||||
import { PostState } from './PostState'
|
||||
import { IPostAction } from './IPostAction'
|
||||
import { Post } from 'src/core/domain/posts/post'
|
||||
import CommonAPI from 'src/api/CommonAPI'
|
||||
|
||||
/**
|
||||
* Post reducer
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export let postReducer = (state: PostState = new PostState(), action: IPostAction) => {
|
||||
const { payload } = action
|
||||
switch (action.type) {
|
||||
case PostActionType.CLEAR_ALL_DATA_POST:
|
||||
return new PostState()
|
||||
|
||||
case PostActionType.ADD_IMAGE_POST:
|
||||
return {
|
||||
...state,
|
||||
userPosts: {
|
||||
...state.userPosts,
|
||||
[payload.uid]: {
|
||||
...state.userPosts[payload.uid],
|
||||
[payload.post.id]: { ...payload.post }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PostActionType.ADD_POST:
|
||||
return {
|
||||
...state,
|
||||
userPosts: {
|
||||
...state.userPosts,
|
||||
[payload.uid]: {
|
||||
...state.userPosts[payload.uid],
|
||||
[payload.post.id]: { ...payload.post }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PostActionType.UPDATE_POST:
|
||||
const post: Post = payload.post
|
||||
return {
|
||||
...state,
|
||||
userPosts: {
|
||||
...state.userPosts,
|
||||
[post.ownerUserId!]: {
|
||||
...state.userPosts[post.ownerUserId!],
|
||||
[payload.post.id]: {
|
||||
...payload.post,
|
||||
comments: post.comments,
|
||||
votes: post.votes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PostActionType.DELETE_POST:
|
||||
let filteredPosts = {}
|
||||
Object.keys(state.userPosts[payload.uid]).map((key) => {
|
||||
if (key !== payload.id) {
|
||||
return _.merge(filteredPosts, { [key]: { ...state.userPosts[payload.uid][key] } })
|
||||
}
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
userPosts: {
|
||||
...state.userPosts,
|
||||
[payload.uid]: {
|
||||
...filteredPosts
|
||||
}
|
||||
}
|
||||
}
|
||||
case PostActionType.ADD_LIST_POST:
|
||||
const newUserPosts = payload.userPosts as { [userId: string]: { [postId: string]: Post } }
|
||||
const mergedObject = _.merge(state.userPosts, newUserPosts)
|
||||
return {
|
||||
...state,
|
||||
userPosts: {
|
||||
...mergedObject
|
||||
},
|
||||
loaded: true
|
||||
|
||||
}
|
||||
case PostActionType.HAS_MORE_DATA_STREAM:
|
||||
return {
|
||||
...state,
|
||||
stream: {
|
||||
...state.stream,
|
||||
hasMoreData: true
|
||||
}
|
||||
|
||||
}
|
||||
case PostActionType.NOT_MORE_DATA_STREAM:
|
||||
return {
|
||||
...state,
|
||||
stream: {
|
||||
...state.stream,
|
||||
hasMoreData: false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case PostActionType.REQUEST_PAGE_STREAM:
|
||||
return {
|
||||
...state,
|
||||
stream: {
|
||||
...state.stream,
|
||||
lastPageRequest: payload.page
|
||||
}
|
||||
}
|
||||
|
||||
case PostActionType.LAST_POST_STREAM:
|
||||
return {
|
||||
...state,
|
||||
stream: {
|
||||
...state.stream,
|
||||
lastPostId: payload.lastPostId
|
||||
}
|
||||
}
|
||||
case PostActionType.HAS_MORE_DATA_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
profile: {
|
||||
...state.profile,
|
||||
hasMoreData: true
|
||||
}
|
||||
|
||||
}
|
||||
case PostActionType.NOT_MORE_DATA_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
profile: {
|
||||
...state.profile,
|
||||
[payload.userId]: {
|
||||
...state.profile![payload.userId],
|
||||
hasMoreData: false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case PostActionType.REQUEST_PAGE_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
profile: {
|
||||
...state.profile,
|
||||
[payload.userId]: {
|
||||
...state.profile![payload.userId],
|
||||
lastPageRequest: payload.page
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PostActionType.LAST_POST_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
profile: {
|
||||
...state.profile,
|
||||
[payload.userId]: {
|
||||
...state.profile![payload.userId],
|
||||
lastPostId: payload.lastPostId
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
}
|
||||
9
src/store/reducers/posts/postSelector.ts
Normal file
9
src/store/reducers/posts/postSelector.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
const getPost = (state: any, userId: string, postId: string) => {
|
||||
return (state.post.userPosts && state.post.userPosts[userId] && state.post.userPosts[userId][postId])
|
||||
? state.post.userPosts[userId][postId]
|
||||
: null
|
||||
}
|
||||
|
||||
export const postSelector = {
|
||||
getPost
|
||||
}
|
||||
31
src/store/reducers/rootReducer.ts
Normal file
31
src/store/reducers/rootReducer.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as redux from 'redux'
|
||||
import { localeReducer as locale } from 'react-localize-redux'
|
||||
|
||||
// - Import reducers
|
||||
import { authorizeReducer } from './authorize'
|
||||
import { circleReducer } from './circles'
|
||||
import { commentReducer } from './comments'
|
||||
import { globalReducer } from './global'
|
||||
import { imageGalleryReducer } from './imageGallery'
|
||||
import { notificationReducer } from './notifications'
|
||||
import { postReducer } from './posts'
|
||||
import { userReducer } from './users'
|
||||
import { voteReducer } from './votes'
|
||||
import { serverReducer } from './server'
|
||||
import { routerReducer, routerMiddleware } from 'react-router-redux'
|
||||
|
||||
// - Reducers
|
||||
export const rootReducer = redux.combineReducers({
|
||||
locale,
|
||||
imageGallery: imageGalleryReducer,
|
||||
post: postReducer,
|
||||
circle: circleReducer,
|
||||
comment: commentReducer,
|
||||
vote: voteReducer,
|
||||
server: serverReducer,
|
||||
authorize: authorizeReducer,
|
||||
router: routerReducer,
|
||||
user: userReducer,
|
||||
notify: notificationReducer,
|
||||
global: globalReducer
|
||||
} as any)
|
||||
13
src/store/reducers/server/IServerAction.ts
Normal file
13
src/store/reducers/server/IServerAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { ServerActionType } from 'constants/serverActionType'
|
||||
|
||||
/**
|
||||
* Server action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IServerAction
|
||||
*/
|
||||
export interface IServerAction {
|
||||
payload: any,
|
||||
type: ServerActionType
|
||||
|
||||
}
|
||||
16
src/store/reducers/server/ServerState.ts
Normal file
16
src/store/reducers/server/ServerState.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ServerRequestModel } from 'src/models/server'
|
||||
|
||||
/**
|
||||
* Server state
|
||||
*
|
||||
* @export
|
||||
* @class ServerState
|
||||
*/
|
||||
export class ServerState {
|
||||
|
||||
/**
|
||||
* The list of posts server
|
||||
* @memberof ServerState
|
||||
*/
|
||||
request: {[requestId: string]: ServerRequestModel} | null = {}
|
||||
}
|
||||
3
src/store/reducers/server/index.ts
Normal file
3
src/store/reducers/server/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { serverReducer } from './serverReducer'
|
||||
|
||||
export {serverReducer}
|
||||
78
src/store/reducers/server/serverReducer.ts
Normal file
78
src/store/reducers/server/serverReducer.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
// - Import react components
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import action types
|
||||
import { ServerActionType } from 'constants/serverActionType'
|
||||
|
||||
// Import domain
|
||||
|
||||
import { ServerState } from './ServerState'
|
||||
import { IServerAction } from './IServerAction'
|
||||
import { ServerRequestModel } from 'src/models/server/serverRequestModel'
|
||||
import { ServerRequestStatusType } from 'store/actions/serverRequestStatusType'
|
||||
|
||||
/**
|
||||
* Server actions
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export let serverReducer = (state: ServerState = new ServerState(), action: IServerAction) => {
|
||||
let { payload } = action
|
||||
const request = (payload ? payload.request : {}) as ServerRequestModel
|
||||
switch (action.type) {
|
||||
|
||||
/* _____________ CRUD _____________ */
|
||||
case ServerActionType.ADD_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
request: {
|
||||
...state.request,
|
||||
[request.id]: {
|
||||
...request
|
||||
}
|
||||
}
|
||||
}
|
||||
case ServerActionType.DELETE_REQUEST:
|
||||
let parsedRequests = {}
|
||||
Object.keys(state.request!).forEach((id) => {
|
||||
if (id !== request.id) {
|
||||
_.merge(parsedRequests, { [id]: { ...state.request![id] } })
|
||||
}
|
||||
|
||||
})
|
||||
return {
|
||||
...state,
|
||||
request: parsedRequests
|
||||
}
|
||||
|
||||
case ServerActionType.ERROR_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
request: {
|
||||
...state.request,
|
||||
[request.id]: {
|
||||
...state.request![request.id],
|
||||
status: ServerRequestStatusType.Error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case ServerActionType.OK_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
request: {
|
||||
...state.request,
|
||||
[request.id]: {
|
||||
...state.request![request.id],
|
||||
status: ServerRequestStatusType.OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case ServerActionType.CLEAR_ALL_DATA_REQUEST:
|
||||
return new ServerState()
|
||||
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
13
src/store/reducers/users/IUserAction.ts
Normal file
13
src/store/reducers/users/IUserAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { UserActionType } from 'constants/userActionType'
|
||||
|
||||
/**
|
||||
* User action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IUserAction
|
||||
*/
|
||||
export interface IUserAction {
|
||||
payload: any,
|
||||
type: UserActionType
|
||||
|
||||
}
|
||||
39
src/store/reducers/users/UserState.ts
Normal file
39
src/store/reducers/users/UserState.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { User,Profile } from 'src/core/domain/users'
|
||||
|
||||
/**
|
||||
* User state
|
||||
*
|
||||
* @export
|
||||
* @class UserState
|
||||
*/
|
||||
export class UserState {
|
||||
/**
|
||||
* The list of users information
|
||||
*
|
||||
* @type {({[userId: string]: Profile} | null)}
|
||||
* @memberof UserState
|
||||
*/
|
||||
info: {[userId: string]: Profile} = {}
|
||||
|
||||
/**
|
||||
* If users profile are loaded
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof UserState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
|
||||
/**
|
||||
* If edit profile is open {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof UserState
|
||||
*/
|
||||
openEditProfile: Boolean = false
|
||||
|
||||
/**
|
||||
* People data storage
|
||||
*/
|
||||
people?: {hasMoreData: boolean, lastPageRequest: number, lastUserId: string} =
|
||||
{hasMoreData: true, lastPageRequest: -1, lastUserId: ''}
|
||||
}
|
||||
3
src/store/reducers/users/index.ts
Normal file
3
src/store/reducers/users/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { userReducer } from './userReducer'
|
||||
|
||||
export {userReducer}
|
||||
112
src/store/reducers/users/userReducer.ts
Normal file
112
src/store/reducers/users/userReducer.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
// - Import action types
|
||||
import { UserActionType } from 'constants/userActionType'
|
||||
|
||||
// - Import domain
|
||||
import { User,Profile } from 'src/core/domain/users'
|
||||
|
||||
import { UserState } from './UserState'
|
||||
import { IUserAction } from './IUserAction'
|
||||
|
||||
/**
|
||||
* User reducer
|
||||
*/
|
||||
export let userReducer = (state: UserState = new UserState(), action: IUserAction) => {
|
||||
const { payload } = action
|
||||
switch (action.type) {
|
||||
case UserActionType.USER_INFO:
|
||||
return {
|
||||
...state,
|
||||
info: {
|
||||
...state.info,
|
||||
[payload.uid]: {
|
||||
...payload.info
|
||||
}
|
||||
}
|
||||
}
|
||||
case UserActionType.ADD_USER_INFO:
|
||||
return {
|
||||
...state,
|
||||
info: {
|
||||
...state.info,
|
||||
[payload.uid]: {
|
||||
...payload.info
|
||||
}
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
case UserActionType.ADD_PEOPLE_INFO:
|
||||
return {
|
||||
...state,
|
||||
info: {
|
||||
...state.info,
|
||||
...payload
|
||||
}
|
||||
}
|
||||
|
||||
case UserActionType.UPDATE_USER_INFO:
|
||||
return {
|
||||
...state,
|
||||
info: {
|
||||
...state.info,
|
||||
[payload.uid]: {
|
||||
...state.info![payload.uid],
|
||||
...payload.info
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case UserActionType.CLEAR_ALL_DATA_USER:
|
||||
return new UserState()
|
||||
|
||||
case UserActionType.CLOSE_EDIT_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
openEditProfile: false
|
||||
}
|
||||
|
||||
case UserActionType.OPEN_EDIT_PROFILE:
|
||||
return {
|
||||
...state,
|
||||
openEditProfile: true
|
||||
}
|
||||
case UserActionType.HAS_MORE_DATA_PEOPLE:
|
||||
return {
|
||||
...state,
|
||||
people: {
|
||||
...state.people,
|
||||
hasMoreData: true
|
||||
}
|
||||
|
||||
}
|
||||
case UserActionType.NOT_MORE_DATA_PEOPLE:
|
||||
return {
|
||||
...state,
|
||||
people: {
|
||||
...state.people,
|
||||
hasMoreData: false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case UserActionType.REQUEST_PAGE_PEOPLE:
|
||||
return {
|
||||
...state,
|
||||
people: {
|
||||
...state.people,
|
||||
lastPageRequest: payload.page
|
||||
}
|
||||
}
|
||||
|
||||
case UserActionType.LAST_USER_PEOPLE:
|
||||
return {
|
||||
...state,
|
||||
people: {
|
||||
...state.people,
|
||||
lastUserId: payload.lastUserId
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
13
src/store/reducers/votes/IVoteAction.ts
Normal file
13
src/store/reducers/votes/IVoteAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { VoteActionType } from 'constants/voteActionType'
|
||||
|
||||
/**
|
||||
* Vote action interface
|
||||
*
|
||||
* @export
|
||||
* @interface IVoteAction
|
||||
*/
|
||||
export interface IVoteAction {
|
||||
payload: any,
|
||||
type: VoteActionType
|
||||
|
||||
}
|
||||
26
src/store/reducers/votes/VoteState.ts
Normal file
26
src/store/reducers/votes/VoteState.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Vote } from 'src/core/domain/votes'
|
||||
|
||||
/**
|
||||
* Vote state
|
||||
*
|
||||
* @export
|
||||
* @class VoteState
|
||||
*/
|
||||
export class VoteState {
|
||||
|
||||
/**
|
||||
* The list of posts vote
|
||||
*
|
||||
* @type {({[postId: string]: {[voteId: string]: Vote}} | null)}
|
||||
* @memberof VoteState
|
||||
*/
|
||||
postVotes: {[postId: string]: {[voteId: string]: Vote}} | null = null
|
||||
|
||||
/**
|
||||
* If posts vote are loaded {true} or not {false}
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @memberof VoteState
|
||||
*/
|
||||
loaded: Boolean = false
|
||||
}
|
||||
3
src/store/reducers/votes/index.ts
Normal file
3
src/store/reducers/votes/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { voteReducer } from './voteReducer'
|
||||
|
||||
export {voteReducer}
|
||||
75
src/store/reducers/votes/voteReducer.ts
Normal file
75
src/store/reducers/votes/voteReducer.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
// - Import react components
|
||||
import moment from 'moment/moment'
|
||||
import _ from 'lodash'
|
||||
|
||||
// - Import action types
|
||||
import { VoteActionType } from 'constants/voteActionType'
|
||||
|
||||
// Import domain
|
||||
import { Vote } from 'src/core/domain/votes'
|
||||
|
||||
import { VoteState } from './VoteState'
|
||||
import { IVoteAction } from './IVoteAction'
|
||||
|
||||
/**
|
||||
* Vote actions
|
||||
* @param {object} state
|
||||
* @param {object} action
|
||||
*/
|
||||
export let voteReducer = (state: VoteState = new VoteState(), action: IVoteAction) => {
|
||||
let { payload } = action
|
||||
switch (action.type) {
|
||||
|
||||
/* _____________ CRUD _____________ */
|
||||
case VoteActionType.ADD_VOTE:
|
||||
return {
|
||||
...state,
|
||||
postVotes: {
|
||||
...state.postVotes,
|
||||
[payload.postId]: {
|
||||
...state.postVotes![payload.postId],
|
||||
[payload.userId]: {
|
||||
...payload
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
case VoteActionType.ADD_VOTE_LIST:
|
||||
return {
|
||||
...state,
|
||||
postVotes: {
|
||||
...payload
|
||||
},
|
||||
loaded: true
|
||||
}
|
||||
|
||||
case VoteActionType.DELETE_VOTE:
|
||||
let parsedVotes = {}
|
||||
if (state.postVotes![payload.postId]) {
|
||||
Object.keys(state.postVotes![payload.postId]).map((id) => {
|
||||
if (id !== payload.userId) {
|
||||
_.merge(parsedVotes, { [id]: { ...state.postVotes![payload.postId][id] } })
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
postVotes: {
|
||||
...state.postVotes,
|
||||
[payload.postId]: {
|
||||
...parsedVotes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case VoteActionType.CLEAR_ALL_DATA_VOTE:
|
||||
return new VoteState()
|
||||
|
||||
default:
|
||||
return state
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user