diff options
| author | crupest <crupest@outlook.com> | 2021-01-11 21:58:32 +0800 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-11 21:58:32 +0800 | 
| commit | 5d3a3111bbc349d5d5ff0a4ed92f97b14a9d65fe (patch) | |
| tree | d635081fb6eaa0222270bfb4ac29906fb767a9bd /FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx | |
| parent | 777efa6e0405f4e871de4da21b939e30ed07f754 (diff) | |
| parent | 26f02d90c2571251b32c3b03b970dd290e3892e6 (diff) | |
| download | timeline-5d3a3111bbc349d5d5ff0a4ed92f97b14a9d65fe.tar.gz timeline-5d3a3111bbc349d5d5ff0a4ed92f97b14a9d65fe.tar.bz2 timeline-5d3a3111bbc349d5d5ff0a4ed92f97b14a9d65fe.zip | |
Merge pull request #206 from crupest/front-dev
Front development.
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx')
| -rw-r--r-- | FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx | 238 | 
1 files changed, 103 insertions, 135 deletions
| diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx index 7f5c8206..f8b2b38b 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx @@ -1,16 +1,10 @@  import React from "react";  import { useTranslation } from "react-i18next"; -import { of } from "rxjs"; -import { catchError } from "rxjs/operators";  import { UiLogicError } from "@/common";  import { pushAlert } from "@/services/alert"; -import { useUser, userInfoService, UserNotExistError } from "@/services/user"; -import { -  timelineService, -  usePostList, -  useTimelineInfo, -} from "@/services/timeline"; +import { useUser } from "@/services/user"; +import { timelineService, usePosts, useTimeline } from "@/services/timeline";  import { getHttpBookmarkClient } from "@/http/bookmark";  import { getHttpHighlightClient } from "@/http/highlight"; @@ -18,8 +12,8 @@ import { TimelineMemberDialog } from "./TimelineMember";  import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog";  import { TimelinePageTemplateUIProps } from "./TimelinePageTemplateUI";  import { TimelinePostSendCallback } from "./TimelinePostEdit"; -import { TimelineSyncStatus } from "./SyncStatusBadge";  import { TimelinePostInfoEx } from "./Timeline"; +import { mergeDataStatus } from "@/services/DataHub2";  export interface TimelinePageTemplateProps<TManageItem> {    name: string; @@ -45,8 +39,8 @@ export default function TimelinePageTemplate<TManageItem>(      null    ); -  const timelineState = useTimelineInfo(name); -  const postListState = usePostList(name); +  const timelineAndStatus = useTimeline(name); +  const postsAndState = usePosts(name);    const onPost: TimelinePostSendCallback = React.useCallback(      (req) => { @@ -68,111 +62,104 @@ export default function TimelinePageTemplate<TManageItem>(      [onManageProp]    ); -  const childProps = ((): [ -    data: TimelinePageTemplateUIProps<TManageItem>["data"], -    syncStatus: TimelineSyncStatus -  ] => { -    if (timelineState == null) { -      return [undefined, "syncing"]; +  const data = ((): TimelinePageTemplateUIProps<TManageItem>["data"] => { +    const { status, data: timeline } = timelineAndStatus; +    if (timeline == null) { +      if (status === "offline") { +        return { type: "custom", value: "Network Error" }; +      } else { +        return undefined; +      } +    } else if (timeline === "notexist") { +      return props.notFoundI18nKey;      } else { -      const { type, timeline } = timelineState; -      if (timeline == null) { -        if (type === "offline") { -          return [{ type: "custom", value: "Network Error" }, "offline"]; -        } else if (type === "synced") { -          return [props.notFoundI18nKey, "synced"]; +      const posts = ((): TimelinePostInfoEx[] | "forbid" | undefined => { +        const { data: postsInfo } = postsAndState; +        if (postsInfo === "forbid") { +          return "forbid"; +        } else if (postsInfo == null || postsInfo === "notexist") { +          return undefined;          } 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"]; +          return postsInfo.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 posts: -          | TimelinePostInfoEx[] -          | undefined = postListState?.posts?.map((post) => ({ -          ...post, -          onDelete: service.hasModifyPostPermission(user, timeline, post) +      })(); + +      const operations = { +        onPost: service.hasPostPermission(user, timeline) ? onPost : undefined, +        onManage: service.hasManagePermission(user, timeline) +          ? onManage +          : undefined, +        onMember: () => setDialog("member"), +        onBookmark: +          user != null              ? () => { -                service.deletePost(name, post.id).subscribe({ -                  error: () => { +                const { isBookmark } = timeline; +                const client = getHttpBookmarkClient(); +                const promise = isBookmark +                  ? client.delete(name) +                  : client.put(name); +                promise.then( +                  () => { +                    void timelineService.syncTimeline(name); +                  }, +                  () => {                      pushAlert({ +                      message: { +                        type: "i18n", +                        key: isBookmark +                          ? "timeline.removeBookmarkFail" +                          : "timeline.addBookmarkFail", +                      },                        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"), -          onBookmark: -            user != null -              ? () => { -                  void getHttpBookmarkClient() -                    .put(name, user.token) -                    .then(() => { -                      pushAlert({ -                        message: { -                          type: "i18n", -                          key: "timeline.addBookmarkSuccess", -                        }, -                        type: "success", -                      }); -                    }); -                } -              : undefined, -          onHighlight: -            user != null && user.hasHighlightTimelineAdministrationPermission -              ? () => { -                  void getHttpHighlightClient() -                    .put(name, user.token) -                    .then(() => { -                      pushAlert({ -                        message: { -                          type: "i18n", -                          key: "timeline.addHighlightSuccess", -                        }, -                        type: "success", -                      }); +        onHighlight: +          user != null && user.hasHighlightTimelineAdministrationPermission +            ? () => { +                const { isHighlight } = timeline; +                const client = getHttpHighlightClient(); +                const promise = isHighlight +                  ? client.delete(name) +                  : client.put(name); +                promise.then( +                  () => { +                    void timelineService.syncTimeline(name); +                  }, +                  () => { +                    pushAlert({ +                      message: { +                        type: "i18n", +                        key: isHighlight +                          ? "timeline.removeHighlightFail" +                          : "timeline.addHighlightFail", +                      }, +                      type: "danger",                      }); -                } -              : undefined, -        }; +                  } +                ); +              } +            : undefined, +      }; -        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 { timeline, posts, operations };      } -    throw new UiLogicError("Failed to calculate TimelinePageUITemplate props.");    })();    const closeDialog = React.useCallback((): void => { @@ -181,10 +168,10 @@ export default function TimelinePageTemplate<TManageItem>(    let dialogElement: React.ReactElement | undefined; -  const timeline = timelineState?.timeline; +  const timeline = timelineAndStatus?.data;    if (dialog === "property") { -    if (timeline == null) { +    if (timeline == null || timeline === "notexist") {        throw new UiLogicError(          "Timeline is null but attempt to open change property dialog."        ); @@ -205,7 +192,7 @@ export default function TimelinePageTemplate<TManageItem>(        />      );    } else if (dialog === "member") { -    if (timeline == null) { +    if (timeline == null || timeline === "notexist") {        throw new UiLogicError(          "Timeline is null but attempt to open change property dialog."        ); @@ -215,33 +202,8 @@ export default function TimelinePageTemplate<TManageItem>(        <TimelineMemberDialog          open          onClose={closeDialog} -        members={[timeline.owner, ...timeline.members]} -        edit={ -          service.hasManagePermission(user, timeline) -            ? { -                onCheckUser: (u) => { -                  return userInfoService -                    .getUserInfo(u) -                    .pipe( -                      catchError((e) => { -                        if (e instanceof UserNotExistError) { -                          return of(null); -                        } else { -                          throw e; -                        } -                      }) -                    ) -                    .toPromise(); -                }, -                onAddUser: (u) => { -                  return service.addMember(name, u.username).toPromise().then(); -                }, -                onRemoveUser: (u) => { -                  service.removeMember(name, u); -                }, -              } -            : null -        } +        timeline={timeline} +        editable={service.hasManagePermission(user, timeline)}        />      );    } @@ -250,7 +212,13 @@ export default function TimelinePageTemplate<TManageItem>(    return (      <> -      <UiComponent data={childProps[0]} syncStatus={childProps[1]} /> +      <UiComponent +        data={data} +        syncStatus={mergeDataStatus([ +          timelineAndStatus.status, +          postsAndState.status, +        ])} +      />        {dialogElement}      </>    ); | 
