aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-04-11 23:14:23 +0800
committercrupest <crupest@outlook.com>2022-04-11 23:14:23 +0800
commitc645e08ffd2fa572504b77d705a8f9d1507a718e (patch)
treeea3a6a7477b391fbf86077a636595141a6de2256
parent9c0cb8f8d3944c813ef28ff9f736f148fd701a66 (diff)
downloadtimeline-c645e08ffd2fa572504b77d705a8f9d1507a718e.tar.gz
timeline-c645e08ffd2fa572504b77d705a8f9d1507a718e.tar.bz2
timeline-c645e08ffd2fa572504b77d705a8f9d1507a718e.zip
...
-rw-r--r--FrontEnd/src/common.ts2
-rw-r--r--FrontEnd/src/views/center/CenterBoards.tsx61
-rw-r--r--FrontEnd/src/views/center/TimelineBoard.tsx55
-rw-r--r--FrontEnd/src/views/home/index.tsx4
-rw-r--r--FrontEnd/src/views/timeline/Timeline.tsx2
-rw-r--r--FrontEnd/src/views/timeline/TimelineCard.tsx29
6 files changed, 83 insertions, 70 deletions
diff --git a/FrontEnd/src/common.ts b/FrontEnd/src/common.ts
index 91d58562..b819d209 100644
--- a/FrontEnd/src/common.ts
+++ b/FrontEnd/src/common.ts
@@ -29,3 +29,5 @@ export function convertI18nText(
return text.value;
}
}
+
+export const highlightTimelineUsername = "crupest";
diff --git a/FrontEnd/src/views/center/CenterBoards.tsx b/FrontEnd/src/views/center/CenterBoards.tsx
index 392c2d08..e95f4cb8 100644
--- a/FrontEnd/src/views/center/CenterBoards.tsx
+++ b/FrontEnd/src/views/center/CenterBoards.tsx
@@ -1,12 +1,13 @@
import React from "react";
import { useTranslation } from "react-i18next";
+import { highlightTimelineUsername } from "@/common";
+
import { pushAlert } from "@/services/alert";
import { useUserLoggedIn } from "@/services/user";
import { getHttpTimelineClient } from "@/http/timeline";
import { getHttpBookmarkClient } from "@/http/bookmark";
-import { getHttpHighlightClient } from "@/http/highlight";
import TimelineBoard from "./TimelineBoard";
@@ -23,11 +24,15 @@ const CenterBoards: React.FC = () => {
<div className="col col-12 my-2">
<TimelineBoard
title={t("home.bookmarkTimeline")}
- load={() => getHttpBookmarkClient().list()}
+ load={() =>
+ getHttpBookmarkClient()
+ .list(user.username)
+ .then((p) => p.items)
+ }
editHandler={{
- onDelete: (timeline) => {
+ onDelete: (owner, timeline) => {
return getHttpBookmarkClient()
- .delete(timeline)
+ .delete(user.username, owner, timeline)
.catch((e) => {
pushAlert({
message: "home.message.deleteBookmarkFail",
@@ -36,10 +41,13 @@ const CenterBoards: React.FC = () => {
throw e;
});
},
- onMove: (timeline, index, offset) => {
+ onMove: (owner, timeline, index, offset) => {
return getHttpBookmarkClient()
.move(
- { timeline, newPosition: index + offset + 1 } // +1 because backend contract: index starts at 1
+ user.username,
+ owner,
+ timeline,
+ index + offset + 1 // +1 because backend contract: index starts at 1
)
.catch((e) => {
pushAlert({
@@ -47,7 +55,8 @@ const CenterBoards: React.FC = () => {
type: "danger",
});
throw e;
- });
+ })
+ .then();
},
}}
/>
@@ -55,13 +64,17 @@ const CenterBoards: React.FC = () => {
<div className="col col-12 my-2">
<TimelineBoard
title={t("home.highlightTimeline")}
- load={() => getHttpHighlightClient().list()}
+ load={() =>
+ getHttpBookmarkClient()
+ .list(highlightTimelineUsername)
+ .then((p) => p.items)
+ }
editHandler={
- user.hasHighlightTimelineAdministrationPermission
+ user.username === highlightTimelineUsername
? {
- onDelete: (timeline) => {
- return getHttpHighlightClient()
- .delete(timeline)
+ onDelete: (owner, timeline) => {
+ return getHttpBookmarkClient()
+ .delete(highlightTimelineUsername, owner, timeline)
.catch((e) => {
pushAlert({
message: "home.message.deleteHighlightFail",
@@ -70,18 +83,22 @@ const CenterBoards: React.FC = () => {
throw e;
});
},
- onMove: (timeline, index, offset) => {
- return getHttpHighlightClient()
+ onMove: (owner, timeline, index, offset) => {
+ return getHttpBookmarkClient()
.move(
- { timeline, newPosition: index + offset + 1 } // +1 because backend contract: index starts at 1
+ highlightTimelineUsername,
+ owner,
+ timeline,
+ index + offset + 1 // +1 because backend contract: index starts at 1
)
.catch((e) => {
pushAlert({
- message: "home.message.moveHighlightFail",
+ message: "home.message.moveBookmarkFail",
type: "danger",
});
throw e;
- });
+ })
+ .then();
},
}
: undefined
@@ -94,7 +111,15 @@ const CenterBoards: React.FC = () => {
<TimelineBoard
title={t("home.relatedTimeline")}
load={() =>
- getHttpTimelineClient().listTimeline({ relate: user.username })
+ getHttpTimelineClient()
+ .listTimeline({ relate: user.username })
+ .then((l) =>
+ l.map((t, index) => ({
+ timelineOwner: t.owner.username,
+ timelineName: t.nameV2,
+ position: index + 1,
+ }))
+ )
}
/>
</div>
diff --git a/FrontEnd/src/views/center/TimelineBoard.tsx b/FrontEnd/src/views/center/TimelineBoard.tsx
index f8dc4bfd..45b4a8a5 100644
--- a/FrontEnd/src/views/center/TimelineBoard.tsx
+++ b/FrontEnd/src/views/center/TimelineBoard.tsx
@@ -2,7 +2,7 @@ import React from "react";
import classnames from "classnames";
import { Link } from "react-router-dom";
-import { HttpTimelineInfo } from "@/http/timeline";
+import { TimelineBookmark } from "@/http/bookmark";
import TimelineLogo from "../common/TimelineLogo";
import LoadFailReload from "../common/LoadFailReload";
@@ -11,7 +11,7 @@ import Card from "../common/Card";
import Spinner from "../common/Spinner";
interface TimelineBoardItemProps {
- timeline: HttpTimelineInfo;
+ timeline: TimelineBookmark;
// In height.
offset?: number;
// In px.
@@ -33,15 +33,12 @@ const TimelineBoardItem: React.FC<TimelineBoardItemProps> = ({
offset,
actions,
}) => {
- const { title } = timeline;
-
const content = (
<>
<TimelineLogo className="icon" />
- <span className="title">{title}</span>
- <small className="ms-2 cru-color-secondary">
- {timeline.owner.username}/{timeline.nameV2}
- </small>
+ <span className="title">
+ {timeline.timelineOwner}/{timeline.timelineName}
+ </span>
<span className="flex-grow-1"></span>
{actions != null ? (
<div className="right">
@@ -83,7 +80,7 @@ const TimelineBoardItem: React.FC<TimelineBoardItemProps> = ({
return actions == null ? (
<Link
- to={`${timeline.owner.username}/${timeline.nameV2}`}
+ to={`${timeline.timelineOwner}/${timeline.timelineName}`}
className="timeline-board-item"
>
{content}
@@ -96,7 +93,7 @@ const TimelineBoardItem: React.FC<TimelineBoardItemProps> = ({
};
interface TimelineBoardItemContainerProps {
- timelines: HttpTimelineInfo[];
+ timelines: TimelineBookmark[];
editHandler?: {
// offset may exceed index range plusing index.
onMove: (
@@ -156,7 +153,7 @@ const TimelineBoardItemContainer: React.FC<TimelineBoardItemContainerProps> = ({
return (
<TimelineBoardItem
- key={`${timeline.owner.username}/${timeline.nameV2}`}
+ key={timeline.timelineOwner + "/" + timeline.timelineName}
timeline={timeline}
offset={offset}
arbitraryOffset={arbitraryOffset}
@@ -165,8 +162,8 @@ const TimelineBoardItemContainer: React.FC<TimelineBoardItemContainerProps> = ({
? {
onDelete: () => {
editHandler.onDelete(
- timeline.owner.username,
- timeline.nameV2
+ timeline.timelineOwner,
+ timeline.timelineName
);
},
onMove: {
@@ -192,8 +189,8 @@ const TimelineBoardItemContainer: React.FC<TimelineBoardItemContainerProps> = ({
moveState.offset / height
);
editHandler.onMove(
- timeline.owner.username,
- timeline.nameV2,
+ timeline.timelineOwner,
+ timeline.timelineName,
moveState.index,
offsetCount
);
@@ -214,7 +211,7 @@ const TimelineBoardItemContainer: React.FC<TimelineBoardItemContainerProps> = ({
interface TimelineBoardUIProps {
title?: string;
state: "offline" | "loading" | "loaded";
- timelines: HttpTimelineInfo[];
+ timelines: TimelineBookmark[];
onReload: () => void;
className?: string;
editHandler?: {
@@ -299,10 +296,15 @@ const TimelineBoardUI: React.FC<TimelineBoardUIProps> = (props) => {
export interface TimelineBoardProps {
title?: string;
className?: string;
- load: () => Promise<HttpTimelineInfo[]>;
+ load: () => Promise<TimelineBookmark[]>;
editHandler?: {
- onMove: (timeline: string, index: number, offset: number) => Promise<void>;
- onDelete: (timeline: string) => Promise<void>;
+ onMove: (
+ owner: string,
+ timeline: string,
+ index: number,
+ offset: number
+ ) => Promise<void>;
+ onDelete: (owner: string, timeline: string) => Promise<void>;
};
}
@@ -315,7 +317,7 @@ const TimelineBoard: React.FC<TimelineBoardProps> = ({
const [state, setState] = React.useState<"offline" | "loading" | "loaded">(
"loading"
);
- const [timelines, setTimelines] = React.useState<HttpTimelineInfo[]>([]);
+ const [timelines, setTimelines] = React.useState<TimelineBookmark[]>([]);
React.useEffect(() => {
let subscribe = true;
@@ -354,20 +356,23 @@ const TimelineBoard: React.FC<TimelineBoardProps> = ({
const [t] = newTimelines.splice(index, 1);
newTimelines.splice(index + offset, 0, t);
setTimelines(newTimelines);
- editHandler.onMove(timeline, index, offset).then(null, () => {
- setTimelines(timelines);
- });
+ editHandler
+ .onMove(owner, timeline, index, offset)
+ .then(null, () => {
+ setTimelines(timelines);
+ });
},
onDelete: (owner, timeline) => {
const newTimelines = timelines.slice();
newTimelines.splice(
timelines.findIndex(
- (t) => t.owner.username === owner && t.nameV2 === timeline
+ (t) =>
+ t.timelineOwner === owner && t.timelineName === timeline
),
1
);
setTimelines(newTimelines);
- editHandler.onDelete(timeline).then(null, () => {
+ editHandler.onDelete(owner, timeline).then(null, () => {
setTimelines(timelines);
});
},
diff --git a/FrontEnd/src/views/home/index.tsx b/FrontEnd/src/views/home/index.tsx
index 0eeb4b77..d734b2b7 100644
--- a/FrontEnd/src/views/home/index.tsx
+++ b/FrontEnd/src/views/home/index.tsx
@@ -1,6 +1,8 @@
import React from "react";
import { useNavigate } from "react-router-dom";
+import { highlightTimelineUsername } from "@/common";
+
import { Page } from "@/http/common";
import { getHttpBookmarkClient, TimelineBookmark } from "@/http/bookmark";
@@ -10,8 +12,6 @@ import WebsiteIntroduction from "./WebsiteIntroduction";
import "./index.css";
-const highlightTimelineUsername = "crupest";
-
const highlightTimelineMessageMap = {
loading: "home.loadingHighlightTimelines",
done: "home.loadedHighlightTimelines",
diff --git a/FrontEnd/src/views/timeline/Timeline.tsx b/FrontEnd/src/views/timeline/Timeline.tsx
index e8ed9fe5..a2047651 100644
--- a/FrontEnd/src/views/timeline/Timeline.tsx
+++ b/FrontEnd/src/views/timeline/Timeline.tsx
@@ -89,7 +89,7 @@ const Timeline: React.FC<TimelineProps> = (props) => {
([t, p]) => {
if (subscribe) {
setTimeline(t);
- setPosts(p);
+ setPosts(p.items);
setState("loaded");
onTimelineLoaded.current?.(t);
}
diff --git a/FrontEnd/src/views/timeline/TimelineCard.tsx b/FrontEnd/src/views/timeline/TimelineCard.tsx
index dcf5e870..872ad6d3 100644
--- a/FrontEnd/src/views/timeline/TimelineCard.tsx
+++ b/FrontEnd/src/views/timeline/TimelineCard.tsx
@@ -8,7 +8,6 @@ import { timelineVisibilityTooltipTranslationMap } from "@/services/timeline";
import { useUser } from "@/services/user";
import { pushAlert } from "@/services/alert";
import { HttpTimelineInfo } from "@/http/timeline";
-import { getHttpHighlightClient } from "@/http/highlight";
import { getHttpBookmarkClient } from "@/http/bookmark";
import UserAvatar from "../common/user/UserAvatar";
@@ -71,28 +70,6 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
{t(timelineVisibilityTooltipTranslationMap[timeline.visibility])}
</small>
<div className="mt-2 cru-text-end">
- <i
- className={classnames(
- timeline.isHighlight ? "bi-star-fill" : "bi-star",
- "icon-button cru-color-primary me-3"
- )}
- onClick={
- user?.hasHighlightTimelineAdministrationPermission
- ? () => {
- getHttpHighlightClient()
- [timeline.isHighlight ? "delete" : "put"](timeline.nameV2)
- .then(onReload, () => {
- pushAlert({
- message: timeline.isHighlight
- ? "timeline.removeHighlightFail"
- : "timeline.addHighlightFail",
- type: "danger",
- });
- });
- }
- : undefined
- }
- />
{user != null ? (
<i
className={classnames(
@@ -101,7 +78,11 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
)}
onClick={() => {
getHttpBookmarkClient()
- [timeline.isBookmark ? "delete" : "put"](timeline.nameV2)
+ [timeline.isBookmark ? "delete" : "post"](
+ user.username,
+ timeline.owner.username,
+ timeline.nameV2
+ )
.then(onReload, () => {
pushAlert({
message: timeline.isBookmark