From e6ccc0174a86a0ade240e6551228598cd81f984b Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Tue, 1 Aug 2023 00:29:35 +0800
Subject: ...

---
 FrontEnd/src/pages/timeline/TimelinePostList.tsx | 76 ++++++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 FrontEnd/src/pages/timeline/TimelinePostList.tsx

(limited to 'FrontEnd/src/pages/timeline/TimelinePostList.tsx')

diff --git a/FrontEnd/src/pages/timeline/TimelinePostList.tsx b/FrontEnd/src/pages/timeline/TimelinePostList.tsx
new file mode 100644
index 00000000..a3501b33
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/TimelinePostList.tsx
@@ -0,0 +1,76 @@
+import { useMemo, Fragment } from "react";
+
+import { HttpTimelinePostInfo } from "@/http/timeline";
+
+import TimelinePostView from "./TimelinePostView";
+import TimelineDateLabel from "./TimelineDateLabel";
+
+import "./TimelinePostList.css";
+
+function dateEqual(left: Date, right: Date): boolean {
+  return (
+    left.getDate() == right.getDate() &&
+    left.getMonth() == right.getMonth() &&
+    left.getFullYear() == right.getFullYear()
+  );
+}
+
+interface TimelinePostListViewProps {
+  posts: HttpTimelinePostInfo[];
+  onReload: () => void;
+}
+
+export default function TimelinePostList(props: TimelinePostListViewProps) {
+  const { posts, onReload } = props;
+
+  const groupedPosts = useMemo<
+    {
+      date: Date;
+      posts: (HttpTimelinePostInfo & { index: number })[];
+    }[]
+  >(() => {
+    const result: {
+      date: Date;
+      posts: (HttpTimelinePostInfo & { index: number })[];
+    }[] = [];
+    let index = 0;
+    for (const post of posts) {
+      const time = new Date(post.time);
+      if (result.length === 0) {
+        result.push({ date: time, posts: [{ ...post, index }] });
+      } else {
+        const lastGroup = result[result.length - 1];
+        if (dateEqual(lastGroup.date, time)) {
+          lastGroup.posts.push({ ...post, index });
+        } else {
+          result.push({ date: time, posts: [{ ...post, index }] });
+        }
+      }
+      index++;
+    }
+    return result;
+  }, [posts]);
+
+  return (
+    <div>
+      <div className="timeline-post-timeline" />
+      {groupedPosts.map((group) => {
+        return (
+          <Fragment key={group.date.toDateString()}>
+            <TimelineDateLabel date={group.date} />
+            {group.posts.map((post) => {
+              return (
+                <TimelinePostView
+                  key={post.id}
+                  post={post}
+                  onChanged={onReload}
+                  onDeleted={onReload}
+                />
+              );
+            })}
+          </Fragment>
+        );
+      })}
+    </div>
+  );
+}
-- 
cgit v1.2.3

