From 7a3683758594c20a15450f140fde6e6af3018f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 12 Apr 2022 22:40:09 +0200 Subject: [PATCH] typescript, FC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../features/aliases/components/search.js | 84 ------------------- .../features/aliases/components/search.tsx | 65 ++++++++++++++ .../components/account.js | 60 ------------- .../components/account.tsx | 46 ++++++++++ .../follow_recommendations_container.js | 39 --------- .../follow_recommendations_container.tsx | 30 +++++++ .../components/follow_recommendations_list.js | 62 -------------- .../follow_recommendations_list.tsx | 45 ++++++++++ .../features/follow_recommendations/index.js | 28 ------- .../features/follow_recommendations/index.tsx | 22 +++++ .../intentional_error/{index.js => index.tsx} | 10 +-- 11 files changed, 212 insertions(+), 279 deletions(-) delete mode 100644 app/soapbox/features/aliases/components/search.js create mode 100644 app/soapbox/features/aliases/components/search.tsx delete mode 100644 app/soapbox/features/follow_recommendations/components/account.js create mode 100644 app/soapbox/features/follow_recommendations/components/account.tsx delete mode 100644 app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js create mode 100644 app/soapbox/features/follow_recommendations/components/follow_recommendations_container.tsx delete mode 100644 app/soapbox/features/follow_recommendations/components/follow_recommendations_list.js create mode 100644 app/soapbox/features/follow_recommendations/components/follow_recommendations_list.tsx delete mode 100644 app/soapbox/features/follow_recommendations/index.js create mode 100644 app/soapbox/features/follow_recommendations/index.tsx rename app/soapbox/features/intentional_error/{index.js => index.tsx} (50%) diff --git a/app/soapbox/features/aliases/components/search.js b/app/soapbox/features/aliases/components/search.js deleted file mode 100644 index 4311685e7..000000000 --- a/app/soapbox/features/aliases/components/search.js +++ /dev/null @@ -1,84 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; -import { connect } from 'react-redux'; - -import Icon from 'soapbox/components/icon'; -import { Button } from 'soapbox/components/ui'; - -import { fetchAliasesSuggestions, clearAliasesSuggestions, changeAliasesSuggestions } from '../../../actions/aliases'; - -const messages = defineMessages({ - search: { id: 'aliases.search', defaultMessage: 'Search your old account' }, - searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' }, -}); - -const mapStateToProps = state => ({ - value: state.getIn(['aliases', 'suggestions', 'value']), -}); - -const mapDispatchToProps = dispatch => ({ - onSubmit: value => dispatch(fetchAliasesSuggestions(value)), - onClear: () => dispatch(clearAliasesSuggestions()), - onChange: value => dispatch(changeAliasesSuggestions(value)), -}); - -export default @connect(mapStateToProps, mapDispatchToProps) -@injectIntl -class Search extends React.PureComponent { - - static propTypes = { - intl: PropTypes.object.isRequired, - value: PropTypes.string.isRequired, - onChange: PropTypes.func.isRequired, - onSubmit: PropTypes.func.isRequired, - onClear: PropTypes.func.isRequired, - }; - - handleChange = e => { - this.props.onChange(e.target.value); - } - - handleKeyUp = e => { - if (e.keyCode === 13) { - this.props.onSubmit(this.props.value); - } - } - - handleSubmit = () => { - this.props.onSubmit(this.props.value); - } - - handleClear = () => { - this.props.onClear(); - } - - render() { - const { value, intl } = this.props; - const hasValue = value.length > 0; - - return ( -
- - -
- -
- -
- ); - } - -} diff --git a/app/soapbox/features/aliases/components/search.tsx b/app/soapbox/features/aliases/components/search.tsx new file mode 100644 index 000000000..516a38884 --- /dev/null +++ b/app/soapbox/features/aliases/components/search.tsx @@ -0,0 +1,65 @@ +import classNames from 'classnames'; +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; +import { useDispatch } from 'react-redux'; + +import { fetchAliasesSuggestions, clearAliasesSuggestions, changeAliasesSuggestions } from 'soapbox/actions/aliases'; +import Icon from 'soapbox/components/icon'; +import { Button } from 'soapbox/components/ui'; +import { useAppSelector } from 'soapbox/hooks'; + +const messages = defineMessages({ + search: { id: 'aliases.search', defaultMessage: 'Search your old account' }, + searchTitle: { id: 'tabs_bar.search', defaultMessage: 'Search' }, +}); + +const Search: React.FC = () => { + const dispatch = useDispatch(); + const intl = useIntl(); + + const value = useAppSelector(state => state.aliases.getIn(['suggestions', 'value'])) as string; + + const handleChange = (e: React.ChangeEvent) => { + dispatch(changeAliasesSuggestions(e.target.value)); + }; + + const handleKeyUp = (e: React.KeyboardEvent) => { + if (e.keyCode === 13) { + dispatch(fetchAliasesSuggestions(value)); + } + }; + + const handleSubmit = () => { + dispatch(fetchAliasesSuggestions(value)); + }; + + const handleClear = () => { + dispatch(clearAliasesSuggestions()); + }; + + const hasValue = value.length > 0; + + return ( +
+ + +
+ +
+ +
+ ); +}; + +export default Search; diff --git a/app/soapbox/features/follow_recommendations/components/account.js b/app/soapbox/features/follow_recommendations/components/account.js deleted file mode 100644 index c15fc6bcc..000000000 --- a/app/soapbox/features/follow_recommendations/components/account.js +++ /dev/null @@ -1,60 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import Avatar from 'soapbox/components/avatar'; -import DisplayName from 'soapbox/components/display_name'; -import Permalink from 'soapbox/components/permalink'; -import ActionButton from 'soapbox/features/ui/components/action_button'; -import { makeGetAccount } from 'soapbox/selectors'; - -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); - - const mapStateToProps = (state, props) => ({ - account: getAccount(state, props.id), - }); - - return mapStateToProps; -}; - -const getFirstSentence = str => { - const arr = str.split(/(([.?!]+\s)|[.。?!\n•])/); - - return arr[0]; -}; - -export default @connect(makeMapStateToProps) -class Account extends ImmutablePureComponent { - - static propTypes = { - account: ImmutablePropTypes.record.isRequired, - intl: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired, - }; - - render() { - const { account } = this.props; - - return ( -
-
- -
- - - -
{getFirstSentence(account.get('note_plain'))}
-
- -
- -
-
-
- ); - } - -} diff --git a/app/soapbox/features/follow_recommendations/components/account.tsx b/app/soapbox/features/follow_recommendations/components/account.tsx new file mode 100644 index 000000000..8ba56b497 --- /dev/null +++ b/app/soapbox/features/follow_recommendations/components/account.tsx @@ -0,0 +1,46 @@ +import React from 'react'; + +import Avatar from 'soapbox/components/avatar'; +import DisplayName from 'soapbox/components/display_name'; +import Permalink from 'soapbox/components/permalink'; +import ActionButton from 'soapbox/features/ui/components/action_button'; +import { useAppSelector } from 'soapbox/hooks'; +import { makeGetAccount } from 'soapbox/selectors'; + +const getAccount = makeGetAccount(); + +const getFirstSentence = (str: string) => { + const arr = str.split(/(([.?!]+\s)|[.。?!\n•])/); + + return arr[0]; +}; + +interface IAccount { + id: string, +} + +const Account: React.FC = ({ id }) => { + const account = useAppSelector((state) => getAccount(state, id)); + + if (!account) return null; + + return ( +
+
+ +
+ + + +
{getFirstSentence(account.get('note_plain'))}
+
+ +
+ +
+
+
+ ); +}; + +export default Account; diff --git a/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js b/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js deleted file mode 100644 index 59c4f382b..000000000 --- a/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { FormattedMessage } from 'react-intl'; - -import { Button } from 'soapbox/components/ui'; - -import FollowRecommendationsList from './follow_recommendations_list'; - -export default class FollowRecommendationsContainer extends React.Component { - - static propTypes = { - onDone: PropTypes.func.isRequired, - } - - handleDone = () => { - this.props.onDone(); - } - - render() { - return ( -
-
-

-

-

-
- - - -
- -
-
- ); - } - -} diff --git a/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.tsx b/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.tsx new file mode 100644 index 000000000..c3f198f94 --- /dev/null +++ b/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +import { Button } from 'soapbox/components/ui'; + +import FollowRecommendationsList from './follow_recommendations_list'; + +interface IFollowRecommendationsContainer { + onDone: () => void, +} + +const FollowRecommendationsContainer: React.FC = ({ onDone }) => ( +
+
+

+

+

+
+ + + +
+ +
+
+); + +export default FollowRecommendationsContainer; diff --git a/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.js b/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.js deleted file mode 100644 index 7fc06319b..000000000 --- a/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.js +++ /dev/null @@ -1,62 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; - -import { fetchSuggestions } from 'soapbox/actions/suggestions'; -import { Spinner } from 'soapbox/components/ui'; - -import Account from './account'; - -const mapStateToProps = state => ({ - suggestions: state.getIn(['suggestions', 'items']), - isLoading: state.getIn(['suggestions', 'isLoading']), -}); - -export default @connect(mapStateToProps) -class FollowRecommendationsList extends ImmutablePureComponent { - - static propTypes = { - dispatch: PropTypes.func.isRequired, - suggestions: ImmutablePropTypes.list, - isLoading: PropTypes.bool, - }; - - componentDidMount() { - const { dispatch, suggestions } = this.props; - - // Don't re-fetch if we're e.g. navigating backwards to this page, - // since we don't want followed accounts to disappear from the list - if (suggestions.size === 0) { - dispatch(fetchSuggestions(true)); - } - } - - render() { - const { suggestions, isLoading } = this.props; - - if (isLoading) { - return ( -
- -
- ); - } - - return ( -
- {suggestions.size > 0 ? suggestions.map(suggestion => ( - - )) : ( -
- -
- )} -
- ); - - } - -} diff --git a/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.tsx b/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.tsx new file mode 100644 index 000000000..4ca838072 --- /dev/null +++ b/app/soapbox/features/follow_recommendations/components/follow_recommendations_list.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { useEffect } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { useDispatch } from 'react-redux'; + +import { fetchSuggestions } from 'soapbox/actions/suggestions'; +import { Spinner } from 'soapbox/components/ui'; +import { useAppSelector } from 'soapbox/hooks'; + +import Account from './account'; + +const FollowRecommendationsList: React.FC = () => { + const dispatch = useDispatch(); + + const suggestions = useAppSelector((state) => state.suggestions.get('items')); + const isLoading = useAppSelector((state) => state.suggestions.get('isLoading')); + + useEffect(() => { + if (suggestions.size === 0) { + dispatch(fetchSuggestions()); + } + }, []); + + if (isLoading) { + return ( +
+ +
+ ); + } + + return ( +
+ {suggestions.size > 0 ? suggestions.map((suggestion: { account: string }) => ( + + )) : ( +
+ +
+ )} +
+ ); +}; + +export default FollowRecommendationsList; diff --git a/app/soapbox/features/follow_recommendations/index.js b/app/soapbox/features/follow_recommendations/index.js deleted file mode 100644 index 2e9e3bcc3..000000000 --- a/app/soapbox/features/follow_recommendations/index.js +++ /dev/null @@ -1,28 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { withRouter } from 'react-router-dom'; - -import Column from 'soapbox/features/ui/components/column'; - -import FollowRecommendationsContainer from './components/follow_recommendations_container'; - -export default @withRouter -class FollowRecommendations extends React.Component { - - static propTypes = { - history: PropTypes.object.isRequired, - }; - - onDone = () => { - this.props.history.push('/'); - } - - render() { - return ( - - - - ); - } - -} diff --git a/app/soapbox/features/follow_recommendations/index.tsx b/app/soapbox/features/follow_recommendations/index.tsx new file mode 100644 index 000000000..444504532 --- /dev/null +++ b/app/soapbox/features/follow_recommendations/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { useHistory } from 'react-router-dom'; + +import Column from 'soapbox/features/ui/components/column'; + +import FollowRecommendationsContainer from './components/follow_recommendations_container'; + +const FollowRecommendations: React.FC = () => { + const history = useHistory(); + + const onDone = () => { + history.push('/'); + }; + + return ( + + + + ); +}; + +export default FollowRecommendations; diff --git a/app/soapbox/features/intentional_error/index.js b/app/soapbox/features/intentional_error/index.tsx similarity index 50% rename from app/soapbox/features/intentional_error/index.js rename to app/soapbox/features/intentional_error/index.tsx index b3d7fa0f7..01ae3a5c4 100644 --- a/app/soapbox/features/intentional_error/index.js +++ b/app/soapbox/features/intentional_error/index.tsx @@ -4,10 +4,8 @@ import React from 'react'; * IntentionalError: * For testing logging/monitoring & previewing ErrorBoundary design. */ -export default class IntentionalError extends React.Component { +const IntentionalError: React.FC = () => { + throw 'This error is intentional.'; +}; - render() { - throw 'This error is intentional.'; - } - -} +export default IntentionalError;