aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx')
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx238
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}
</>
);