diff options
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx')
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx | 122 |
1 files changed, 63 insertions, 59 deletions
diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx index 207bf6af..7c49e5bb 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx @@ -5,8 +5,14 @@ import { Button, Spinner, Row, Col, Form } from "react-bootstrap"; import { UiLogicError } from "@/common"; +import { + getHttpTimelineClient, + HttpTimelineInfo, + HttpTimelinePostPostRequestData, +} from "@/http/timeline"; + import { pushAlert } from "@/services/alert"; -import { TimelineCreatePostRequest } from "@/services/timeline"; +import { base64 } from "@/http/common"; interface TimelinePostEditImageProps { onSelect: (blob: Blob | null) => void; @@ -74,19 +80,15 @@ const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => { ); }; -export type TimelinePostSendCallback = ( - content: TimelineCreatePostRequest -) => Promise<void>; - export interface TimelinePostEditProps { className?: string; - onPost: TimelinePostSendCallback; + timeline: HttpTimelineInfo; + onPosted: () => void; onHeightChange?: (height: number) => void; - timelineUniqueId: string; } const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { - const { onPost } = props; + const { timeline, onHeightChange, className, onPosted } = props; const { t } = useTranslation(); @@ -95,7 +97,7 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { const [text, setText] = React.useState<string>(""); const [imageBlob, setImageBlob] = React.useState<Blob | null>(null); - const draftLocalStorageKey = `timeline.${props.timelineUniqueId}.postDraft`; + const draftLocalStorageKey = `timeline.${timeline.name}.postDraft`; React.useEffect(() => { setText(window.localStorage.getItem(draftLocalStorageKey) ?? ""); @@ -107,18 +109,18 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { const containerRef = React.useRef<HTMLDivElement>(null!); const notifyHeightChange = (): void => { - if (props.onHeightChange) { - props.onHeightChange(containerRef.current.clientHeight); + if (onHeightChange) { + onHeightChange(containerRef.current.clientHeight); } }; React.useEffect(() => { - if (props.onHeightChange) { - props.onHeightChange(containerRef.current.clientHeight); + if (onHeightChange) { + onHeightChange(containerRef.current.clientHeight); } return () => { - if (props.onHeightChange) { - props.onHeightChange(0); + if (onHeightChange) { + onHeightChange(0); } }; }); @@ -128,53 +130,55 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { setImageBlob(null); }, []); - const onSend = React.useCallback(() => { + const onSend = async (): Promise<void> => { setState("process"); - const req: TimelineCreatePostRequest = (() => { - switch (kind) { - case "text": - return { - content: { - type: "text", - text: text, - }, - } as TimelineCreatePostRequest; - case "image": - if (imageBlob == null) { - throw new UiLogicError( - "Content type is image but image blob is null." - ); - } - return { - content: { - type: "image", - data: imageBlob, - }, - } as TimelineCreatePostRequest; - default: - throw new UiLogicError("Unknown content type."); - } - })(); + let requestData: HttpTimelinePostPostRequestData; + switch (kind) { + case "text": + requestData = { + contentType: "text/plain", + data: await base64(new Blob([text])), + }; + break; + case "image": + if (imageBlob == null) { + throw new UiLogicError( + "Content type is image but image blob is null." + ); + } + requestData = { + contentType: imageBlob.type, + data: await base64(imageBlob), + }; + break; + default: + throw new UiLogicError("Unknown content type."); + } - onPost(req).then( - (_) => { - if (kind === "text") { - setText(""); - window.localStorage.removeItem(draftLocalStorageKey); + getHttpTimelineClient() + .postPost(timeline.name, { + dataList: [requestData], + }) + .then( + (_) => { + if (kind === "text") { + setText(""); + window.localStorage.removeItem(draftLocalStorageKey); + } + setState("input"); + setKind("text"); + onPosted(); + }, + (_) => { + pushAlert({ + type: "danger", + message: t("timeline.sendPostFailed"), + }); + setState("input"); } - setState("input"); - setKind("text"); - }, - (_) => { - pushAlert({ - type: "danger", - message: t("timeline.sendPostFailed"), - }); - setState("input"); - } - ); - }, [onPost, kind, text, imageBlob, t, draftLocalStorageKey]); + ); + }; const onImageSelect = React.useCallback((blob: Blob | null) => { setImageBlob(blob); @@ -183,7 +187,7 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { return ( <div ref={containerRef} - className={clsx("container-fluid bg-light", props.className)} + className={clsx("container-fluid bg-light", className)} > <Row> <Col className="px-1 py-1"> |