Various commenting improvements (#4941)

* fix: New threads attached to previous as replies

* fix: Cannot use floating toolbar properly in comments

* perf: Avoid re-writing history on click in editor

* fix: Comment on text selection

* fix: 'Copy link' on comments uses wrong hostname

* Show comment buttons on input focus rather than non-empty input
Increase maximum sidebar size

* Allow opening comments from document menu

* fix: Clicking comment menu should not focus thread

* fix: Selection color

* fix: Draft comments not restored

* Add border above document level comment input

* fix: Floating toolbar not constrainted by offset parent

* fix flash of no comment on saving

* fix: Clicking on editor does not remove draft mark
This commit is contained in:
Tom Moor
2023-02-27 19:50:35 -05:00
committed by GitHub
parent 6b00ced48f
commit fff0812659
7 changed files with 91 additions and 72 deletions

View File

@@ -3,6 +3,7 @@ import { action } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { v4 as uuidv4 } from "uuid";
import { CommentValidation } from "@shared/validations";
import Comment from "~/models/Comment";
import Avatar from "~/components/Avatar";
@@ -59,13 +60,13 @@ function CommentForm({
}: Props) {
const { editor } = useDocumentContext();
const [data, setData] = usePersistedState<Record<string, any> | undefined>(
`draft-${documentId}-${thread?.id ?? "new"}`,
`draft-${documentId}-${!thread ? "new" : thread?.id}`,
undefined
);
const formRef = React.useRef<HTMLFormElement>(null);
const editorRef = React.useRef<SharedEditor>(null);
const [forceRender, setForceRender] = React.useState(0);
const [inputFocused, setInputFocused] = React.useState(false);
const [inputFocused, setInputFocused] = React.useState(autoFocus);
const { t } = useTranslation();
const { showToast } = useToasts();
const { comments } = useStores();
@@ -87,6 +88,7 @@ function CommentForm({
setData(undefined);
setForceRender((s) => ++s);
setInputFocused(false);
const comment =
thread ??
@@ -110,10 +112,11 @@ function CommentForm({
// optimistically update the comment model
comment.isNew = false;
comment.createdById = user.id;
comment.createdBy = user;
});
const handleCreateReply = async (event: React.FormEvent) => {
const handleCreateReply = action(async (event: React.FormEvent) => {
event.preventDefault();
if (!data) {
return;
@@ -121,17 +124,31 @@ function CommentForm({
setData(undefined);
setForceRender((s) => ++s);
setInputFocused(false);
try {
await comments.save({
const comment = new Comment(
{
parentCommentId: thread?.id,
documentId,
data,
});
} catch (error) {
},
comments
);
comment.id = uuidv4();
comments.add(comment);
comment.save().catch(() => {
comments.remove(comment.id);
comment.isNew = true;
showToast(t("Error creating comment"), { type: "error" });
}
};
});
// optimistically update the comment model
comment.isNew = false;
comment.createdById = user.id;
comment.createdBy = user;
});
const handleChange = (
value: (asString: boolean, trim: boolean) => Record<string, any>
@@ -155,6 +172,7 @@ function CommentForm({
const handleCancel = () => {
setData(undefined);
setForceRender((s) => ++s);
setInputFocused(false);
};
const handleFocus = () => {
@@ -164,7 +182,6 @@ function CommentForm({
const handleBlur = () => {
onBlur?.();
setInputFocused(false);
};
// Focus the editor when it's a new comment just mounted, after a delay as the
@@ -219,6 +236,7 @@ function CommentForm({
<CommentEditor
key={`${forceRender}`}
ref={editorRef}
defaultValue={data}
onChange={handleChange}
onSave={handleSave}
onFocus={handleFocus}