From aa89b6cce7701a57b0c377d938788b4c940013d6 Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Tue, 1 Sep 2020 02:32:06 +0800
Subject: ...

---
 .../src/app/timeline/TimelinePostEdit.tsx          | 232 ---------------------
 1 file changed, 232 deletions(-)
 delete mode 100644 Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx

(limited to 'Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx')

diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx
deleted file mode 100644
index b30dc8d3..00000000
--- a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import React from "react";
-import { Button, Spinner, Row, Col } from "reactstrap";
-import { useTranslation } from "react-i18next";
-import Svg from "react-inlinesvg";
-import textIcon from "bootstrap-icons/icons/card-text.svg";
-import imageIcon from "bootstrap-icons/icons/image.svg";
-
-import { pushAlert } from "../common/alert-service";
-import { TimelineCreatePostRequest } from "../data/timeline";
-import FileInput from "../common/FileInput";
-import { UiLogicError } from "../common";
-
-interface TimelinePostEditImageProps {
-  onSelect: (blob: Blob | null) => void;
-}
-
-const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => {
-  const { onSelect } = props;
-  const { t } = useTranslation();
-
-  const [file, setFile] = React.useState<File | null>(null);
-  const [fileUrl, setFileUrl] = React.useState<string | null>(null);
-  const [error, setError] = React.useState<string | null>(null);
-
-  React.useEffect(() => {
-    if (file != null) {
-      const url = URL.createObjectURL(file);
-      setFileUrl(url);
-      return () => {
-        URL.revokeObjectURL(url);
-      };
-    }
-  }, [file]);
-
-  const onInputChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback(
-    (e) => {
-      const files = e.target.files;
-      if (files == null || files.length === 0) {
-        setFile(null);
-        setFileUrl(null);
-      } else {
-        setFile(files[0]);
-      }
-      onSelect(null);
-      setError(null);
-    },
-    [onSelect]
-  );
-
-  const onImgLoad = React.useCallback(() => {
-    onSelect(file);
-  }, [onSelect, file]);
-
-  const onImgError = React.useCallback(() => {
-    setError("loadImageError");
-  }, []);
-
-  return (
-    <>
-      <FileInput
-        labelText={t("chooseImage")}
-        onChange={onInputChange}
-        accept="image/*"
-        className="mx-3 my-1"
-      />
-      {fileUrl && error == null && (
-        <img
-          src={fileUrl}
-          className="timeline-post-edit-image"
-          onLoad={onImgLoad}
-          onError={onImgError}
-        />
-      )}
-      {error != null && <div className="text-danger">{t(error)}</div>}
-    </>
-  );
-};
-
-export type TimelinePostSendCallback = (
-  content: TimelineCreatePostRequest
-) => Promise<void>;
-
-export interface TimelinePostEditProps {
-  className?: string;
-  onPost: TimelinePostSendCallback;
-  onHeightChange?: (height: number) => void;
-  timelineUniqueId: string;
-}
-
-const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
-  const { onPost } = props;
-
-  const { t } = useTranslation();
-
-  const [state, setState] = React.useState<"input" | "process">("input");
-  const [kind, setKind] = React.useState<"text" | "image">("text");
-  const [text, setText] = React.useState<string>("");
-  const [imageBlob, setImageBlob] = React.useState<Blob | null>(null);
-
-  const draftLocalStorageKey = `timeline.${props.timelineUniqueId}.postDraft`;
-
-  React.useEffect(() => {
-    setText(window.localStorage.getItem(draftLocalStorageKey) ?? "");
-  }, [draftLocalStorageKey]);
-
-  const canSend = kind === "text" || (kind === "image" && imageBlob != null);
-
-  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-  const containerRef = React.useRef<HTMLDivElement>(null!);
-
-  const notifyHeightChange = (): void => {
-    if (props.onHeightChange) {
-      props.onHeightChange(containerRef.current.clientHeight);
-    }
-  };
-
-  React.useEffect(() => {
-    if (props.onHeightChange) {
-      props.onHeightChange(containerRef.current.clientHeight);
-    }
-    return () => {
-      if (props.onHeightChange) {
-        props.onHeightChange(0);
-      }
-    };
-  });
-
-  const toggleKind = React.useCallback(() => {
-    setKind((oldKind) => (oldKind === "text" ? "image" : "text"));
-    setImageBlob(null);
-  }, []);
-
-  const onSend = React.useCallback(() => {
-    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.");
-      }
-    })();
-
-    onPost(req).then(
-      (_) => {
-        if (kind === "text") {
-          setText("");
-          window.localStorage.removeItem(draftLocalStorageKey);
-        }
-        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);
-  }, []);
-
-  return (
-    <div ref={containerRef} className="container-fluid fixed-bottom bg-light">
-      <Row>
-        <Col className="px-1 py-1">
-          {kind === "text" ? (
-            <textarea
-              className="w-100 h-100 timeline-post-edit"
-              value={text}
-              disabled={state === "process"}
-              onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => {
-                const value = event.currentTarget.value;
-                setText(value);
-                window.localStorage.setItem(draftLocalStorageKey, value);
-              }}
-            />
-          ) : (
-            <TimelinePostEditImage onSelect={onImageSelect} />
-          )}
-        </Col>
-        <Col sm="col-auto align-self-end m-1">
-          {(() => {
-            if (state === "input") {
-              return (
-                <>
-                  <div className="d-block text-center mt-1 mb-2">
-                    <Svg
-                      onLoad={notifyHeightChange}
-                      src={kind === "text" ? imageIcon : textIcon}
-                      className="icon-button"
-                      onClick={toggleKind}
-                    />
-                  </div>
-                  <Button color="primary" onClick={onSend} disabled={!canSend}>
-                    {t("timeline.send")}
-                  </Button>
-                </>
-              );
-            } else {
-              return <Spinner />;
-            }
-          })()}
-        </Col>
-      </Row>
-    </div>
-  );
-};
-
-export default TimelinePostEdit;
-- 
cgit v1.2.3

