From 232a19d7dfe0e3847b3a9a9a9be83485ffb9031c Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Sat, 30 May 2020 16:23:25 +0800
Subject: Merge front end to this repo. But I need to wait for aspnet core
 support for custom port and package manager for dev server.

---
 Timeline/ClientApp/src/timeline/Timeline.tsx | 87 ++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 Timeline/ClientApp/src/timeline/Timeline.tsx

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

diff --git a/Timeline/ClientApp/src/timeline/Timeline.tsx b/Timeline/ClientApp/src/timeline/Timeline.tsx
new file mode 100644
index 00000000..defca4c3
--- /dev/null
+++ b/Timeline/ClientApp/src/timeline/Timeline.tsx
@@ -0,0 +1,87 @@
+import React from 'react';
+import clsx from 'clsx';
+import { Container } from 'reactstrap';
+
+import { TimelinePostInfo } from '../data/timeline';
+import { useUser } from '../data/user';
+import { useAvatarVersion } from '../user/api';
+
+import TimelineItem from './TimelineItem';
+
+export interface TimelinePostInfoEx extends TimelinePostInfo {
+  deletable: boolean;
+}
+
+export type TimelineDeleteCallback = (index: number, id: number) => void;
+
+export interface TimelineProps {
+  className?: string;
+  posts: TimelinePostInfoEx[];
+  onDelete: TimelineDeleteCallback;
+}
+
+const Timeline: React.FC<TimelineProps> = (props) => {
+  const user = useUser();
+  const avatarVersion = useAvatarVersion();
+
+  const { posts, onDelete } = props;
+
+  const [indexShowDeleteButton, setIndexShowDeleteButton] = React.useState<
+    number
+  >(-1);
+
+  const onItemClick = React.useCallback(() => {
+    setIndexShowDeleteButton(-1);
+  }, []);
+
+  const onToggleDelete = React.useMemo(() => {
+    return posts.map((post, i) => {
+      return post.deletable
+        ? () => {
+            setIndexShowDeleteButton((oldIndexShowDeleteButton) => {
+              return oldIndexShowDeleteButton !== i ? i : -1;
+            });
+          }
+        : undefined;
+    });
+  }, [posts]);
+
+  const onItemDelete = React.useMemo(() => {
+    return posts.map((post, i) => {
+      return () => {
+        onDelete(i, post.id);
+      };
+    });
+  }, [posts, onDelete]);
+
+  return (
+    <div className={clsx('pr-2', props.className)}>
+      <Container fluid className="d-flex flex-column">
+        {(() => {
+          const length = posts.length;
+          return posts.map((post, i) => {
+            const av: number | undefined =
+              user != null && user.username === post.author.username
+                ? avatarVersion
+                : undefined;
+
+            return (
+              <TimelineItem
+                post={post}
+                key={post.id}
+                current={length - 1 === i}
+                showDeleteButton={indexShowDeleteButton === i}
+                toggleMore={onToggleDelete[i]}
+                onDelete={onItemDelete[i]}
+                onClick={onItemClick}
+                avatarVersion={av}
+              />
+            );
+          });
+        })()}
+      </Container>
+    </div>
+  );
+};
+
+export default Timeline;
-- 
cgit v1.2.3

