Add a button to upload images into comments (#6092)

This commit is contained in:
Tom Moor
2023-10-29 20:42:49 -04:00
committed by GitHub
parent 44cbf4359f
commit d593976b4d
4 changed files with 72 additions and 10 deletions

View File

@@ -1,16 +1,22 @@
import { m } from "framer-motion";
import { action } from "mobx";
import { observer } from "mobx-react";
import { ImageIcon } from "outline-icons";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { VisuallyHidden } from "reakit";
import { toast } from "sonner";
import { useTheme } from "styled-components";
import { v4 as uuidv4 } from "uuid";
import { CommentValidation } from "@shared/validations";
import { getEventFiles } from "@shared/utils/files";
import { AttachmentValidation, CommentValidation } from "@shared/validations";
import Comment from "~/models/Comment";
import Avatar from "~/components/Avatar";
import ButtonSmall from "~/components/ButtonSmall";
import { useDocumentContext } from "~/components/DocumentContext";
import Flex from "~/components/Flex";
import NudeButton from "~/components/NudeButton";
import Tooltip from "~/components/Tooltip";
import type { Editor as SharedEditor } from "~/editor";
import useCurrentUser from "~/hooks/useCurrentUser";
import useOnClickOutside from "~/hooks/useOnClickOutside";
@@ -64,6 +70,8 @@ function CommentForm({
const editorRef = React.useRef<SharedEditor>(null);
const [forceRender, setForceRender] = React.useState(0);
const [inputFocused, setInputFocused] = React.useState(autoFocus);
const file = React.useRef<HTMLInputElement>(null);
const theme = useTheme();
const { t } = useTranslation();
const { comments } = useStores();
const user = useCurrentUser();
@@ -188,6 +196,23 @@ function CommentForm({
onBlur?.();
};
const handleFilePicked = (event: React.ChangeEvent<HTMLInputElement>) => {
event.stopPropagation();
event.preventDefault();
const files = getEventFiles(event);
if (!files.length) {
return;
}
editorRef.current?.insertFiles(event, files);
};
const handleImageUpload = (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
event.preventDefault();
file.current?.click();
};
// Focus the editor when it's a new comment just mounted, after a delay as the
// editor is mounted within a fade transition.
React.useEffect(() => {
@@ -227,6 +252,15 @@ function CommentForm({
{...presence}
{...rest}
>
<VisuallyHidden>
<input
ref={file}
type="file"
onChange={handleFilePicked}
accept={AttachmentValidation.imageContentTypes.join(", ")}
tabIndex={-1}
/>
</VisuallyHidden>
<Flex gap={8} align="flex-start" reverse={dir === "rtl"}>
<Avatar model={user} size={24} style={{ marginTop: 8 }} />
<Bubble
@@ -256,13 +290,20 @@ function CommentForm({
}
/>
{(inputFocused || data) && (
<Flex justify={dir === "rtl" ? "flex-end" : "flex-start"} gap={8}>
<ButtonSmall type="submit" borderOnHover>
{thread && !thread.isNew ? t("Reply") : t("Post")}
</ButtonSmall>
<ButtonSmall onClick={handleCancel} neutral borderOnHover>
{t("Cancel")}
</ButtonSmall>
<Flex justify="space-between" reverse={dir === "rtl"} gap={8}>
<Flex gap={8}>
<ButtonSmall type="submit" borderOnHover>
{thread && !thread.isNew ? t("Reply") : t("Post")}
</ButtonSmall>
<ButtonSmall onClick={handleCancel} neutral borderOnHover>
{t("Cancel")}
</ButtonSmall>
</Flex>
<Tooltip delay={500} tooltip={t("Upload image")} placement="top">
<NudeButton onClick={handleImageUpload}>
<ImageIcon color={theme.textTertiary} />
</NudeButton>
</Tooltip>
</Flex>
)}
</Bubble>