From e83da106a259f4a8ab11324eceef2c15a9a08bf0 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 18 Mar 2021 21:01:07 +0800 Subject: ... --- .../app/views/timeline-common/MarkdownPostEdit.tsx | 147 ++++++++++-------- .../timeline-common/TimelinePostContentView.tsx | 2 +- .../app/views/timeline-common/TimelinePostEdit.tsx | 167 ++++++++++----------- .../app/views/timeline-common/timeline-common.sass | 8 + 4 files changed, 176 insertions(+), 148 deletions(-) (limited to 'FrontEnd/src/app/views/timeline-common') diff --git a/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx b/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx index 079344e1..d43077b4 100644 --- a/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx +++ b/FrontEnd/src/app/views/timeline-common/MarkdownPostEdit.tsx @@ -1,24 +1,31 @@ import React from "react"; -import { Nav, Form } from "react-bootstrap"; +import { Form } from "react-bootstrap"; import { useTranslation } from "react-i18next"; import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; +import TabPages from "../common/TabPages"; import TimelinePostBuilder from "@/services/TimelinePostBuilder"; export interface MarkdownPostEditProps { timeline: string; onPosted: (post: HttpTimelinePostInfo) => void; + onPostError: () => void; + onClose: () => void; + className?: string; + style?: React.CSSProperties; } const MarkdownPostEdit: React.FC = ({ timeline: timelineName, onPosted, + onClose, + onPostError, + className, + style, }) => { const { t } = useTranslation(); - const [tab, setTab] = React.useState<"text" | "images" | "preview">("text"); - const [process, setProcess] = React.useState(false); const [text, _setText] = React.useState(""); @@ -48,68 +55,88 @@ const MarkdownPostEdit: React.FC = ({ }, []); const send = async (): Promise => { - const dataList = await getBuilder().build(); - const post = await getHttpTimelineClient().postPost(timelineName, { - dataList, - }); - onPosted(post); + setProcess(true); + try { + const dataList = await getBuilder().build(); + const post = await getHttpTimelineClient().postPost(timelineName, { + dataList, + }); + onPosted(post); + onClose(); + } catch (e) { + setProcess(false); + onPostError(); + } }; return ( -
- -
- {(() => { - if (tab === "text") { - return ( - { - getBuilder().setMarkdownText(event.currentTarget.value); + +
+ {t("operationDialog.cancel")} +
+
+ {t("timeline.send")} +
+ + } + pages={[ + { + id: "text", + tabText: "edit", + page: ( + { + getBuilder().setMarkdownText(event.currentTarget.value); + }} + /> + ), + }, + { + id: "images", + tabText: "image", + page: ( +
+ {images.map((image) => ( + + ))} + ) => { + const { files } = event.currentTarget; + if (files != null && files.length !== 0) { + getBuilder().appendImage(files[0]); + } }} + disabled={process} /> - ); - } else if (tab === "images") { - return
; - } else { - return
; - } - })()} -
-
+
+ ), + }, + { + id: "preview", + tabText: "preview", + page: ( +
+ ), + }, + ]} + /> ); }; diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx index d836d1db..58fae4c7 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx @@ -152,7 +152,7 @@ const MarkdownView: React.FC = (props) => { } return (
= (props) => { const [process, setProcess] = React.useState(false); - const [kind, setKind] = React.useState("text"); + const [kind, setKind] = React.useState>("text"); + const [showMarkdown, setShowMarkdown] = React.useState(false); const [text, setText] = React.useState(""); - const [markdown, setMarkdown] = React.useState(""); const [image, setImage] = React.useState(null); const draftTextLocalStorageKey = `timeline.${timeline.name}.postDraft.text`; - const draftMarkdownLocalStorageKey = `timeline.${timeline.name}.postDraft.markdown`; React.useEffect(() => { setText(window.localStorage.getItem(draftTextLocalStorageKey) ?? ""); - setMarkdown( - window.localStorage.getItem(draftMarkdownLocalStorageKey) ?? "" - ); - }, [draftTextLocalStorageKey, draftMarkdownLocalStorageKey]); + }, [draftTextLocalStorageKey]); const canSend = (kind === "text" && text.length !== 0) || - (kind === "image" && image != null) || - (kind === "markdown" && markdown.length !== 0); + (kind === "image" && image != null); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const containerRef = React.useRef(null!); @@ -160,6 +156,13 @@ const TimelinePostEdit: React.FC = (props) => { }; }); + const onPostError = (): void => { + pushAlert({ + type: "danger", + message: "timeline.sendPostFailed", + }); + }; + const onSend = async (): Promise => { setProcess(true); @@ -171,12 +174,6 @@ const TimelinePostEdit: React.FC = (props) => { data: await base64(text), }; break; - case "markdown": - requestData = { - contentType: "text/markdown", - data: await base64(markdown), - }; - break; case "image": if (image == null) { throw new UiLogicError( @@ -201,20 +198,14 @@ const TimelinePostEdit: React.FC = (props) => { if (kind === "text") { setText(""); window.localStorage.removeItem(draftTextLocalStorageKey); - } else if (kind === "markdown") { - setMarkdown(""); - window.localStorage.removeItem(draftMarkdownLocalStorageKey); } setProcess(false); setKind("text"); onPosted(data); }, (_) => { - pushAlert({ - type: "danger", - message: "timeline.sendPostFailed", - }); setProcess(false); + onPostError(); } ); }; @@ -224,73 +215,75 @@ const TimelinePostEdit: React.FC = (props) => { ref={containerRef} className={clsx("container-fluid bg-light", className)} > - - - {(() => { - if (kind === "text") { - return ( - { - setText(t); - window.localStorage.setItem(draftTextLocalStorageKey, t); - }} - /> - ); - } else if (kind === "image") { - return ( - - ); - } else if (kind === "markdown") { - return ( - { - setMarkdown(t); - window.localStorage.setItem( - draftMarkdownLocalStorageKey, - t - ); - }} + {showMarkdown ? ( + setShowMarkdown(false)} + timeline={timeline.name} + onPosted={onPosted} + onPostError={onPostError} + /> + ) : ( + + + {(() => { + if (kind === "text") { + return ( + { + setText(t); + window.localStorage.setItem(draftTextLocalStorageKey, t); + }} + /> + ); + } else if (kind === "image") { + return ( + + ); + } + })()} + + +
+ ({ + type: "button", + text: `timeline.post.type.${kind}`, + iconClassName: postKindIconClassNameMap[kind], + onClick: () => { + if (kind === "markdown") { + setShowMarkdown(true); + } else { + setKind(kind); + } + }, + }))} + > + - ); - } - })()} - - -
- ({ - type: "button", - text: `timeline.post.type.${kind}`, - iconClassName: postKindIconClassNameMap[kind], - onClick: () => { - setKind(kind); - }, - }))} + +
+ - -
-
- - {t("timeline.send")} - - -
+ {t("timeline.send")} + + +
+ )}
); }; diff --git a/FrontEnd/src/app/views/timeline-common/timeline-common.sass b/FrontEnd/src/app/views/timeline-common/timeline-common.sass index 43c4d0f7..04318674 100644 --- a/FrontEnd/src/app/views/timeline-common/timeline-common.sass +++ b/FrontEnd/src/app/views/timeline-common/timeline-common.sass @@ -170,3 +170,11 @@ $timeline-line-color-current: #36c2e6 top: 56px right: 0 margin: 0.5em + +.timeline-markdown-post-edit-page + overflow: scroll + max-height: 300px + +.timeline-markdown-post-edit-image + max-width: 100% + max-height: 200px -- cgit v1.2.3