diff options
Diffstat (limited to 'Timeline/ClientApp/src/app/timeline/Timeline.tsx')
-rw-r--r-- | Timeline/ClientApp/src/app/timeline/Timeline.tsx | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/Timeline/ClientApp/src/app/timeline/Timeline.tsx b/Timeline/ClientApp/src/app/timeline/Timeline.tsx new file mode 100644 index 00000000..849933cf --- /dev/null +++ b/Timeline/ClientApp/src/app/timeline/Timeline.tsx @@ -0,0 +1,91 @@ +import React from 'react';
+import clsx from 'clsx';
+
+import { TimelinePostInfo } from '../data/timeline';
+
+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;
+ onResize?: () => void;
+ containerRef?: React.Ref<HTMLDivElement>;
+}
+
+const Timeline: React.FC<TimelineProps> = (props) => {
+ const { posts, onDelete, onResize } = 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
+ ref={props.containerRef}
+ className={clsx(
+ 'container-fluid d-flex flex-column position-relative',
+ props.className
+ )}
+ >
+ <div className="timeline-enter-animation-mask" />
+ {(() => {
+ const length = posts.length;
+ return posts.map((post, i) => {
+ const toggleMore = onToggleDelete[i];
+
+ return (
+ <TimelineItem
+ post={post}
+ key={post.id}
+ current={length - 1 === i}
+ more={
+ toggleMore
+ ? {
+ isOpen: indexShowDeleteButton === i,
+ toggle: toggleMore,
+ onDelete: onItemDelete[i],
+ }
+ : undefined
+ }
+ onClick={onItemClick}
+ onResize={onResize}
+ />
+ );
+ });
+ })()}
+ </div>
+ );
+};
+
+export default Timeline;
|