From a337ce43ae91c0c9a1c359dbb91faf75f1375505 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 22 Dec 2020 00:27:33 +0800 Subject: ... --- .../app/views/timeline-common/InfoCardTemplate.tsx | 26 ----- .../views/timeline-common/TimelineCardTemplate.tsx | 100 ++++++++++++++++ .../src/app/views/timeline/TimelineInfoCard.tsx | 128 +++++++++------------ FrontEnd/src/app/views/user/UserInfoCard.tsx | 123 +++++++++----------- 4 files changed, 208 insertions(+), 169 deletions(-) delete mode 100644 FrontEnd/src/app/views/timeline-common/InfoCardTemplate.tsx create mode 100644 FrontEnd/src/app/views/timeline-common/TimelineCardTemplate.tsx (limited to 'FrontEnd/src') diff --git a/FrontEnd/src/app/views/timeline-common/InfoCardTemplate.tsx b/FrontEnd/src/app/views/timeline-common/InfoCardTemplate.tsx deleted file mode 100644 index a8de20aa..00000000 --- a/FrontEnd/src/app/views/timeline-common/InfoCardTemplate.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import clsx from "clsx"; - -import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; -import SyncStatusBadge from "../timeline-common/SyncStatusBadge"; -import CollapseButton from "../timeline-common/CollapseButton"; - -const InfoCardTemplate: React.FC< - Pick< - TimelineCardComponentProps<"">, - "collapse" | "toggleCollapse" | "syncStatus" | "className" - > & { children: React.ReactElement[] } -> = ({ collapse, toggleCollapse, syncStatus, className, children }) => { - return ( -
-
- - -
- -
{children}
-
- ); -}; - -export default InfoCardTemplate; diff --git a/FrontEnd/src/app/views/timeline-common/TimelineCardTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelineCardTemplate.tsx new file mode 100644 index 00000000..a47b3d76 --- /dev/null +++ b/FrontEnd/src/app/views/timeline-common/TimelineCardTemplate.tsx @@ -0,0 +1,100 @@ +import React from "react"; +import clsx from "clsx"; +import { useTranslation } from "react-i18next"; +import { Dropdown, Button } from "react-bootstrap"; +import Svg from "react-inlinesvg"; +import bookmarkIcon from "bootstrap-icons/icons/bookmark.svg"; + +import { timelineVisibilityTooltipTranslationMap } from "@/services/timeline"; + +import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; +import SyncStatusBadge from "../timeline-common/SyncStatusBadge"; +import CollapseButton from "../timeline-common/CollapseButton"; + +export interface TimelineCardTemplateProps + extends Omit, "onManage" | "onMember"> { + infoArea: React.ReactElement; + manageArea: + | { type: "member"; onMember: () => void } + | { + type: "manage"; + items: ( + | { + type: "button"; + text: string; + color?: string; + onClick: () => void; + } + | { type: "divider" } + )[]; + }; +} + +function TimelineCardTemplate({ + timeline, + collapse, + infoArea, + manageArea, + onBookmark, + toggleCollapse, + syncStatus, + className, +}: TimelineCardTemplateProps): React.ReactElement | null { + const { t } = useTranslation(); + + return ( +
+
+ + +
+
+ {infoArea} +

{timeline.description}

+ + {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + +
+ {onBookmark != null ? ( + + ) : null} + {manageArea.type === "manage" ? ( + + + {t("timeline.manage")} + + + {manageArea.items.map((item, index) => { + if (item.type === "divider") { + return ; + } else { + return ( + + {t(item.text)} + + ); + } + })} + + + ) : ( + + )} +
+
+
+ ); +} + +export default TimelineCardTemplate; diff --git a/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx b/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx index 8f967a34..f4dbb67d 100644 --- a/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx +++ b/FrontEnd/src/app/views/timeline/TimelineInfoCard.tsx @@ -1,93 +1,73 @@ import React from "react"; -import { useTranslation } from "react-i18next"; -import { Dropdown, Button } from "react-bootstrap"; -import Svg from "react-inlinesvg"; -import bookmarkIcon from "bootstrap-icons/icons/bookmark.svg"; import { useAvatar } from "@/services/user"; -import { timelineVisibilityTooltipTranslationMap } from "@/services/timeline"; import BlobImage from "../common/BlobImage"; +import TimelineCardTemplate, { + TimelineCardTemplateProps, +} from "../timeline-common/TimelineCardTemplate"; import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; -import InfoCardTemplate from "../timeline-common/InfoCardTemplate"; export type OrdinaryTimelineManageItem = "delete"; export type TimelineInfoCardProps = TimelineCardComponentProps; const TimelineInfoCard: React.FC = (props) => { - const { - timeline, - collapse, - onMember, - onBookmark, - onManage, - syncStatus, - toggleCollapse, - } = props; - - const { t } = useTranslation(); + const { onMember, onManage, ...otherProps } = props; + const { timeline } = props; const avatar = useAvatar(timeline?.owner?.username); return ( - -

- {timeline.title} - {timeline.name} -

-
- - {timeline.owner.nickname} - - @{timeline.owner.username} - -
-

{timeline.description}

- - {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} - -
- {onBookmark != null ? ( - - ) : null} - {onManage != null ? ( - - - {t("timeline.manage")} - - - onManage("property")}> - {t("timeline.manageItem.property")} - - - {t("timeline.manageItem.member")} - - - onManage("delete")} - > - {t("timeline.manageItem.delete")} - - - - ) : ( - - )} -
-
+ +

+ {timeline.title} + {timeline.name} +

+
+ + {timeline.owner.nickname} + + @{timeline.owner.username} + +
+ + } + manageArea={((): TimelineCardTemplateProps["manageArea"] => { + if (onManage == null) { + return { type: "member", onMember }; + } else { + return { + type: "manage", + items: [ + { + type: "button", + text: "timeline.manageItem.property", + onClick: () => onManage("property"), + }, + { + type: "button", + onClick: onMember, + text: "timeline.manageItem.member", + }, + { type: "divider" }, + { + type: "button", + onClick: () => onManage("delete"), + color: "danger", + text: "timeline.manageItem.delete", + }, + ], + }; + } + })()} + {...otherProps} + /> ); }; diff --git a/FrontEnd/src/app/views/user/UserInfoCard.tsx b/FrontEnd/src/app/views/user/UserInfoCard.tsx index 0e1e093a..f31a939f 100644 --- a/FrontEnd/src/app/views/user/UserInfoCard.tsx +++ b/FrontEnd/src/app/views/user/UserInfoCard.tsx @@ -1,88 +1,73 @@ import React from "react"; -import { useTranslation } from "react-i18next"; -import { Dropdown, Button } from "react-bootstrap"; -import Svg from "react-inlinesvg"; -import bookmarkIcon from "bootstrap-icons/icons/bookmark.svg"; -import { timelineVisibilityTooltipTranslationMap } from "@/services/timeline"; import { useAvatar } from "@/services/user"; import BlobImage from "../common/BlobImage"; +import TimelineCardTemplate, { + TimelineCardTemplateProps, +} from "../timeline-common/TimelineCardTemplate"; import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; -import InfoCardTemplate from "../timeline-common/InfoCardTemplate"; export type PersonalTimelineManageItem = "avatar" | "nickname"; export type UserInfoCardProps = TimelineCardComponentProps; const UserInfoCard: React.FC = (props) => { - const { - timeline, - collapse, - onMember, - onManage, - onBookmark, - syncStatus, - toggleCollapse, - } = props; - const { t } = useTranslation(); + const { onMember, onManage, ...otherProps } = props; + const { timeline } = props; const avatar = useAvatar(timeline?.owner?.username); return ( - -

- {timeline.title} - {timeline.name} -

-
- - {timeline.owner.nickname} -
-

{timeline.description}

- - {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} - -
- {onBookmark != null ? ( - - ) : null} - {onManage != null ? ( - - - {t("timeline.manage")} - - - onManage("nickname")}> - {t("timeline.manageItem.nickname")} - - onManage("avatar")}> - {t("timeline.manageItem.avatar")} - - onManage("property")}> - {t("timeline.manageItem.property")} - - - {t("timeline.manageItem.member")} - - - - ) : ( - - )} -
-
+ +

+ {timeline.title} + {timeline.name} +

+
+ + {timeline.owner.nickname} +
+ + } + manageArea={((): TimelineCardTemplateProps["manageArea"] => { + if (onManage == null) { + return { type: "member", onMember }; + } else { + return { + type: "manage", + items: [ + { + type: "button", + text: "timeline.manageItem.nickname", + onClick: () => onManage("nickname"), + }, + { + type: "button", + text: "timeline.manageItem.avatar", + onClick: () => onManage("avatar"), + }, + { + type: "button", + text: "timeline.manageItem.property", + onClick: () => onManage("property"), + }, + { + type: "button", + onClick: onMember, + text: "timeline.manageItem.member", + }, + ], + }; + } + })()} + {...otherProps} + /> ); }; -- cgit v1.2.3