diff options
author | crupest <crupest@outlook.com> | 2021-02-13 21:55:47 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-02-13 21:55:47 +0800 |
commit | 2c3b2917c123708f39c1d5288b850a23f0e6042f (patch) | |
tree | e655a7d3b851ee3682db8895d13d2e688d180364 /FrontEnd/src/app/views | |
parent | 50dbdde46eed6f2ff4c9691eea4414c1712af8e5 (diff) | |
download | timeline-2c3b2917c123708f39c1d5288b850a23f0e6042f.tar.gz timeline-2c3b2917c123708f39c1d5288b850a23f0e6042f.tar.bz2 timeline-2c3b2917c123708f39c1d5288b850a23f0e6042f.zip |
...
Diffstat (limited to 'FrontEnd/src/app/views')
7 files changed, 51 insertions, 23 deletions
diff --git a/FrontEnd/src/app/views/timeline-common/Timeline.tsx b/FrontEnd/src/app/views/timeline-common/Timeline.tsx index d41588bb..07ca2924 100644 --- a/FrontEnd/src/app/views/timeline-common/Timeline.tsx +++ b/FrontEnd/src/app/views/timeline-common/Timeline.tsx @@ -15,10 +15,20 @@ export interface TimelineProps { timelineName: string; reloadKey: number; onReload: () => void; + additionalPosts?: HttpTimelinePostInfo[]; + onLoad?: () => void; } const Timeline: React.FC<TimelineProps> = (props) => { - const { timelineName, className, style, reloadKey, onReload } = props; + const { + timelineName, + className, + style, + reloadKey, + onReload, + additionalPosts, + onLoad, + } = props; const [posts, setPosts] = React.useState< | HttpTimelinePostInfo[] @@ -59,6 +69,12 @@ const Timeline: React.FC<TimelineProps> = (props) => { }; }, [timelineName, reloadKey]); + React.useEffect(() => { + if (Array.isArray(posts)) { + onLoad?.(); + } + }, [posts, additionalPosts, onLoad]); + switch (posts) { case "loading": return ( @@ -91,7 +107,12 @@ const Timeline: React.FC<TimelineProps> = (props) => { </div> ); default: - return <TimelinePostListView posts={posts} onReload={onReload} />; + return ( + <TimelinePostListView + posts={[...posts, ...(additionalPosts ?? [])]} + onReload={onReload} + /> + ); } }; diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx index 6a8dd63c..92eb0887 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplate.tsx @@ -29,15 +29,6 @@ export default function TimelinePageTemplate<TManageItem>( null ); - // TODO: Auto scroll. - // const [scrollBottomKey, _setScrollBottomKey] = React.useState<number>(0); - - // React.useEffect(() => { - // if (scrollBottomKey > 0) { - // window.scrollTo(0, document.body.scrollHeight); - // } - // }, [scrollBottomKey]); - const [timeline, setTimeline] = React.useState< HttpTimelineInfo | "loading" | "offline" | "notexist" | "error" >("loading"); diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx index d133bd34..7fcf2d52 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePageTemplateUI.tsx @@ -4,7 +4,7 @@ import { Spinner } from "react-bootstrap"; import { getAlertHost } from "@/services/alert"; -import { HttpTimelineInfo } from "@/http/timeline"; +import { HttpTimelineInfo, HttpTimelinePostInfo } from "@/http/timeline"; import Timeline from "./Timeline"; import TimelinePostEdit from "./TimelinePostEdit"; @@ -47,10 +47,20 @@ export default function TimelinePageTemplateUI<TManageItems>( const { t } = useTranslation(); + const scrollToBottom = React.useCallback(() => { + window.scrollTo(0, document.body.scrollHeight); + }, []); + const [bottomSpaceHeight, setBottomSpaceHeight] = React.useState<number>(0); const [timelineReloadKey, setTimelineReloadKey] = React.useState<number>(0); - const reloadTimeline = (): void => setTimelineReloadKey((old) => old + 1); + + const [newPosts, setNewPosts] = React.useState<HttpTimelinePostInfo[]>([]); + + const reloadTimeline = (): void => { + setTimelineReloadKey((old) => old + 1); + setNewPosts([]); + }; const onPostEditHeightChange = React.useCallback((height: number): void => { setBottomSpaceHeight(height); @@ -129,6 +139,8 @@ export default function TimelinePageTemplateUI<TManageItems>( timelineName={timeline.name} reloadKey={timelineReloadKey} onReload={reloadTimeline} + additionalPosts={newPosts} + onLoad={scrollToBottom} /> </div> {timeline.postable ? ( @@ -141,7 +153,9 @@ export default function TimelinePageTemplateUI<TManageItems>( className="fixed-bottom" timeline={timeline} onHeightChange={onPostEditHeightChange} - onPosted={reloadTimeline} + onPosted={(newPost) => { + setNewPosts((old) => [...old, newPost]); + }} /> </> ) : null} diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx index 69954040..67871c48 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePostContentView.tsx @@ -1,5 +1,6 @@ import React from "react"; import { Spinner } from "react-bootstrap"; +import clsx from "clsx"; import { HttpNetworkError } from "@/http/common"; import { getHttpTimelineClient, HttpTimelinePostInfo } from "@/http/timeline"; @@ -38,7 +39,7 @@ const TextView: React.FC<TimelinePostContentViewProps> = (props) => { return () => { subscribe = false; }; - }, [post]); + }, [post.timelineName, post.id]); if (error != null) { // TODO: i18n @@ -69,7 +70,7 @@ const ImageView: React.FC<TimelinePostContentViewProps> = (props) => { post.timelineName, post.id )} - className={className} + className={clsx(className, "timeline-content-image")} style={style} /> ); diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx index 7c49e5bb..3ce7d53b 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx @@ -8,6 +8,7 @@ import { UiLogicError } from "@/common"; import { getHttpTimelineClient, HttpTimelineInfo, + HttpTimelinePostInfo, HttpTimelinePostPostRequestData, } from "@/http/timeline"; @@ -83,7 +84,7 @@ const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => { export interface TimelinePostEditProps { className?: string; timeline: HttpTimelineInfo; - onPosted: () => void; + onPosted: (newPost: HttpTimelinePostInfo) => void; onHeightChange?: (height: number) => void; } @@ -161,14 +162,14 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => { dataList: [requestData], }) .then( - (_) => { + (data) => { if (kind === "text") { setText(""); window.localStorage.removeItem(draftLocalStorageKey); } setState("input"); setKind("text"); - onPosted(); + onPosted(data); }, (_) => { pushAlert({ diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostListView.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostListView.tsx index 63255619..961b4667 100644 --- a/FrontEnd/src/app/views/timeline-common/TimelinePostListView.tsx +++ b/FrontEnd/src/app/views/timeline-common/TimelinePostListView.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { Fragment } from "react"; import clsx from "clsx"; import { HttpTimelinePostInfo } from "@/http/timeline"; @@ -53,7 +53,7 @@ const TimelinePostListView: React.FC<TimelinePostListViewProps> = (props) => { <div style={style} className={clsx("timeline", className)}> {groupedPosts.map((group) => { return ( - <> + <Fragment key={group.date.toDateString()}> <TimelineDateLabel date={group.date} /> {group.posts.map((post) => { return ( @@ -65,7 +65,7 @@ const TimelinePostListView: React.FC<TimelinePostListViewProps> = (props) => { /> ); })} - </> + </Fragment> ); })} </div> diff --git a/FrontEnd/src/app/views/timeline-common/timeline-common.sass b/FrontEnd/src/app/views/timeline-common/timeline-common.sass index 642301b0..1a7bfc3b 100644 --- a/FrontEnd/src/app/views/timeline-common/timeline-common.sass +++ b/FrontEnd/src/app/views/timeline-common/timeline-common.sass @@ -127,7 +127,7 @@ $timeline-line-color-current: #36c2e6 white-space: pre-line .timeline-content-image - max-width: 60% + max-width: 80% max-height: 200px .timeline-date-item |