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

message editing form works properly

This commit is contained in:
Fedor Katurov 2020-09-07 18:00:49 +07:00
parent c8ecb9085a
commit 47cd66496b
7 changed files with 47 additions and 23 deletions

View file

@ -57,6 +57,7 @@
"@hot-loader/react-dom": "^16.10.2", "@hot-loader/react-dom": "^16.10.2",
"@typescript-eslint/eslint-plugin": "^1.13.0", "@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0", "@typescript-eslint/parser": "^1.13.0",
"autosize": "^4.0.2",
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-runtime": "^6.26.0", "babel-runtime": "^6.26.0",
"body-scroll-lock": "^2.6.4", "body-scroll-lock": "^2.6.4",

View file

@ -13,10 +13,11 @@ interface IProps {
incoming: boolean; incoming: boolean;
onEdit: (id: number) => void; onEdit: (id: number) => void;
onDelete: (id: number) => void; onDelete: (id: number) => void;
onCancelEdit: () => void;
isEditing: boolean; isEditing: boolean;
} }
const Message: FC<IProps> = ({ message, incoming, onEdit, onDelete, isEditing }) => { const Message: FC<IProps> = ({ message, incoming, onEdit, onDelete, isEditing, onCancelEdit }) => {
const onEditClicked = useCallback(() => onEdit(message.id), [message.id]); const onEditClicked = useCallback(() => onEdit(message.id), [message.id]);
const onDeleteClicked = useCallback(() => onDelete(message.id), [message.id]); const onDeleteClicked = useCallback(() => onDelete(message.id), [message.id]);
@ -24,7 +25,7 @@ const Message: FC<IProps> = ({ message, incoming, onEdit, onDelete, isEditing })
<div className={classNames(styles.message, { [styles.incoming]: incoming })}> <div className={classNames(styles.message, { [styles.incoming]: incoming })}>
{isEditing ? ( {isEditing ? (
<div className={styles.form}> <div className={styles.form}>
<MessageForm id={message.id} text={message.text} /> <MessageForm id={message.id} text={message.text} onCancel={onCancelEdit} />
</div> </div>
) : ( ) : (
<div className={styles.text}> <div className={styles.text}>

View file

@ -1,4 +1,4 @@
import React, { FC, useState, useCallback, KeyboardEventHandler } from 'react'; import React, { FC, useState, useCallback, KeyboardEventHandler, useMemo } from 'react';
import styles from './styles.scss'; import styles from './styles.scss';
import { Textarea } from '~/components/input/Textarea'; import { Textarea } from '~/components/input/Textarea';
import { Filler } from '~/components/containers/Filler'; import { Filler } from '~/components/containers/Filler';
@ -22,19 +22,27 @@ type IProps = ReturnType<typeof mapStateToProps> &
typeof mapDispatchToProps & { typeof mapDispatchToProps & {
id?: number; id?: number;
text?: string; text?: string;
onCancel?: () => void;
}; };
const MessageFormUnconnected: FC<IProps> = ({ const MessageFormUnconnected: FC<IProps> = ({
id = 0,
text: initialText = '',
profile: { is_sending_messages, is_loading_messages, messages_error }, profile: { is_sending_messages, is_loading_messages, messages_error },
authSendMessage, authSendMessage,
id = 0,
text: initialText = '',
onCancel,
}) => { }) => {
const isEditing = useMemo(() => id > 0, [id]);
const [text, setText] = useState(initialText); const [text, setText] = useState(initialText);
const onSuccess = useCallback(() => { const onSuccess = useCallback(() => {
setText(''); setText('');
}, [setText]);
if (isEditing) {
onCancel();
}
}, [setText, isEditing, onCancel]);
const onSubmit = useCallback(() => { const onSubmit = useCallback(() => {
authSendMessage({ text, id }, onSuccess); authSendMessage({ text, id }, onSuccess);
@ -61,7 +69,7 @@ const MessageFormUnconnected: FC<IProps> = ({
value={text} value={text}
handler={setText} handler={setText}
minRows={1} minRows={1}
maxRows={4} maxRows={isEditing ? 15 : 5}
seamless seamless
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
disabled={is_sending_messages} disabled={is_sending_messages}
@ -73,6 +81,12 @@ const MessageFormUnconnected: FC<IProps> = ({
{is_sending_messages && <LoaderCircle size={20} />} {is_sending_messages && <LoaderCircle size={20} />}
{isEditing && (
<Button size="small" color="link" onClick={onCancel}>
Отмена
</Button>
)}
<Button <Button
size="small" size="small"
color="gray" color="gray"
@ -80,7 +94,7 @@ const MessageFormUnconnected: FC<IProps> = ({
disabled={is_sending_messages} disabled={is_sending_messages}
onClick={onSubmit} onClick={onSubmit}
> >
Сказать {isEditing ? 'Схоронить' : 'Сказать'}
</Button> </Button>
</Group> </Group>
</Group> </Group>

View file

@ -20,6 +20,7 @@
justify-content: center; justify-content: center;
flex-direction: row; flex-direction: row;
padding: 0 $gap / 2 $gap / 2 $gap / 2; padding: 0 $gap / 2 $gap / 2 $gap / 2;
border-radius: 0 0 $radius $radius;
:global(.loader-circle) { :global(.loader-circle) {
svg { svg {

View file

@ -23,6 +23,7 @@ const ProfileMessagesUnconnected: FC<IProps> = ({ profile, user: { id }, authGet
const [editingMessageId, setEditingMessageId] = useState(0); const [editingMessageId, setEditingMessageId] = useState(0);
const onEditMessage = useCallback((id: number) => setEditingMessageId(id), [setEditingMessageId]); const onEditMessage = useCallback((id: number) => setEditingMessageId(id), [setEditingMessageId]);
const onCancelEdit = useCallback(() => setEditingMessageId(0), [setEditingMessageId]);
const onDeleteMessage = useCallback((id: number) => console.log({ id }), []); const onDeleteMessage = useCallback((id: number) => console.log({ id }), []);
useEffect(() => { useEffect(() => {
@ -57,6 +58,7 @@ const ProfileMessagesUnconnected: FC<IProps> = ({ profile, user: { id }, authGet
onEdit={onEditMessage} onEdit={onEditMessage}
onDelete={onDeleteMessage} onDelete={onDeleteMessage}
isEditing={editingMessageId === message.id} isEditing={editingMessageId === message.id}
onCancelEdit={onCancelEdit}
/> />
))} ))}

View file

@ -31,7 +31,7 @@
padding: 0; padding: 0;
textarea { textarea {
padding: $gap; padding: $gap / 2 $gap;
} }
} }
} }
@ -77,20 +77,20 @@
color: white; color: white;
position: relative; position: relative;
&::before { //&::before {
content: ' '; // content: ' ';
background: linear-gradient(270deg, $input_bg_color $gap, transparentize($input_bg_color, 1)); // background: linear-gradient(270deg, $input_bg_color $gap, transparentize($input_bg_color, 1));
position: absolute; // position: absolute;
width: $gap * 2; // width: $gap * 2;
height: $input_height; // height: $input_height;
top: 1px; // top: 1px;
right: 1px; // right: 1px;
transform: translateX(0); // transform: translateX(0);
transition: transform 0.25s; // transition: transform 0.25s;
border-radius: 0 $input_radius $input_radius 0; // border-radius: 0 $input_radius $input_radius 0;
pointer-events: none; // pointer-events: none;
touch-action: none; // touch-action: none;
} //}
} }
&.required { &.required {

View file

@ -1368,6 +1368,11 @@ autoresponsive-react@^1.1.31:
autoresponsive-core "^1.0.1" autoresponsive-core "^1.0.1"
exenv "^1.2.0" exenv "^1.2.0"
autosize@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.2.tgz#073cfd07c8bf45da4b9fd153437f5bafbba1e4c9"
integrity sha512-jnSyH2d+qdfPGpWlcuhGiHmqBJ6g3X+8T+iRwFrHPLVcdoGJE/x6Qicm6aDHfTsbgZKxyV8UU/YB2p4cjKDRRA==
awesome-typescript-loader@^5.2.1: awesome-typescript-loader@^5.2.1:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz#a41daf7847515f4925cdbaa3075d61f289e913fc" resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz#a41daf7847515f4925cdbaa3075d61f289e913fc"