import { useState, useEffect, ChangeEventHandler } from "react"; import { useTranslation } from "react-i18next"; import classNames from "classnames"; import { UiLogicError } from "~src/common"; import { getHttpTimelineClient, HttpTimelineInfo, HttpTimelinePostInfo, HttpTimelinePostPostRequestData, } from "~src/http/timeline"; import base64 from "~src/utilities/base64"; import { pushAlert } from "~src/components/alert"; import LoadingButton from "~src/components/button/LoadingButton"; import PopupMenu from "~src/components/menu/PopupMenu"; import TimelinePostCard from "../TimelinePostCard"; import TimelinePostContainer from "../TimelinePostContainer"; import IconButton from "~src/components/button/IconButton"; import PlainTextPostEdit from './PlainTextPostEdit' import MarkdownPostEdit from "./MarkdownPostEdit"; import "./TimelinePostCreateView.css"; type PostKind = "text" | "markdown" | "image"; const postKindIconMap: Record = { text: "fonts", markdown: "markdown", image: "image", }; export interface TimelinePostEditProps { className?: string; timeline: HttpTimelineInfo; onPosted: (newPost: HttpTimelinePostInfo) => void; } function TimelinePostEdit(props: TimelinePostEditProps) { const { timeline, className, onPosted } = props; const { t } = useTranslation(); const [process, setProcess] = useState(false); const [kind, setKind] = useState>("text"); const [showMarkdown, setShowMarkdown] = useState(false); const [text, setText] = useState(""); const [image, setImage] = useState(null); const draftTextLocalStorageKey = `timeline.${timeline.owner.username}.${timeline.nameV2}.postDraft.text`; useEffect(() => { setText(window.localStorage.getItem(draftTextLocalStorageKey) ?? ""); }, [draftTextLocalStorageKey]); const canSend = (kind === "text" && text.length !== 0) || (kind === "image" && image != null); const onPostError = (): void => { pushAlert({ color: "danger", message: "timeline.sendPostFailed", }); }; const onSend = async (): Promise => { setProcess(true); let requestData: HttpTimelinePostPostRequestData; switch (kind) { case "text": requestData = { contentType: "text/plain", data: await base64(text), }; break; case "image": if (image == null) { throw new UiLogicError( "Content type is image but image blob is null.", ); } requestData = { contentType: image.type, data: await base64(image), }; break; default: throw new UiLogicError("Unknown content type."); } getHttpTimelineClient() .postPost(timeline.owner.username, timeline.nameV2, { dataList: [requestData], }) .then( (data) => { if (kind === "text") { setText(""); window.localStorage.removeItem(draftTextLocalStorageKey); } setProcess(false); setKind("text"); onPosted(data); }, () => { setProcess(false); onPostError(); }, ); }; return ( {showMarkdown ? ( setShowMarkdown(false)} owner={timeline.owner.username} timeline={timeline.nameV2} onPosted={onPosted} onPostError={onPostError} /> ) : (
{(() => { if (kind === "text") { return ( { setText(text); window.localStorage.setItem( draftTextLocalStorageKey, text, ); }} /> ); } else if (kind === "image") { return ( ); } })()}
({ type: "button", text: `timeline.post.type.${kind}`, iconClassName: postKindIconMap[kind], onClick: () => { if (kind === "markdown") { setShowMarkdown(true); } else { setKind(kind); } }, }))} > void onSend()} color="primary" disabled={!canSend} loading={process} > {t("timeline.send")}
)}
); } export default TimelinePostEdit;