aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/src/app/locales/en/translation.json2
-rw-r--r--FrontEnd/src/app/locales/zh/translation.json2
-rw-r--r--FrontEnd/src/app/views/home-v2/TimelineListView.tsx32
-rw-r--r--FrontEnd/src/app/views/home-v2/home-v2.sass11
-rw-r--r--FrontEnd/src/app/views/home-v2/index.tsx47
5 files changed, 84 insertions, 10 deletions
diff --git a/FrontEnd/src/app/locales/en/translation.json b/FrontEnd/src/app/locales/en/translation.json
index 6707105a..a878badd 100644
--- a/FrontEnd/src/app/locales/en/translation.json
+++ b/FrontEnd/src/app/locales/en/translation.json
@@ -28,6 +28,8 @@
"loadImageError": "Failed to load image.",
"home": {
"loadingHighlightTimelines": "Loading highlight timelines...",
+ "loadedHighlightTimelines": "Here are some highlight timelines💡",
+ "errorHighlightTimelines": "Failed to load highlight timelines, please try reloading!",
"highlightTimeline": "Highlight Timelines",
"relatedTimeline": "Timelines Related To You",
"publicTimeline": "Public Timelines",
diff --git a/FrontEnd/src/app/locales/zh/translation.json b/FrontEnd/src/app/locales/zh/translation.json
index dbff0a28..3f956d3d 100644
--- a/FrontEnd/src/app/locales/zh/translation.json
+++ b/FrontEnd/src/app/locales/zh/translation.json
@@ -28,6 +28,8 @@
"loadImageError": "加载图片失败",
"home": {
"loadingHighlightTimelines": "正在加载高光时间线...",
+ "loadedHighlightTimelines": "康康以下这些高光时间线💡",
+ "errorHighlightTimelines": "加载高光时间线失败,刷新试试!",
"highlightTimeline": "高光时间线",
"relatedTimeline": "关于你的时间线",
"publicTimeline": "公开时间线",
diff --git a/FrontEnd/src/app/views/home-v2/TimelineListView.tsx b/FrontEnd/src/app/views/home-v2/TimelineListView.tsx
index 1ba9f765..9c44a0c2 100644
--- a/FrontEnd/src/app/views/home-v2/TimelineListView.tsx
+++ b/FrontEnd/src/app/views/home-v2/TimelineListView.tsx
@@ -4,14 +4,23 @@ import { convertI18nText, I18nText } from "@/common";
import { HttpTimelineInfo } from "@/http/timeline";
import { useTranslation } from "react-i18next";
+import { Link } from "react-router-dom";
interface TimelineListItemProps {
timeline: HttpTimelineInfo;
}
const TimelineListItem: React.FC<TimelineListItemProps> = ({ timeline }) => {
+ const url = React.useMemo(
+ () =>
+ timeline.name.startsWith("@")
+ ? `/users/${timeline.owner.username}`
+ : `/timelines/${timeline.name}`,
+ [timeline]
+ );
+
return (
- <div className="home-v2-timeline-list-item">
+ <div className="home-v2-timeline-list-item home-v2-timeline-list-item-timeline">
<svg className="home-v2-timeline-list-item-line" viewBox="0 0 120 100">
<path
d="M 80,50 m 0,-12 a 12 12 180 1 1 0,24 12 12 180 1 1 0,-24 z M 60,0 h 40 v 100 h -40 z"
@@ -19,12 +28,20 @@ const TimelineListItem: React.FC<TimelineListItemProps> = ({ timeline }) => {
fill="#007bff"
/>
</svg>
- <div>{timeline.title}</div>
+ <div>
+ <div>{timeline.title}</div>
+ <div>
+ <small className="text-secondary">{timeline.description}</small>
+ </div>
+ </div>
+ <Link to={url}>
+ <i className="icon-button bi-arrow-right ml-3" />
+ </Link>
</div>
);
};
-const TimelineListLoading: React.FC = () => {
+const TimelineListArrow: React.FC = () => {
return (
<div>
<div className="home-v2-timeline-list-item">
@@ -73,11 +90,10 @@ const TimelineListView: React.FC<TimelineListViewProps> = ({
</svg>
<h3>{convertI18nText(headerText, t)}</h3>
</div>
- {timelines != null ? (
- timelines.map((t) => <TimelineListItem key={t.name} timeline={t} />)
- ) : (
- <TimelineListLoading />
- )}
+ {timelines != null
+ ? timelines.map((t) => <TimelineListItem key={t.name} timeline={t} />)
+ : null}
+ <TimelineListArrow />
</div>
);
};
diff --git a/FrontEnd/src/app/views/home-v2/home-v2.sass b/FrontEnd/src/app/views/home-v2/home-v2.sass
index a3218f08..56049994 100644
--- a/FrontEnd/src/app/views/home-v2/home-v2.sass
+++ b/FrontEnd/src/app/views/home-v2/home-v2.sass
@@ -2,6 +2,17 @@
display: flex
align-items: center
+.home-v2-timeline-list-item-timeline
+ transition: background 0.8s
+ animation: 0.8s home-v2-timeline-list-item-timeline-enter
+ &:hover
+ background: $gray-200
+
+@keyframes home-v2-timeline-list-item-timeline-enter
+ from
+ transform: translate(-100%,0)
+ opacity: 0
+
.home-v2-timeline-list-item-line
width: 80px
flex-shrink: 0
diff --git a/FrontEnd/src/app/views/home-v2/index.tsx b/FrontEnd/src/app/views/home-v2/index.tsx
index 75c51540..cb3c1428 100644
--- a/FrontEnd/src/app/views/home-v2/index.tsx
+++ b/FrontEnd/src/app/views/home-v2/index.tsx
@@ -8,6 +8,14 @@ import SearchInput from "../common/SearchInput";
import TimelineListView from "./TimelineListView";
import TimelineCreateDialog from "../home/TimelineCreateDialog";
+import { HttpTimelineInfo } from "@/http/timeline";
+import { getHttpHighlightClient } from "@/http/highlight";
+
+const highlightTimelineMessageMap = {
+ loading: "home.loadingHighlightTimelines",
+ done: "home.loadedHighlightTimelines",
+ error: "home.errorHighlightTimelines",
+} as const;
const HomeV2: React.FC = () => {
const history = useHistory();
@@ -20,11 +28,43 @@ const HomeV2: React.FC = () => {
const [dialog, setDialog] = React.useState<"create" | null>(null);
+ const [highlightTimelineState, setHighlightTimelineState] = React.useState<
+ "loading" | "done" | "error"
+ >("loading");
+ const [highlightTimelines, setHighlightTimelines] = React.useState<
+ HttpTimelineInfo[] | undefined
+ >();
+
+ React.useEffect(() => {
+ if (highlightTimelineState === "loading") {
+ let subscribe = true;
+ void getHttpHighlightClient()
+ .list()
+ .then(
+ (data) => {
+ if (subscribe) {
+ setHighlightTimelineState("done");
+ setHighlightTimelines(data);
+ }
+ },
+ () => {
+ if (subscribe) {
+ setHighlightTimelineState("error");
+ setHighlightTimelines(undefined);
+ }
+ }
+ );
+ return () => {
+ subscribe = false;
+ };
+ }
+ }, [highlightTimelineState]);
+
return (
<>
<Container fluid className="px-0">
<Row className="mx-0 my-3 px-2 justify-content-end">
- <Col xs="auto">
+ <Col xs="12" sm="auto">
<SearchInput
value={navText}
onChange={setNavText}
@@ -46,7 +86,10 @@ const HomeV2: React.FC = () => {
/>
</Col>
</Row>
- <TimelineListView headerText="home.loadingHighlightTimelines" />
+ <TimelineListView
+ headerText={highlightTimelineMessageMap[highlightTimelineState]}
+ timelines={highlightTimelines}
+ />
</Container>
{dialog === "create" && (
<TimelineCreateDialog open close={() => setDialog(null)} />