From 538d6830a0022b49b99695095d85e567b0c86e71 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 30 Jul 2023 23:47:53 +0800 Subject: ... --- FrontEnd/src/pages/timeline/TimelinePostView.tsx | 149 +++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 FrontEnd/src/pages/timeline/TimelinePostView.tsx (limited to 'FrontEnd/src/pages/timeline/TimelinePostView.tsx') diff --git a/FrontEnd/src/pages/timeline/TimelinePostView.tsx b/FrontEnd/src/pages/timeline/TimelinePostView.tsx new file mode 100644 index 00000000..f7aec169 --- /dev/null +++ b/FrontEnd/src/pages/timeline/TimelinePostView.tsx @@ -0,0 +1,149 @@ +import * as React from "react"; +import classnames from "classnames"; + +import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; + +import { pushAlert } from "@/services/alert"; + +import { useClickOutside } from "@/utilities/hooks"; + +import UserAvatar from "@/views/common/user/UserAvatar"; +import Card from "@/views/common/Card"; +import FlatButton from "@/views/common/button/FlatButton"; +import ConfirmDialog from "@/views/common/dialog/ConfirmDialog"; +import TimelineLine from "./TimelineLine"; +import TimelinePostContentView from "./TimelinePostContentView"; +import IconButton from "@/views/common/button/IconButton"; + +export interface TimelinePostViewProps { + post: HttpTimelinePostInfo; + className?: string; + style?: React.CSSProperties; + cardStyle?: React.CSSProperties; + onChanged: (post: HttpTimelinePostInfo) => void; + onDeleted: () => void; +} + +const TimelinePostView: React.FC = (props) => { + const { post, className, style, cardStyle, onChanged, onDeleted } = props; + + const [operationMaskVisible, setOperationMaskVisible] = + React.useState(false); + const [dialog, setDialog] = React.useState< + "delete" | "changeproperty" | null + >(null); + + const [maskElement, setMaskElement] = React.useState( + null, + ); + + useClickOutside(maskElement, () => setOperationMaskVisible(false)); + + const cardRef = React.useRef(null); + React.useEffect(() => { + const cardIntersectionObserver = new IntersectionObserver(([e]) => { + if (e.intersectionRatio > 0) { + if (cardRef.current != null) { + cardRef.current.style.animationName = "timeline-post-enter"; + } + } + }); + if (cardRef.current) { + cardIntersectionObserver.observe(cardRef.current); + } + + return () => { + cardIntersectionObserver.disconnect(); + }; + }, []); + + return ( +
+ + + {post.editable ? ( + { + setOperationMaskVisible(true); + e.stopPropagation(); + }} + /> + ) : null} +
+ + + + {post.author.nickname} + + {new Date(post.time).toLocaleTimeString()} + + + +
+
+ +
+ {operationMaskVisible ? ( +
{ + setOperationMaskVisible(false); + }} + > + { + setDialog("changeproperty"); + e.stopPropagation(); + }} + /> + { + setDialog("delete"); + e.stopPropagation(); + }} + /> +
+ ) : null} +
+ { + setDialog(null); + setOperationMaskVisible(false); + }} + onConfirm={() => { + void getHttpTimelineClient() + .deletePost(post.timelineOwnerV2, post.timelineNameV2, post.id) + .then(onDeleted, () => { + pushAlert({ + type: "danger", + message: "timeline.deletePostFailed", + }); + }); + }} + /> +
+ ); +}; + +export default TimelinePostView; -- cgit v1.2.3