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.
This commit is contained in:
Christopher Gurnee 2022-04-08 17:54:32 +00:00
parent 5ea27dd616
commit 69e59a75d2
3 changed files with 30 additions and 10 deletions

View file

@ -18,7 +18,7 @@ export default (props) => {
<Link class="thread-title" to={permalink}>[removed too quickly to be archived]</Link>
<div class="total-comments">
<a href={`https://www.reddit.com${permalink}`}>reddit</a>&nbsp;
<a href={`https://reveddit.com${permalink}`}>reveddit</a>
<a href={`https://www.reveddit.com${permalink}`}>reveddit</a>
</div>
</div>
</div>
@ -76,7 +76,7 @@ export default (props) => {
<span>{props.num_comments} comments</span> :
<Link to={props.permalink}>{props.num_comments}&nbsp;comments</Link>}&nbsp;
<a href={`https://www.reddit.com${props.permalink}`}>reddit</a>&nbsp;
<a href={`https://reveddit.com${props.permalink}`}>reveddit</a>
<a href={`https://www.reveddit.com${props.permalink}`}>reveddit</a>
{props.hasOwnProperty('edited_selftext') &&
<a onClick= {() => setShowEdited(!showEdited)}
onKeyDown={e => e.key == 'Enter' && setShowEdited(!showEdited)}

View file

@ -45,7 +45,8 @@ const Comment = (props) => {
activeClassName='wait'
>parent</NavLink>
:
<a href={`#${props.parent_id}`}>parent</a>
// Use a function, not just an object--state is recreated and scrollBehavior is always initialized
<Link to={() => ({hash: `#${props.parent_id}`, state: {scrollBehavior: 'smooth'}})}>parent</Link>
)
return (
@ -75,9 +76,9 @@ const Comment = (props) => {
<div style={collapsed ? {display: 'none'} : {}}>
<div className='comment-body' dangerouslySetInnerHTML={{ __html: showEdited ? editedInnerHTML : innerHTML }} />
<div className='comment-links'>
<Link to={permalink}>permalink</Link>
<Link to={() => ({pathname: permalink, hash: '#comment-info', state: {scrollBehavior: 'auto'}})}>permalink</Link>
<a href={`https://www.reddit.com${permalink}`}>reddit</a>
<a href={`https://reveddit.com${permalink}`}>reveddit</a>
<a href={`https://www.reveddit.com${permalink}`}>reveddit</a>
{parentlink}
{props.hasOwnProperty('edited_body') &&
<a onClick= {() => setShowEdited(!showEdited)}

View file

@ -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 {
<div>you are viewing a single comment's thread.</div>
{this.state.reloadingComments ?
<div className='faux-link'>view the rest of the comments</div> :
<Link to={linkToRestOfComments}>view the rest of the comments</Link>
<Link to={() => ({
pathname: `/r/${subreddit}/comments/${id}/_/`,
hash: '#comment-info',
state: {scrollBehavior: 'smooth'}}
)}>view the rest of the comments</Link>
}
</div>
}