From e45dee3c9f7366f126f59b6967ce002209e38bef Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Tue, 12 Nov 2019 09:58:47 +0700 Subject: [PATCH] fetching messages for user --- .../containers/BlurWrapper/index.tsx | 5 +-- src/constants/api.ts | 9 ++--- .../dialogs/ProfileDialog/index.tsx | 8 ++--- .../profile/ProfileMessages/index.tsx | 36 +++++++++++++++++++ .../profile/ProfileMessages/styles.scss | 0 src/redux/auth/actions.ts | 5 +++ src/redux/auth/api.ts | 11 +++++- src/redux/auth/constants.ts | 1 + src/redux/auth/reducer.ts | 3 ++ src/redux/auth/sagas.ts | 32 ++++++++++++++++- src/redux/auth/types.ts | 5 ++- src/redux/types.ts | 5 +++ 12 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 src/containers/profile/ProfileMessages/index.tsx create mode 100644 src/containers/profile/ProfileMessages/styles.scss diff --git a/src/components/containers/BlurWrapper/index.tsx b/src/components/containers/BlurWrapper/index.tsx index a1bf0a52..913afa0c 100644 --- a/src/components/containers/BlurWrapper/index.tsx +++ b/src/components/containers/BlurWrapper/index.tsx @@ -4,10 +4,7 @@ import * as styles from './styles.scss'; type IProps = AllHTMLAttributes & { is_blurred: boolean }; export const BlurWrapper: FC = ({ children, is_blurred }) => ( -
+
{children}
); diff --git a/src/constants/api.ts b/src/constants/api.ts index f8c8bab2..5d3864c1 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -3,11 +3,12 @@ import { INode } from '~/redux/types'; export const API = { BASE: process.env.API_HOST, USER: { - LOGIN: '/auth/login', - VKONTAKTE_LOGIN: `${process.env.API_HOST}/auth/vkontakte`, - ME: '/auth/', + LOGIN: '/user/login', + VKONTAKTE_LOGIN: `${process.env.API_HOST}/user/vkontakte`, + ME: '/user/', + PROFILE: (username: string) => `/user/${username}/profile`, + MESSAGES: (username: string) => `/user/${username}/messages`, UPLOAD: (target, type) => `/upload/${target}/${type}`, - PROFILE: (username: string) => `/auth/user/${username}`, }, NODE: { SAVE: '/node/', diff --git a/src/containers/dialogs/ProfileDialog/index.tsx b/src/containers/dialogs/ProfileDialog/index.tsx index 3ff1b7f2..718f5ab6 100644 --- a/src/containers/dialogs/ProfileDialog/index.tsx +++ b/src/containers/dialogs/ProfileDialog/index.tsx @@ -7,6 +7,7 @@ import { connect } from 'react-redux'; import { selectAuthProfile } from '~/redux/auth/selectors'; import { NodeNoComments } from '~/components/node/NodeNoComments'; import { CommentForm } from '~/components/node/CommentForm'; +import { ProfileMessages } from '~/containers/profile/ProfileMessages'; const mapStateToProps = selectAuthProfile; const mapDispatchToProps = {}; @@ -16,14 +17,9 @@ type IProps = IDialogProps & ReturnType & {}; const ProfileDialogUnconnected: FC = ({ onRequestClose, is_loading, user }) => ( } - footer={} onClose={onRequestClose} > -
- - - -
+
); diff --git a/src/containers/profile/ProfileMessages/index.tsx b/src/containers/profile/ProfileMessages/index.tsx new file mode 100644 index 00000000..397cf878 --- /dev/null +++ b/src/containers/profile/ProfileMessages/index.tsx @@ -0,0 +1,36 @@ +import React, { FC, useEffect } from 'react'; +import { connect } from 'react-redux'; +import { selectAuthProfile } from '~/redux/auth/selectors'; +import { NodeNoComments } from '~/components/node/NodeNoComments'; +import styles from './styles.scss'; +import * as AUTH_ACTIONS from '~/redux/auth/actions'; + +const mapStateToProps = state => ({ profile: selectAuthProfile(state) }); +const mapDispatchToProps = { + authGetMessages: AUTH_ACTIONS.authGetMessages, +}; + +type IProps = ReturnType & typeof mapDispatchToProps & {}; + +const ProfileMessagesUnconnected: FC = ({ profile, authGetMessages }) => { + useEffect(() => { + if (profile.is_loading || !profile.user || !profile.user.username) return; + + authGetMessages(profile.user.username); + }, [profile.user]); + + return ( +
+ {profile.messages.map(message => ( +
{message.text}
+ ))} +
+ ); +}; + +const ProfileMessages = connect( + mapStateToProps, + mapDispatchToProps +)(ProfileMessagesUnconnected); + +export { ProfileMessages }; diff --git a/src/containers/profile/ProfileMessages/styles.scss b/src/containers/profile/ProfileMessages/styles.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/redux/auth/actions.ts b/src/redux/auth/actions.ts index a40bcc6d..75f717cb 100644 --- a/src/redux/auth/actions.ts +++ b/src/redux/auth/actions.ts @@ -42,3 +42,8 @@ export const authSetProfile = (profile: Partial) => ({ type: AUTH_USER_ACTIONS.SET_PROFILE, profile, }); + +export const authGetMessages = (username: string) => ({ + type: AUTH_USER_ACTIONS.GET_MESSAGES, + username, +}); diff --git a/src/redux/auth/api.ts b/src/redux/auth/api.ts index 6035c14f..d95a41b6 100644 --- a/src/redux/auth/api.ts +++ b/src/redux/auth/api.ts @@ -1,6 +1,6 @@ import { api, errorMiddleware, resultMiddleware, configWithToken } from '~/utils/api'; import { API } from '~/constants/api'; -import { IResultWithStatus } from '~/redux/types'; +import { IResultWithStatus, IMessage } from '~/redux/types'; import { userLoginTransform } from '~/redux/auth/transforms'; import { IUser } from './types'; @@ -31,3 +31,12 @@ export const apiAuthGetUserProfile = ({ .get(API.USER.PROFILE(username), configWithToken(access)) .then(resultMiddleware) .catch(errorMiddleware); + +export const apiAuthGetUserMessages = ({ + access, + username, +}): Promise> => + api + .get(API.USER.MESSAGES(username), configWithToken(access)) + .then(resultMiddleware) + .catch(errorMiddleware); diff --git a/src/redux/auth/constants.ts b/src/redux/auth/constants.ts index b81c62fb..abfb1a76 100644 --- a/src/redux/auth/constants.ts +++ b/src/redux/auth/constants.ts @@ -11,6 +11,7 @@ export const AUTH_USER_ACTIONS = { GOT_AUTH_POST_MESSAGE: 'GOT_POST_MESSAGE', OPEN_PROFILE: 'OPEN_PROFILE', SET_PROFILE: 'SET_PROFILE', + GET_MESSAGES: 'GET_MESSAGES', }; export const USER_ERRORS = { diff --git a/src/redux/auth/reducer.ts b/src/redux/auth/reducer.ts index 49fcc49c..69c35901 100644 --- a/src/redux/auth/reducer.ts +++ b/src/redux/auth/reducer.ts @@ -18,7 +18,10 @@ const INITIAL_STATE: IAuthState = { profile: { is_loading: true, + is_loading_messages: true, user: null, + messages: [], + messages_errors: {}, }, }; diff --git a/src/redux/auth/sagas.ts b/src/redux/auth/sagas.ts index b7261dc9..d085c49c 100644 --- a/src/redux/auth/sagas.ts +++ b/src/redux/auth/sagas.ts @@ -8,8 +8,14 @@ import { gotAuthPostMessage, authOpenProfile, authSetProfile, + authGetMessages, } from '~/redux/auth/actions'; -import { apiUserLogin, apiAuthGetUser, apiAuthGetUserProfile } from '~/redux/auth/api'; +import { + apiUserLogin, + apiAuthGetUser, + apiAuthGetUserProfile, + apiAuthGetUserMessages, +} from '~/redux/auth/api'; import { modalSetShown, modalShowDialog } from '~/redux/modal/actions'; import { selectToken } from './selectors'; import { IResultWithStatus } from '../types'; @@ -18,6 +24,7 @@ import { REHYDRATE, RehydrateAction } from 'redux-persist'; import { selectModal } from '../modal/selectors'; import { IModalState } from '../modal/reducer'; import { DIALOGS } from '../modal/constants'; +import { ERRORS } from '~/constants/errors'; export function* reqWrapper(requestAction, props = {}): ReturnType { const access = yield select(selectToken); @@ -75,6 +82,7 @@ function* refreshUser() { function* checkUserSaga({ key }: RehydrateAction) { if (key !== 'auth') return; yield call(refreshUser); + yield put(authOpenProfile('gvorcek')); } function* gotPostMessageSaga({ token }: ReturnType) { @@ -107,12 +115,34 @@ function* openProfile({ username }: ReturnType) { yield put(authSetProfile({ is_loading: false, user })); } +function* getMessages({ username }: ReturnType) { + yield put(modalShowDialog(DIALOGS.PROFILE)); + yield put(authSetProfile({ is_loading_messages: true })); + + const { + error, + data: { messages }, + } = yield call(reqWrapper, apiAuthGetUserMessages, { username }); + + if (error || !messages) { + return yield put( + authSetProfile({ + is_loading_messages: false, + messages_errors: { network: ERRORS.EMPTY_RESPONSE }, + }) + ); + } + + yield put(authSetProfile({ is_loading_messages: false, messages })); +} + function* authSaga() { yield takeLatest(REHYDRATE, checkUserSaga); yield takeLatest(AUTH_USER_ACTIONS.LOGOUT, logoutSaga); yield takeLatest(AUTH_USER_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga); yield takeLatest(AUTH_USER_ACTIONS.GOT_AUTH_POST_MESSAGE, gotPostMessageSaga); yield takeLatest(AUTH_USER_ACTIONS.OPEN_PROFILE, openProfile); + yield takeLatest(AUTH_USER_ACTIONS.GET_MESSAGES, getMessages); } export default authSaga; diff --git a/src/redux/auth/types.ts b/src/redux/auth/types.ts index 135bc194..0a26ca9a 100644 --- a/src/redux/auth/types.ts +++ b/src/redux/auth/types.ts @@ -1,4 +1,4 @@ -import { IFile } from '../types'; +import { IFile, IMessage } from '../types'; export interface IToken { access: string; @@ -31,6 +31,9 @@ export type IAuthState = Readonly<{ profile: { is_loading: boolean; + is_loading_messages: boolean; user: IUser; + messages: IMessage[]; + messages_errors: Record; }; }>; diff --git a/src/redux/types.ts b/src/redux/types.ts index 75069c48..adfd79c6 100644 --- a/src/redux/types.ts +++ b/src/redux/types.ts @@ -146,6 +146,11 @@ export interface IComment { update_at?: string; } +export type IMessage = Omit & { + from: IUser; + to: IUser; +}; + export interface ICommentGroup { user: IUser; comments: IComment[];