0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-15 03:01:37 -05:00

Combined add and reply form into one and adjusted styles

This commit is contained in:
James Morris 2022-07-08 10:33:20 +02:00
parent 10626d9bf7
commit 19d2fba350
4 changed files with 54 additions and 99 deletions
apps/comments-ui/src/components

View file

@ -6,7 +6,7 @@ import Reply from './Reply';
import More from './More';
import EditForm from './EditForm';
import Replies from './Replies';
import ReplyForm from './ReplyForm';
import Form from './Form';
import AppContext from '../AppContext';
import {formatRelativeTime} from '../utils/helpers';
@ -72,7 +72,7 @@ const Comment = (props) => {
leaveTo="opacity-0"
>
<div className="ml-14 my-10">
<ReplyForm parent={comment} toggle={toggleReplyMode} avatarSaturation={props.avatarSaturation} />
<Form parent={comment} toggle={toggleReplyMode} avatarSaturation={props.avatarSaturation} isReply={true} />
</div>
</Transition>
{hasReplies &&

View file

@ -1,7 +1,8 @@
import React from 'react';
import AppContext from '../AppContext';
import NotSignedInBox from './NotSignedInBox';
import AddForm from './AddForm';
// import AddForm from './AddForm';
import Form from './Form';
import Comment from './Comment';
import Pagination from './Pagination';
@ -59,7 +60,7 @@ class CommentsBox extends React.Component {
{comments}
</div>
<div>
{ this.context.member ? <AddForm commentsCount={commentsCount} avatarSaturation={this.props.avatarSaturation} /> : <NotSignedInBox /> }
{ this.context.member ? <Form commentsCount={commentsCount} avatarSaturation={this.props.avatarSaturation} /> : <NotSignedInBox /> }
</div>
</section>
);

View file

@ -5,12 +5,21 @@ import Avatar from './Avatar';
import {useEditor, EditorContent} from '@tiptap/react';
import {getEditorConfig} from '../utils/editor';
const AddForm = (props) => {
const {member, postId, onAction} = useContext(AppContext);
const Form = (props) => {
const {member, postId, dispatchAction, onAction} = useContext(AppContext);
const editorAddConfig = {
placeholder: 'Join the discussion',
autofocus: false
};
const editorReplyConfig = {
placeholder: 'Reply to comment',
autofocus: false
};
const editor = useEditor({
...getEditorConfig({
placeholder: 'Join the discussion'
})
...getEditorConfig(props.isReply ? editorReplyConfig : editorAddConfig)
});
const focused = editor?.isFocused || !editor?.isEmpty;
@ -22,19 +31,40 @@ const AddForm = (props) => {
return;
}
try {
// Send comment to server
await onAction('addComment', {
post_id: postId,
status: 'published',
html: editor.getHTML()
});
if (props.isReply) {
try {
// Send comment to server
await dispatchAction('addReply', {
parent: props.parent,
reply: {
post_id: postId,
status: 'published',
html: editor.getHTML()
}
});
// Clear message and blur on success
editor.chain().clearContent().blur().run();
props.toggle();
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
} else {
try {
// Send comment to server
await onAction('addComment', {
post_id: postId,
status: 'published',
html: editor.getHTML()
});
// Clear message and blur on success
editor.chain().clearContent().blur().run();
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
// Clear message and blur on success
editor.chain().clearContent().blur().run();
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}
};
@ -56,7 +86,7 @@ const AddForm = (props) => {
type="button"
onClick={submitForm}
>
Add comment
Add {props.isReply ? 'reply' : 'comment'}
</button>
</div>
</div>
@ -81,4 +111,4 @@ const AddForm = (props) => {
);
};
export default AddForm;
export default Form;

View file

@ -1,76 +0,0 @@
import React, {useContext} from 'react';
import AppContext from '../AppContext';
import Avatar from './Avatar';
import {useEditor, EditorContent} from '@tiptap/react';
import {getEditorConfig} from '../utils/editor';
const ReplyForm = (props) => {
const {postId, dispatchAction} = useContext(AppContext);
const editor = useEditor({
...getEditorConfig({
placeholder: 'Reply to comment',
autofocus: true
})
});
const focused = editor?.isFocused || !editor?.isEmpty;
const submitForm = async (event) => {
event.preventDefault();
if (editor.isEmpty) {
return;
}
try {
// Send comment to server
await dispatchAction('addReply', {
parent: props.parent,
reply: {
post_id: postId,
status: 'published',
html: editor.getHTML()
}
});
// Clear message and blur on success
editor.chain().clearContent().blur().run();
props.toggle();
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
};
const focusEditor = (event) => {
editor.commands.focus();
};
return (
<form onClick={focusEditor} className={`bg-white dark:bg-[rgba(255,255,255,0.08)] comment-form transition duration-200 rounded-md px-3 pt-3 pb-2 -ml-[13px] -mr-[12px] -mt-[15px] shadow-lg hover:shadow-xl ${focused ? 'cursor-default' : 'cursor-pointer'}`}>
<div className="w-full relative">
<div className="pr-3 font-sans leading-normal dark:text-neutral-300">
<div className="relative w-full">
<EditorContent
className={`transition-[height] pl-[56px] pt-0 duration-150 w-full dark:placeholder:text-[rgba(255,255,255,0.3)] placeholder:text-neutral-300 text-[16.5px] border-none resize-none rounded-md border border-slate-50 px-0 py-3 font-sans mb-1 leading-normal focus:outline-0 bg-transparent dark:text-[rgba(255,255,255,0.9)] ${focused ? 'cursor-text h-40' : 'cursor-pointer overflow-hidden h-12 hover:border-slate-300'}`}
editor={editor}
/>
<button
className={`transition-[opacity] duration-150 absolute -right-3 bottom-2 rounded-md border py-3 px-4 font-sans text-sm text-center bg-black font-semibold text-white dark:bg-[rgba(255,255,255,0.8)] dark:text-neutral-800`}
type="button"
onClick={submitForm}
>
Add reply
</button>
</div>
</div>
<div className="flex mb-1 justify-start items-center absolute top-[2px] left-0">
<Avatar saturation={props.avatarSaturation} />
</div>
</div>
</form>
);
};
export default ReplyForm;