mirror of
https://github.com/gurnec/removeddit.git
synced 2026-03-11 08:54:27 +00:00
Switch from JS Standard Style to plain ESLint
The codebase hasn't been checked against Standard in ages, so remove it and configure plain ESLint and eslint-plugin-react instead. Also fix a few small bugs discovered by ESLint and plugin-react.
This commit is contained in:
parent
763516b19d
commit
529162bec0
12 changed files with 255 additions and 2542 deletions
38
.eslintrc.json
Normal file
38
.eslintrc.json
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended"
|
||||
],
|
||||
"overrides": [
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"rules": {
|
||||
"react/prop-types": "off",
|
||||
"no-constant-condition": ["error", { "checkLoops": false }]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
},
|
||||
"componentWrapperFunctions": [
|
||||
"connect"
|
||||
],
|
||||
"linkComponents": [
|
||||
{"name": "Link", "linkAttribute": "to"},
|
||||
{"name": "NavLink", "linkAttribute": "to"}
|
||||
]
|
||||
}
|
||||
}
|
||||
2659
package-lock.json
generated
2659
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -19,13 +19,11 @@
|
|||
"url": "https://github.com/gurnec/removeddit/issues"
|
||||
},
|
||||
"homepage": "https://github.com/gurnec/removeddit#readme",
|
||||
"standard": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --mode development",
|
||||
"build": "webpack --mode production",
|
||||
"css": "sass -s compressed src/sass/index.sass >dist/main.css && sass -s compressed node_modules/css-toggle-switch/dist/toggle-switch-px.css >>dist/main.css"
|
||||
"css": "sass -s compressed src/sass/index.sass >dist/main.css && sass -s compressed node_modules/css-toggle-switch/dist/toggle-switch-px.css >>dist/main.css",
|
||||
"eslint": "eslint src/*.js 'src/api/**' 'src/pages/**'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ali-tas/htmldiff-js": "^1.1.3",
|
||||
|
|
@ -48,8 +46,8 @@
|
|||
"babel-loader": "^8.2.5",
|
||||
"css-toggle-switch": "^4.1.0",
|
||||
"eslint": "^8.25.0",
|
||||
"eslint-plugin-react": "^7.31.10",
|
||||
"sass": "^1.55.0",
|
||||
"standard": "^16.0.4",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^4.11.1"
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export const getComments = async (callback, threadID, maxComments, after = 0, be
|
|||
return getComments(callback, threadID, maxComments, 1503014401, before)
|
||||
firstChunk = false
|
||||
|
||||
const loadedAllComments = response.metadata.hasOwnProperty('total_results') ?
|
||||
const loadedAllComments = Object.prototype.hasOwnProperty.call(response.metadata, 'total_results') ?
|
||||
response.metadata.results_returned >= response.metadata.total_results :
|
||||
comments.length < chunkSize/2
|
||||
if (comments.length)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import About from './pages/about'
|
|||
import Thread from './pages/thread'
|
||||
import NotFound from './pages/404'
|
||||
|
||||
/* global __dirname */ // an eslint directive
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider>
|
||||
<BrowserRouter basename={__dirname}>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
|
||||
export default () => (
|
||||
<h2>404 Error - Not found</h2>
|
||||
)
|
||||
export default function NotFound() {
|
||||
return <h2>404 Error - Not found</h2>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,23 +43,23 @@ const About = props => {
|
|||
</p>
|
||||
<p>
|
||||
Created by <a href='https://github.com/JubbeArt/'>Jesper Wrang</a> and
|
||||
uses <a href='https://pushshift.io/'>Jason Baumgartner's service</a> for getting removed comments.
|
||||
uses <a href='https://pushshift.io/'>Jason Baumgartner's service</a> for getting removed comments.
|
||||
</p>
|
||||
<h2 className='todo'>FAQ</h2>
|
||||
<div id='delete' className={hash == '#delete' ? 'highlighted' : undefined}>
|
||||
<b className='question'><Link to='/about#delete'>Q:</Link> I posted some sensitive information on Reddit. Can you delete this from your page?</b>
|
||||
<p>
|
||||
No, I can't remove anything myself since I am not the not the one storing all the deleted comments.
|
||||
No, I can't remove anything myself since I am not the not the one storing all the deleted comments.
|
||||
This is done by an external service called Pushshift.io.
|
||||
If you want something sensitive removed permanently you should follow the <a href='https://www.reddit.com/r/pushshift/comments/pat409/online_removal_request_form_for_removal_requests/'>instructions here</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div id='removeddit' className={hash == '#removeddit' ? 'highlighted' : undefined}>
|
||||
<b className='question'><Link to='/about#removeddit'>Q:</Link> Didn't this site used to be named Removeddit?</b>
|
||||
<b className='question'><Link to='/about#removeddit'>Q:</Link> Didn't this site used to be named Removeddit?</b>
|
||||
<p>
|
||||
The Removeddit site stopped working a short while ago, and this site was made to partially replace it.
|
||||
All creddit for the software which makes this site possible goes to the original author, Jesper Wrang.
|
||||
Any bugs or problems are due to this site's operator.
|
||||
Any bugs or problems are due to this site's operator.
|
||||
In particular, Unddit does not currently support browsing subreddits, only specific posts.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -69,23 +69,23 @@ const About = props => {
|
|||
This page is only possible because of the amazing work done by Jason.
|
||||
His service <a href='https://pushshift.io/'>Pushshift.io</a> actively listens for new comments on Reddit and stores them in a database.
|
||||
Then sites like Unddit and Reveddit can fetch these comments from Pushshift.
|
||||
Unddit knows what comments Reddit shows (from Reddit's API) and what comments should be shown (from Pushshift's API).
|
||||
Unddit knows what comments Reddit shows (from Reddit's API) and what comments should be shown (from Pushshift's API).
|
||||
By comparing the comments from these 2 APIs, it can figure out what has been deleted and removed.
|
||||
</p>
|
||||
</div>
|
||||
<div id='firefox' className={hash == '#firefox' ? 'highlighted' : undefined}>
|
||||
<b className='question'><Link to='/about#firefox'>Q:</Link> Why doesn't it work in Firefox?</b>
|
||||
<b className='question'><Link to='/about#firefox'>Q:</Link> Why doesn't it work in Firefox?</b>
|
||||
<p>
|
||||
If you have enabled Strict Enhanced Tracking Protection in Firefox, this will prevent Unddit from contacting Reddit's API.
|
||||
If you have enabled Strict Enhanced Tracking Protection in Firefox, this will prevent Unddit from contacting Reddit's API.
|
||||
Luckily there is an easy workaround.
|
||||
Click on the shield symbol on the left side of the address bar, and then switch off Enhanced Tracking Protection for this site.
|
||||
It will still be enabled for other sites.
|
||||
</p>
|
||||
</div>
|
||||
<div id='edge' className={hash == '#edge' ? 'highlighted' : undefined}>
|
||||
<b className='question'><Link to='/about#edge'>Q:</Link> Why doesn't it work in Edge?</b>
|
||||
<b className='question'><Link to='/about#edge'>Q:</Link> Why doesn't it work in Edge?</b>
|
||||
<p>
|
||||
If you have enabled Strict Tracking Protection in Edge, this will prevent Unddit from contacting Reddit's API.
|
||||
If you have enabled Strict Tracking Protection in Edge, this will prevent Unddit from contacting Reddit's API.
|
||||
Luckily there is an easy workaround.
|
||||
Click on the padlock symbol on the left side of the address bar, and then switch off Tracking Protection for this site.
|
||||
It will still be enabled for other sites.
|
||||
|
|
@ -101,18 +101,18 @@ const About = props => {
|
|||
</p>
|
||||
</div>
|
||||
<div id='difference' className={hash == '#difference' ? 'highlighted' : undefined}>
|
||||
<b className='question'><Link to='/about#difference'>Q:</Link> What's the difference between Ceddit and Removeddit/Unddit?</b>
|
||||
<b className='question'><Link to='/about#difference'>Q:</Link> What's the difference between Ceddit and Removeddit/Unddit?</b>
|
||||
<p>
|
||||
Not much. Removeddit was created as a temporary replacement for Ceddit, at a time when Ceddit didn't work.
|
||||
Not much. Removeddit was created as a temporary replacement for Ceddit, at a time when Ceddit didn't work.
|
||||
Jesper thought this was necessary since he used Ceddit more then Reddit itself.
|
||||
Months later Ceddit was fixed, but he didn't see any reason to remove what he had built.
|
||||
Months later Ceddit was fixed, but he didn't see any reason to remove what he had built.
|
||||
Today both sites live side by side and strive for the same goal.
|
||||
</p>
|
||||
<div>
|
||||
There are some minor differences in them though:
|
||||
<ul>
|
||||
<li>
|
||||
Ceddit respects user-made deletions while Removeddit does not. This decision was made early on and I feel like it's too late to change now.
|
||||
Ceddit respects user-made deletions while Removeddit does not. This decision was made early on and I feel like it's too late to change now.
|
||||
If I had created Removeddit today I might had thought more about what was right here.
|
||||
</li>
|
||||
<li>
|
||||
|
|
@ -120,7 +120,7 @@ const About = props => {
|
|||
Removeddit also uses significantly less JavaScript on the page which also should make the page load faster.
|
||||
</li>
|
||||
<li>
|
||||
Ceddit provides user lookup while Removeddit doesn't.
|
||||
Ceddit provides user lookup while Removeddit doesn't.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import { prettyScore, prettyDate, prettyTimeDiff, exactDateTime, parse, redditTh
|
|||
isDeleted, isRemoved, editedModes, editedTitles } from '../../utils'
|
||||
import { Diff } from '@ali-tas/htmldiff-js'
|
||||
|
||||
export default (props) => {
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
const Post = (props) => {
|
||||
if (!props.title) {
|
||||
const permalink = `/r/${props.subreddit}/comments/${props.id}/`
|
||||
return <div className={props.removed ? 'thread removed' : 'thread'} key={props.removed ? 'post-removed' : 'post-empty'}>
|
||||
|
|
@ -59,15 +61,15 @@ export default (props) => {
|
|||
|
||||
const innerHTML = Array(editedModes.length)
|
||||
if (props.removed && isRemoved(props.selftext)) {
|
||||
if (!props.hasOwnProperty('retrieved_utc') && !props.hasOwnProperty('retrieved_on') || !props.hasOwnProperty('created_utc')) {
|
||||
if (!hasOwnProperty.call(props, 'retrieved_utc') && !hasOwnProperty.call(props, 'retrieved_on') || !hasOwnProperty.call(props, 'created_utc')) {
|
||||
innerHTML[editedModes.orig] = '<p>[removed too quickly to be archived]</p>'
|
||||
} else {
|
||||
const retrieved = props.hasOwnProperty('retrieved_utc') ? props.retrieved_utc : props.retrieved_on;
|
||||
const retrieved = hasOwnProperty.call(props, 'retrieved_utc') ? props.retrieved_utc : props.retrieved_on;
|
||||
innerHTML[editedModes.orig] = `<p>[removed within ${prettyTimeDiff(retrieved - props.created_utc)}]</p>`
|
||||
}
|
||||
} else if (props.selftext && (props.is_self || !isDeleted(props.selftext))) {
|
||||
innerHTML[editedModes.orig] = parse(props.selftext)
|
||||
if (props.hasOwnProperty('edited_selftext')) {
|
||||
if (hasOwnProperty.call(props, 'edited_selftext')) {
|
||||
innerHTML[editedModes.edited] = parse(props.edited_selftext)
|
||||
innerHTML[editedModes.rich] = Diff.execute(innerHTML[editedModes.orig], innerHTML[editedModes.edited])
|
||||
}
|
||||
|
|
@ -83,7 +85,7 @@ export default (props) => {
|
|||
<Link to={props.permalink} replace={props.isLocFullPost}>{props.num_comments} comments</Link>
|
||||
<a href={`https://www.reddit.com${props.permalink}`}>reddit</a>
|
||||
<a href={`https://www.reveddit.com${props.permalink}`}>reveddit</a>
|
||||
{props.hasOwnProperty('edited_selftext') &&
|
||||
{hasOwnProperty.call(props, 'edited_selftext') &&
|
||||
<a onClick= {() => setEditedMode((editedMode + 1) % editedModes.length)}
|
||||
onKeyDown={e => e.key == 'Enter' && setEditedMode((editedMode + 1) % editedModes.length)}
|
||||
tabIndex= {0}
|
||||
|
|
@ -129,3 +131,5 @@ export default (props) => {
|
|||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default Post
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { prettyScore, prettyDate, prettyTimeDiff, exactDateTime,
|
|||
parse, isRemoved, editedModes, editedTitles } from '../../utils'
|
||||
import { Diff } from '@ali-tas/htmldiff-js'
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
|
||||
const Comment = (props) => {
|
||||
let commentStyle = 'comment '
|
||||
|
||||
|
|
@ -20,23 +22,23 @@ const Comment = (props) => {
|
|||
|
||||
const innerHTML = Array(editedModes.length)
|
||||
if (props.removed && isRemoved(props.body)) {
|
||||
if (!props.hasOwnProperty('retrieved_utc') && !props.hasOwnProperty('retrieved_on') || !props.hasOwnProperty('created_utc')) {
|
||||
if (!hasOwnProperty.call(props, 'retrieved_utc') && !hasOwnProperty.call(props, 'retrieved_on') || !hasOwnProperty.call(props, 'created_utc')) {
|
||||
innerHTML[editedModes.orig] = '<p>[removed too quickly to be archived]</p>'
|
||||
} else if (props.created_utc < 1627776000) { // Aug 1 2021
|
||||
const retrieved = props.hasOwnProperty('retrieved_utc') ? props.retrieved_utc : props.retrieved_on;
|
||||
const retrieved = hasOwnProperty.call(props, 'retrieved_utc') ? props.retrieved_utc : props.retrieved_on;
|
||||
innerHTML[editedModes.orig] = `<p>[removed within ${prettyTimeDiff(retrieved - props.created_utc)}]</p>`
|
||||
}
|
||||
// After around Aug 1 2021, Pushshift began updating comments from Reddit after around
|
||||
// 24-48 hours, including removing(?) comments that were removed from Reddit. The presence
|
||||
// of either retrieved_utc or retrieved_on can currently be used to test for this behaviour.
|
||||
else if (props.hasOwnProperty('retrieved_utc')) {
|
||||
else if (hasOwnProperty.call(props, 'retrieved_utc')) {
|
||||
innerHTML[editedModes.orig] = `<p>[removed within ${prettyTimeDiff(props.retrieved_utc - props.created_utc)}]</p>`
|
||||
} else {
|
||||
innerHTML[editedModes.orig] = `<p>[either removed too quickly, or <a href='https://www.reddit.com/r/pushshift/comments/pgzdav/the_api_now_appears_to_rewrite_nearly_all/'>removed(?) from archive</a> after ${prettyTimeDiff(props.retrieved_on - props.created_utc, true)}]</p>`
|
||||
}
|
||||
} else {
|
||||
innerHTML[editedModes.orig] = parse(props.body)
|
||||
if (props.hasOwnProperty('edited_body')) {
|
||||
if (hasOwnProperty.call(props, 'edited_body')) {
|
||||
innerHTML[editedModes.edited] = parse(props.edited_body)
|
||||
innerHTML[editedModes.rich] = Diff.execute(innerHTML[editedModes.orig], innerHTML[editedModes.edited])
|
||||
}
|
||||
|
|
@ -80,7 +82,7 @@ const Comment = (props) => {
|
|||
<span className='space' />
|
||||
{props.created_utc &&
|
||||
<span className='comment-time' title={exactDateTime(props.created_utc)}>{prettyDate(props.created_utc)}</span>}
|
||||
{(props.hasOwnProperty('edited_body') || props.edited) &&
|
||||
{(hasOwnProperty.call(props, 'edited_body') || props.edited) &&
|
||||
<span className='comment-time' title={props.edited ? exactDateTime(props.edited) : 'within 3 minutes'}
|
||||
>* (last edited {prettyDate(props.edited ? props.edited : props.created_utc)})</span>}
|
||||
</div>
|
||||
|
|
@ -91,7 +93,7 @@ const Comment = (props) => {
|
|||
<a href={`https://www.reddit.com${permalink}`}>reddit</a>
|
||||
<a href={`https://www.reveddit.com${permalink}`}>reveddit</a>
|
||||
{parentlink}
|
||||
{props.hasOwnProperty('edited_body') &&
|
||||
{hasOwnProperty.call(props, 'edited_body') &&
|
||||
<a onClick= {() => setEditedMode((editedMode + 1) % editedModes.length)}
|
||||
onKeyDown={e => e.key == "Enter" && setEditedMode((editedMode + 1) % editedModes.length)}
|
||||
tabIndex= {0}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import React from 'react'
|
|||
|
||||
const getProcent = (part, total) => (total === 0 ? '0.0' : ((100 * part) / total).toFixed(1))
|
||||
|
||||
export default props => (
|
||||
<div id='comment-info'>
|
||||
export default function CommentInfo(props) {
|
||||
return <div id='comment-info'>
|
||||
<span className='nowrap removed-text'>
|
||||
removed comments: {props.removed}/{props.total} ({getProcent(props.removed, props.total)}%)
|
||||
</span>
|
||||
|
|
@ -11,4 +11,4 @@ export default props => (
|
|||
deleted comments: {props.deleted}/{props.total} ({getProcent(props.deleted, props.total)}%)
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,11 +97,11 @@ class Thread extends React.Component {
|
|||
// the comment's ids must have already been updated by fullnamesToShortIDs()
|
||||
useRedditComment (comment) {
|
||||
if (isRemoved(comment.body)) {
|
||||
this.state.removed++
|
||||
commentHint.removed = true
|
||||
this.state.removed++ // eslint-disable-line react/no-direct-mutation-state
|
||||
comment.removed = true
|
||||
} else if (isDeleted(comment.body)) {
|
||||
this.state.deleted++
|
||||
commentHint.deleted = true
|
||||
this.state.deleted++ // eslint-disable-line react/no-direct-mutation-state
|
||||
comment.deleted = true
|
||||
}
|
||||
this.state.pushshiftCommentLookup.set(comment.id, comment)
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ class Thread extends React.Component {
|
|||
componentDidMount () {
|
||||
const { subreddit, threadID, commentID } = this.props.match.params
|
||||
const { location } = this.props
|
||||
this.state.post = { subreddit, id: threadID }
|
||||
this.setState({ post: {subreddit, id: threadID} })
|
||||
this.props.global.setLoading('Loading post...')
|
||||
console.time('Load comments')
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ class Thread extends React.Component {
|
|||
if (comment?.link_id != threadID) {
|
||||
console.timeEnd('Load comments')
|
||||
this.props.global.setError({ message: 'Invalid permalink' })
|
||||
this.state.loadingComments = false
|
||||
this.setState({loadingComments: false})
|
||||
console.error('link_id mismatch:', comment)
|
||||
return
|
||||
}
|
||||
|
|
@ -659,7 +659,7 @@ class Thread extends React.Component {
|
|||
<>
|
||||
{isSingleComment &&
|
||||
<div className='view-rest-of-comment'>
|
||||
<div>you are viewing a single comment's thread.</div><div>
|
||||
<div>you are viewing a single comment's thread.</div><div>
|
||||
{this.state.reloadingComments ?
|
||||
<span className='nowrap faux-link'>view the rest of the comments →</span> :
|
||||
<span className='nowrap'><Link to={() => ({
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ class GlobalState extends Container {
|
|||
|
||||
// A redux-like connect function for Unstated
|
||||
export const connect = Component => {
|
||||
return props => (
|
||||
<Subscribe to={[GlobalState]}>
|
||||
return function Connected(props) {
|
||||
return <Subscribe to={[GlobalState]}>
|
||||
{globalState => <Component {...props} global={globalState} />}
|
||||
</Subscribe>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue