diff options
Diffstat (limited to 'FrontEnd/src/app/views/timeline-common/Timeline.tsx')
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/Timeline.tsx | 176 |
1 files changed, 79 insertions, 97 deletions
diff --git a/FrontEnd/src/app/views/timeline-common/Timeline.tsx b/FrontEnd/src/app/views/timeline-common/Timeline.tsx index 288be141..d41588bb 100644 --- a/FrontEnd/src/app/views/timeline-common/Timeline.tsx +++ b/FrontEnd/src/app/views/timeline-common/Timeline.tsx @@ -1,116 +1,98 @@ import React from "react"; -import clsx from "clsx"; import { - TimelineInfo, - TimelinePostInfo, - timelineService, -} from "@/services/timeline"; -import { useUser } from "@/services/user"; -import { pushAlert } from "@/services/alert"; + HttpForbiddenError, + HttpNetworkError, + HttpNotFoundError, +} from "@/http/common"; +import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; -import TimelineItem from "./TimelineItem"; -import TimelineTop from "./TimelineTop"; -import TimelineDateItem from "./TimelineDateItem"; - -function dateEqual(left: Date, right: Date): boolean { - return ( - left.getDate() == right.getDate() && - left.getMonth() == right.getMonth() && - left.getFullYear() == right.getFullYear() - ); -} +import TimelinePostListView from "./TimelinePostListView"; export interface TimelineProps { className?: string; style?: React.CSSProperties; - timeline: TimelineInfo; - posts: TimelinePostInfo[]; + timelineName: string; + reloadKey: number; + onReload: () => void; } const Timeline: React.FC<TimelineProps> = (props) => { - const { timeline, posts } = props; + const { timelineName, className, style, reloadKey, onReload } = props; - const user = useUser(); + const [posts, setPosts] = React.useState< + | HttpTimelinePostInfo[] + | "loading" + | "offline" + | "notexist" + | "forbid" + | "error" + >("loading"); - const [showMoreIndex, setShowMoreIndex] = React.useState<number>(-1); + React.useEffect(() => { + let subscribe = true; - const groupedPosts = React.useMemo< - { date: Date; posts: (TimelinePostInfo & { index: number })[] }[] - >(() => { - const result: { - date: Date; - posts: (TimelinePostInfo & { index: number })[]; - }[] = []; - let index = 0; - for (const post of posts) { - const { time } = post; - if (result.length === 0) { - result.push({ date: time, posts: [{ ...post, index }] }); - } else { - const lastGroup = result[result.length - 1]; - if (dateEqual(lastGroup.date, time)) { - lastGroup.posts.push({ ...post, index }); - } else { - result.push({ date: time, posts: [{ ...post, index }] }); + setPosts("loading"); + + void getHttpTimelineClient() + .listPost(timelineName) + .then( + (data) => { + if (subscribe) setPosts(data); + }, + (error) => { + if (error instanceof HttpNetworkError) { + setPosts("offline"); + } else if (error instanceof HttpForbiddenError) { + setPosts("forbid"); + } else if (error instanceof HttpNotFoundError) { + setPosts("notexist"); + } else { + console.error(error); + setPosts("error"); + } } - } - index++; - } - return result; - }, [posts]); + ); + + return () => { + subscribe = false; + }; + }, [timelineName, reloadKey]); - return ( - <div style={props.style} className={clsx("timeline", props.className)}> - <TimelineTop height="56px" /> - {groupedPosts.map((group) => { - return ( - <> - <TimelineDateItem date={group.date} /> - {group.posts.map((post) => { - const deletable = timelineService.hasModifyPostPermission( - user, - timeline, - post - ); - return ( - <TimelineItem - post={post} - key={post.id} - current={posts.length - 1 === post.index} - more={ - deletable - ? { - isOpen: showMoreIndex === post.index, - toggle: () => - setShowMoreIndex((old) => - old === post.index ? -1 : post.index - ), - onDelete: () => { - timelineService - .deletePost(timeline.name, post.id) - .catch(() => { - pushAlert({ - type: "danger", - message: { - type: "i18n", - key: "timeline.deletePostFailed", - }, - }); - }); - }, - } - : undefined - } - onClick={() => setShowMoreIndex(-1)} - /> - ); - })} - </> - ); - })} - </div> - ); + switch (posts) { + case "loading": + return ( + <div className={className} style={style}> + Loading. + </div> + ); + case "offline": + return ( + <div className={className} style={style}> + Offline. + </div> + ); + case "notexist": + return ( + <div className={className} style={style}> + Not exist. + </div> + ); + case "forbid": + return ( + <div className={className} style={style}> + Forbid. + </div> + ); + case "error": + return ( + <div className={className} style={style}> + Error. + </div> + ); + default: + return <TimelinePostListView posts={posts} onReload={onReload} />; + } }; export default Timeline; |