aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/pages/timeline/TimelinePostView.tsx
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-09-20 20:26:42 +0800
committerGitHub <noreply@github.com>2023-09-20 20:26:42 +0800
commitf836d77e73f3ea0af45c5f71dae7268143d6d86f (patch)
tree573cfafd972106d69bef0d41ff5f270ec3c43ec2 /FrontEnd/src/pages/timeline/TimelinePostView.tsx
parent4a069bf1268f393d5467166356f691eb89963152 (diff)
parent901fe3d7c032d284da5c9bce24c4aaee9054c7ac (diff)
downloadtimeline-f836d77e73f3ea0af45c5f71dae7268143d6d86f.tar.gz
timeline-f836d77e73f3ea0af45c5f71dae7268143d6d86f.tar.bz2
timeline-f836d77e73f3ea0af45c5f71dae7268143d6d86f.zip
Merge pull request #1395 from crupest/dev
Refector 2023 v0.1
Diffstat (limited to 'FrontEnd/src/pages/timeline/TimelinePostView.tsx')
-rw-r--r--FrontEnd/src/pages/timeline/TimelinePostView.tsx123
1 files changed, 123 insertions, 0 deletions
diff --git a/FrontEnd/src/pages/timeline/TimelinePostView.tsx b/FrontEnd/src/pages/timeline/TimelinePostView.tsx
new file mode 100644
index 00000000..4f0460ff
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/TimelinePostView.tsx
@@ -0,0 +1,123 @@
+import { useState } from "react";
+
+import {
+ getHttpTimelineClient,
+ HttpTimelinePostInfo,
+} from "~src/http/timeline";
+
+import { pushAlert } from "~src/components/alert";
+import { useClickOutside } from "~src/components/hooks";
+import UserAvatar from "~src/components/user/UserAvatar";
+import { DialogProvider, useDialog } from "~src/components/dialog";
+import FlatButton from "~src/components/button/FlatButton";
+import ConfirmDialog from "~src/components/dialog/ConfirmDialog";
+import TimelinePostContentView from "./view/TimelinePostContentView";
+import IconButton from "~src/components/button/IconButton";
+
+import TimelinePostContainer from "./TimelinePostContainer";
+import TimelinePostCard from "./TimelinePostCard";
+
+import "./TimelinePostView.css";
+
+interface TimelinePostViewProps {
+ post: HttpTimelinePostInfo;
+ className?: string;
+ onChanged: (post: HttpTimelinePostInfo) => void;
+ onDeleted: () => void;
+}
+
+export default function TimelinePostView(props: TimelinePostViewProps) {
+ const { post, onDeleted } = props;
+
+ const [operationMaskVisible, setOperationMaskVisible] =
+ useState<boolean>(false);
+
+ const { controller, switchDialog } = useDialog(
+ {
+ delete: (
+ <ConfirmDialog
+ title="timeline.post.deleteDialog.title"
+ body="timeline.post.deleteDialog.prompt"
+ onConfirm={() => {
+ void getHttpTimelineClient()
+ .deletePost(post.timelineOwnerV2, post.timelineNameV2, post.id)
+ .then(onDeleted, () => {
+ pushAlert({
+ color: "danger",
+ message: "timeline.deletePostFailed",
+ });
+ });
+ }}
+ />
+ ),
+ },
+ {
+ onClose: {
+ delete: () => {
+ setOperationMaskVisible(false);
+ },
+ },
+ },
+ );
+
+ const [maskElement, setMaskElement] = useState<HTMLElement | null>(null);
+ useClickOutside(maskElement, () => setOperationMaskVisible(false));
+
+ return (
+ <TimelinePostContainer>
+ <TimelinePostCard className="cru-primary">
+ {post.editable && (
+ <IconButton
+ color="primary"
+ icon="chevron-down"
+ className="timeline-post-edit-button"
+ onClick={(e) => {
+ setOperationMaskVisible(true);
+ e.stopPropagation();
+ }}
+ />
+ )}
+ <div className="timeline-post-header">
+ <UserAvatar
+ username={post.author.username}
+ className="timeline-post-author-avatar"
+ />
+ <small className="timeline-post-author-nickname">
+ {post.author.nickname}
+ </small>
+ <small className="timeline-post-time">
+ {new Date(post.time).toLocaleTimeString()}
+ </small>
+ </div>
+ <div className="timeline-post-content">
+ <TimelinePostContentView post={post} />
+ </div>
+ {operationMaskVisible ? (
+ <div
+ ref={setMaskElement}
+ className="timeline-post-options-mask"
+ onClick={() => {
+ setOperationMaskVisible(false);
+ }}
+ >
+ <FlatButton
+ text="changeProperty"
+ onClick={(e) => {
+ e.stopPropagation();
+ }}
+ />
+ <FlatButton
+ text="delete"
+ color="danger"
+ onClick={(e) => {
+ switchDialog("delete");
+ e.stopPropagation();
+ }}
+ />
+ </div>
+ ) : null}
+ </TimelinePostCard>
+ <DialogProvider controller={controller} />
+ </TimelinePostContainer>
+ );
+}