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

messages form

This commit is contained in:
Fedor Katurov 2019-11-12 15:15:45 +07:00
parent 98c66dec8c
commit 371f47f866
7 changed files with 98 additions and 16 deletions

View file

@ -1,14 +1,14 @@
import React, { FC } from 'react';
import * as styles from './styles.scss';
import { Icon } from '../Icon';
import { describeArc } from '~/utils/dom';
import classNames from 'classnames';
interface IProps {
size?: number;
}
export const LoaderCircle: FC<IProps> = ({ size = 24 }) => (
<div className={styles.wrap}>
<div className={classNames(styles.wrap, 'loader-circle')}>
<svg className={styles.icon} width={size} height={size}>
<path d={describeArc(size / 2, size / 2, size / 2, 0, 90)} />
<path d={describeArc(size / 2, size / 2, size / 2, 180, 270)} />

View file

@ -1,4 +1,4 @@
import React, { FC, useState, useCallback } from 'react';
import React, { FC, useState, useCallback, KeyboardEventHandler } from 'react';
import styles from './styles.scss';
import { Textarea } from '~/components/input/Textarea';
import { Filler } from '~/components/containers/Filler';
@ -21,7 +21,7 @@ const mapDispatchToProps = {
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
const MessageFormUnconnected: FC<IProps> = ({
profile: { is_sending_messages, messages_error },
profile: { is_sending_messages, is_loading_messages, messages_error },
authSendMessage,
}) => {
const [text, setText] = useState('');
@ -34,14 +34,35 @@ const MessageFormUnconnected: FC<IProps> = ({
authSendMessage({ text }, onSuccess);
}, [authSendMessage, text, onSuccess]);
const onKeyDown = useCallback<KeyboardEventHandler<HTMLTextAreaElement>>(
({ ctrlKey, key }) => {
if (!!ctrlKey && key === 'Enter') onSubmit();
},
[onSubmit]
);
return (
<div className={styles.wrap}>
{messages_error && <div className={styles.error}>{ERROR_LITERAL[messages_error]}</div>}
{is_loading_messages && !messages_error && (
<Group className={styles.loader} horizontal>
<LoaderCircle size={20} />
<div>Обновляем</div>
</Group>
)}
<Group className={styles.content}>
<Textarea value={text} handler={setText} minRows={1} maxRows={4} seamless />
<Textarea
value={text}
handler={setText}
minRows={1}
maxRows={4}
seamless
onKeyDown={onKeyDown}
disabled={is_sending_messages}
autoFocus
/>
<div className={styles.buttons}>
<Group className={styles.buttons} horizontal>
<Filler />
{is_sending_messages && <LoaderCircle size={20} />}
@ -55,7 +76,7 @@ const MessageFormUnconnected: FC<IProps> = ({
>
Сказать
</Button>
</div>
</Group>
</Group>
</div>
);

View file

@ -2,10 +2,11 @@
@include outer_shadow();
padding: $gap;
background: $content_bg;
position: relative;
// position: relative;
textarea {
// margin-bottom: 40px;
padding-bottom: 0 !important;
}
}
@ -21,6 +22,12 @@
justify-content: center;
flex-direction: row;
padding: 0 $gap / 2 $gap / 2 $gap / 2;
:global(.loader-circle) {
svg {
fill: $wisegreen;
}
}
}
.error {
@ -35,3 +42,19 @@
text-align: center;
border-radius: 0 0 $radius $radius;
}
.loader {
position: absolute;
right: 50%;
bottom: 0;
z-index: 2;
padding: $gap;
text-transform: uppercase;
background: $wisegreen;
border-radius: $radius;
transform: translate(50%, -10px);
svg {
fill: white;
}
}

View file

@ -0,0 +1,15 @@
import React, { FC } from 'react';
import styles from './styles.scss';
import { LoaderCircle } from '~/components/input/LoaderCircle';
interface IProps {}
const ProfileLoader: FC<IProps> = ({}) => {
return (
<div className={styles.loader}>
<LoaderCircle size={40} />
</div>
);
};
export { ProfileLoader };

View file

@ -0,0 +1,6 @@
.loader {
min-height: 33vh;
display: flex;
align-items: center;
justify-content: center;
}

View file

@ -6,6 +6,7 @@ import * as AUTH_ACTIONS from '~/redux/auth/actions';
import { Message } from '~/components/profile/Message';
import { Group } from '~/components/containers/Group';
import pick from 'ramda/es/pick';
import { NodeNoComments } from '~/components/node/NodeNoComments';
const mapStateToProps = state => ({
profile: selectAuthProfile(state),
@ -25,6 +26,9 @@ const ProfileMessagesUnconnected: FC<IProps> = ({ profile, user: { id }, authGet
authGetMessages(profile.user.username);
}, [profile.user]);
if (!profile.messages.length || profile.is_loading)
return <NodeNoComments is_loading={profile.is_loading_messages || profile.is_loading} />;
return (
<Group className={styles.messages}>
{profile.messages

View file

@ -114,19 +114,32 @@ function* openProfile({ username }: ReturnType<typeof authOpenProfile>) {
return yield put(modalSetShown(false));
}
yield put(authSetProfile({ is_loading: false, user }));
yield put(authSetProfile({ is_loading: false, user, messages: [] }));
}
function* getMessages({ username }: ReturnType<typeof authGetMessages>) {
yield put(modalShowDialog(DIALOGS.PROFILE));
yield put(authSetProfile({ is_loading_messages: true }));
// yield put(modalShowDialog(DIALOGS.PROFILE));
const { messages } = yield select(selectAuthProfile);
yield put(
authSetProfile({
is_loading_messages: true,
messages:
messages &&
messages.length > 0 &&
(messages[0].to.username === username || messages[0].from.username === username)
? messages
: [],
})
);
const {
error,
data: { messages },
data,
// data: { messages },
} = yield call(reqWrapper, apiAuthGetUserMessages, { username });
if (error || !messages) {
if (error || !data.messages) {
return yield put(
authSetProfile({
is_loading_messages: false,
@ -135,7 +148,7 @@ function* getMessages({ username }: ReturnType<typeof authGetMessages>) {
);
}
yield put(authSetProfile({ is_loading_messages: false, messages }));
yield put(authSetProfile({ is_loading_messages: false, messages: data.messages }));
}
function* sendMessage({ message, onSuccess }: ReturnType<typeof authSendMessage>) {
@ -169,7 +182,7 @@ function* sendMessage({ message, onSuccess }: ReturnType<typeof authSendMessage>
yield put(
authSetProfile({
is_sending_messages: false,
messages: [message, ...messages],
messages: [data.message, ...messages],
})
);