From 6c45dcb1092e2f441535df23db0018614c34af7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 7 Jun 2022 18:25:53 +0200 Subject: [PATCH] TypeScript, FC (reducers, search) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/components/dropdown_menu.tsx | 2 + app/soapbox/components/hashtag.tsx | 20 +- app/soapbox/components/pullable.tsx | 2 +- app/soapbox/components/ui/column/column.tsx | 2 +- .../containers/dropdown_menu_container.ts | 2 +- .../features/compose/components/search.tsx | 4 +- .../compose/components/search_results.js | 173 ------------------ .../compose/components/search_results.tsx | 172 +++++++++++++++++ .../containers/search_results_container.js | 33 ---- .../containers/status_check_box_container.js | 3 +- .../features/search/components/header.js | 60 ------ app/soapbox/features/search/index.tsx | 4 +- .../__tests__/trends-panel.test.tsx | 38 ++-- .../ui/components/account_note_modal.js | 101 ---------- .../ui/components/account_note_modal.tsx | 68 +++++++ .../{actions_modal.js => actions_modal.tsx} | 39 ++-- app/soapbox/features/ui/components/column.js | 37 ---- app/soapbox/features/ui/components/column.tsx | 36 ++++ .../ui/components/column_forbidden.js | 32 ---- .../ui/components/column_forbidden.tsx | 23 +++ .../features/ui/components/column_header.js | 40 ---- .../features/ui/components/column_header.tsx | 47 +++++ .../{column_loading.js => column_loading.tsx} | 0 .../modals/report-modal/report-modal.tsx | 12 +- .../report-modal/steps/other-actions-step.tsx | 8 +- .../modals/report-modal/steps/reason-step.tsx | 7 +- .../features/ui/components/mute_modal.js | 2 +- .../features/ui/components/trends-panel.tsx | 9 +- app/soapbox/reducers/__tests__/modals-test.js | 4 +- .../reducers/__tests__/reports-test.js | 14 +- app/soapbox/reducers/__tests__/trends-test.js | 8 +- app/soapbox/reducers/account_notes.ts | 4 +- app/soapbox/reducers/{modals.js => modals.ts} | 17 +- .../reducers/{reports.js => reports.ts} | 52 +++--- app/soapbox/reducers/{search.js => search.ts} | 60 ++++-- .../reducers/{security.tsx => security.ts} | 3 +- app/soapbox/reducers/trending_statuses.js | 31 ---- app/soapbox/reducers/trending_statuses.ts | 37 ++++ app/soapbox/reducers/trends.js | 28 --- app/soapbox/reducers/trends.ts | 47 +++++ 40 files changed, 609 insertions(+), 672 deletions(-) delete mode 100644 app/soapbox/features/compose/components/search_results.js create mode 100644 app/soapbox/features/compose/components/search_results.tsx delete mode 100644 app/soapbox/features/compose/containers/search_results_container.js delete mode 100644 app/soapbox/features/search/components/header.js delete mode 100644 app/soapbox/features/ui/components/account_note_modal.js create mode 100644 app/soapbox/features/ui/components/account_note_modal.tsx rename app/soapbox/features/ui/components/{actions_modal.js => actions_modal.tsx} (71%) delete mode 100644 app/soapbox/features/ui/components/column.js create mode 100644 app/soapbox/features/ui/components/column.tsx delete mode 100644 app/soapbox/features/ui/components/column_forbidden.js create mode 100644 app/soapbox/features/ui/components/column_forbidden.tsx delete mode 100644 app/soapbox/features/ui/components/column_header.js create mode 100644 app/soapbox/features/ui/components/column_header.tsx rename app/soapbox/features/ui/components/{column_loading.js => column_loading.tsx} (100%) rename app/soapbox/reducers/{modals.js => modals.ts} (50%) rename app/soapbox/reducers/{reports.js => reports.ts} (54%) rename app/soapbox/reducers/{search.js => search.ts} (56%) rename app/soapbox/reducers/{security.tsx => security.ts} (97%) delete mode 100644 app/soapbox/reducers/trending_statuses.js create mode 100644 app/soapbox/reducers/trending_statuses.ts delete mode 100644 app/soapbox/reducers/trends.js create mode 100644 app/soapbox/reducers/trends.ts diff --git a/app/soapbox/components/dropdown_menu.tsx b/app/soapbox/components/dropdown_menu.tsx index d56a72a01..7a59e4932 100644 --- a/app/soapbox/components/dropdown_menu.tsx +++ b/app/soapbox/components/dropdown_menu.tsx @@ -26,6 +26,8 @@ export interface MenuItem { icon: string, count?: number, destructive?: boolean, + meta?: string, + active?: boolean, } export type Menu = Array; diff --git a/app/soapbox/components/hashtag.tsx b/app/soapbox/components/hashtag.tsx index c8e45a084..8206f3f62 100644 --- a/app/soapbox/components/hashtag.tsx +++ b/app/soapbox/components/hashtag.tsx @@ -10,24 +10,26 @@ import { shortNumberFormat } from '../utils/numbers'; import Permalink from './permalink'; import { HStack, Stack, Text } from './ui'; -import type { Map as ImmutableMap } from 'immutable'; +import type { Hashtag as HashtagEntity } from 'soapbox/reducers/search'; +import type { TrendingHashtag } from 'soapbox/reducers/trends'; interface IHashtag { - hashtag: ImmutableMap, + hashtag: HashtagEntity | TrendingHashtag, } const Hashtag: React.FC = ({ hashtag }) => { - const count = Number(hashtag.getIn(['history', 0, 'accounts'])); - const brandColor = useSelector((state) => getSoapboxConfig(state).get('brandColor')); + const history = (hashtag as TrendingHashtag).history; + const count = Number(history?.get(0)?.accounts); + const brandColor = useSelector((state) => getSoapboxConfig(state).brandColor); return ( - - #{hashtag.get('name')} + + #{hashtag.name} - {hashtag.get('history') && ( + {history && ( = ({ hashtag }) => { )} - {hashtag.get('history') && ( + {history && (
) => day.get('uses')).toArray()} + data={history.reverse().map((day) => +day.uses).toArray()} > diff --git a/app/soapbox/components/pullable.tsx b/app/soapbox/components/pullable.tsx index 0304a1d46..03840d2c1 100644 --- a/app/soapbox/components/pullable.tsx +++ b/app/soapbox/components/pullable.tsx @@ -3,7 +3,7 @@ import React from 'react'; import PullToRefresh from './pull-to-refresh'; interface IPullable { - children: JSX.Element, + children: React.ReactNode, } /** diff --git a/app/soapbox/components/ui/column/column.tsx b/app/soapbox/components/ui/column/column.tsx index dde81736a..5ac4f350e 100644 --- a/app/soapbox/components/ui/column/column.tsx +++ b/app/soapbox/components/ui/column/column.tsx @@ -7,7 +7,7 @@ import { useSoapboxConfig } from 'soapbox/hooks'; import { Card, CardBody, CardHeader, CardTitle } from '../card/card'; -interface IColumn { +export interface IColumn { /** Route the back button goes to. */ backHref?: string, /** Column title text. */ diff --git a/app/soapbox/containers/dropdown_menu_container.ts b/app/soapbox/containers/dropdown_menu_container.ts index d3e7149e4..b047edfff 100644 --- a/app/soapbox/containers/dropdown_menu_container.ts +++ b/app/soapbox/containers/dropdown_menu_container.ts @@ -10,7 +10,7 @@ import type { DropdownPlacement, IDropdown } from 'soapbox/components/dropdown_m import type { RootState } from 'soapbox/store'; const mapStateToProps = (state: RootState) => ({ - isModalOpen: Boolean(state.modals.size && state.modals.last().modalType === 'ACTIONS'), + isModalOpen: Boolean(state.modals.size && state.modals.last()!.modalType === 'ACTIONS'), dropdownPlacement: state.dropdown_menu.placement, openDropdownId: state.dropdown_menu.openId, openedViaKeyboard: state.dropdown_menu.keyboard, diff --git a/app/soapbox/features/compose/components/search.tsx b/app/soapbox/features/compose/components/search.tsx index d68f82bc2..e70786cb7 100644 --- a/app/soapbox/features/compose/components/search.tsx +++ b/app/soapbox/features/compose/components/search.tsx @@ -50,8 +50,8 @@ const Search = (props: ISearch) => { const history = useHistory(); const intl = useIntl(); - const value = useAppSelector((state) => state.search.get('value')); - const submitted = useAppSelector((state) => state.search.get('submitted')); + const value = useAppSelector((state) => state.search.value); + const submitted = useAppSelector((state) => state.search.submitted); const debouncedSubmit = debounce(() => { dispatch(submitSearch()); diff --git a/app/soapbox/features/compose/components/search_results.js b/app/soapbox/features/compose/components/search_results.js deleted file mode 100644 index e4dfa936b..000000000 --- a/app/soapbox/features/compose/components/search_results.js +++ /dev/null @@ -1,173 +0,0 @@ -import classNames from 'classnames'; -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 { defineMessages, injectIntl } from 'react-intl'; - -import Hashtag from 'soapbox/components/hashtag'; -import ScrollableList from 'soapbox/components/scrollable_list'; -import { Tabs } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account_container'; -import StatusContainer from 'soapbox/containers/status_container'; -import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account'; -import PlaceholderHashtag from 'soapbox/features/placeholder/components/placeholder_hashtag'; -import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; - -const messages = defineMessages({ - accounts: { id: 'search_results.accounts', defaultMessage: 'People' }, - statuses: { id: 'search_results.statuses', defaultMessage: 'Posts' }, - hashtags: { id: 'search_results.hashtags', defaultMessage: 'Hashtags' }, -}); - -export default @injectIntl -class SearchResults extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - results: ImmutablePropTypes.map.isRequired, - submitted: PropTypes.bool, - expandSearch: PropTypes.func.isRequired, - selectedFilter: PropTypes.string.isRequired, - selectFilter: PropTypes.func.isRequired, - features: PropTypes.object.isRequired, - suggestions: ImmutablePropTypes.list, - trendingStatuses: ImmutablePropTypes.list, - trends: ImmutablePropTypes.list, - intl: PropTypes.object.isRequired, - }; - - handleLoadMore = () => this.props.expandSearch(this.props.selectedFilter); - - handleSelectFilter = newActiveFilter => this.props.selectFilter(newActiveFilter); - - componentDidMount() { - this.props.fetchTrendingStatuses(); - } - - renderFilterBar() { - const { intl, selectedFilter } = this.props; - - const items = [ - { - text: intl.formatMessage(messages.accounts), - action: () => this.handleSelectFilter('accounts'), - name: 'accounts', - }, - { - text: intl.formatMessage(messages.statuses), - action: () => this.handleSelectFilter('statuses'), - name: 'statuses', - }, - { - text: intl.formatMessage(messages.hashtags), - action: () => this.handleSelectFilter('hashtags'), - name: 'hashtags', - }, - ]; - - return ; - } - - render() { - const { value, results, submitted, selectedFilter, suggestions, trendingStatuses, trends } = this.props; - - let searchResults; - let hasMore = false; - let loaded; - let noResultsMessage; - let placeholderComponent = PlaceholderStatus; - - if (selectedFilter === 'accounts') { - hasMore = results.get('accountsHasMore'); - loaded = results.get('accountsLoaded'); - placeholderComponent = PlaceholderAccount; - - if (results.get('accounts') && results.get('accounts').size > 0) { - searchResults = results.get('accounts').map(accountId => ); - } else if (!submitted && suggestions && !suggestions.isEmpty()) { - searchResults = suggestions.map(suggestion => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - if (selectedFilter === 'statuses') { - hasMore = results.get('statusesHasMore'); - loaded = results.get('statusesLoaded'); - - if (results.get('statuses') && results.get('statuses').size > 0) { - searchResults = results.get('statuses').map(statusId => ); - } else if (!submitted && trendingStatuses && !trendingStatuses.isEmpty()) { - searchResults = trendingStatuses.map(statusId => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - if (selectedFilter === 'hashtags') { - hasMore = results.get('hashtagsHasMore'); - loaded = results.get('hashtagsLoaded'); - placeholderComponent = PlaceholderHashtag; - - if (results.get('hashtags') && results.get('hashtags').size > 0) { - searchResults = results.get('hashtags').map(hashtag => ); - } else if (!submitted && suggestions && !suggestions.isEmpty()) { - searchResults = trends.map(hashtag => ); - } else if (loaded) { - noResultsMessage = ( -
- -
- ); - } - } - - return ( - <> - {this.renderFilterBar()} - - {noResultsMessage || ( - - {searchResults} - - )} - - ); - } - -} diff --git a/app/soapbox/features/compose/components/search_results.tsx b/app/soapbox/features/compose/components/search_results.tsx new file mode 100644 index 000000000..91e7ff287 --- /dev/null +++ b/app/soapbox/features/compose/components/search_results.tsx @@ -0,0 +1,172 @@ +import classNames from 'classnames'; +import React from 'react'; +import { useEffect } from 'react'; +import { FormattedMessage, useIntl } from 'react-intl'; +import { defineMessages } from 'react-intl'; + +import { expandSearch, setFilter } from 'soapbox/actions/search'; +import { fetchTrendingStatuses } from 'soapbox/actions/trending_statuses'; +import Hashtag from 'soapbox/components/hashtag'; +import ScrollableList from 'soapbox/components/scrollable_list'; +import { Tabs } from 'soapbox/components/ui'; +import AccountContainer from 'soapbox/containers/account_container'; +import StatusContainer from 'soapbox/containers/status_container'; +import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account'; +import PlaceholderHashtag from 'soapbox/features/placeholder/components/placeholder_hashtag'; +import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; +import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; + +import type { SearchFilter } from 'soapbox/reducers/search'; + +const messages = defineMessages({ + accounts: { id: 'search_results.accounts', defaultMessage: 'People' }, + statuses: { id: 'search_results.statuses', defaultMessage: 'Posts' }, + hashtags: { id: 'search_results.hashtags', defaultMessage: 'Hashtags' }, +}); + +const SearchResults = () => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + + const value = useAppSelector((state) => state.search.submittedValue); + const results = useAppSelector((state) => state.search.results); + const suggestions = useAppSelector((state) => state.suggestions.items); + const trendingStatuses = useAppSelector((state) => state.trending_statuses.items); + const trends = useAppSelector((state) => state.trends.items); + const submitted = useAppSelector((state) => state.search.submitted); + const selectedFilter = useAppSelector((state) => state.search.filter); + + const handleLoadMore = () => dispatch(expandSearch(selectedFilter)); + + const selectFilter = (newActiveFilter: SearchFilter) => dispatch(setFilter(newActiveFilter)); + + const renderFilterBar = () => { + const items = [ + { + text: intl.formatMessage(messages.accounts), + action: () => selectFilter('accounts'), + name: 'accounts', + }, + { + text: intl.formatMessage(messages.statuses), + action: () => selectFilter('statuses'), + name: 'statuses', + }, + { + text: intl.formatMessage(messages.hashtags), + action: () => selectFilter('hashtags'), + name: 'hashtags', + }, + ]; + + return ; + }; + + useEffect(() => { + dispatch(fetchTrendingStatuses()); + }, []); + + let searchResults; + let hasMore = false; + let loaded; + let noResultsMessage; + let placeholderComponent = PlaceholderStatus as React.ComponentType; + + if (selectedFilter === 'accounts') { + hasMore = results.accountsHasMore; + loaded = results.accountsLoaded; + placeholderComponent = PlaceholderAccount; + + if (results.accounts && results.accounts.size > 0) { + searchResults = results.accounts.map(accountId => ); + } else if (!submitted && suggestions && !suggestions.isEmpty()) { + searchResults = suggestions.map(suggestion => ); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + if (selectedFilter === 'statuses') { + hasMore = results.statusesHasMore; + loaded = results.statusesLoaded; + + if (results.statuses && results.statuses.size > 0) { + searchResults = results.statuses.map((statusId: string) => ( + // @ts-ignore + + )); + } else if (!submitted && trendingStatuses && !trendingStatuses.isEmpty()) { + searchResults = trendingStatuses.map((statusId: string) => ( + // @ts-ignore + + )); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + if (selectedFilter === 'hashtags') { + hasMore = results.hashtagsHasMore; + loaded = results.hashtagsLoaded; + placeholderComponent = PlaceholderHashtag; + + if (results.hashtags && results.hashtags.size > 0) { + searchResults = results.hashtags.map(hashtag => ); + } else if (!submitted && suggestions && !suggestions.isEmpty()) { + searchResults = trends.map(hashtag => ); + } else if (loaded) { + noResultsMessage = ( +
+ +
+ ); + } + } + + return ( + <> + {renderFilterBar()} + + {noResultsMessage || ( + + {searchResults || []} + + )} + + ); +}; + +export default SearchResults; diff --git a/app/soapbox/features/compose/containers/search_results_container.js b/app/soapbox/features/compose/containers/search_results_container.js deleted file mode 100644 index e284060d9..000000000 --- a/app/soapbox/features/compose/containers/search_results_container.js +++ /dev/null @@ -1,33 +0,0 @@ -import { connect } from 'react-redux'; - -import { expandSearch, setFilter } from 'soapbox/actions/search'; -import { fetchSuggestions, dismissSuggestion } from 'soapbox/actions/suggestions'; -import { fetchTrendingStatuses } from 'soapbox/actions/trending_statuses'; -import { getFeatures } from 'soapbox/utils/features'; - -import SearchResults from '../components/search_results'; - -const mapStateToProps = state => { - const instance = state.get('instance'); - - return { - value: state.getIn(['search', 'submittedValue']), - results: state.getIn(['search', 'results']), - suggestions: state.getIn(['suggestions', 'items']), - trendingStatuses: state.getIn(['trending_statuses', 'items']), - trends: state.getIn(['trends', 'items']), - submitted: state.getIn(['search', 'submitted']), - selectedFilter: state.getIn(['search', 'filter']), - features: getFeatures(instance), - }; -}; - -const mapDispatchToProps = dispatch => ({ - fetchSuggestions: () => dispatch(fetchSuggestions()), - fetchTrendingStatuses: () => dispatch(fetchTrendingStatuses()), - expandSearch: type => dispatch(expandSearch(type)), - dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))), - selectFilter: newActiveFilter => dispatch(setFilter(newActiveFilter)), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(SearchResults); diff --git a/app/soapbox/features/report/containers/status_check_box_container.js b/app/soapbox/features/report/containers/status_check_box_container.js index 75daf7e2d..49bcf70f3 100644 --- a/app/soapbox/features/report/containers/status_check_box_container.js +++ b/app/soapbox/features/report/containers/status_check_box_container.js @@ -1,4 +1,3 @@ -import { Set as ImmutableSet } from 'immutable'; import { connect } from 'react-redux'; import { toggleStatusReport } from '../../../actions/reports'; @@ -6,7 +5,7 @@ import StatusCheckBox from '../components/status_check_box'; const mapStateToProps = (state, { id }) => ({ status: state.getIn(['statuses', id]), - checked: state.getIn(['reports', 'new', 'status_ids'], ImmutableSet()).includes(id), + checked: state.reports.new.status_ids.includes(id), }); const mapDispatchToProps = (dispatch, { id }) => ({ diff --git a/app/soapbox/features/search/components/header.js b/app/soapbox/features/search/components/header.js deleted file mode 100644 index 14f9d5ddb..000000000 --- a/app/soapbox/features/search/components/header.js +++ /dev/null @@ -1,60 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; -import { NavLink } from 'react-router-dom'; - -const mapStateToProps = state => ({ - value: state.getIn(['search', 'value']), - submitted: state.getIn(['search', 'submitted']), -}); - -class Header extends ImmutablePureComponent { - - static propTypes = { - value: PropTypes.string, - submitted: PropTypes.bool, - }; - - state = { - submittedValue: '', - }; - - componentDidUpdate(prevProps) { - if (this.props.submitted) { - const submittedValue = this.props.value; - this.setState({ submittedValue }); - } - } - - render() { - const { submittedValue } = this.state; - - if (!submittedValue) { - return null; - } - - return ( -
-
-

- {submittedValue} -

-
-
-
-
- - - -
-
-
-
- ); - } - -} - -export default connect(mapStateToProps)(Header); diff --git a/app/soapbox/features/search/index.tsx b/app/soapbox/features/search/index.tsx index 3fdf625f6..c17691c37 100644 --- a/app/soapbox/features/search/index.tsx +++ b/app/soapbox/features/search/index.tsx @@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl'; import { Column } from 'soapbox/components/ui'; import Search from 'soapbox/features/compose/components/search'; -import SearchResultsContainer from 'soapbox/features/compose/containers/search_results_container'; +import SearchResults from 'soapbox/features/compose/components/search_results'; const messages = defineMessages({ heading: { id: 'column.search', defaultMessage: 'Search' }, @@ -16,7 +16,7 @@ const SearchPage = () => {
- +
); diff --git a/app/soapbox/features/ui/components/__tests__/trends-panel.test.tsx b/app/soapbox/features/ui/components/__tests__/trends-panel.test.tsx index d122090c2..6701c928d 100644 --- a/app/soapbox/features/ui/components/__tests__/trends-panel.test.tsx +++ b/app/soapbox/features/ui/components/__tests__/trends-panel.test.tsx @@ -1,4 +1,4 @@ -import { Map as ImmutableMap, fromJS } from 'immutable'; +import { List as ImmutableList } from 'immutable'; import React from 'react'; import { render, screen } from '../../../../jest/test-helpers'; @@ -7,16 +7,16 @@ import TrendsPanel from '../trends-panel'; describe('', () => { it('renders trending hashtags', () => { const store = { - trends: ImmutableMap({ - items: fromJS([{ + trends: { + items: ImmutableList([{ name: 'hashtag 1', - history: [{ + history: ImmutableList([{ day: '1652745600', uses: '294', accounts: '180', - }], + }]), }]), - }), + }, }; render(, null, store); @@ -27,18 +27,18 @@ describe('', () => { it('renders multiple trends', () => { const store = { - trends: ImmutableMap({ - items: fromJS([ + trends: { + items: ImmutableList([ { name: 'hashtag 1', - history: [{ accounts: [] }], + history: ImmutableList([{ accounts: [] }]), }, { name: 'hashtag 2', - history: [{ accounts: [] }], + history: ImmutableList([{ accounts: [] }]), }, ]), - }), + }, }; render(, null, store); @@ -47,18 +47,18 @@ describe('', () => { it('respects the limit prop', () => { const store = { - trends: ImmutableMap({ - items: fromJS([ + trends: { + items: ImmutableList([ { name: 'hashtag 1', - history: [{ accounts: [] }], + history: ImmutableList([{ accounts: [] }]), }, { name: 'hashtag 2', - history: [{ accounts: [] }], + history: ImmutableList([{ accounts: [] }]), }, ]), - }), + }, }; render(, null, store); @@ -67,9 +67,9 @@ describe('', () => { it('renders empty', () => { const store = { - trends: ImmutableMap({ - items: fromJS([]), - }), + trends: { + items: ImmutableList([]), + }, }; render(, null, store); diff --git a/app/soapbox/features/ui/components/account_note_modal.js b/app/soapbox/features/ui/components/account_note_modal.js deleted file mode 100644 index 9242b7b8f..000000000 --- a/app/soapbox/features/ui/components/account_note_modal.js +++ /dev/null @@ -1,101 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; - -import { changeAccountNoteComment, submitAccountNote } from 'soapbox/actions/account-notes'; -import { closeModal } from 'soapbox/actions/modals'; -import { Modal, Text } from 'soapbox/components/ui'; -import { makeGetAccount } from 'soapbox/selectors'; - - -const messages = defineMessages({ - placeholder: { id: 'account_note.placeholder', defaultMessage: 'No comment provided' }, - save: { id: 'account_note.save', defaultMessage: 'Save' }, -}); - -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); - - const mapStateToProps = state => ({ - isSubmitting: state.getIn(['account_notes', 'edit', 'isSubmitting']), - account: getAccount(state, state.getIn(['account_notes', 'edit', 'account_id'])), - comment: state.getIn(['account_notes', 'edit', 'comment']), - }); - - return mapStateToProps; -}; - -const mapDispatchToProps = dispatch => { - return { - onConfirm() { - dispatch(submitAccountNote()); - }, - - onClose() { - dispatch(closeModal()); - }, - - onCommentChange(comment) { - dispatch(changeAccountNoteComment(comment)); - }, - }; -}; - -export default @connect(makeMapStateToProps, mapDispatchToProps) -@injectIntl -class AccountNoteModal extends React.PureComponent { - - static propTypes = { - isSubmitting: PropTypes.bool, - account: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired, - onCommentChange: PropTypes.func.isRequired, - comment: PropTypes.string, - intl: PropTypes.object.isRequired, - }; - - handleCommentChange = e => { - this.props.onCommentChange(e.target.value); - } - - handleSubmit = () => { - this.props.onConfirm(); - } - - handleKeyDown = e => { - if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { - this.handleSubmit(); - } - } - - render() { - const { account, isSubmitting, comment, onClose, intl } = this.props; - - return ( - } - onClose={onClose} - confirmationAction={this.handleSubmit} - confirmationText={intl.formatMessage(messages.save)} - confirmationDisabled={isSubmitting} - > - - - - -