From c40fdd0eeb04622999c4d51f3ff5d32c598095c6 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 9 Jun 2020 17:54:41 +0800 Subject: fix(front): Attempt to fix scroll problem in timeline page. --- Timeline/ClientApp/src/timeline/Timeline.tsx | 4 +++- Timeline/ClientApp/src/timeline/TimelineItem.tsx | 12 +++++++--- .../src/timeline/TimelinePageTemplate.tsx | 9 -------- .../src/timeline/TimelinePageTemplateUI.tsx | 27 +++++++++++++++++++++- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Timeline/ClientApp/src/timeline/Timeline.tsx b/Timeline/ClientApp/src/timeline/Timeline.tsx index acc3ba0a..a2c14815 100644 --- a/Timeline/ClientApp/src/timeline/Timeline.tsx +++ b/Timeline/ClientApp/src/timeline/Timeline.tsx @@ -18,13 +18,14 @@ export interface TimelineProps { className?: string; posts: TimelinePostInfoEx[]; onDelete: TimelineDeleteCallback; + onLoad?: () => void; } const Timeline: React.FC = (props) => { const user = useUser(); const avatarVersion = useAvatarVersion(); - const { posts, onDelete } = props; + const { posts, onDelete, onLoad } = props; const [indexShowDeleteButton, setIndexShowDeleteButton] = React.useState< number @@ -83,6 +84,7 @@ const Timeline: React.FC = (props) => { } onClick={onItemClick} avatarVersion={av} + onLoad={onLoad} /> ); }); diff --git a/Timeline/ClientApp/src/timeline/TimelineItem.tsx b/Timeline/ClientApp/src/timeline/TimelineItem.tsx index 7d488826..b10e6aca 100644 --- a/Timeline/ClientApp/src/timeline/TimelineItem.tsx +++ b/Timeline/ClientApp/src/timeline/TimelineItem.tsx @@ -55,6 +55,7 @@ export interface TimelineItemProps { }; onClick?: () => void; avatarVersion?: number; + onLoad?: () => void; } const TimelineItem: React.FC = (props) => { @@ -62,7 +63,8 @@ const TimelineItem: React.FC = (props) => { const current = props.current === true; - const { more } = props; + const { more, onLoad + } = props; const avatarUrl = useAvatarUrlWithGivenVersion( props.avatarVersion, @@ -117,7 +119,7 @@ const TimelineItem: React.FC = (props) => { className="float-right float-sm-left mx-2" to={'/users/' + props.post.author.username} > - + {(() => { const { content } = props.post; @@ -125,7 +127,11 @@ const TimelineItem: React.FC = (props) => { return content.text; } else { return ( - + ); } })()} diff --git a/Timeline/ClientApp/src/timeline/TimelinePageTemplate.tsx b/Timeline/ClientApp/src/timeline/TimelinePageTemplate.tsx index 2cfb4341..f8721985 100644 --- a/Timeline/ClientApp/src/timeline/TimelinePageTemplate.tsx +++ b/Timeline/ClientApp/src/timeline/TimelinePageTemplate.tsx @@ -114,15 +114,6 @@ export default function TimelinePageTemplate< }; }, [name, service, user, t, props.dataVersion, props.notFoundI18nKey]); - React.useEffect(() => { - if (posts != null) { - window.scrollTo( - 0, - document.body.scrollHeight || document.documentElement.scrollHeight - ); - } - }, [posts]); - const closeDialog = React.useCallback((): void => { setDialog(null); }, []); diff --git a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx index 6d834832..cd9393c2 100644 --- a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Spinner } from 'reactstrap'; import { useTranslation } from 'react-i18next'; +import { Subject } from 'rxjs'; import { getAlertHost } from '../common/alert-service'; @@ -67,6 +68,26 @@ export default function TimelinePageTemplateUI< } }, []); + const onLoadSubject = React.useMemo(() => new Subject(), []); + const triggerLoadEvent = React.useCallback(() => { + onLoadSubject.next(null); + }, [onLoadSubject]); + + React.useEffect(() => { + let jumpToBottom = true; + const timerTag = window.setTimeout(() => { + jumpToBottom = false; + }, 1000); + const subscription = onLoadSubject.subscribe(() => { + if (jumpToBottom) + window.scrollTo(0, document.body.getBoundingClientRect().height); + }); + return () => { + clearTimeout(timerTag); + subscription.unsubscribe(); + }; + }, [onLoadSubject, timeline, props.posts]); + const [cardHeight, setCardHeight] = React.useState(0); const onCardHeightChange = React.useCallback((height: number) => { @@ -104,7 +125,11 @@ export default function TimelinePageTemplateUI< ); } else { timelineBody = ( - + ); if (props.onPost != null) { timelineBody = ( -- cgit v1.2.3 From 0fd5c2026e266a8bf5f120cdd21b4cd5a5bae755 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 10 Jun 2020 00:24:16 +0800 Subject: Rename. --- Timeline/ClientApp/src/timeline/Timeline.tsx | 6 +++--- Timeline/ClientApp/src/timeline/TimelineItem.tsx | 9 ++++----- Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx | 14 +++++++------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Timeline/ClientApp/src/timeline/Timeline.tsx b/Timeline/ClientApp/src/timeline/Timeline.tsx index a2c14815..f6ff8949 100644 --- a/Timeline/ClientApp/src/timeline/Timeline.tsx +++ b/Timeline/ClientApp/src/timeline/Timeline.tsx @@ -18,14 +18,14 @@ export interface TimelineProps { className?: string; posts: TimelinePostInfoEx[]; onDelete: TimelineDeleteCallback; - onLoad?: () => void; + onResize?: () => void; } const Timeline: React.FC = (props) => { const user = useUser(); const avatarVersion = useAvatarVersion(); - const { posts, onDelete, onLoad } = props; + const { posts, onDelete, onResize } = props; const [indexShowDeleteButton, setIndexShowDeleteButton] = React.useState< number @@ -84,7 +84,7 @@ const Timeline: React.FC = (props) => { } onClick={onItemClick} avatarVersion={av} - onLoad={onLoad} + onResize={onResize} /> ); }); diff --git a/Timeline/ClientApp/src/timeline/TimelineItem.tsx b/Timeline/ClientApp/src/timeline/TimelineItem.tsx index b10e6aca..215c7b12 100644 --- a/Timeline/ClientApp/src/timeline/TimelineItem.tsx +++ b/Timeline/ClientApp/src/timeline/TimelineItem.tsx @@ -55,7 +55,7 @@ export interface TimelineItemProps { }; onClick?: () => void; avatarVersion?: number; - onLoad?: () => void; + onResize?: () => void; } const TimelineItem: React.FC = (props) => { @@ -63,8 +63,7 @@ const TimelineItem: React.FC = (props) => { const current = props.current === true; - const { more, onLoad - } = props; + const { more, onResize } = props; const avatarUrl = useAvatarUrlWithGivenVersion( props.avatarVersion, @@ -119,7 +118,7 @@ const TimelineItem: React.FC = (props) => { className="float-right float-sm-left mx-2" to={'/users/' + props.post.author.username} > - + {(() => { const { content } = props.post; @@ -128,7 +127,7 @@ const TimelineItem: React.FC = (props) => { } else { return ( diff --git a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx index cd9393c2..8fc3815b 100644 --- a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx @@ -68,17 +68,17 @@ export default function TimelinePageTemplateUI< } }, []); - const onLoadSubject = React.useMemo(() => new Subject(), []); - const triggerLoadEvent = React.useCallback(() => { - onLoadSubject.next(null); - }, [onLoadSubject]); + const resizeSubject = React.useMemo(() => new Subject(), []); + const triggerResizeEvent = React.useCallback(() => { + resizeSubject.next(null); + }, [resizeSubject]); React.useEffect(() => { let jumpToBottom = true; const timerTag = window.setTimeout(() => { jumpToBottom = false; }, 1000); - const subscription = onLoadSubject.subscribe(() => { + const subscription = resizeSubject.subscribe(() => { if (jumpToBottom) window.scrollTo(0, document.body.getBoundingClientRect().height); }); @@ -86,7 +86,7 @@ export default function TimelinePageTemplateUI< clearTimeout(timerTag); subscription.unsubscribe(); }; - }, [onLoadSubject, timeline, props.posts]); + }, [resizeSubject, timeline, props.posts]); const [cardHeight, setCardHeight] = React.useState(0); @@ -128,7 +128,7 @@ export default function TimelinePageTemplateUI< ); if (props.onPost != null) { -- cgit v1.2.3 From 5f9f27fd7001df347ab65e0cba849e583db31dc8 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 10 Jun 2020 00:40:32 +0800 Subject: Finally one. --- .../src/timeline/TimelinePageTemplateUI.tsx | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx index 8fc3815b..1cd772c2 100644 --- a/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/timeline/TimelinePageTemplateUI.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Spinner } from 'reactstrap'; import { useTranslation } from 'react-i18next'; -import { Subject } from 'rxjs'; +import { Subject, fromEvent } from 'rxjs'; import { getAlertHost } from '../common/alert-service'; @@ -74,17 +74,23 @@ export default function TimelinePageTemplateUI< }, [resizeSubject]); React.useEffect(() => { - let jumpToBottom = true; - const timerTag = window.setTimeout(() => { - jumpToBottom = false; - }, 1000); - const subscription = resizeSubject.subscribe(() => { - if (jumpToBottom) - window.scrollTo(0, document.body.getBoundingClientRect().height); - }); + let scrollToBottom = true; + const disableScrollToBottom = (): void => { + scrollToBottom = false; + }; + + const subscriptions = [ + fromEvent(window, 'wheel').subscribe(disableScrollToBottom), + fromEvent(window, 'pointerdown').subscribe(disableScrollToBottom), + resizeSubject.subscribe(() => { + if (scrollToBottom) { + window.scrollTo(0, document.body.scrollHeight); + } + }), + ]; + return () => { - clearTimeout(timerTag); - subscription.unsubscribe(); + subscriptions.forEach((s) => s.unsubscribe()); }; }, [resizeSubject, timeline, props.posts]); -- cgit v1.2.3