1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 12:56:41 +07:00

fetching messages for user

This commit is contained in:
Fedor Katurov 2019-11-12 09:58:47 +07:00
parent 54687b131c
commit e45dee3c9f
12 changed files with 103 additions and 17 deletions

View file

@ -4,10 +4,7 @@ import * as styles from './styles.scss';
type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean }; type IProps = AllHTMLAttributes<HTMLDivElement> & { is_blurred: boolean };
export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => ( export const BlurWrapper: FC<IProps> = ({ children, is_blurred }) => (
<div <div className={styles.blur} style={{ filter: `blur(${is_blurred ? 15 : 0}px)` }}>
className={styles.blur}
style={{ filter: `blur(${is_blurred ? 15 : 0}px) saturate(${is_blurred ? 3 : 1})` }}
>
{children} {children}
</div> </div>
); );

View file

@ -3,11 +3,12 @@ import { INode } from '~/redux/types';
export const API = { export const API = {
BASE: process.env.API_HOST, BASE: process.env.API_HOST,
USER: { USER: {
LOGIN: '/auth/login', LOGIN: '/user/login',
VKONTAKTE_LOGIN: `${process.env.API_HOST}/auth/vkontakte`, VKONTAKTE_LOGIN: `${process.env.API_HOST}/user/vkontakte`,
ME: '/auth/', ME: '/user/',
PROFILE: (username: string) => `/user/${username}/profile`,
MESSAGES: (username: string) => `/user/${username}/messages`,
UPLOAD: (target, type) => `/upload/${target}/${type}`, UPLOAD: (target, type) => `/upload/${target}/${type}`,
PROFILE: (username: string) => `/auth/user/${username}`,
}, },
NODE: { NODE: {
SAVE: '/node/', SAVE: '/node/',

View file

@ -7,6 +7,7 @@ import { connect } from 'react-redux';
import { selectAuthProfile } from '~/redux/auth/selectors'; import { selectAuthProfile } from '~/redux/auth/selectors';
import { NodeNoComments } from '~/components/node/NodeNoComments'; import { NodeNoComments } from '~/components/node/NodeNoComments';
import { CommentForm } from '~/components/node/CommentForm'; import { CommentForm } from '~/components/node/CommentForm';
import { ProfileMessages } from '~/containers/profile/ProfileMessages';
const mapStateToProps = selectAuthProfile; const mapStateToProps = selectAuthProfile;
const mapDispatchToProps = {}; const mapDispatchToProps = {};
@ -16,14 +17,9 @@ type IProps = IDialogProps & ReturnType<typeof mapStateToProps> & {};
const ProfileDialogUnconnected: FC<IProps> = ({ onRequestClose, is_loading, user }) => ( const ProfileDialogUnconnected: FC<IProps> = ({ onRequestClose, is_loading, user }) => (
<BetterScrollDialog <BetterScrollDialog
header={<ProfileInfo is_loading={is_loading} user={user} />} header={<ProfileInfo is_loading={is_loading} user={user} />}
footer={<CommentForm id="0" />}
onClose={onRequestClose} onClose={onRequestClose}
> >
<div className={styles.messages}> <ProfileMessages />
<NodeNoComments />
<NodeNoComments />
<NodeNoComments />
</div>
</BetterScrollDialog> </BetterScrollDialog>
); );

View file

@ -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 mapStateToProps> & typeof mapDispatchToProps & {};
const ProfileMessagesUnconnected: FC<IProps> = ({ profile, authGetMessages }) => {
useEffect(() => {
if (profile.is_loading || !profile.user || !profile.user.username) return;
authGetMessages(profile.user.username);
}, [profile.user]);
return (
<div className={styles.messages}>
{profile.messages.map(message => (
<div key={message.id}>{message.text}</div>
))}
</div>
);
};
const ProfileMessages = connect(
mapStateToProps,
mapDispatchToProps
)(ProfileMessagesUnconnected);
export { ProfileMessages };

View file

@ -42,3 +42,8 @@ export const authSetProfile = (profile: Partial<IAuthState['profile']>) => ({
type: AUTH_USER_ACTIONS.SET_PROFILE, type: AUTH_USER_ACTIONS.SET_PROFILE,
profile, profile,
}); });
export const authGetMessages = (username: string) => ({
type: AUTH_USER_ACTIONS.GET_MESSAGES,
username,
});

View file

@ -1,6 +1,6 @@
import { api, errorMiddleware, resultMiddleware, configWithToken } from '~/utils/api'; import { api, errorMiddleware, resultMiddleware, configWithToken } from '~/utils/api';
import { API } from '~/constants/api'; import { API } from '~/constants/api';
import { IResultWithStatus } from '~/redux/types'; import { IResultWithStatus, IMessage } from '~/redux/types';
import { userLoginTransform } from '~/redux/auth/transforms'; import { userLoginTransform } from '~/redux/auth/transforms';
import { IUser } from './types'; import { IUser } from './types';
@ -31,3 +31,12 @@ export const apiAuthGetUserProfile = ({
.get(API.USER.PROFILE(username), configWithToken(access)) .get(API.USER.PROFILE(username), configWithToken(access))
.then(resultMiddleware) .then(resultMiddleware)
.catch(errorMiddleware); .catch(errorMiddleware);
export const apiAuthGetUserMessages = ({
access,
username,
}): Promise<IResultWithStatus<{ messages: IMessage }>> =>
api
.get(API.USER.MESSAGES(username), configWithToken(access))
.then(resultMiddleware)
.catch(errorMiddleware);

View file

@ -11,6 +11,7 @@ export const AUTH_USER_ACTIONS = {
GOT_AUTH_POST_MESSAGE: 'GOT_POST_MESSAGE', GOT_AUTH_POST_MESSAGE: 'GOT_POST_MESSAGE',
OPEN_PROFILE: 'OPEN_PROFILE', OPEN_PROFILE: 'OPEN_PROFILE',
SET_PROFILE: 'SET_PROFILE', SET_PROFILE: 'SET_PROFILE',
GET_MESSAGES: 'GET_MESSAGES',
}; };
export const USER_ERRORS = { export const USER_ERRORS = {

View file

@ -18,7 +18,10 @@ const INITIAL_STATE: IAuthState = {
profile: { profile: {
is_loading: true, is_loading: true,
is_loading_messages: true,
user: null, user: null,
messages: [],
messages_errors: {},
}, },
}; };

View file

@ -8,8 +8,14 @@ import {
gotAuthPostMessage, gotAuthPostMessage,
authOpenProfile, authOpenProfile,
authSetProfile, authSetProfile,
authGetMessages,
} from '~/redux/auth/actions'; } 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 { modalSetShown, modalShowDialog } from '~/redux/modal/actions';
import { selectToken } from './selectors'; import { selectToken } from './selectors';
import { IResultWithStatus } from '../types'; import { IResultWithStatus } from '../types';
@ -18,6 +24,7 @@ import { REHYDRATE, RehydrateAction } from 'redux-persist';
import { selectModal } from '../modal/selectors'; import { selectModal } from '../modal/selectors';
import { IModalState } from '../modal/reducer'; import { IModalState } from '../modal/reducer';
import { DIALOGS } from '../modal/constants'; import { DIALOGS } from '../modal/constants';
import { ERRORS } from '~/constants/errors';
export function* reqWrapper(requestAction, props = {}): ReturnType<typeof requestAction> { export function* reqWrapper(requestAction, props = {}): ReturnType<typeof requestAction> {
const access = yield select(selectToken); const access = yield select(selectToken);
@ -75,6 +82,7 @@ function* refreshUser() {
function* checkUserSaga({ key }: RehydrateAction) { function* checkUserSaga({ key }: RehydrateAction) {
if (key !== 'auth') return; if (key !== 'auth') return;
yield call(refreshUser); yield call(refreshUser);
yield put(authOpenProfile('gvorcek'));
} }
function* gotPostMessageSaga({ token }: ReturnType<typeof gotAuthPostMessage>) { function* gotPostMessageSaga({ token }: ReturnType<typeof gotAuthPostMessage>) {
@ -107,12 +115,34 @@ function* openProfile({ username }: ReturnType<typeof authOpenProfile>) {
yield put(authSetProfile({ is_loading: false, user })); yield put(authSetProfile({ is_loading: false, user }));
} }
function* getMessages({ username }: ReturnType<typeof authGetMessages>) {
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() { function* authSaga() {
yield takeLatest(REHYDRATE, checkUserSaga); yield takeLatest(REHYDRATE, checkUserSaga);
yield takeLatest(AUTH_USER_ACTIONS.LOGOUT, logoutSaga); yield takeLatest(AUTH_USER_ACTIONS.LOGOUT, logoutSaga);
yield takeLatest(AUTH_USER_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga); yield takeLatest(AUTH_USER_ACTIONS.SEND_LOGIN_REQUEST, sendLoginRequestSaga);
yield takeLatest(AUTH_USER_ACTIONS.GOT_AUTH_POST_MESSAGE, gotPostMessageSaga); yield takeLatest(AUTH_USER_ACTIONS.GOT_AUTH_POST_MESSAGE, gotPostMessageSaga);
yield takeLatest(AUTH_USER_ACTIONS.OPEN_PROFILE, openProfile); yield takeLatest(AUTH_USER_ACTIONS.OPEN_PROFILE, openProfile);
yield takeLatest(AUTH_USER_ACTIONS.GET_MESSAGES, getMessages);
} }
export default authSaga; export default authSaga;

View file

@ -1,4 +1,4 @@
import { IFile } from '../types'; import { IFile, IMessage } from '../types';
export interface IToken { export interface IToken {
access: string; access: string;
@ -31,6 +31,9 @@ export type IAuthState = Readonly<{
profile: { profile: {
is_loading: boolean; is_loading: boolean;
is_loading_messages: boolean;
user: IUser; user: IUser;
messages: IMessage[];
messages_errors: Record<string, string>;
}; };
}>; }>;

View file

@ -146,6 +146,11 @@ export interface IComment {
update_at?: string; update_at?: string;
} }
export type IMessage = Omit<IComment, 'user' | 'node'> & {
from: IUser;
to: IUser;
};
export interface ICommentGroup { export interface ICommentGroup {
user: IUser; user: IUser;
comments: IComment[]; comments: IComment[];