diff --git a/app/soapbox/components/ui/input/input.tsx b/app/soapbox/components/ui/input/input.tsx index 343a9d0dd..5314ee583 100644 --- a/app/soapbox/components/ui/input/input.tsx +++ b/app/soapbox/components/ui/input/input.tsx @@ -19,7 +19,7 @@ interface IInput extends Pick, 'onCh name?: string, placeholder?: string, value?: string, - onChange?: () => void, + onChange?: (event: React.ChangeEvent) => void, type: 'text' | 'email' | 'tel' | 'password' } diff --git a/app/soapbox/features/admin/components/latest_accounts_panel.tsx b/app/soapbox/features/admin/components/latest_accounts_panel.tsx index 7f53abd46..b1e9a441b 100644 --- a/app/soapbox/features/admin/components/latest_accounts_panel.tsx +++ b/app/soapbox/features/admin/components/latest_accounts_panel.tsx @@ -9,7 +9,7 @@ import compareId from 'soapbox/compare_id'; import { Text, Widget } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account_container'; import { useAppSelector } from 'soapbox/hooks'; -import { useAppDispatch } from 'soapbox/hooks/useAppDispatch'; +import { useAppDispatch } from 'soapbox/hooks'; const messages = defineMessages({ title: { id: 'admin.latest_accounts_panel.title', defaultMessage: 'Latest Accounts' }, diff --git a/app/soapbox/features/delete_account/index.js b/app/soapbox/features/delete_account/index.tsx similarity index 94% rename from app/soapbox/features/delete_account/index.js rename to app/soapbox/features/delete_account/index.tsx index f0d902e4a..733b9554c 100644 --- a/app/soapbox/features/delete_account/index.js +++ b/app/soapbox/features/delete_account/index.tsx @@ -1,11 +1,11 @@ import PropTypes from 'prop-types'; import * as React from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { useDispatch } from 'react-redux'; import { deleteAccount } from 'soapbox/actions/security'; import snackbar from 'soapbox/actions/snackbar'; import { Button, Card, CardBody, CardHeader, CardTitle, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui'; +import { useAppDispatch } from 'soapbox/hooks'; const messages = defineMessages({ passwordFieldLabel: { id: 'security.fields.password.label', defaultMessage: 'Password' }, @@ -18,12 +18,12 @@ const messages = defineMessages({ const DeleteAccount = () => { const intl = useIntl(); - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const [password, setPassword] = React.useState(''); const [isLoading, setLoading] = React.useState(false); - const handleInputChange = React.useCallback((event) => { + const handleInputChange = React.useCallback((event: React.ChangeEvent) => { event.persist(); setPassword(event.target.value); diff --git a/app/soapbox/features/developers/developers_challenge.js b/app/soapbox/features/developers/developers_challenge.js deleted file mode 100644 index b62191227..000000000 --- a/app/soapbox/features/developers/developers_challenge.js +++ /dev/null @@ -1,92 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; -import { connect } from 'react-redux'; - -import { changeSettingImmediate } from 'soapbox/actions/settings'; -import snackbar from 'soapbox/actions/snackbar'; -import { Button, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui'; - - -import Column from '../ui/components/column'; - -const messages = defineMessages({ - heading: { id: 'column.developers', defaultMessage: 'Developers' }, - answerLabel: { id: 'developers.challenge.answer_label', defaultMessage: 'Answer' }, - answerPlaceholder: { id: 'developers.challenge.answer_placeholder', defaultMessage: 'Your answer' }, - success: { id: 'developers.challenge.success', defaultMessage: 'You are now a developer' }, - fail: { id: 'developers.challenge.fail', defaultMessage: 'Wrong answer' }, -}); - -export default @connect() -@injectIntl -class DevelopersChallenge extends React.Component { - - static propTypes = { - intl: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - } - - state = { - answer: '', - } - - handleChangeAnswer = e => { - this.setState({ answer: e.target.value }); - } - - handleSubmit = e => { - const { intl, dispatch } = this.props; - const { answer } = this.state; - - if (answer === 'boxsoap') { - dispatch(changeSettingImmediate(['isDeveloper'], true)); - dispatch(snackbar.success(intl.formatMessage(messages.success))); - } else { - dispatch(snackbar.error(intl.formatMessage(messages.fail))); - } - } - - render() { - const { intl } = this.props; - - const challenge = `function soapbox() { - return 'soap|box'.split('|').reverse().join(''); -}`; - - return ( - -
- - soapbox() }} - /> - - - {challenge} - - - - - - - - - -
-
- ); - } - -} diff --git a/app/soapbox/features/developers/developers_challenge.tsx b/app/soapbox/features/developers/developers_challenge.tsx new file mode 100644 index 000000000..d27b46429 --- /dev/null +++ b/app/soapbox/features/developers/developers_challenge.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { useState } from 'react'; +import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; +import { useDispatch } from 'react-redux'; + +import { changeSettingImmediate } from 'soapbox/actions/settings'; +import snackbar from 'soapbox/actions/snackbar'; +import { Button, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui'; + + +import Column from '../ui/components/column'; + +const messages = defineMessages({ + heading: { id: 'column.developers', defaultMessage: 'Developers' }, + answerLabel: { id: 'developers.challenge.answer_label', defaultMessage: 'Answer' }, + answerPlaceholder: { id: 'developers.challenge.answer_placeholder', defaultMessage: 'Your answer' }, + success: { id: 'developers.challenge.success', defaultMessage: 'You are now a developer' }, + fail: { id: 'developers.challenge.fail', defaultMessage: 'Wrong answer' }, +}); + +const DevelopersChallenge = () => { + const dispatch = useDispatch(); + const intl = useIntl(); + + const [answer, setAnswer] = useState(''); + + const handleChangeAnswer = (e: React.ChangeEvent) => { + setAnswer(e.target.value); + }; + + const handleSubmit = () => { + if (answer === 'boxsoap') { + dispatch(changeSettingImmediate(['isDeveloper'], true)); + dispatch(snackbar.success(intl.formatMessage(messages.success))); + } else { + dispatch(snackbar.error(intl.formatMessage(messages.fail))); + } + }; + + const challenge = `function soapbox() { + return 'soap|box'.split('|').reverse().join(''); +}`; + + return ( + +
+ + soapbox() }} + /> + + + {challenge} + + + + + + + + + +
+
+ ); +}; + +export default DevelopersChallenge; diff --git a/app/soapbox/features/developers/developers_menu.js b/app/soapbox/features/developers/developers_menu.tsx similarity index 97% rename from app/soapbox/features/developers/developers_menu.js rename to app/soapbox/features/developers/developers_menu.tsx index 832c0bd60..6cabd36a0 100644 --- a/app/soapbox/features/developers/developers_menu.js +++ b/app/soapbox/features/developers/developers_menu.tsx @@ -20,7 +20,7 @@ const Developers = () => { const history = useHistory(); const intl = useIntl(); - const leaveDevelopers = (e) => { + const leaveDevelopers = (e: React.MouseEvent) => { e.preventDefault(); dispatch(changeSettingImmediate(['isDeveloper'], false)); diff --git a/app/soapbox/features/developers/index.js b/app/soapbox/features/developers/index.js deleted file mode 100644 index 3d58c9249..000000000 --- a/app/soapbox/features/developers/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; - -import { getSettings } from 'soapbox/actions/settings'; - -import DevelopersChallenge from './developers_challenge'; -import DevelopersMenu from './developers_menu'; - -const mapStateToProps = state => { - const settings = getSettings(state); - - return { - isDeveloper: settings.get('isDeveloper'), - }; -}; - -export default @connect(mapStateToProps) -class Developers extends React.Component { - - static propTypes = { - isDeveloper: PropTypes.bool.isRequired, - } - - render() { - const { isDeveloper } = this.props; - return isDeveloper ? : ; - } - -} diff --git a/app/soapbox/features/developers/index.tsx b/app/soapbox/features/developers/index.tsx new file mode 100644 index 000000000..a192f1683 --- /dev/null +++ b/app/soapbox/features/developers/index.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import { getSettings } from 'soapbox/actions/settings'; +import { useAppSelector } from 'soapbox/hooks'; + +import DevelopersChallenge from './developers_challenge'; +import DevelopersMenu from './developers_menu'; + +const Developers: React.FC = () => { + const isDeveloper = useAppSelector((state) => getSettings(state).get('isDeveloper')); + + return isDeveloper ? : ; +}; + +export default Developers; diff --git a/app/soapbox/hooks/index.ts b/app/soapbox/hooks/index.ts index d3c5f4700..6ec919a94 100644 --- a/app/soapbox/hooks/index.ts +++ b/app/soapbox/hooks/index.ts @@ -1,3 +1,4 @@ +export { useAppDispatch } from './useAppDispatch'; export { useAppSelector } from './useAppSelector'; export { useFeatures } from './useFeatures'; export { useOnScreen } from './useOnScreen';