aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/pages/timeline/TimelinePostView.tsx
blob: b09fe6f81cfcc9a803bc21531ef571bef1c048b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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 "./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>
  );
}