diff --git a/dist/main.css b/dist/main.css index 6d8c07d..b666ba0 100644 --- a/dist/main.css +++ b/dist/main.css @@ -1 +1 @@ -html,body{margin:0;padding:0;background-color:#262626;font-family:verdana,arial,helvetica,sans-serif}.main{margin:15px;color:#fff}.removed{background-color:#840c09}.deleted{background-color:#00007d}.removed-text{color:#c70300}.deleted-text{color:blue}a{color:#8cb3d9}a:link,a:visited,a:active{text-decoration:none}a:hover{text-decoration:underline}.author{color:#6a98af}.author:not([href]){color:inherit;text-decoration:none}.space{margin-left:5px}select{background:transparent;border:0;color:#828282}header{background-color:#c70300;display:flex;justify-content:space-between;align-items:center;padding:10px}header #header a{color:#fff}header #header h1{margin:7px 0;text-align:center}header #header h1 a{transition:color .3s}header #header h1 a:hover{text-decoration:none;color:#ff8b88}header #header nav a{margin:0 7px;font-size:20px}header #status{display:flex;justify-content:space-between;align-items:center}header #status #status-text,header #status #status-helpurl{color:#fff;margin:0 20px 0 0}header #status #status-helpurl{font-size:20px}header #status #status-image{height:64px;width:64px;border-radius:32px}#main-box{margin:0 auto;padding:20px;border-radius:5px;color:#ddd;word-wrap:break-word;max-width:800px;background-color:#161616}#main-box h2{margin:20px 0px 12px}#main-box h2.about{margin:0;color:#c70300}#main-box h2.todo{color:#239f2b}#main-box h2.contact{color:#1b767a}#main-box .highlighted{animation:highlighted-anim 3s ease-out}@keyframes highlighted-anim{0%{background-color:#add8e6}100%{background-color:#161616}}#main-box .question{font-size:18px;color:#add8e6}#main-box ul{padding-left:30px;margin:0}#main-box .bookmarklet{background:#c70300;color:#fff;padding:9px;font-size:large;font-weight:bold;display:inline-block;border-radius:5px;margin:0 7px}.comment{min-width:240px;margin:0 0 8px 0;padding:5px 8px 5px 20px;border:1px solid #333;border-radius:3px;color:#ddd;font-size:14px}.comment .comment-head{font-size:10px}.comment .comment-collapse{cursor:pointer}.comment .comment-collapsed span,.comment .comment-collapsed a:not(.comment-collapse){color:#828282;font-style:oblique}.comment .comment-author{font-weight:bold}.comment .comment-author:not([href]){color:#828282}.comment .comment-poster{color:#ddd;background-color:#0055df;padding:0 2px;border-radius:3px}.comment .comment-score{color:#b4b4b4;font-weight:bold}.comment .comment-time{color:#828282}.comment .comment-body{max-width:840px;line-height:20px}.comment .comment-body p{margin:5px 0;line-height:20px}.comment .comment-body a:hover{text-decoration:none}.comment .comment-links{margin-bottom:6px}.comment .comment-links a{color:#828282;font-weight:bold;font-size:10px;margin-right:4px;cursor:pointer}.comment-odd{background-color:#121212}.comment-even{background-color:#161616}#comment-info{margin-top:13px;font-weight:bold;padding-bottom:5px;border-bottom:1px dotted gray;font-size:16px}#sort-by{color:#828282;font-size:12px;margin:5px 0 10px}#comment-info{color:#ca302c;margin-top:10px;font-weight:bold;padding-bottom:5px;border-bottom:1px dotted gray;font-size:16px}#comment-sort,#comment-sort input{color:gray;font-size:12px;margin:5px 0;background-color:#262626}#comment-sort input{border-color:#767676}#comment-sort input[type=number]{width:54px;appearance:textfield}#comment-sort input[type=number]:hover,#comment-sort input[type=number]:focus{appearance:none}#comment-sort input:hover,#comment-sort input:focus,#comment-sort select:hover,#comment-sort select:focus{color:#ddd}#comment-sort option{color:#ddd;background-color:#262626}.thread{display:flex;flex-grow:1;margin-bottom:7px;border-radius:1px;padding-top:6px}.thread .thumbnail{width:70px;margin-right:3px;margin-top:-2px}.thread .thumbnail img{border-radius:1px}.thread .thumbnail-default{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1099px;background-repeat:no-repeat;height:50px}.thread .thumbnail-self{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1267px;background-repeat:no-repeat;height:50px}.thread .thumbnail-image{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1043px;background-repeat:no-repeat;height:50px}.thread .thumbnail-nsfw{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1155px;background-repeat:no-repeat;height:50px}.thread .thread-score-box{margin:0 7px;width:43px}.thread .vote{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAcCAMAAADC4sagAAABFFBMVEUjJCQiIiIjIyMkIiIkJCQlJSUlJicmJiYnIyEnJycnKCsoKCgpLC8rIyErKyssMDUvLy8wJCAwMDAxMTEyMjI0NDQ2NjY3JR83Nzc5OTk7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NGRkZISEhKSkpKV2tLS0tMTExOTk5PT09QYHdSUlJTU1NVVVVWVlZXV1dXaINYWFhaWlpabYlbW1tecpBgYGBhYWFid5dkZGRle5xlfJ1pgKRrhKhshKlshapuLhZwirFyjbV0j7h4lL97mcZ9MBR/nsyCo9OOMxGcNQ+eNg+kNw6sOA2vOAy0OQy7Ogq/OwrBOwrDPAnLPQjPPQfTPgfbPwXjQQTrQgPzQwLKxGgxAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlJREFUOMu9lF1TwjAQRTcMvmeQOi1QPmxFBQTxW1ERUUFEUVRU/P//w9yGmBTFyZPnpXNmbju76W6IJM8Uw49rLa6Tz4mpq/mCqY3Gvqnj6XQ61lp0mGd8favCwx2tow8wUlpwGWOZrNJKjXO+UVc6fJcMZzV7IswSOU/qej0l0rwyq33wphhAM1kWkcy70GB7mUfUNqG9V02PyPMTMs2Wig5RaTctwzxVXyPqvJh0VkJBIKJ4huncCRAvHOEZyGKegO4a6UDrIdLGCT4C6/QDsE7fA+v0HdAadWqk0SH9D3sgXkm4uJIDYKTFnwwXd3kMrNOnwDp9BmzS5QuTshN1iDRwfkxV9VJTJXLzSWYM+NzEEjWvFE2oGvCE7/2yDeL8riWzM8xmorRazLlNI2rdgNb3ZYLF1Es/t8VE7X6/39Yqlt4tLLwhiLq3XVNLfumP24fo3Opm+wLGCVa252Y8tQAAAABJRU5ErkJggg==);background-repeat:no-repeat;margin-left:auto;margin-right:auto;width:15px;height:14px;cursor:pointer}.thread .upvote{background-position:-15px 0px;margin-top:2px}.thread .downvote{background-position:-15px -14px;margin-top:2px}.thread .thread-score{color:#646464;font-size:13px;font-weight:bold;text-align:center}.thread .thread-content{flex:1;float:left;margin-left:3px}.thread .link-flair{display:inline-block;color:#c8c8c8;background-color:#404040;margin-right:5px;border:1px solid #4d4d4d;border-radius:2px;padding:0 2px;font-size:10px}.thread .thread-title{color:#a6a6a6;margin-right:5px}.thread .thread-title:hover{text-decoration:none}.thread .domain{color:#888;font-size:10px}.thread .thread-selftext{border:1px solid #666;border-radius:7px;margin:5px 0 7px;padding:5px 10px;max-width:840px;color:#ddd;font-size:14px}.thread .thread-selftext p{margin:5px 0;line-height:20px}.thread .thread-selftext a:hover{text-decoration:none}.thread .thread-selftext p:first-child{margin-top:0px}.thread .thread-selftext p:last-child{margin-bottom:0px}.thread .thread-image{max-width:768px;max-height:768px}.thread .thread-info{color:#828282;font-size:10px;margin-top:2px}.thread .total-comments{color:#828282;font-size:10px;margin:4px 0}.thread .grey-link,.thread .grey-link:link,.thread .grey-link:visited,.thread .grey-link:hover,.thread .grey-link:focus,.thread .grey-link:active{color:#828282;margin-right:4px}.view-rest-of-comment{background-color:#264d73;border-color:#2966a3;font-size:13px;padding:10px;color:#ccc;margin-bottom:10px}.post-rank{min-width:20px;color:#505050;font-size:16px;text-align:right;margin:14px 4px 0 0} +html,body{margin:0;padding:0;background-color:#262626;font-family:verdana,arial,helvetica,sans-serif}.wait{cursor:wait}.main{margin:15px;color:#fff}.removed{background-color:#840c09}.deleted{background-color:#00007d}.removed-text{color:#c70300}.deleted-text{color:blue}a{color:#8cb3d9}a:link,a:visited,a:active{text-decoration:none}a:hover{text-decoration:underline}.author{color:#6a98af}.author:not([href]){color:inherit;text-decoration:none}.space{margin-left:5px}select{background:transparent;border:0;color:#828282}header{background-color:#c70300;display:flex;justify-content:space-between;align-items:center;padding:10px}header #header a{color:#fff}header #header h1{margin:7px 0;text-align:center}header #header h1 a{transition:color .3s}header #header h1 a:hover{text-decoration:none;color:#ff8b88}header #header nav a{margin:0 7px;font-size:20px}header #status{display:flex;justify-content:space-between;align-items:center}header #status #status-text,header #status #status-helpurl{color:#fff;margin:0 20px 0 0}header #status #status-helpurl{font-size:20px}header #status #status-image{height:64px;width:64px;border-radius:32px}#main-box{margin:0 auto;padding:20px;border-radius:5px;color:#ddd;word-wrap:break-word;max-width:800px;background-color:#161616}#main-box h2{margin:20px 0px 12px}#main-box h2.about{margin:0;color:#c70300}#main-box h2.todo{color:#239f2b}#main-box h2.contact{color:#1b767a}#main-box .highlighted{animation:highlighted-anim 3s ease-out}@keyframes highlighted-anim{0%{background-color:#add8e6}100%{background-color:#161616}}#main-box .question{font-size:18px;color:#add8e6}#main-box ul{padding-left:30px;margin:0}#main-box .bookmarklet{background:#c70300;color:#fff;padding:9px;font-size:large;font-weight:bold;display:inline-block;border-radius:5px;margin:0 7px}.comment{min-width:240px;margin:0 0 8px 0;padding:5px 8px 5px 20px;border:1px solid #333;border-radius:3px;color:#ddd;font-size:14px}.comment .comment-head{font-size:10px}.comment .comment-collapse{cursor:pointer}.comment .comment-collapsed span,.comment .comment-collapsed a:not(.comment-collapse){color:#828282;font-style:oblique}.comment .comment-author{font-weight:bold}.comment .comment-author:not([href]){color:#828282}.comment .comment-poster{color:#ddd;background-color:#0055df;padding:0 2px;border-radius:3px}.comment .comment-score{color:#b4b4b4;font-weight:bold}.comment .comment-time{color:#828282}.comment .comment-body{max-width:840px;line-height:20px}.comment .comment-body p{margin:5px 0;line-height:20px}.comment .comment-body a:hover{text-decoration:none}.comment .comment-links{margin-bottom:6px}.comment .comment-links a{color:#828282;font-weight:bold;font-size:10px;margin-right:4px;cursor:pointer}.comment-odd{background-color:#121212}.comment-even{background-color:#161616}#comment-info{margin-top:13px;font-weight:bold;padding-bottom:5px;border-bottom:1px dotted gray;font-size:16px}#sort-by{color:#828282;font-size:12px;margin:5px 0 10px}#comment-info{color:#ca302c;margin-top:10px;font-weight:bold;padding-bottom:5px;border-bottom:1px dotted gray;font-size:16px}#comment-sort,#comment-sort input{color:gray;font-size:12px;margin:5px 0;background-color:#262626}#comment-sort input{border-color:#767676}#comment-sort input[type=number]{width:54px;appearance:textfield}#comment-sort input[type=number]:hover,#comment-sort input[type=number]:focus{appearance:none}#comment-sort input:hover,#comment-sort input:focus,#comment-sort select:hover,#comment-sort select:focus{color:#ddd}#comment-sort option{color:#ddd;background-color:#262626}.thread{display:flex;flex-grow:1;margin-bottom:7px;border-radius:1px;padding-top:6px}.thread .thumbnail{width:70px;margin-right:3px;margin-top:-2px}.thread .thumbnail img{border-radius:1px}.thread .thumbnail-default{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1099px;background-repeat:no-repeat;height:50px}.thread .thumbnail-self{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1267px;background-repeat:no-repeat;height:50px}.thread .thumbnail-image{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1043px;background-repeat:no-repeat;height:50px}.thread .thumbnail-nsfw{background-image:url("https://www.redditstatic.com/sprite-reddit.6Om8v6KMv28.png");background-position:0px -1155px;background-repeat:no-repeat;height:50px}.thread .thread-score-box{margin:0 7px;width:43px}.thread .vote{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAcCAMAAADC4sagAAABFFBMVEUjJCQiIiIjIyMkIiIkJCQlJSUlJicmJiYnIyEnJycnKCsoKCgpLC8rIyErKyssMDUvLy8wJCAwMDAxMTEyMjI0NDQ2NjY3JR83Nzc5OTk7Ozs8PDw9PT0+Pj4/Pz9AQEBBQUFCQkJDQ0NGRkZISEhKSkpKV2tLS0tMTExOTk5PT09QYHdSUlJTU1NVVVVWVlZXV1dXaINYWFhaWlpabYlbW1tecpBgYGBhYWFid5dkZGRle5xlfJ1pgKRrhKhshKlshapuLhZwirFyjbV0j7h4lL97mcZ9MBR/nsyCo9OOMxGcNQ+eNg+kNw6sOA2vOAy0OQy7Ogq/OwrBOwrDPAnLPQjPPQfTPgfbPwXjQQTrQgPzQwLKxGgxAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlJREFUOMu9lF1TwjAQRTcMvmeQOi1QPmxFBQTxW1ERUUFEUVRU/P//w9yGmBTFyZPnpXNmbju76W6IJM8Uw49rLa6Tz4mpq/mCqY3Gvqnj6XQ61lp0mGd8favCwx2tow8wUlpwGWOZrNJKjXO+UVc6fJcMZzV7IswSOU/qej0l0rwyq33wphhAM1kWkcy70GB7mUfUNqG9V02PyPMTMs2Wig5RaTctwzxVXyPqvJh0VkJBIKJ4huncCRAvHOEZyGKegO4a6UDrIdLGCT4C6/QDsE7fA+v0HdAadWqk0SH9D3sgXkm4uJIDYKTFnwwXd3kMrNOnwDp9BmzS5QuTshN1iDRwfkxV9VJTJXLzSWYM+NzEEjWvFE2oGvCE7/2yDeL8riWzM8xmorRazLlNI2rdgNb3ZYLF1Es/t8VE7X6/39Yqlt4tLLwhiLq3XVNLfumP24fo3Opm+wLGCVa252Y8tQAAAABJRU5ErkJggg==);background-repeat:no-repeat;margin-left:auto;margin-right:auto;width:15px;height:14px;cursor:pointer}.thread .upvote{background-position:-15px 0px;margin-top:2px}.thread .downvote{background-position:-15px -14px;margin-top:2px}.thread .thread-score{color:#646464;font-size:13px;font-weight:bold;text-align:center}.thread .thread-content{flex:1;float:left;margin-left:3px}.thread .link-flair{display:inline-block;color:#c8c8c8;background-color:#404040;margin-right:5px;border:1px solid #4d4d4d;border-radius:2px;padding:0 2px;font-size:10px}.thread .thread-title{color:#a6a6a6;margin-right:5px}.thread .thread-title:hover{text-decoration:none}.thread .domain{color:#888;font-size:10px}.thread .thread-selftext{border:1px solid #666;border-radius:7px;margin:5px 0 7px;padding:5px 10px;max-width:840px;color:#ddd;font-size:14px}.thread .thread-selftext p{margin:5px 0;line-height:20px}.thread .thread-selftext a:hover{text-decoration:none}.thread .thread-selftext p:first-child{margin-top:0px}.thread .thread-selftext p:last-child{margin-bottom:0px}.thread .thread-image{max-width:768px;max-height:768px}.thread .thread-info{color:#828282;font-size:10px;margin-top:2px}.thread .total-comments{color:#828282;font-size:10px;margin:4px 0}.thread .grey-link,.thread .grey-link:link,.thread .grey-link:visited,.thread .grey-link:hover,.thread .grey-link:focus,.thread .grey-link:active{color:#828282;margin-right:4px}.view-rest-of-comment{background-color:#264d73;border-color:#2966a3;font-size:13px;padding:10px;color:#ccc;margin-bottom:10px}.post-rank{min-width:20px;color:#505050;font-size:16px;text-align:right;margin:14px 4px 0 0} diff --git a/src/api/pushshift/index.js b/src/api/pushshift/index.js index aef8458..b9bd991 100644 --- a/src/api/pushshift/index.js +++ b/src/api/pushshift/index.js @@ -67,10 +67,8 @@ export const getPost = async threadID => { } } -export const getComments = async (threadID, maxComments) => { - let chunks = Math.ceil(maxComments / chunkSize) - let after = 0, comments - const allComments = new Map() +export const getComments = async (allComments, threadID, maxComments, after) => { + let chunks = Math.ceil(maxComments / chunkSize), comments while (true) { let delay = 0 @@ -97,8 +95,8 @@ export const getComments = async (threadID, maxComments) => { })) if (comments.length < chunkSize/2 || chunks <= 1) break - chunks -= 1 + chunks-- after = Math.max(comments[comments.length - 1].created_utc - 1, after + 1) } - return allComments + return comments[comments.length - 1].created_utc } diff --git a/src/pages/thread/SortBy.js b/src/pages/thread/SortBy.js index 105f5c1..02c75c6 100644 --- a/src/pages/thread/SortBy.js +++ b/src/pages/thread/SortBy.js @@ -42,7 +42,7 @@ const sortBy = props => { { ...(isFirefox ? { onClick: e => e.target.focus() } : {}) } defaultValue={props.global.state.maxComments} type='number' maxLength='5' required min='100' max={maxCommentsLimit} step='100' /> - {reloadVisible && <> + {reloadVisible && !props.reloadingComments && <> {props.global.loadMaxComments(); setReloadVisible(false)}} type='button' value='Reload' /> } diff --git a/src/pages/thread/index.js b/src/pages/thread/index.js index 0f5bf39..3ea81ff 100644 --- a/src/pages/thread/index.js +++ b/src/pages/thread/index.js @@ -21,7 +21,8 @@ class Thread extends React.Component { pushshiftCommentLookup: new Map(), removed: [], deleted: [], - loadingComments: true + loadingComments: true, + reloadingComments: false } componentDidMount () { @@ -67,32 +68,30 @@ class Thread extends React.Component { this.props.global.setLoading('Loading comments from Pushshift...') }) - this.getComments() + this.getComments(this.props.global.state.maxComments, 0) } componentDidUpdate () { - if (this.props.global.state.maxComments > this.curMaxComments) { + const newCommentCount = this.props.global.state.maxComments - this.curMaxComments + if (newCommentCount > 0) { this.curMaxComments = this.props.global.state.maxComments - this.setState({ - pushshiftCommentLookup: new Map(), - removed: [], - deleted: [], - loadingComments: true - }) - this.props.global.setLoading('Loading comments from Pushshift...') - this.getComments() + this.setState({reloadingComments: true}) + this.props.global.setLoading('Loading more comments from Pushshift...') + this.getComments(newCommentCount, this.lastCreatedUtc - 1) } } - getComments () { + getComments (newCommentCount, after) { const { threadID } = this.props.match.params + const pushshiftCommentLookup = this.state.pushshiftCommentLookup // Get comment ids from pushshift - getPushshiftComments(threadID, this.props.global.state.maxComments) - .then(pushshiftCommentLookup => { + getPushshiftComments(pushshiftCommentLookup, threadID, newCommentCount, after) + .then(lastCreatedUtc => { console.log(`Pushshift: ${pushshiftCommentLookup.size} comments`) const ids = [] const missingIds = new Set() + this.lastCreatedUtc = lastCreatedUtc // Extract ids from pushshift response pushshiftCommentLookup.forEach(comment => { @@ -152,7 +151,8 @@ class Thread extends React.Component { pushshiftCommentLookup, removed, deleted, - loadingComments: false + loadingComments: false, + reloadingComments: false }) }) .catch(e => { @@ -196,7 +196,9 @@ class Thread extends React.Component { removed={this.state.removed.length} deleted={this.state.deleted.length} /> - + {isSingleComment &&
you are viewing a single comment's thread.
diff --git a/src/sass/common.sass b/src/sass/common.sass index 9a0fea4..3b95b08 100644 --- a/src/sass/common.sass +++ b/src/sass/common.sass @@ -4,6 +4,9 @@ html, body background-color: $background font-family: verdana, arial, helvetica, sans-serif +.wait + cursor: wait + .main margin: 15px color: white diff --git a/src/state.js b/src/state.js index 9edb4b4..f766894 100644 --- a/src/state.js +++ b/src/state.js @@ -56,14 +56,24 @@ class GlobalState extends Container { loadMaxComments = () => this.setState({maxComments: get(maxCommentsKey, maxCommentsDefault)}) - setSuccess = () => this.setState({statusText: '', statusHelpUrl: undefined, statusImage: '/images/success.png'}) - setLoading = (text) => this.setState({statusText: text, statusImage: '/images/loading.gif'}) + setSuccess = () => { + this.setState({statusText: '', statusHelpUrl: undefined, statusImage: '/images/success.png'}) + document.body.classList.remove('wait') + } + setLoading = text => { + this.setState({statusText: text, statusImage: '/images/loading.gif'}) + document.body.classList.add('wait') + } setError = (error, helpUrl = undefined) => { this.setState({statusText: error.message, statusImage: '/images/error.png'}) if (helpUrl) this.setState({statusHelpUrl: helpUrl}) + document.body.classList.remove('wait') + } + clearStatus = () => { + this.setState({statusText: '', statusHelpUrl: undefined, statusImage: undefined}) + document.body.classList.remove('wait') } - clearStatus = () => this.setState({statusText: '', statusHelpUrl: undefined, statusImage: undefined}) } // A redux-like connect function for Unstated