From 98132cee7e4c427cab4cec2af45e1b8102c59c3b Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 11 Nov 2020 21:02:15 +0800 Subject: refactor: Refactor timeline props. --- .../views/timeline-common/TimelinePageTemplate.tsx | 153 +++++++++++++-------- 1 file changed, 95 insertions(+), 58 deletions(-) (limited to 'FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx') diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx index 0f792b53..6c57e91d 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx @@ -12,11 +12,12 @@ import { useTimelineInfo, } from "@/services/timeline"; -import { TimelineDeleteCallback } from "./Timeline"; import { TimelineMemberDialog } from "./TimelineMember"; import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog"; import { TimelinePageTemplateUIProps } from "./TimelinePageTemplateUI"; import { TimelinePostSendCallback } from "./TimelinePostEdit"; +import { TimelineSyncStatus } from "./SyncStatusBadge"; +import { TimelinePostInfoEx } from "./Timeline"; export interface TimelinePageTemplateProps { name: string; @@ -43,19 +44,101 @@ export default function TimelinePageTemplate( ); const timelineState = useTimelineInfo(name); + const postListState = usePostList(name); - const timeline = timelineState?.timeline; + const onPost: TimelinePostSendCallback = React.useCallback( + (req) => { + return service.createPost(name, req).toPromise().then(); + }, + [service, name] + ); - const postListState = usePostList(name); + const onManageProp = props.onManage; - const error: string | undefined = (() => { - if (timelineState != null) { + const onManage = React.useCallback( + (item: "property" | TManageItem) => { + if (item === "property") { + setDialog(item); + } else { + onManageProp(item); + } + }, + [onManageProp] + ); + + const childProps = ((): [ + data: TimelinePageTemplateUIProps["data"], + syncStatus: TimelineSyncStatus + ] => { + if (timelineState == null) { + return [undefined, "syncing"]; + } else { const { type, timeline } = timelineState; - if (type === "offline" && timeline == null) return "Network Error"; - if (type === "synced" && timeline == null) - return t(props.notFoundI18nKey); + if (timeline == null) { + if (type === "offline") { + return [{ type: "custom", value: "Network Error" }, "offline"]; + } else if (type === "synced") { + return [props.notFoundI18nKey, "synced"]; + } else { + return [undefined, "syncing"]; + } + } else { + if (postListState != null && postListState.type === "notexist") { + return [props.notFoundI18nKey, "synced"]; + } + if (postListState != null && postListState.type === "forbid") { + return ["timeline.messageCantSee", "synced"]; + } + + const posts: + | TimelinePostInfoEx[] + | undefined = postListState?.posts?.map((post) => ({ + ...post, + onDelete: service.hasModifyPostPermission(user, timeline, post) + ? () => { + service.deletePost(name, post.id).subscribe({ + error: () => { + pushAlert({ + type: "danger", + message: t("timeline.deletePostFailed"), + }); + }, + }); + } + : undefined, + })); + + const others = { + onPost: service.hasPostPermission(user, timeline) + ? onPost + : undefined, + onManage: service.hasManagePermission(user, timeline) + ? onManage + : undefined, + onMember: () => setDialog("member"), + }; + + if (type === "cache") { + return [{ timeline, posts, ...others }, "syncing"]; + } else if (type === "offline") { + return [{ timeline, posts, ...others }, "offline"]; + } else { + if (postListState == null) { + return [{ timeline, posts, ...others }, "syncing"]; + } else { + const { type: postListType } = postListState; + if (postListType === "synced") { + return [{ timeline, posts, ...others }, "synced"]; + } else if (postListType === "cache") { + return [{ timeline, posts, ...others }, "syncing"]; + } else if (postListType === "offline") { + return [{ timeline, posts, ...others }, "offline"]; + } + } + } + } } - return undefined; + throw new UiLogicError("Failed to calculate TimelinePageUITemplate props."); })(); const closeDialog = React.useCallback((): void => { @@ -64,6 +147,8 @@ export default function TimelinePageTemplate( let dialogElement: React.ReactElement | undefined; + const timeline = timelineState?.timeline; + if (dialog === "property") { if (timeline == null) { throw new UiLogicError( @@ -129,57 +214,9 @@ export default function TimelinePageTemplate( const { UiComponent } = props; - const onDelete: TimelineDeleteCallback = React.useCallback( - (index, id) => { - service.deletePost(name, id).subscribe(null, () => { - pushAlert({ - type: "danger", - message: t("timeline.deletePostFailed"), - }); - }); - }, - [service, name, t] - ); - - const onPost: TimelinePostSendCallback = React.useCallback( - (req) => { - return service.createPost(name, req).toPromise().then(); - }, - [service, name] - ); - - const onManageProp = props.onManage; - - const onManage = React.useCallback( - (item: "property" | TManageItem) => { - if (item === "property") { - setDialog(item); - } else { - onManageProp(item); - } - }, - [onManageProp] - ); - return ( <> - setDialog("member")} - /> + {dialogElement} ); -- cgit v1.2.3