diff options
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx')
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx b/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx deleted file mode 100644 index 685e17be..00000000 --- a/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import React from "react"; -import classnames from "classnames"; -import { Form, Spinner } from "react-bootstrap"; -import { useTranslation } from "react-i18next"; -import { Prompt } from "react-router"; - -import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; - -import FlatButton from "../common/FlatButton"; -import TabPages from "../common/TabPages"; -import TimelinePostBuilder from "@/services/TimelinePostBuilder"; -import ConfirmDialog from "../common/ConfirmDialog"; - -export interface MarkdownPostEditProps { - timeline: string; - onPosted: (post: HttpTimelinePostInfo) => void; - onPostError: () => void; - onClose: () => void; - className?: string; - style?: React.CSSProperties; -} - -const MarkdownPostEdit: React.FC<MarkdownPostEditProps> = ({ - timeline: timelineName, - onPosted, - onClose, - onPostError, - className, - style, -}) => { - const { t } = useTranslation(); - - const [canLeave, setCanLeave] = React.useState<boolean>(true); - - const [process, setProcess] = React.useState<boolean>(false); - - const [showLeaveConfirmDialog, setShowLeaveConfirmDialog] = - React.useState<boolean>(false); - - const [text, _setText] = React.useState<string>(""); - const [images, _setImages] = React.useState<{ file: File; url: string }[]>( - [] - ); - const [previewHtml, _setPreviewHtml] = React.useState<string>(""); - - const _builder = React.useRef<TimelinePostBuilder | null>(null); - - const getBuilder = (): TimelinePostBuilder => { - if (_builder.current == null) { - const builder = new TimelinePostBuilder(() => { - setCanLeave(builder.isEmpty); - _setText(builder.text); - _setImages(builder.images); - _setPreviewHtml(builder.renderHtml()); - }); - _builder.current = builder; - } - return _builder.current; - }; - - const canSend = text.length > 0; - - React.useEffect(() => { - return () => { - getBuilder().dispose(); - }; - }, []); - - React.useEffect(() => { - window.onbeforeunload = (): unknown => { - if (!canLeave) { - return t("timeline.confirmLeave"); - } - }; - - return () => { - window.onbeforeunload = null; - }; - }, [canLeave, t]); - - const send = async (): Promise<void> => { - setProcess(true); - try { - const dataList = await getBuilder().build(); - const post = await getHttpTimelineClient().postPost(timelineName, { - dataList, - }); - onPosted(post); - onClose(); - } catch (e) { - setProcess(false); - onPostError(); - } - }; - - return ( - <> - <Prompt when={!canLeave} message={t("timeline.confirmLeave")} /> - <TabPages - className={className} - style={style} - pageContainerClassName="py-2" - actions={ - process ? ( - <Spinner variant="primary" animation="border" size="sm" /> - ) : ( - <> - <FlatButton - className="me-2" - variant="danger" - onClick={() => { - if (canLeave) { - onClose(); - } else { - setShowLeaveConfirmDialog(true); - } - }} - > - {t("operationDialog.cancel")} - </FlatButton> - <FlatButton onClick={send} disabled={!canSend}> - {t("timeline.send")} - </FlatButton> - </> - ) - } - pages={[ - { - id: "text", - tabText: "edit", - page: ( - <Form.Control - as="textarea" - value={text} - disabled={process} - onChange={(event) => { - getBuilder().setMarkdownText(event.currentTarget.value); - }} - /> - ), - }, - { - id: "images", - tabText: "image", - page: ( - <div className="timeline-markdown-post-edit-page"> - {images.map((image, index) => ( - <div - key={image.url} - className="timeline-markdown-post-edit-image-container" - > - <img - src={image.url} - className="timeline-markdown-post-edit-image" - /> - <i - className={classnames( - "bi-trash text-danger icon-button timeline-markdown-post-edit-image-delete-button", - process && "d-none" - )} - onClick={() => { - getBuilder().deleteImage(index); - }} - /> - </div> - ))} - <Form.Control - type="file" - accept="image/jpeg,image/jpg,image/png,image/gif,image/webp" - onChange={(event: React.ChangeEvent<HTMLInputElement>) => { - const { files } = event.currentTarget; - if (files != null && files.length !== 0) { - getBuilder().appendImage(files[0]); - } - }} - disabled={process} - /> - </div> - ), - }, - { - id: "preview", - tabText: "preview", - page: ( - <div - className="markdown-container timeline-markdown-post-edit-page" - dangerouslySetInnerHTML={{ __html: previewHtml }} - /> - ), - }, - ]} - /> - {showLeaveConfirmDialog && ( - <ConfirmDialog - onClose={() => setShowLeaveConfirmDialog(false)} - onConfirm={onClose} - title="timeline.dropDraft" - body="timeline.confirmLeave" - /> - )} - </> - ); -}; - -export default MarkdownPostEdit; |