From fe5128137f530daf8ca315cb89811121c6c2c9da Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Sat, 13 Feb 2021 21:23:30 +0800
Subject: ...

---
 .../timeline-common/TimelinePostContentView.tsx    | 114 +++++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx

(limited to 'FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx')

diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx
new file mode 100644
index 00000000..69954040
--- /dev/null
+++ b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx
@@ -0,0 +1,114 @@
+import React from "react";
+import { Spinner } from "react-bootstrap";
+
+import { HttpNetworkError } from "@/http/common";
+import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline";
+
+import { useUser } from "@/services/user";
+
+const TextView: React.FC<TimelinePostContentViewProps> = (props) => {
+  const { post, className, style } = props;
+
+  const [text, setText] = React.useState<string | null>(null);
+  const [error, setError] = React.useState<"offline" | "error" | null>(null);
+
+  React.useEffect(() => {
+    let subscribe = true;
+
+    setText(null);
+    setError(null);
+
+    void getHttpTimelineClient()
+      .getPostDataAsString(post.timelineName, post.id)
+      .then(
+        (data) => {
+          if (subscribe) setText(data);
+        },
+        (error) => {
+          if (subscribe) {
+            if (error instanceof HttpNetworkError) {
+              setError("offline");
+            } else {
+              setError("error");
+            }
+          }
+        }
+      );
+
+    return () => {
+      subscribe = false;
+    };
+  }, [post]);
+
+  if (error != null) {
+    // TODO: i18n
+    return (
+      <div className={className} style={style}>
+        Error!
+      </div>
+    );
+  } else if (text == null) {
+    return <Spinner variant="primary" animation="grow" />;
+  } else {
+    return (
+      <div className={className} style={style}>
+        {text}
+      </div>
+    );
+  }
+};
+
+const ImageView: React.FC<TimelinePostContentViewProps> = (props) => {
+  const { post, className, style } = props;
+
+  useUser();
+
+  return (
+    <img
+      src={getHttpTimelineClient().generatePostDataUrl(
+        post.timelineName,
+        post.id
+      )}
+      className={className}
+      style={style}
+    />
+  );
+};
+
+const MarkdownView: React.FC<TimelinePostContentViewProps> = (_props) => {
+  // TODO: Implement this.
+  return <div>Unsupported now!</div>;
+};
+
+export interface TimelinePostContentViewProps {
+  post: HttpTimelinePostInfo;
+  className?: string;
+  style?: React.CSSProperties;
+}
+
+const viewMap: Record<string, React.FC<TimelinePostContentViewProps>> = {
+  "text/plain": TextView,
+  "text/markdown": MarkdownView,
+  "image/png": ImageView,
+  "image/jpeg": ImageView,
+  "image/gif": ImageView,
+  "image/webp": ImageView,
+};
+
+const TimelinePostContentView: React.FC<TimelinePostContentViewProps> = (
+  props
+) => {
+  const { post, className, style } = props;
+
+  const type = post.dataList[0].kind;
+
+  if (type in viewMap) {
+    const View = viewMap[type];
+    return <View post={post} className={className} style={style} />;
+  } else {
+    // TODO: i18n
+    return <div>Error, unknown post type!</div>;
+  }
+};
+
+export default TimelinePostContentView;
-- 
cgit v1.2.3

