diff --git a/.eslintrc b/.eslintrc
index 1122f7e2e2..bc716af7d6 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,5 +1,5 @@
{
- "extends": "airbnb",
+ "extends": ["airbnb", "prettier"],
"parser": "babel-eslint",
"env": {
"browser": true,
@@ -16,12 +16,12 @@
"import/no-unresolved": 0,
"import/no-named-as-default": 2,
"comma-dangle": 0, // not sure why airbnb turned this on. gross!
- "indent": [2, 2, {"SwitchCase": 1}],
+ "indent": 0,
"no-console": 0,
"no-alert": 0,
"no-underscore-dangle": 0,
"max-len": [1, 120, 2, {"ignoreComments": true, "ignoreTemplateLiterals": true}],
- "quote-props": [1, "consistent-as-needed"],
+ "quote-props": [1, "as-needed"],
"no-unused-vars": [1, {"vars": "local", "args": "none"}],
"consistent-return": ["error", { "treatUndefinedAsUnspecified": true }],
"no-param-reassign": [2, { "props": false }],
@@ -60,10 +60,13 @@
},
"allowChildren": false
}
+ ],
+ "prettier/prettier": [
+ "error"
]
},
"plugins": [
- "react", "jsx-a11y", "import"
+ "react", "jsx-a11y", "import", "prettier"
],
"settings": {
"import/parser": "babel-eslint",
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000000..be8ed7938d
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,18 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "htmlWhitespaceSensitivity": "css",
+ "insertPragma": false,
+ "jsxBracketSameLine": false,
+ "jsxSingleQuote": false,
+ "parser": "babel",
+ "printWidth": 80,
+ "proseWrap": "never",
+ "requirePragma": false,
+ "semi": true,
+ "singleQuote": true,
+ "tabWidth": 2,
+ "trailingComma": "none",
+ "useTabs": false,
+ "quoteProps": "as-needed"
+}
\ No newline at end of file
diff --git a/client/common/Button.jsx b/client/common/Button.jsx
index 20bd9c2537..3009ab338b 100644
--- a/client/common/Button.jsx
+++ b/client/common/Button.jsx
@@ -8,7 +8,7 @@ import { remSize, prop } from '../theme';
const kinds = {
block: 'block',
icon: 'icon',
- inline: 'inline',
+ inline: 'inline'
};
// The '&&&' will increase the specificity of the
@@ -34,7 +34,7 @@ const StyledButton = styled.button`
svg * {
fill: ${prop('Button.default.foreground')};
}
-
+
&:hover:not(:disabled) {
color: ${prop('Button.hover.foreground')};
background-color: ${prop('Button.hover.background')};
@@ -115,7 +115,7 @@ const StyledIconButton = styled.button`
border-radius: 50%;
padding: ${remSize(8)} ${remSize(25)};
line-height: 1;
-
+
&:hover:not(:disabled) {
color: ${prop('Button.hover.foreground')};
background-color: ${prop('Button.hover.background')};
@@ -150,10 +150,24 @@ const StyledIconButton = styled.button`
* A Button performs an primary action
*/
const Button = ({
- children, href, kind, iconBefore, iconAfter, 'aria-label': ariaLabel, to, type, ...props
+ children,
+ href,
+ kind,
+ iconBefore,
+ iconAfter,
+ 'aria-label': ariaLabel,
+ to,
+ type,
+ ...props
}) => {
const hasChildren = React.Children.count(children) > 0;
- const content = <>{iconBefore}{hasChildren && {children}}{iconAfter}>;
+ const content = (
+ <>
+ {iconBefore}
+ {hasChildren && {children}}
+ {iconAfter}
+ >
+ );
let StyledComponent = StyledButton;
if (kind === kinds.inline) {
@@ -177,22 +191,36 @@ const Button = ({
}
if (to) {
- return
+
{t('PreviewNav.ByUser')}
- {owner.username} + + {owner.username} +@@ -85,7 +111,8 @@ function About(props) { href="https://github.com/processing/p5.js-web-editor/issues/new" target="_blank" rel="noopener noreferrer" - >{t('About.Report')} + > + {t('About.Report')}
@@ -93,7 +120,8 @@ function About(props) { href="https://twitter.com/p5xjs?lang=en" target="_blank" rel="noopener noreferrer" - >Twitter + > + Twitter
{this.props.t('AssetList.NoUploadedAssets')}
); + return ( ++ {this.props.t('AssetList.NoUploadedAssets')} +
+ ); } return null; } @@ -183,7 +193,7 @@ class AssetList extends React.Component { {this.renderLoader()} {this.renderEmptyTable()} - {this.hasAssets() && + {this.hasAssets() && ({this.props.t('CollectionList.NoCollections')}
); + return ( ++ {this.props.t('CollectionList.NoCollections')} +
+ ); } return null; } @@ -89,17 +97,25 @@ class CollectionList extends React.Component { let buttonLabel; if (field !== fieldName) { if (field === 'name') { - buttonLabel = this.props.t('CollectionList.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('CollectionList.ButtonLabelAscendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('CollectionList.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('CollectionList.ButtonLabelDescendingARIA', { + displayName + }); } } else if (direction === SortingActions.DIRECTION.ASC) { - buttonLabel = this.props.t('CollectionList.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('CollectionList.ButtonLabelDescendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('CollectionList.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('CollectionList.ButtonLabelAscendingARIA', { + displayName + }); } return buttonLabel; - } + }; _renderFieldHeader = (fieldName, displayName) => { const { field, direction } = this.props.sorting; @@ -116,19 +132,36 @@ class CollectionList extends React.Component { aria-label={buttonLabel} > {displayName} - {field === fieldName && direction === SortingActions.DIRECTION.ASC && -{this.props.t('EditorAccessibility.CurrentLine')} - +
+ {' '} + {this.props.t('EditorAccessibility.CurrentLine')} + + {' '} +
{this.props.t('ErrorModal.MessageLogin')} - {this.props.t('ErrorModal.Login')} + + {' '} + {this.props.t('ErrorModal.Login')} + {this.props.t('ErrorModal.LoginOr')} - {this.props.t('ErrorModal.SignUp')}. + + {this.props.t('ErrorModal.SignUp')} + + .
); } @@ -32,17 +38,16 @@ class ErrorModal extends React.Component { return ({this.props.t('ErrorModal.MessageLoggedOut')} - {this.props.t('ErrorModal.LogIn')}. + + {this.props.t('ErrorModal.LogIn')} + + .
); } staleProject() { - return ( -- {this.props.t('ErrorModal.SavedDifferentWindow')} -
- ); + return{this.props.t('ErrorModal.SavedDifferentWindow')}
; } render() { diff --git a/client/modules/IDE/components/Feedback.jsx b/client/modules/IDE/components/Feedback.jsx index 37ed571282..9739ad1252 100644 --- a/client/modules/IDE/components/Feedback.jsx +++ b/client/modules/IDE/components/Feedback.jsx @@ -10,11 +10,10 @@ function Feedback(props) {- {'If you\'re familiar with Github, this is our preferred method for receiving bug reports and feedback.'} + {`If you're familiar with Github, this is our preferred method for + receiving bug reports and feedback.`}
You can also submit this quick form.
@@ -40,7 +41,8 @@ function Feedback(props) { href="https://docs.google.com/forms/d/e/1FAIpQLSexU8W2EIhXjktl-_XzwjH6vgnelHirH4Yn4liN5BXltPWqBg/viewform" target="_blank" rel="noopener noreferrer" - >Go to Form + > + Go to Form- {t('KeyboardShortcuts.ShortcutsFollow')} {t('KeyboardShortcuts.SublimeText')}. + {t('KeyboardShortcuts.ShortcutsFollow')}{' '} + + {t('KeyboardShortcuts.SublimeText')} + + .
{this.props.t('SketchList.NoSketches')}
); + return ( ++ {this.props.t('SketchList.NoSketches')} +
+ ); } return null; } @@ -384,17 +416,25 @@ class SketchList extends React.Component { let buttonLabel; if (field !== fieldName) { if (field === 'name') { - buttonLabel = this.props.t('SketchList.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('SketchList.ButtonLabelAscendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('SketchList.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('SketchList.ButtonLabelDescendingARIA', { + displayName + }); } } else if (direction === SortingActions.DIRECTION.ASC) { - buttonLabel = this.props.t('SketchList.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('SketchList.ButtonLabelDescendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('SketchList.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('SketchList.ButtonLabelAscendingARIA', { + displayName + }); } return buttonLabel; - } + }; _renderFieldHeader = (fieldName, displayName) => { const { field, direction } = this.props.sorting; @@ -411,19 +451,32 @@ class SketchList extends React.Component { aria-label={buttonLabel} > {displayName} - {field === fieldName && direction === SortingActions.DIRECTION.ASC && -- {t(props.text)} -
-{t(props.text)}
+- {this.props.t('Toolbar.By')} {this.props.owner.username} + {this.props.t('Toolbar.By')}{' '} + + {this.props.owner.username} +
); } @@ -187,7 +196,7 @@ Toolbar.propTypes = { project: PropTypes.shape({ name: PropTypes.string.isRequired, isEditingName: PropTypes.bool, - id: PropTypes.string, + id: PropTypes.string }).isRequired, showEditProjectName: PropTypes.func.isRequired, hideEditProjectName: PropTypes.func.isRequired, @@ -201,7 +210,6 @@ Toolbar.propTypes = { saveProject: PropTypes.func.isRequired, currentUser: PropTypes.string, t: PropTypes.func.isRequired - }; Toolbar.defaultProps = { @@ -217,14 +225,14 @@ function mapStateToProps(state) { isPlaying: state.ide.isPlaying, owner: state.project.owner, preferencesIsVisible: state.ide.preferencesIsVisible, - project: state.project, + project: state.project }; } const mapDispatchToProps = { ...IDEActions, ...preferenceActions, - ...projectActions, + ...projectActions }; export const ToolbarComponent = withTranslation()(Toolbar); diff --git a/client/modules/IDE/components/Toolbar.test.jsx b/client/modules/IDE/components/Toolbar.test.jsx index 79b0f9ee1a..0d13d633af 100644 --- a/client/modules/IDE/components/Toolbar.test.jsx +++ b/client/modules/IDE/components/Toolbar.test.jsx @@ -5,35 +5,38 @@ import { fireEvent, render, screen, waitFor } from '../../../test-utils'; import { ToolbarComponent } from './Toolbar'; const renderComponent = (extraProps = {}) => { - const props = lodash.merge({ - isPlaying: false, - preferencesIsVisible: false, - stopSketch: jest.fn(), - setProjectName: jest.fn(), - openPreferences: jest.fn(), - showEditProjectName: jest.fn(), - hideEditProjectName: jest.fn(), - infiniteLoop: false, - autorefresh: false, - setAutorefresh: jest.fn(), - setTextOutput: jest.fn(), - setGridOutput: jest.fn(), - startSketch: jest.fn(), - startAccessibleSketch: jest.fn(), - saveProject: jest.fn(), - currentUser: 'me', - originalProjectName: 'testname', - - owner: { - username: 'me' + const props = lodash.merge( + { + isPlaying: false, + preferencesIsVisible: false, + stopSketch: jest.fn(), + setProjectName: jest.fn(), + openPreferences: jest.fn(), + showEditProjectName: jest.fn(), + hideEditProjectName: jest.fn(), + infiniteLoop: false, + autorefresh: false, + setAutorefresh: jest.fn(), + setTextOutput: jest.fn(), + setGridOutput: jest.fn(), + startSketch: jest.fn(), + startAccessibleSketch: jest.fn(), + saveProject: jest.fn(), + currentUser: 'me', + originalProjectName: 'testname', + + owner: { + username: 'me' + }, + project: { + name: 'testname', + isEditingName: false, + id: 'id' + }, + t: jest.fn() }, - project: { - name: 'testname', - isEditingName: false, - id: 'id', - }, - t: jest.fn() - }, extraProps); + extraProps + ); render(- {this.props.t('UploadFileModal.SizeLimitError', { sizeLimit: limitText })} - assets + {this.props.t('UploadFileModal.SizeLimitError', { + sizeLimit: limitText + })} + + assets + .
- } - { !this.props.reachedTotalSizeLimit && + )} + {!this.props.reachedTotalSizeLimit && ({this.props.t('APIKeyForm.NoTokens')}
; } render() { - const keyWithToken = this.props.apiKeys.find(k => !!k.token); + const keyWithToken = this.props.apiKeys.find((k) => !!k.token); return (- {this.props.t('APIKeyForm.NewTokenInfo')} -
-+ {this.props.t('APIKeyForm.NewTokenInfo')} +
+
-
- {t('AccountForm.Unconfirmed')}
- {
- user.emailVerificationInitiate === true ?
- (
- {t('AccountForm.EmailSent')}
- ) :
- (
-
+
+ {t('AccountForm.Unconfirmed')}
+
+ {user.emailVerificationInitiate === true ? (
+
+ {' '}
+ {t('AccountForm.EmailSent')}
+
+ ) : (
+
-
-
-
- {
- this.isOwner() ?
-
{this.props.t('Collection.By')} - {owner.username} +
+ {this.props.t('Collection.By')} + + {owner.username} +
-{this.props.t('Collection.NumSketches', { count: items.length }) }
++ {this.props.t('Collection.NumSketches', { count: items.length })} +
{this.props.t('Collection.NoSketches')}
); + return ( ++ {this.props.t('Collection.NoSketches')} +
+ ); } return null; } @@ -317,22 +355,30 @@ class Collection extends React.Component { let buttonLabel; if (field !== fieldName) { if (field === 'name') { - buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { + displayName + }); } } else if (direction === SortingActions.DIRECTION.ASC) { - buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { displayName }); + buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { + displayName + }); } else { - buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { displayName }); + buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { + displayName + }); } return buttonLabel; - } + }; _renderFieldHeader(fieldName, displayName) { const { field, direction } = this.props.sorting; const headerClass = classNames({ - 'arrowDown': true, + arrowDown: true, 'sketches-table__header--selected': field === fieldName }); const buttonLabel = this._getButtonLabel(fieldName, displayName); @@ -344,12 +390,22 @@ class Collection extends React.Component { aria-label={buttonLabel} > {displayName} - {field === fieldName && direction === SortingActions.DIRECTION.ASC && -
-
-
-
-
-
-
-
-
-
-
-
{/* eslint-disable-next-line react/prop-types */} - {props.t('AccountView.SocialLoginDescription')} + {t('AccountView.SocialLoginDescription')}
{this.props.t('EmailVerificationView.InvalidTokenNull')}
- ); + status ={this.props.t('EmailVerificationView.InvalidTokenNull')}
; } else if (emailVerificationTokenState === 'checking') { - status = ( -{this.props.t('EmailVerificationView.Checking')}
- ); + status ={this.props.t('EmailVerificationView.Checking')}
; } else if (emailVerificationTokenState === 'verified') { - status = ( -{this.props.t('EmailVerificationView.Verified')}
- ); + status ={this.props.t('EmailVerificationView.Verified')}
; setTimeout(() => browserHistory.push('/'), 1000); } else if (emailVerificationTokenState === 'invalid') { - status = ( -{this.props.t('EmailVerificationView.InvalidState')}
- ); + status ={this.props.t('EmailVerificationView.InvalidState')}
; } return ( @@ -57,7 +46,9 @@ class EmailVerificationView extends React.Component {{t('LoginView.DontHaveAccount')} - {t('LoginView.SignUp')} + + {t('LoginView.SignUp')} +
{t('LoginView.ForgotPassword')} - {t('LoginView.ResetPassword')} + + {' '} + {t('LoginView.ResetPassword')} +
diff --git a/client/modules/User/pages/NewPasswordView.jsx b/client/modules/User/pages/NewPasswordView.jsx index 3ef0ae8bca..506471bf5c 100644 --- a/client/modules/User/pages/NewPasswordView.jsx +++ b/client/modules/User/pages/NewPasswordView.jsx @@ -11,7 +11,9 @@ import Nav from '../../../components/Nav'; function NewPasswordView(props) { const { t } = useTranslation(); const resetPasswordToken = props.params.reset_password_token; - const resetPasswordInvalid = useSelector(state => state.user.resetPasswordInvalid); + const resetPasswordInvalid = useSelector( + (state) => state.user.resetPasswordInvalid + ); const dispatch = useDispatch(); useEffect(() => { @@ -22,7 +24,7 @@ function NewPasswordView(props) { 'new-password': true, 'new-password--invalid': resetPasswordInvalid, 'form-container': true, - 'user': true + user: true }); return ({t('NewPasswordView.TokenInvalidOrExpired')} @@ -45,7 +49,7 @@ function NewPasswordView(props) { NewPasswordView.propTypes = { params: PropTypes.shape({ - reset_password_token: PropTypes.string, + reset_password_token: PropTypes.string }).isRequired }; diff --git a/client/modules/User/pages/ResetPasswordView.jsx b/client/modules/User/pages/ResetPasswordView.jsx index ec3ac65fea..d3af6c125c 100644 --- a/client/modules/User/pages/ResetPasswordView.jsx +++ b/client/modules/User/pages/ResetPasswordView.jsx @@ -9,12 +9,14 @@ import Nav from '../../../components/Nav'; function ResetPasswordView() { const { t } = useTranslation(); - const resetPasswordInitiate = useSelector(state => state.user.resetPasswordInitiate); + const resetPasswordInitiate = useSelector( + (state) => state.user.resetPasswordInitiate + ); const resetPasswordClass = classNames({ 'reset-password': true, 'reset-password--submitted': resetPasswordInitiate, 'form-container': true, - 'user': true + user: true }); return (
{t('ResetPasswordView.Submitted')}
- {t('ResetPasswordView.Login')} + + {t('ResetPasswordView.Login')} + {t('ResetPasswordView.LoginOr')} - {t('ResetPasswordView.SignUp')} + + {t('ResetPasswordView.SignUp')} +
{t('SignupView.AlreadyHave')} - {t('SignupView.Login')} + + {t('SignupView.Login')} +
'); html[0] = `${html[0]}`; htmlFile = html.join(''); }); - cssFiles.forEach((file) => { // Add css files as style tags + cssFiles.forEach((file) => { + // Add css files as style tags const html = htmlFile.split(''); html[0] = `${html[0]}`; htmlFile = html.join(''); }); - linkedFiles.forEach((file) => { // Add linked files as link tags + linkedFiles.forEach((file) => { + // Add linked files as link tags const html = htmlFile.split('
'); html[1] = `${html[1]}`; htmlFile = html.join('
'); @@ -118,22 +131,26 @@ export function get404Sketch(callback) { ); // Change canvas size - htmlFile = htmlFile.replace(/createCanvas\(\d+, ?\d+/g, instanceMode ? - 'createCanvas(p.windowWidth, p.windowHeight' - : - 'createCanvas(windowWidth, windowHeight'); + htmlFile = htmlFile.replace( + /createCanvas\(\d+, ?\d+/g, + instanceMode + ? 'createCanvas(p.windowWidth, p.windowHeight' + : 'createCanvas(windowWidth, windowHeight' + ); callback(htmlFile); }); } else { - callback(insertErrorMessage(` + callback( + insertErrorMessage(`
-