aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/pages/timeline
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-07-31 00:08:48 +0800
committercrupest <crupest@outlook.com>2023-07-31 00:09:12 +0800
commitd9c1d512fa64ef4f8c08ca34f7a5842642879bcc (patch)
treee71cd57b30ed67462ecaf010812b6d902c7fa675 /FrontEnd/src/pages/timeline
parent538d6830a0022b49b99695095d85e567b0c86e71 (diff)
downloadtimeline-d9c1d512fa64ef4f8c08ca34f7a5842642879bcc.tar.gz
timeline-d9c1d512fa64ef4f8c08ca34f7a5842642879bcc.tar.bz2
timeline-d9c1d512fa64ef4f8c08ca34f7a5842642879bcc.zip
...
Diffstat (limited to 'FrontEnd/src/pages/timeline')
-rw-r--r--FrontEnd/src/pages/timeline/Timeline.css7
-rw-r--r--FrontEnd/src/pages/timeline/Timeline.tsx15
-rw-r--r--FrontEnd/src/pages/timeline/TimelineCard.css18
-rw-r--r--FrontEnd/src/pages/timeline/TimelineCard.tsx59
-rw-r--r--FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx4
-rw-r--r--FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx4
6 files changed, 55 insertions, 52 deletions
diff --git a/FrontEnd/src/pages/timeline/Timeline.css b/FrontEnd/src/pages/timeline/Timeline.css
index 4dd4fdcc..f071f163 100644
--- a/FrontEnd/src/pages/timeline/Timeline.css
+++ b/FrontEnd/src/pages/timeline/Timeline.css
@@ -230,13 +230,6 @@
margin-right: 0.6em;
}
-.timeline-card {
- position: fixed;
- z-index: 1029;
- top: 56px;
- right: 0;
- margin: 0.5em;
-}
.timeline-top {
position: sticky;
diff --git a/FrontEnd/src/pages/timeline/Timeline.tsx b/FrontEnd/src/pages/timeline/Timeline.tsx
index 3a7fbd00..f93e1623 100644
--- a/FrontEnd/src/pages/timeline/Timeline.tsx
+++ b/FrontEnd/src/pages/timeline/Timeline.tsx
@@ -41,7 +41,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
const [timeline, setTimeline] = React.useState<HttpTimelineInfo | null>(null);
const [posts, setPosts] = React.useState<HttpTimelinePostInfo[] | null>(null);
const [signalrState, setSignalrState] = React.useState<HubConnectionState>(
- HubConnectionState.Connecting
+ HubConnectionState.Connecting,
);
const [error, setError] = React.useState<
"offline" | "forbid" | "notfound" | "error" | null
@@ -81,7 +81,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
console.error(error);
setError("error");
}
- }
+ },
);
}, [timelineOwner, timelineName, timelineReloadKey]);
@@ -91,7 +91,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
.then(
(page) => {
setPosts(
- page.items.filter((p): p is HttpTimelinePostInfo => !p.deleted)
+ page.items.filter((p): p is HttpTimelinePostInfo => !p.deleted),
);
setTotalPage(page.totalPageCount);
},
@@ -106,14 +106,14 @@ const Timeline: React.FC<TimelineProps> = (props) => {
console.error(error);
setError("error");
}
- }
+ },
);
}, [timelineOwner, timelineName, postsReloadKey]);
React.useEffect(() => {
const timelinePostUpdate$ = getTimelinePostUpdate$(
timelineOwner,
- timelineName
+ timelineName,
);
const subscription = timelinePostUpdate$.subscribe(({ update, state }) => {
if (update) {
@@ -134,7 +134,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
.then(
(page) => {
const ps = page.items.filter(
- (p): p is HttpTimelinePostInfo => !p.deleted
+ (p): p is HttpTimelinePostInfo => !p.deleted,
);
setPosts((old) => [...(old ?? []), ...ps]);
},
@@ -149,7 +149,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
console.error(error);
setError("error");
}
- }
+ },
);
}, currentPage < totalPage);
@@ -183,7 +183,6 @@ const Timeline: React.FC<TimelineProps> = (props) => {
{timeline == null && posts == null && <TimelineLoading />}
{timeline && (
<TimelineCard
- className="timeline-card"
timeline={timeline}
connectionStatus={signalrState}
onReload={updateTimeline}
diff --git a/FrontEnd/src/pages/timeline/TimelineCard.css b/FrontEnd/src/pages/timeline/TimelineCard.css
new file mode 100644
index 00000000..75ce6c51
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/TimelineCard.css
@@ -0,0 +1,18 @@
+.timeline-card {
+ position: fixed;
+ z-index: 1029;
+ top: 56px;
+ right: 0;
+ margin: 0.5em;
+}
+
+.timeline-card-title {
+ display: inline-block;
+ vertical-align: middle;
+ color: var(--cru-key-on-color);
+}
+
+.timeline-card-title-name {
+ margin-inline-start: 1em;
+ color: var(--cru-surface-on-color);
+} \ No newline at end of file
diff --git a/FrontEnd/src/pages/timeline/TimelineCard.tsx b/FrontEnd/src/pages/timeline/TimelineCard.tsx
index 8ce133c0..bcdfa4c2 100644
--- a/FrontEnd/src/pages/timeline/TimelineCard.tsx
+++ b/FrontEnd/src/pages/timeline/TimelineCard.tsx
@@ -1,5 +1,4 @@
-import * as React from "react";
-import { useTranslation } from "react-i18next";
+import { useState } from "react";
import classnames from "classnames";
import { HubConnectionState } from "@microsoft/signalr";
@@ -10,6 +9,8 @@ import { pushAlert } from "@/services/alert";
import { HttpTimelineInfo } from "@/http/timeline";
import { getHttpBookmarkClient } from "@/http/bookmark";
+import { useC } from "@/views/common/common";
+import { useDialog } from "@/views/common/dialog";
import UserAvatar from "@/views/common/user/UserAvatar";
import PopupMenu from "@/views/common/menu/PopupMenu";
import FullPageDialog from "@/views/common/dialog/FullPageDialog";
@@ -21,36 +22,36 @@ import { TimelineMemberDialog } from "./TimelineMember";
import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog";
import IconButton from "@/views/common/button/IconButton";
-export interface TimelinePageCardProps {
+import "./TimelineCard.css";
+
+interface TimelinePageCardProps {
timeline: HttpTimelineInfo;
connectionStatus: HubConnectionState;
- className?: string;
onReload: () => void;
}
-const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
- const { timeline, connectionStatus, onReload, className } = props;
+export default function TimelineCard(props: TimelinePageCardProps) {
+ const { timeline, connectionStatus, onReload } = props;
- const { t } = useTranslation();
+ const user = useUser();
- const [dialog, setDialog] = React.useState<
- "member" | "property" | "delete" | null
- >(null);
+ const c = useC();
- const [collapse, setCollapse] = React.useState(true);
+ const [collapse, setCollapse] = useState(true);
const toggleCollapse = (): void => {
setCollapse((o) => !o);
};
const isSmallScreen = useIsSmallScreen();
- const user = useUser();
+ const { createDialogSwitch, dialog, dialogPropsMap, switchDialog } =
+ useDialog(["member", "property", "delete"]);
const content = (
- <>
- <h3 className="cru-color-primary d-inline-block align-middle">
+ <div className="cru-primary">
+ <h3 className="timeline-card-title">
{timeline.title}
- <small className="ms-3 cru-color-secondary">{timeline.nameV2}</small>
+ <small className="timeline-card-title-name">{timeline.nameV2}</small>
</h3>
<div>
<UserAvatar
@@ -64,7 +65,7 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
</div>
<p className="mb-0">{timeline.description}</p>
<small className="mt-1 d-block">
- {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])}
+ {c(timelineVisibilityTooltipTranslationMap[timeline.visibility])}
</small>
<div className="mt-2 cru-text-end">
{user != null ? (
@@ -92,7 +93,7 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
<IconButton
icon="people"
className="me-3"
- onClick={() => setDialog("member")}
+ onClick={createDialogSwitch("member")}
/>
{timeline.manageable ? (
<PopupMenu
@@ -100,12 +101,12 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
{
type: "button",
text: "timeline.manageItem.property",
- onClick: () => setDialog("property"),
+ onClick: createDialogSwitch("property"),
},
{ type: "divider" },
{
type: "button",
- onClick: () => setDialog("delete"),
+ onClick: createDialogSwitch("delete"),
color: "danger",
text: "timeline.manageItem.delete",
},
@@ -116,12 +117,12 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
</PopupMenu>
) : null}
</div>
- </>
+ </div>
);
return (
<>
- <Card className={classnames("p-2 cru-clearfix", className)}>
+ <Card className="timeline-card">
<div
className={classnames(
"cru-float-right d-flex align-items-center",
@@ -145,23 +146,15 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
</Card>
<TimelineMemberDialog
timeline={timeline}
- onClose={() => setDialog(null)}
- open={dialog === "member"}
onChange={onReload}
+ {...dialogPropsMap["member"]}
/>
<TimelinePropertyChangeDialog
timeline={timeline}
- close={() => setDialog(null)}
- open={dialog === "property"}
onChange={onReload}
+ {...dialogPropsMap["property"]}
/>
- <TimelineDeleteDialog
- timeline={timeline}
- open={dialog === "delete"}
- close={() => setDialog(null)}
- />
+ <TimelineDeleteDialog timeline={timeline} {...dialogPropsMap["delete"]} />
</>
);
-};
-
-export default TimelineCard;
+}
diff --git a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
index d5b22aee..0a5a2491 100644
--- a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
+++ b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
@@ -9,7 +9,7 @@ import OperationDialog from "@/views/common/dialog/OperationDialog";
interface TimelineDeleteDialog {
timeline: HttpTimelineInfo;
open: boolean;
- close: () => void;
+ onClose: () => void;
}
const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
@@ -20,7 +20,7 @@ const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
return (
<OperationDialog
open={props.open}
- onClose={props.close}
+ onClose={props.onClose}
title="timeline.deleteDialog.title"
color="danger"
inputPrompt={() => (
diff --git a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
index e26df3eb..b57135bb 100644
--- a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
+++ b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
@@ -12,7 +12,7 @@ import OperationDialog from "@/views/common/dialog/OperationDialog";
export interface TimelinePropertyChangeDialogProps {
open: boolean;
- close: () => void;
+ onClose: () => void;
timeline: HttpTimelineInfo;
onChange: () => void;
}
@@ -64,7 +64,7 @@ const TimelinePropertyChangeDialog: React.FC<
},
}}
open={props.open}
- onClose={props.close}
+ onClose={props.onClose}
onProcess={({ title, visibility, description }) => {
const req: HttpTimelinePatchRequest = {};
if (title !== timeline.title) {