From 69e59a75d2ba5198f2240a0598b61f6847e2e538 Mon Sep 17 00:00:00 2001 From: Christopher Gurnee Date: Fri, 8 Apr 2022 17:54:32 +0000 Subject: [PATCH] Improve scrolling with parent and permalinks Visiting a permalink (from an internal or external link) now scrolls to just past the post, and both parent and permalinks scroll smoothly where appropriate; it makes sense for internal permalinks to immediately jump. --- src/pages/common/Post.js | 4 ++-- src/pages/thread/Comment.js | 7 ++++--- src/pages/thread/index.js | 29 ++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/pages/common/Post.js b/src/pages/common/Post.js index 3857463..6c547cb 100644 --- a/src/pages/common/Post.js +++ b/src/pages/common/Post.js @@ -18,7 +18,7 @@ export default (props) => { [removed too quickly to be archived]
reddit  - reveddit + reveddit
@@ -76,7 +76,7 @@ export default (props) => { {props.num_comments} comments : {props.num_comments} comments}  reddit  - reveddit + reveddit {props.hasOwnProperty('edited_selftext') && setShowEdited(!showEdited)} onKeyDown={e => e.key == 'Enter' && setShowEdited(!showEdited)} diff --git a/src/pages/thread/Comment.js b/src/pages/thread/Comment.js index ada629f..3aaf702 100644 --- a/src/pages/thread/Comment.js +++ b/src/pages/thread/Comment.js @@ -45,7 +45,8 @@ const Comment = (props) => { activeClassName='wait' >parent : - parent + // Use a function, not just an object--state is recreated and scrollBehavior is always initialized + ({hash: `#${props.parent_id}`, state: {scrollBehavior: 'smooth'}})}>parent ) return ( @@ -75,9 +76,9 @@ const Comment = (props) => {
- permalink + ({pathname: permalink, hash: '#comment-info', state: {scrollBehavior: 'auto'}})}>permalink reddit - reveddit + reveddit {parentlink} {props.hasOwnProperty('edited_body') && setShowEdited(!showEdited)} diff --git a/src/pages/thread/index.js b/src/pages/thread/index.js index ab40de4..3da586d 100644 --- a/src/pages/thread/index.js +++ b/src/pages/thread/index.js @@ -214,6 +214,11 @@ class Thread extends React.Component { this.contigs.unshift({firstCreated: EARLIEST_CREATED}) this.getComments(maxComments) }) + + // Set the scroll location to just below the post if not already set (only with permalinks) + if (!this.props.location.hash) + this.props.location.hash = '#comment-info' + this.props.location.state = {scrollBehavior: 'smooth'} } } @@ -243,6 +248,7 @@ class Thread extends React.Component { } componentDidUpdate () { + let { loadingComments } = this.state // If the max-to-download Reload button or 'load more comments' was clicked const { loadingMoreComments } = this.props.global.state @@ -255,12 +261,13 @@ class Thread extends React.Component { this.getComments(loadingMoreComments, true) // Otherwise if we're loading a comment tree we haven't downloaded yet - } else if (!this.state.loadingComments && !this.state.reloadingComments && !this.updateCurContig()) { + } else if (!loadingComments && !this.state.reloadingComments && !this.updateCurContig()) { // If we haven't downloaded from the earliest available yet (not a permalink) const { commentID } = this.props.match.params if (commentID === undefined) { - this.setState({loadingComments: true}) + loadingComments = true + this.setState({loadingComments}) this.props.global.setLoading('Loading comments...') console.time('Load comments') this.contigs.unshift({firstCreated: EARLIEST_CREATED}) @@ -296,7 +303,8 @@ class Thread extends React.Component { this.setCurContig(insertBefore - 1) // (this was the failed earlier attempt) console.timeEnd('Load comments') this.props.global.setSuccess() - this.setState({pushshiftCommentLookup, loadingComments: false, reloadingComments: false}) + loadingComments = false + this.setState({pushshiftCommentLookup, loadingComments, reloadingComments: false}) } } else createdUtcNotFound = true @@ -316,6 +324,14 @@ class Thread extends React.Component { }) } } + + if (!loadingComments && this.props.location.state?.scrollBehavior) { + const { location } = this.props + const id = location.hash.substring(1) + if (id) + document.getElementById(id)?.scrollIntoView({behavior: location.state.scrollBehavior}) + delete location.state + } } // Before calling, either create (and set to current) a new contig to begin downloading @@ -484,7 +500,6 @@ class Thread extends React.Component { const reloadingComments = this.state.loadingComments || this.state.reloadingComments || this.props.global.state.loadingMoreComments - const linkToRestOfComments = `/r/${subreddit}/comments/${id}/_/` const isSingleComment = commentID !== undefined const root = isSingleComment ? commentID : id @@ -510,7 +525,11 @@ class Thread extends React.Component {
you are viewing a single comment's thread.
{this.state.reloadingComments ?
view the rest of the comments
: - view the rest of the comments + ({ + pathname: `/r/${subreddit}/comments/${id}/_/`, + hash: '#comment-info', + state: {scrollBehavior: 'smooth'}} + )}>view the rest of the comments }
}