diff --git a/.eslintrc b/.eslintrc index 9515ba9..db78a15 100644 --- a/.eslintrc +++ b/.eslintrc @@ -20,29 +20,12 @@ "import/no-unresolved": "off", "import/prefer-default-export": "off", "jsx-a11y/anchor-has-content": "off", - "jsx-a11y/anchor-is-valid": [ - "error", - { - "aspects": [ - "invalidHref", - "noHref", - "preferButton" - ], - "components": [ - "Link" - ], - "specialLink": [ - "hrefLeft", - "hrefRight", - "to" - ] - } - ], + "jsx-a11y/anchor-is-valid": "off", "jsx-quotes": [ "error", "prefer-single" ], - "max-len": "warn", + "max-len": "off", "no-param-reassign": "warn", "no-plusplus": [ "error", @@ -63,6 +46,8 @@ ], "no-use-before-define": "off", "import/first": "off", - "prefer-destructuring": "off" + "prefer-destructuring": "off", + "jsx-a11y/click-events-have-key-events": "off", + "jsx-a11y/no-static-element-interactions": "off" } } diff --git a/README.md b/README.md index 1e7831b..c4eb14c 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Just go to a reddit thread and change the `reddit` in the URL to `removeddit` to This is a done by comparing the comments found from Reddit API and comments being stored in [Jason Baumgartners](https://pushshift.io/) [Pushshift Reddit API](https://github.com/pushshift/api). The frontend is written in react with redux for state management. There's also a seperate [backend](https://github.com/JubbeArt/removeddit-api) used for storing removed threads and banned subreddits. # Development +Get lastest version of [Node](https://nodejs.org/en/download/current/) + ``` sudo git clone https://github.com/JubbeArt/removeddit.git && cd removeddit npm install diff --git a/server-config/letsencrypt.conf b/production/letsencrypt.conf similarity index 100% rename from server-config/letsencrypt.conf rename to production/letsencrypt.conf diff --git a/server-config/nginx-basic b/production/nginx-basic similarity index 100% rename from server-config/nginx-basic rename to production/nginx-basic diff --git a/server-config/nginx-ssl b/production/nginx-ssl similarity index 100% rename from server-config/nginx-ssl rename to production/nginx-ssl diff --git a/src/js/api/pushshift/index.js b/src/js/api/pushshift/index.js index 45c8ebd..5e6a5d7 100644 --- a/src/js/api/pushshift/index.js +++ b/src/js/api/pushshift/index.js @@ -44,11 +44,13 @@ export const getComments = threadID => { .then(comments => comments.map(comment => { comment._source.id = toBase36(comment._id) + // Missing parent id === direct reply to thread if (!comment._source.parent_id) { - console.error('MISSING PARENT ID') + comment._source.parent_id = threadID + } else { + comment._source.parent_id = toBase36(comment._source.parent_id) } - comment._source.parent_id = toBase36(comment._source.parent_id) return comment._source })) ) diff --git a/src/js/components/Comment.js b/src/js/components/Comment.js index e287c1c..865093e 100644 --- a/src/js/components/Comment.js +++ b/src/js/components/Comment.js @@ -1,7 +1,7 @@ import React from 'react' -import { prettyScore, prettyDate, parse } from 'utils' +import { prettyScore, prettyDate, parse, sortComments } from 'utils' -export default (props) => { +const Comment = (props) => { let commentStyle = 'comment ' if (props.removed) { @@ -18,12 +18,18 @@ export default (props) => { return (
- - + false} className='author'>[–] + + {props.author} {props.deleted && ' (deleted by user)'} + {prettyScore(props.score)} point{(props.score !== 1) && 's'} + {prettyDate(props.created_utc)}
@@ -32,6 +38,16 @@ export default (props) => { reddit ceddit
+
+ {props.replies.map(comment => ( + + ))} +
) } + +export default Comment diff --git a/src/js/components/CommentInfo.js b/src/js/components/CommentInfo.js new file mode 100644 index 0000000..2a0be2a --- /dev/null +++ b/src/js/components/CommentInfo.js @@ -0,0 +1,13 @@ +import React from 'react' + +export default props => ( +
+ + removed comments: {props.removed}/{props.total} ({((100 * props.removed) / props.total).toFixed(1)}%) + +
+ + deleted comments: {props.deleted}/{props.total} ({((100 * props.deleted) / props.total).toFixed(1)}%) + +
+) diff --git a/src/js/components/CommentSection.js b/src/js/components/CommentSection.js index 63cc7ae..521adb4 100644 --- a/src/js/components/CommentSection.js +++ b/src/js/components/CommentSection.js @@ -1,18 +1,81 @@ import React from 'react' +import Comment from 'components/Comment' +import CommentInfo from 'components/CommentInfo' +import SortBy from 'components/SortBy' +import { topSort, bottomSort, newSort, oldSort } from 'utils' -const arrayToLookup = commentList => { +const arrayToLookup = (commentList, removed, deleted) => { + const lookup = {} + + commentList.forEach(comment => { + comment.replies = [] + + if (removed.includes(comment.id)) { + comment.removed = true + } else if (deleted.includes(comment.id)) { + comment.deleted = true + } + + lookup[comment.id] = comment + }) + + return lookup } +const unflatten = (comments, root, removed, deleted) => { + const lookup = arrayToLookup(comments, removed, deleted) + const commentTree = [] + + Object.keys(lookup).forEach(commentID => { + const comment = lookup[commentID] + const parentID = comment.parent_id + + if (parentID === root) { + commentTree.push(comment) + } else { + lookup[parentID].replies.push(comment) + } + }) + + return commentTree +} + +const sortCommentTree = (comments, sortFunction) => { + comments.sort(sortFunction) + + comments.forEach(comment => { + if (comment.replies.length > 0) { + sortCommentTree(comment.replies, sortFunction) + } + }) +} + +const commentSection = (props) => { + const commentTree = unflatten(props.comments, props.root, props.removed, props.deleted) + sortCommentTree(commentTree, newSort)// props.comments.sort(topSort) + -export default (props) => { - const { children } = props console.log('COMMENT SECTION RENDERED') - + console.log(props.root) + console.log(commentTree) return (
-

{props.root}

-

{children}

+ + + {commentTree.map(comment => ( + + ))}
) } + + +export default commentSection diff --git a/src/js/components/SortBy.js b/src/js/components/SortBy.js new file mode 100644 index 0000000..23d466d --- /dev/null +++ b/src/js/components/SortBy.js @@ -0,0 +1,23 @@ +import React from 'react' + +export default props => ( +
+ sorted by: + + + + show: + + +
+) diff --git a/src/js/index.js b/src/js/index.js index 4a9a9ea..ea0aede 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -3,13 +3,12 @@ import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import { store } from 'state' import App from 'App' -// import { setStatusLoading } from 'state' -import '../sass/main.sass' +import '../sass/index.sass' -// ReactDOM.render( -// -// -// , -// document.getElementById('app') -// ) +ReactDOM.render( + + + , + document.getElementById('app') +) diff --git a/src/js/pages/Thread.js b/src/js/pages/Thread.js index 215d90f..677fa5e 100644 --- a/src/js/pages/Thread.js +++ b/src/js/pages/Thread.js @@ -50,14 +50,18 @@ export default class Thread extends React.Component { const pushshiftComments = results[1] this.setState({ pushshiftComments }) + // Extract ids from pushshift response const ids = pushshiftComments.map(comment => comment.id) - + console.log('pushshift:', ids.length) + // Get all the comments from reddit return getRedditComments(ids) }) .then(redditComments => { + console.log('reddit:', redditComments.length) const removed = [] const deleted = [] + // Check what as removed / deleted according to reddit redditComments.forEach(comment => { if (isRemoved(comment.body)) { removed.push(comment.id) @@ -76,11 +80,13 @@ export default class Thread extends React.Component { } render() { + console.log('loading', this.state.loadingComments) + return (
{ - this.state.loadingComments && + !this.state.loadingComments && { return score } + +// Sorting for comments +export const topSort = (commentA, commentB) => { + if (commentA.score > commentB.score) return -1 + if (commentA.score < commentB.score) return 1 + return 0 +} + +export const bottomSort = (commentA, commentB) => { + if (commentA.score < commentB.score) return -1 + if (commentA.score > commentB.score) return 1 + return 0 +} + +export const newSort = (commentA, commentB) => { + if (commentA.created_utc < commentB.created_utc) return -1 + if (commentA.created_utc > commentB.created_utc) return 1 + return 0 +} + +export const oldSort = (commentA, commentB) => { + if (commentA.created_utc < commentB.created_utc) return -1 + if (commentA.created_utc > commentB.created_utc) return 1 + return 0 +} diff --git a/src/sass/about.sass b/src/sass/about.sass index af91164..8055a78 100644 --- a/src/sass/about.sass +++ b/src/sass/about.sass @@ -1,33 +1,33 @@ #main-box - margin: 0 auto - padding: 20px - border-radius: 5px - color: #fff - word-wrap: break-word - max-width: 800px - background-color: #161616 + margin: 0 auto + padding: 20px + border-radius: 5px + color: #fff + word-wrap: break-word + max-width: 800px + background-color: #161616 - h2 - margin: 20px 0px 12px + h2 + margin: 20px 0px 12px - h2.about - margin: 0 - color: $red - h2.todo - color: #239f2b - h2.contact - color: #1b767a + h2.about + margin: 0 + color: $red + h2.todo + color: #239f2b + h2.contact + color: #1b767a - ul - padding-left: 30px - margin: 0 + ul + padding-left: 30px + margin: 0 - .bookmarklet - background: $red - color: #fff - padding: 9px - font-size: large - font-weight: bold - display: inline-block - border-radius: 5px - margin: 0 7px \ No newline at end of file + .bookmarklet + background: $red + color: #fff + padding: 9px + font-size: large + font-weight: bold + display: inline-block + border-radius: 5px + margin: 0 7px \ No newline at end of file diff --git a/src/sass/colors.sass b/src/sass/colors.sass new file mode 100644 index 0000000..735e21c --- /dev/null +++ b/src/sass/colors.sass @@ -0,0 +1,7 @@ +$background: #262626 +$red: #c70300 +$blue: #00007d +$link: #8cb3d9 +$author: #6a98af +$removed: #840c09 +$deleted: #00007d diff --git a/src/sass/comment.sass b/src/sass/comment.sass index 072ed48..a8f9df9 100644 --- a/src/sass/comment.sass +++ b/src/sass/comment.sass @@ -1,46 +1,61 @@ .comment - margin: 0 0 8px 0 - padding: 5px 8px 5px 30px - border: 1px solid #333 - border-radius: 3px - color: #ddd - font-size: 14px + margin: 0 0 8px 0 + padding: 5px 8px 5px 30px + border: 1px solid #333 + border-radius: 3px + color: #ddd + font-size: 14px - .comment-head - font-size: 10px + .comment-head + font-size: 10px - .comment-author - font-weight: bold + .comment-author + font-weight: bold - .comment-score - color: #b4b4b4 - font-weight: bold + .comment-author:not([href]) + color: #828282 - .comment-time - color: #828282 + .comment-score + color: #b4b4b4 + font-weight: bold - .comment-body - max-width: 840px - line-height: 20px - - p - margin: 5px 0 - line-height: 20px - - a:hover - text-decoration: none + .comment-time + color: #828282 - .comment-links - margin-bottom: 6px + .comment-body + max-width: 840px + line-height: 20px + + p + margin: 5px 0 + line-height: 20px + + a:hover + text-decoration: none - .comment-links a - color: #828282 - font-weight: bold - font-size: 10px - margin-right: 4px + .comment-links + margin-bottom: 6px + + .comment-links a + color: #828282 + font-weight: bold + font-size: 10px + margin-right: 4px .comment-odd - background-color: #121212 + background-color: #121212 .comment-even - background-color: #161616 \ No newline at end of file + background-color: #161616 + +#comment-info + margin-top: 13px + font-weight: bold + padding-bottom: 5px + border-bottom: 1px dotted #808080 + font-size: 16px + +#sort-by + color: #828282 + font-size: 12px + margin: 5px 0 10px diff --git a/src/sass/main.sass b/src/sass/common.sass similarity index 60% rename from src/sass/main.sass rename to src/sass/common.sass index c034abf..48d7db9 100644 --- a/src/sass/main.sass +++ b/src/sass/common.sass @@ -1,11 +1,3 @@ -$background: #262626 -$red: #c70300 -$blue: #00007d -$link: #8cb3d9 -$author: #6a98af -$removed: #840c09 -$deleted: #00007d - html, body margin: 0 padding: 0 @@ -16,10 +8,10 @@ html, body margin: 15px .removed - background-color: $removed + background-color: $removed .deleted - background-color: $deleted + background-color: $deleted .removed-text color: $red @@ -43,10 +35,10 @@ a:hover color: inherit text-decoration: none -@import header -@import about -@import comment -@import post -@import thread -@import subreddit -@import search +.space + margin-left: 5px + +select + background: transparent + border: 0 + color: #828282 \ No newline at end of file diff --git a/src/sass/header.sass b/src/sass/header.sass index 545fa07..d84eeee 100644 --- a/src/sass/header.sass +++ b/src/sass/header.sass @@ -1,40 +1,40 @@ header - background-color: $red///*#19171c;/*#181818*/ - display: flex - justify-content: space-between - align-items: center - padding: 10px - - #header - a - color: #fff - - h1 - margin: 7px 0 - text-align: center + background-color: $red///*#19171c;/*#181818*/ + display: flex + justify-content: space-between + align-items: center + padding: 10px + + #header + a + color: #fff + + h1 + margin: 7px 0 + text-align: center - a - transition: color 0.3s - + a + transition: color 0.3s + - a:hover - text-decoration: none - color: #ff8b88 - nav - a - margin: 0 7px - font-size: 20px - - #status - display: flex - justify-content: space-between - align-items: center + a:hover + text-decoration: none + color: #ff8b88 + nav + a + margin: 0 7px + font-size: 20px + + #status + display: flex + justify-content: space-between + align-items: center - #status-text - color: #fff - margin: 0 20px 0 0 + #status-text + color: #fff + margin: 0 20px 0 0 - #status-image - height: 64px - width: 64px - border-radius: 32px \ No newline at end of file + #status-image + height: 64px + width: 64px + border-radius: 32px \ No newline at end of file diff --git a/src/sass/index.sass b/src/sass/index.sass new file mode 100644 index 0000000..5f9c58c --- /dev/null +++ b/src/sass/index.sass @@ -0,0 +1,11 @@ + + +@import colors +@import common +@import header +@import about +@import comment +@import post +@import thread +@import subreddit +@import search diff --git a/src/sass/post.sass b/src/sass/post.sass index b205c04..d89eeca 100644 --- a/src/sass/post.sass +++ b/src/sass/post.sass @@ -1,13 +1,13 @@ #comment-info - color: #ca302c - margin-top: 10px - font-weight: bold - padding-bottom: 5px - border-bottom: 1px dotted #808080 - font-size: 16px + color: #ca302c + margin-top: 10px + font-weight: bold + padding-bottom: 5px + border-bottom: 1px dotted #808080 + font-size: 16px #comment-sort - color: #808080 - font-size: 12px - margin: 5px 0 10px + color: #808080 + font-size: 12px + margin: 5px 0 10px diff --git a/src/sass/search.sass b/src/sass/search.sass index 350236c..f720c3f 100644 --- a/src/sass/search.sass +++ b/src/sass/search.sass @@ -1,52 +1,52 @@ .search-box - font-size: 16px + font-size: 16px - .search-row - padding: 10px 6px 11px - border-bottom: 1px dotted #ccc - min-height: 26px - - .search-left - font-weight: bold - display: inline-block - width: 190px - vertical-align: middle + .search-row + padding: 10px 6px 11px + border-bottom: 1px dotted #ccc + min-height: 26px + + .search-left + font-weight: bold + display: inline-block + width: 190px + vertical-align: middle - input[type="text"] - font-size: 17px - width: 400px - border-radius: 2px - padding-left: 3px - - .radioButton - background: #8a8888 - color: black - border-radius: 3px - display: inline-block - margin-right: 9px - transition: all 0.3s + input[type="text"] + font-size: 17px + width: 400px + border-radius: 2px + padding-left: 3px + + .radioButton + background: #8a8888 + color: black + border-radius: 3px + display: inline-block + margin-right: 9px + transition: all 0.3s - label - padding: 7px 10px 7px 3px - display: inline-block + label + padding: 7px 10px 7px 3px + display: inline-block - input - margin: 0 0 0 5px - height: 35px - display: inline-block - vertical-align: top - - select - padding: 3px - font-size: 15px - border-radius: 2px + input + margin: 0 0 0 5px + height: 35px + display: inline-block + vertical-align: top + + select + padding: 3px + font-size: 15px + border-radius: 2px - input[type="submit"] - margin: 16px auto 0px - display: block - padding: 9px 16px - font-size: 18px - background: #239f2b - border: 0 - border-radius: 2px - color: white \ No newline at end of file + input[type="submit"] + margin: 16px auto 0px + display: block + padding: 9px 16px + font-size: 18px + background: #239f2b + border: 0 + border-radius: 2px + color: white \ No newline at end of file diff --git a/src/sass/subreddit.sass b/src/sass/subreddit.sass index 7bff6ad..4f8c2a6 100644 --- a/src/sass/subreddit.sass +++ b/src/sass/subreddit.sass @@ -1,29 +1,29 @@ .post-rank - min-width: 20px - color: #505050 - font-size: 16px - text-align: right - margin: 14px 4px 0 0 + min-width: 20px + color: #505050 + font-size: 16px + text-align: right + margin: 14px 4px 0 0 .subreddit-info - border-bottom: 1px dotted gray - padding: 5px 10px - color: #ccc - font-size: 14px - margin-bottom: 5px + border-bottom: 1px dotted gray + padding: 5px 10px + color: #ccc + font-size: 14px + margin-bottom: 5px - select - background: #262626 - color: #808080 - font-size: 14px - font-weight: bold - text-decoration: underline - border: 0 + select + background: #262626 + color: #808080 + font-size: 14px + font-weight: bold + text-decoration: underline + border: 0 #pagination - border-top: 1px dotted gray - padding: 5px 10px - color: #ccc - font-size: 16px - span, a - margin: 5px \ No newline at end of file + border-top: 1px dotted gray + padding: 5px 10px + color: #ccc + font-size: 16px + span, a + margin: 5px \ No newline at end of file