mirror of
https://github.com/gurnec/removeddit.git
synced 2026-03-11 08:54:27 +00:00
Speed up and clarify the 'load more comments' UI
* only rerender the comments after loading and iff something changes * change text to 'loading...' and make link unclickable while waiting * if all comments are already loaded, rename to 'load new comments'
This commit is contained in:
parent
59df221ff9
commit
aac22ce109
6 changed files with 70 additions and 26 deletions
2
dist/main.css
vendored
2
dist/main.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -93,10 +93,11 @@ export const getComments = async (allComments, threadID, maxComments, after) =>
|
|||
parent_id: c.parent_id?.substring(3) || threadID,
|
||||
link_id: c.link_id?.substring(3) || threadID
|
||||
}))
|
||||
if (comments.length < chunkSize/2 || chunks <= 1)
|
||||
break
|
||||
if (comments.length < chunkSize/2)
|
||||
return [ comments[comments.length - 1].created_utc, true ]
|
||||
if (chunks <= 1)
|
||||
return [ comments[comments.length - 1].created_utc, false ]
|
||||
chunks--
|
||||
after = Math.max(comments[comments.length - 1].created_utc - 1, after + 1)
|
||||
}
|
||||
return comments[comments.length - 1].created_utc
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import Comment from './Comment'
|
||||
import {connect, sort, filter, maxCommentsDefault} from '../../state'
|
||||
import {sort, filter} from '../../state'
|
||||
import {
|
||||
topSort, bottomSort, newSort, oldSort,
|
||||
showRemovedAndDeleted, showRemoved, showDeleted
|
||||
|
|
@ -71,8 +71,7 @@ const filterCommentTree = (comments, filterFunction) => {
|
|||
const commentSection = (props) => {
|
||||
console.time('render comment section')
|
||||
const commentTree = unflatten(props.comments, props.root, props.removed, props.deleted)
|
||||
const {commentFilter, commentSort} = props.global.state
|
||||
const maxCommentsPreferred = props.global.getMaxComments()
|
||||
const {commentFilter, commentSort} = props
|
||||
|
||||
if (commentFilter === filter.removedDeleted) {
|
||||
filterCommentTree(commentTree, showRemovedAndDeleted)
|
||||
|
|
@ -95,26 +94,29 @@ const commentSection = (props) => {
|
|||
|
||||
return (
|
||||
commentTree.length !== 0
|
||||
? <> {commentTree.map(comment => (
|
||||
? commentTree.map(comment => (
|
||||
<Comment
|
||||
key={comment.id}
|
||||
{...comment}
|
||||
depth={0}
|
||||
postAuthor={props.postAuthor}
|
||||
/>
|
||||
))}
|
||||
<p className='load-more'>
|
||||
{maxCommentsPreferred <= maxCommentsDefault / 2 &&
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsPreferred)}>load {maxCommentsPreferred} more comments</a>
|
||||
}
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsDefault)}>load {maxCommentsDefault} more comments</a>
|
||||
{maxCommentsPreferred >= maxCommentsDefault * 2 &&
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsPreferred)}>load {maxCommentsPreferred} more comments</a>
|
||||
}
|
||||
</p>
|
||||
</>
|
||||
))
|
||||
: <p>No comments found</p>
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(commentSection)
|
||||
const areEqual = (prevProps, nextProps) => {
|
||||
if (prevProps.commentFilter !== nextProps.commentFilter ||
|
||||
prevProps.commentSort !== nextProps.commentSort ||
|
||||
prevProps.root !== nextProps.root)
|
||||
return false
|
||||
if (nextProps.reloadingComments)
|
||||
return true
|
||||
return prevProps.total === nextProps.total &&
|
||||
prevProps.removed.length === nextProps.removed.length &&
|
||||
prevProps.deleted.length === nextProps.deleted.length &&
|
||||
prevProps.postAuthor === nextProps.postAuthor
|
||||
}
|
||||
|
||||
export default React.memo(commentSection, areEqual)
|
||||
|
|
|
|||
25
src/pages/thread/LoadMore.js
Normal file
25
src/pages/thread/LoadMore.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react'
|
||||
import {connect, maxCommentsDefault} from '../../state'
|
||||
|
||||
const loadMore = (props) => {
|
||||
const maxCommentsPreferred = props.global.getMaxComments()
|
||||
|
||||
if (props.reloadingComments)
|
||||
return <p className='loading-more'><span>loading...</span></p>
|
||||
else if (props.loadedAllComments)
|
||||
return <p className='load-more'>
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsDefault)}>load new comments</a>
|
||||
</p>
|
||||
else
|
||||
return <p className='load-more'>
|
||||
{maxCommentsPreferred <= maxCommentsDefault / 2 &&
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsPreferred)}>load {maxCommentsPreferred} more comments</a>
|
||||
}
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsDefault)}>load {maxCommentsDefault} more comments</a>
|
||||
{maxCommentsPreferred >= maxCommentsDefault * 2 &&
|
||||
<a onClick={() => props.global.loadMoreComments(maxCommentsPreferred)}>load {maxCommentsPreferred} more comments</a>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
|
||||
export default connect(loadMore)
|
||||
|
|
@ -14,6 +14,7 @@ import Post from '../common/Post'
|
|||
import CommentSection from './CommentSection'
|
||||
import SortBy from './SortBy'
|
||||
import CommentInfo from './CommentInfo'
|
||||
import LoadMore from './LoadMore'
|
||||
|
||||
class Thread extends React.Component {
|
||||
state = {
|
||||
|
|
@ -21,6 +22,7 @@ class Thread extends React.Component {
|
|||
pushshiftCommentLookup: new Map(),
|
||||
removed: [],
|
||||
deleted: [],
|
||||
loadedAllComments: false,
|
||||
loadingComments: true,
|
||||
reloadingComments: false
|
||||
}
|
||||
|
|
@ -87,7 +89,7 @@ class Thread extends React.Component {
|
|||
|
||||
// Get comment ids from pushshift
|
||||
getPushshiftComments(pushshiftCommentLookup, threadID, newCommentCount, after)
|
||||
.then(lastCreatedUtc => {
|
||||
.then(([lastCreatedUtc, loadedAllComments]) => {
|
||||
console.log(`Pushshift: ${pushshiftCommentLookup.size} comments`)
|
||||
const ids = []
|
||||
const missingIds = new Set()
|
||||
|
|
@ -151,6 +153,7 @@ class Thread extends React.Component {
|
|||
pushshiftCommentLookup,
|
||||
removed,
|
||||
deleted,
|
||||
loadedAllComments,
|
||||
loadingComments: false,
|
||||
reloadingComments: false
|
||||
})
|
||||
|
|
@ -186,11 +189,11 @@ class Thread extends React.Component {
|
|||
const root = isSingleComment ? commentID : id
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<Post {...this.state.post} />
|
||||
{
|
||||
(!this.state.loadingComments && root) &&
|
||||
<React.Fragment>
|
||||
<>
|
||||
<CommentInfo
|
||||
total={this.state.pushshiftCommentLookup.size}
|
||||
removed={this.state.removed.length}
|
||||
|
|
@ -211,10 +214,18 @@ class Thread extends React.Component {
|
|||
removed={this.state.removed}
|
||||
deleted={this.state.deleted}
|
||||
postAuthor={isDeleted(author) ? null : author}
|
||||
commentFilter={this.props.global.state.commentFilter} // need to explicitly
|
||||
commentSort={this.props.global.state.commentSort} // pass in these props
|
||||
reloadingComments={this.state.reloadingComments} // to ensure React.memo
|
||||
total={this.state.pushshiftCommentLookup.size} // works correctly
|
||||
/>
|
||||
</React.Fragment>
|
||||
<LoadMore
|
||||
loadedAllComments={this.state.loadedAllComments}
|
||||
reloadingComments={this.state.reloadingComments}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
</React.Fragment>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,8 +143,13 @@
|
|||
|
||||
|
||||
.load-more a
|
||||
color: $author
|
||||
font-weight: bold
|
||||
font-size: 10px
|
||||
margin-left: 16px
|
||||
cursor: pointer
|
||||
|
||||
.loading-more span
|
||||
color: $link
|
||||
font-weight: bold
|
||||
font-size: 10px
|
||||
margin-left: 16px
|
||||
|
|
|
|||
Loading…
Reference in a new issue