diff options
70 files changed, 153 insertions, 208 deletions
diff --git a/.eslintrc.yml b/.eslintrc.yml index 2fb54ae66..a816bffef 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,7 +1,9 @@ --- +root: true + env: browser: true - node: false + node: true es6: true parser: babel-eslint @@ -52,8 +54,14 @@ rules: no-mixed-spaces-and-tabs: warn no-nested-ternary: warn no-trailing-spaces: warn + no-undef: error no-unreachable: error no-unused-expressions: error + no-unused-vars: + - error + - vars: all + args: after-used + ignoreRestSiblings: true object-curly-spacing: - error - always @@ -81,7 +89,10 @@ rules: - 2 react/jsx-no-bind: error react/jsx-no-duplicate-props: error + react/jsx-no-undef: error react/jsx-tag-spacing: error + react/jsx-uses-react: error + react/jsx-uses-vars: error react/jsx-wrap-multilines: error react/no-multi-comp: off react/no-string-refs: error diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js index a862798f9..03e3d3d9f 100644 --- a/app/javascript/mastodon/actions/accounts.js +++ b/app/javascript/mastodon/actions/accounts.js @@ -1,5 +1,4 @@ import api, { getLinks } from '../api'; -import Immutable from 'immutable'; export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST'; export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS'; @@ -597,7 +596,7 @@ export function authorizeFollowRequest(id) { api(getState) .post(`/api/v1/follow_requests/${id}/authorize`) - .then(response => dispatch(authorizeFollowRequestSuccess(id))) + .then(() => dispatch(authorizeFollowRequestSuccess(id))) .catch(error => dispatch(authorizeFollowRequestFail(id, error))); }; }; @@ -631,7 +630,7 @@ export function rejectFollowRequest(id) { api(getState) .post(`/api/v1/follow_requests/${id}/reject`) - .then(response => dispatch(rejectFollowRequestSuccess(id))) + .then(() => dispatch(rejectFollowRequestSuccess(id))) .catch(error => dispatch(rejectFollowRequestFail(id, error))); }; }; diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js index 530ba9cf1..44363697a 100644 --- a/app/javascript/mastodon/actions/domain_blocks.js +++ b/app/javascript/mastodon/actions/domain_blocks.js @@ -16,7 +16,7 @@ export function blockDomain(domain, accountId) { return (dispatch, getState) => { dispatch(blockDomainRequest(domain)); - api(getState).post('/api/v1/domain_blocks', { domain }).then(response => { + api(getState).post('/api/v1/domain_blocks', { domain }).then(() => { dispatch(blockDomainSuccess(domain, accountId)); }).catch(err => { dispatch(blockDomainFail(domain, err)); @@ -51,7 +51,7 @@ export function unblockDomain(domain, accountId) { return (dispatch, getState) => { dispatch(unblockDomainRequest(domain)); - api(getState).delete('/api/v1/domain_blocks', { params: { domain } }).then(response => { + api(getState).delete('/api/v1/domain_blocks', { params: { domain } }).then(() => { dispatch(unblockDomainSuccess(domain, accountId)); }).catch(err => { dispatch(unblockDomainFail(domain, err)); diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index d3de2d871..cda636139 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -17,7 +17,7 @@ export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL'; export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR'; export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP'; -const messages = defineMessages({ +defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, }); diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 6956447ba..8d385715c 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -74,7 +74,7 @@ export function deleteStatus(id) { return (dispatch, getState) => { dispatch(deleteStatusRequest(id)); - api(getState).delete(`/api/v1/statuses/${id}`).then(response => { + api(getState).delete(`/api/v1/statuses/${id}`).then(() => { dispatch(deleteStatusSuccess(id)); dispatch(deleteFromTimelines(id)); }).catch(error => { @@ -152,7 +152,7 @@ export function muteStatus(id) { return (dispatch, getState) => { dispatch(muteStatusRequest(id)); - api(getState).post(`/api/v1/statuses/${id}/mute`).then(response => { + api(getState).post(`/api/v1/statuses/${id}/mute`).then(() => { dispatch(muteStatusSuccess(id)); }).catch(error => { dispatch(muteStatusFail(id, error)); @@ -186,7 +186,7 @@ export function unmuteStatus(id) { return (dispatch, getState) => { dispatch(unmuteStatusRequest(id)); - api(getState).post(`/api/v1/statuses/${id}/unmute`).then(response => { + api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => { dispatch(unmuteStatusSuccess(id)); }).catch(error => { dispatch(unmuteStatusFail(id, error)); diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 6e394a95d..deaab938e 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -56,7 +56,7 @@ class DropdownMenu extends React.PureComponent { return <li key={`sep-${i}`} className='dropdown__sep' />; } - const { text, action, href = '#' } = item; + const { text, href = '#' } = item; return ( <li className='dropdown__content-list-item' key={`${text}-${i}`}> diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 465130cec..cbed90f82 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -138,7 +138,7 @@ class MediaGallery extends React.PureComponent { visible: !this.props.sensitive, }; - handleOpen = (e) => { + handleOpen = () => { this.setState({ visible: !this.state.visible }); } diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 1363956cf..3be3685ec 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -7,7 +7,6 @@ import RelativeTimestamp from './relative_timestamp'; import DisplayName from './display_name'; import MediaGallery from './media_gallery'; import VideoPlayer from './video_player'; -import AttachmentList from './attachment_list'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; import { FormattedMessage } from 'react-intl'; diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index d02083d3e..605d42138 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -32,7 +32,6 @@ class StatusContent extends React.PureComponent { for (var i = 0; i < links.length; ++i) { let link = links[i]; let mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); - let media = this.props.status.get('media_attachments').find(item => link.href === item.get('text_url') || (item.get('remote_url').length > 0 && link.href === item.get('remote_url'))); if (mention) { link.addEventListener('click', this.onMentionClick.bind(this, mention), false); diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js index b73a73d1b..40e9d38c1 100644 --- a/app/javascript/mastodon/components/status_list.js +++ b/app/javascript/mastodon/components/status_list.js @@ -99,7 +99,7 @@ class StatusList extends ImmutablePureComponent { } render () { - const { statusIds, onScrollToBottom, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, emptyMessage } = this.props; + const { statusIds, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, emptyMessage } = this.props; let loadMore = null; let scrollableArea = null; diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js index d44cb1be4..e3cb815c9 100644 --- a/app/javascript/mastodon/containers/mastodon.js +++ b/app/javascript/mastodon/containers/mastodon.js @@ -3,7 +3,6 @@ import { Provider } from 'react-redux'; import PropTypes from 'prop-types'; import configureStore from '../store/configureStore'; import { - refreshTimelineSuccess, updateTimeline, deleteFromTimelines, refreshHomeTimeline, diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js index 2592e9a69..438ecfe43 100644 --- a/app/javascript/mastodon/containers/status_container.js +++ b/app/javascript/mastodon/containers/status_container.js @@ -19,8 +19,6 @@ import { import { muteStatus, unmuteStatus, deleteStatus } from '../actions/statuses'; import { initReport } from '../actions/reports'; import { openModal } from '../actions/modal'; -import { createSelector } from 'reselect'; -import { isMobile } from '../is_mobile'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; const messages = defineMessages({ diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 653023cba..80a671a01 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -17,7 +17,7 @@ const messages = defineMessages({ }); const makeMapStateToProps = () => { - const mapStateToProps = (state, props) => ({ + const mapStateToProps = state => ({ autoPlayGif: state.getIn(['meta', 'auto_play_gif']), }); diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js index fcbee3c89..1e4af30a4 100644 --- a/app/javascript/mastodon/features/account_gallery/index.js +++ b/app/javascript/mastodon/features/account_gallery/index.js @@ -7,7 +7,6 @@ import { refreshAccountMediaTimeline, expandAccountMediaTimeline } from '../../a import LoadingIndicator from '../../components/loading_indicator'; import Column from '../ui/components/column'; import ColumnBackButton from '../../components/column_back_button'; -import Immutable from 'immutable'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { getAccountGallery } from '../../selectors'; import MediaItem from './components/media_item'; diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.js index dbbe8ceaa..aa487e34e 100644 --- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.js @@ -2,8 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import ColumnCollapsable from '../../../components/column_collapsable'; -import SettingToggle from '../../notifications/components/setting_toggle'; import SettingText from '../../../components/setting_text'; const messages = defineMessages({ @@ -16,12 +14,11 @@ class ColumnSettings extends React.PureComponent { static propTypes = { settings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, - onSave: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; render () { - const { settings, onChange, onSave, intl } = this.props; + const { settings, onChange, intl } = this.props; return ( <div> diff --git a/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js index 1efc2ef33..f3489b409 100644 --- a/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/community_timeline/containers/column_settings_container.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import ColumnSettings from '../components/column_settings'; -import { changeSetting, saveSettings } from '../../../actions/settings'; +import { changeSetting } from '../../../actions/settings'; const mapStateToProps = state => ({ settings: state.getIn(['settings', 'community']), @@ -12,10 +12,6 @@ const mapDispatchToProps = dispatch => ({ dispatch(changeSetting(['community', ...key], checked)); }, - onSave () { - dispatch(saveSettings()); - }, - }); export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js index 4fbe67038..6c4b5dacf 100644 --- a/app/javascript/mastodon/features/community_timeline/index.js +++ b/app/javascript/mastodon/features/community_timeline/index.js @@ -14,7 +14,6 @@ import { } from '../../actions/timelines'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; import ColumnSettingsContainer from './containers/column_settings_container'; import createStream from '../../stream'; diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 0ee45c978..d75bbdf9c 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -7,15 +7,13 @@ import ReplyIndicatorContainer from '../containers/reply_indicator_container'; import AutosuggestTextarea from '../../../components/autosuggest_textarea'; import { debounce } from 'lodash'; import UploadButtonContainer from '../containers/upload_button_container'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import Toggle from 'react-toggle'; +import { defineMessages, injectIntl } from 'react-intl'; import Collapsable from '../../../components/collapsable'; import SpoilerButtonContainer from '../containers/spoiler_button_container'; import PrivacyDropdownContainer from '../containers/privacy_dropdown_container'; import SensitiveButtonContainer from '../containers/sensitive_button_container'; import EmojiPickerDropdown from './emoji_picker_dropdown'; import UploadFormContainer from '../containers/upload_form_container'; -import TextIconButton from './text_icon_button'; import WarningContainer from '../containers/warning_container'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { length } from 'stringz'; @@ -141,7 +139,6 @@ class ComposeForm extends ImmutablePureComponent { const text = [this.props.spoiler_text, this.props.text].join(''); let publishText = ''; - let reply_to_other = false; if (this.props.privacy === 'private' || this.props.privacy === 'direct') { publishText = <span className='compose-form__publish-private'><i className='fa fa-lock' /> {intl.formatMessage(messages.publish)}</span>; diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js index 9ac674bb3..afaff1be1 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -52,7 +52,7 @@ class EmojiPickerDropdown extends React.PureComponent { import(/* webpackChunkName: "emojione_picker" */ 'emojione-picker').then(TheEmojiPicker => { EmojiPicker = TheEmojiPicker.default; this.setState({ loading: false }); - }).catch(err => { + }).catch(() => { // TODO: show the user an error? this.setState({ loading: false }); }); diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js index 1c135a733..00f27dea1 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.js +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js @@ -1,11 +1,8 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Avatar from '../../../components/avatar'; -import IconButton from '../../../components/icon_button'; -import DisplayName from '../../../components/display_name'; import Permalink from '../../../components/permalink'; import { FormattedMessage } from 'react-intl'; -import Link from 'react-router-dom/Link'; import ImmutablePureComponent from 'react-immutable-pure-component'; class NavigationBar extends ImmutablePureComponent { diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js index 49f1179a0..f368186a5 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js @@ -64,7 +64,7 @@ class PrivacyDropdown extends React.PureComponent { } render () { - const { value, onChange, intl } = this.props; + const { value, intl } = this.props; const { open } = this.state; const options = [ diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js index 800080a7d..21b3cf34b 100644 --- a/app/javascript/mastodon/features/compose/components/search.js +++ b/app/javascript/mastodon/features/compose/components/search.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; const messages = defineMessages({ placeholder: { id: 'search.placeholder', defaultMessage: 'Search' }, diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js index 26d766a1c..1a2605c15 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.js +++ b/app/javascript/mastodon/features/compose/components/search_results.js @@ -1,6 +1,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { FormattedMessage } from 'react-intl'; import AccountContainer from '../../../containers/account_container'; import StatusContainer from '../../../containers/status_container'; import Link from 'react-router-dom/Link'; diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js index 326b9851a..0f11b9e8b 100644 --- a/app/javascript/mastodon/features/compose/components/upload_button.js +++ b/app/javascript/mastodon/features/compose/components/upload_button.js @@ -11,7 +11,7 @@ const messages = defineMessages({ }); const makeMapStateToProps = () => { - const mapStateToProps = (state, props) => ({ + const mapStateToProps = state => ({ acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']), }); diff --git a/app/javascript/mastodon/features/compose/containers/navigation_container.js b/app/javascript/mastodon/features/compose/containers/navigation_container.js index 75f288f18..8cc53c087 100644 --- a/app/javascript/mastodon/features/compose/containers/navigation_container.js +++ b/app/javascript/mastodon/features/compose/containers/navigation_container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import NavigationBar from '../components/navigation_bar'; -const mapStateToProps = (state, props) => { +const mapStateToProps = state => { return { account: state.getIn(['accounts', state.getIn(['meta', 'me'])]), }; diff --git a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js index 7f3eeb89c..73f394c1a 100644 --- a/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js +++ b/app/javascript/mastodon/features/compose/containers/reply_indicator_container.js @@ -6,7 +6,7 @@ import ReplyIndicator from '../components/reply_indicator'; const makeMapStateToProps = () => { const getStatus = makeGetStatus(); - const mapStateToProps = (state, props) => ({ + const mapStateToProps = state => ({ status: getStatus(state, state.getIn(['compose', 'in_reply_to'])), }); diff --git a/app/javascript/mastodon/features/compose/containers/upload_form_container.js b/app/javascript/mastodon/features/compose/containers/upload_form_container.js index 3125564c2..4612599f1 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_form_container.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import UploadForm from '../components/upload_form'; import { undoUploadCompose } from '../../../actions/compose'; -const mapStateToProps = (state, props) => ({ +const mapStateToProps = state => ({ media: state.getIn(['compose', 'media_attachments']), }); diff --git a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js b/app/javascript/mastodon/features/compose/containers/upload_progress_container.js index 51af4440c..0cfee96da 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_progress_container.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import UploadProgress from '../components/upload_progress'; -const mapStateToProps = (state, props) => ({ +const mapStateToProps = state => ({ active: state.getIn(['compose', 'is_uploading']), progress: state.getIn(['compose', 'progress']), }); diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index a87e48a23..0452de856 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -1,6 +1,5 @@ import React from 'react'; import ComposeFormContainer from './containers/compose_form_container'; -import UploadFormContainer from './containers/upload_form_container'; import NavigationContainer from './containers/navigation_container'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.js index 2b343ba5a..caf0d2ca2 100644 --- a/app/javascript/mastodon/features/favourited_statuses/index.js +++ b/app/javascript/mastodon/features/favourited_statuses/index.js @@ -1,7 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; import LoadingIndicator from '../../components/loading_indicator'; import { fetchFavouritedStatuses, expandFavouritedStatuses } from '../../actions/favourites'; import Column from '../ui/components/column'; @@ -15,19 +14,15 @@ const messages = defineMessages({ }); const mapStateToProps = state => ({ - statusIds: state.getIn(['status_lists', 'favourites', 'items']), loaded: state.getIn(['status_lists', 'favourites', 'loaded']), - me: state.getIn(['meta', 'me']), }); class Favourites extends ImmutablePureComponent { static propTypes = { dispatch: PropTypes.func.isRequired, - statusIds: ImmutablePropTypes.list.isRequired, loaded: PropTypes.bool, intl: PropTypes.object.isRequired, - me: PropTypes.number.isRequired, }; componentWillMount () { @@ -39,7 +34,7 @@ class Favourites extends ImmutablePureComponent { } render () { - const { statusIds, loaded, intl, me } = this.props; + const { loaded, intl } = this.props; if (!loaded) { return ( diff --git a/app/javascript/mastodon/features/follow_requests/containers/account_authorize_container.js b/app/javascript/mastodon/features/follow_requests/containers/account_authorize_container.js index a423bc79b..8db471f73 100644 --- a/app/javascript/mastodon/features/follow_requests/containers/account_authorize_container.js +++ b/app/javascript/mastodon/features/follow_requests/containers/account_authorize_container.js @@ -14,11 +14,11 @@ const makeMapStateToProps = () => { }; const mapDispatchToProps = (dispatch, { id }) => ({ - onAuthorize (account) { + onAuthorize () { dispatch(authorizeFollowRequest(id)); }, - onReject (account) { + onReject () { dispatch(rejectFollowRequest(id)); }, }); diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index a4549e609..c1eb06fcb 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -2,7 +2,6 @@ import React from 'react'; import Column from '../ui/components/column'; import ColumnLink from '../ui/components/column_link'; import ColumnSubheading from '../ui/components/column_subheading'; -import Link from 'react-router-dom/Link'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js index 3b2f1ba93..853434d4b 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.js +++ b/app/javascript/mastodon/features/hashtag_timeline/index.js @@ -11,7 +11,6 @@ import { deleteFromTimelines, } from '../../actions/timelines'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; import { FormattedMessage } from 'react-intl'; import createStream from '../../stream'; diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.js index 104d8ff37..47cd340af 100644 --- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import ColumnCollapsable from '../../../components/column_collapsable'; import SettingToggle from '../../notifications/components/setting_toggle'; import SettingText from '../../../components/setting_text'; @@ -16,29 +15,28 @@ class ColumnSettings extends React.PureComponent { static propTypes = { settings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, - onSave: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; render () { - const { settings, onChange, onSave, intl } = this.props; + const { settings, onChange, intl } = this.props; return ( <div> <span className='column-settings__section'><FormattedMessage id='home.column_settings.basic' defaultMessage='Basic' /></span> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} /> + <SettingToggle prefix='home_timeline' settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} /> </div> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} /> + <SettingToggle prefix='home_timeline' settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} /> </div> <span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span> <div className='column-settings__row'> - <SettingText settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} /> + <SettingText prefix='home_timeline' settings={settings} settingKey={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} /> </div> </div> ); diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index 7bfd02f11..2051e0c86 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { FormattedMessage } from 'react-intl'; -import ColumnCollapsable from '../../../components/column_collapsable'; import ClearColumnButton from './clear_column_button'; import SettingToggle from './setting_toggle'; @@ -16,7 +15,7 @@ class ColumnSettings extends React.PureComponent { }; render () { - const { settings, onChange, onSave, onClear } = this.props; + const { settings, onChange, onClear } = this.props; const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />; const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />; @@ -31,33 +30,33 @@ class ColumnSettings extends React.PureComponent { <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} /> - <SettingToggle settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} /> - <SettingToggle settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} /> </div> <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} /> - <SettingToggle settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} /> - <SettingToggle settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} /> </div> <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} /> - <SettingToggle settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} /> - <SettingToggle settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} /> </div> <span className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span> <div className='column-settings__row'> - <SettingToggle settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} /> - <SettingToggle settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} /> - <SettingToggle settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} /> </div> </div> ); diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index 6ec4d5dc6..ede37f66a 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -2,7 +2,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import StatusContainer from '../../../containers/status_container'; import AccountContainer from '../../../containers/account_container'; -import Avatar from '../../../components/avatar'; import { FormattedMessage } from 'react-intl'; import Permalink from '../../../components/permalink'; import emojify from '../../../emoji'; diff --git a/app/javascript/mastodon/features/notifications/components/setting_toggle.js b/app/javascript/mastodon/features/notifications/components/setting_toggle.js index a37abbd9c..8707a993e 100644 --- a/app/javascript/mastodon/features/notifications/components/setting_toggle.js +++ b/app/javascript/mastodon/features/notifications/components/setting_toggle.js @@ -6,19 +6,20 @@ import Toggle from 'react-toggle'; class SettingToggle extends React.PureComponent { static propTypes = { + prefix: PropTypes.string, settings: ImmutablePropTypes.map.isRequired, settingKey: PropTypes.array.isRequired, label: PropTypes.node.isRequired, onChange: PropTypes.func.isRequired, } - onChange = (e) => { - this.props.onChange(this.props.settingKey, e.target.checked); + onChange = ({ target }) => { + this.props.onChange(this.props.settingKey, target.checked); } render () { - const { settings, settingKey, label, onChange } = this.props; - const id = `setting-toggle-${settingKey.join('-')}`; + const { prefix, settings, settingKey, label } = this.props; + const id = ['setting-toggle', prefix, ...settingKey].filter(Boolean).join('-'); return ( <div className='setting-toggle'> diff --git a/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js index 62d4e7e5a..203e1da92 100644 --- a/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/public_timeline/containers/column_settings_container.js @@ -1,6 +1,6 @@ import { connect } from 'react-redux'; import ColumnSettings from '../../community_timeline/components/column_settings'; -import { changeSetting, saveSettings } from '../../../actions/settings'; +import { changeSetting } from '../../../actions/settings'; const mapStateToProps = state => ({ settings: state.getIn(['settings', 'public']), @@ -12,10 +12,6 @@ const mapDispatchToProps = dispatch => ({ dispatch(changeSetting(['public', ...key], checked)); }, - onSave () { - dispatch(saveSettings()); - }, - }); export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings); diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js index 02ddb418f..3de54ef8b 100644 --- a/app/javascript/mastodon/features/public_timeline/index.js +++ b/app/javascript/mastodon/features/public_timeline/index.js @@ -14,7 +14,6 @@ import { } from '../../actions/timelines'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; import ColumnSettingsContainer from './containers/column_settings_container'; import createStream from '../../stream'; diff --git a/app/javascript/mastodon/features/report/index.js b/app/javascript/mastodon/features/report/index.js index 23aba39de..0a5268430 100644 --- a/app/javascript/mastodon/features/report/index.js +++ b/app/javascript/mastodon/features/report/index.js @@ -1,6 +1,6 @@ import React from 'react'; import { connect } from 'react-redux'; -import { cancelReport, changeReportComment, submitReport } from '../../actions/reports'; +import { changeReportComment, submitReport } from '../../actions/reports'; import { refreshAccountTimeline } from '../../actions/timelines'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 19cee2435..afd8a7811 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -3,8 +3,6 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { fetchStatus } from '../../actions/statuses'; -import Immutable from 'immutable'; -import EmbeddedStatus from '../../components/status'; import MissingIndicator from '../../components/missing_indicator'; import DetailedStatus from './components/detailed_status'; import ActionBar from './components/action_bar'; @@ -21,17 +19,12 @@ import { } from '../../actions/compose'; import { deleteStatus } from '../../actions/statuses'; import { initReport } from '../../actions/reports'; -import { - makeGetStatus, - getStatusAncestors, - getStatusDescendants, -} from '../../selectors'; +import { makeGetStatus } from '../../selectors'; import { ScrollContainer } from 'react-router-scroll'; import ColumnBackButton from '../../components/column_back_button'; import StatusContainer from '../../containers/status_container'; import { openModal } from '../../actions/modal'; -import { isMobile } from '../../is_mobile'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; const messages = defineMessages({ @@ -159,8 +152,6 @@ class Status extends ImmutablePureComponent { ); } - const account = status.get('account'); - if (ancestorsIds && ancestorsIds.size > 0) { ancestors = <div>{this.renderChildren(ancestorsIds)}</div>; } diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index da2be5264..9a8b96333 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -2,7 +2,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import IconButton from '../../../components/icon_button'; import Button from '../../../components/button'; import StatusContent from '../../../components/status_content'; import Avatar from '../../../components/avatar'; @@ -49,7 +48,7 @@ class BoostModal extends ImmutablePureComponent { } render () { - const { status, intl, onClose } = this.props; + const { status, intl } = this.props; return ( <div className='modal-root__modal boost-modal'> diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.js index f33bfd445..a45c220fa 100644 --- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js +++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { injectIntl, FormattedMessage } from 'react-intl'; import Button from '../../../components/button'; class ConfirmationModal extends React.PureComponent { diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js index a2514d6be..94bf55bad 100644 --- a/app/javascript/mastodon/features/ui/components/image_loader.js +++ b/app/javascript/mastodon/features/ui/components/image_loader.js @@ -41,7 +41,7 @@ class ImageLoader extends React.PureComponent { render() { const { alt, src, previewSrc, width, height } = this.props; - const { loading, error } = this.state; + const { loading } = this.state; return ( <div className='image-loader'> diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js index c6b293aeb..0209bc99b 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.js @@ -1,6 +1,5 @@ import React from 'react'; import ReactSwipeable from 'react-swipeable'; -import LoadingIndicator from '../../../components/loading_indicator'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js index c8985dc83..279599169 100644 --- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js +++ b/app/javascript/mastodon/features/ui/components/onboarding_modal.js @@ -72,7 +72,7 @@ PageTwo.propTypes = { me: ImmutablePropTypes.map.isRequired, }; -const PageThree = ({ me, domain }) => ( +const PageThree = ({ me }) => ( <div className='onboarding-modal__page onboarding-modal__page-three'> <div className='figure non-interactive'> <Search @@ -95,7 +95,6 @@ const PageThree = ({ me, domain }) => ( PageThree.propTypes = { me: ImmutablePropTypes.map.isRequired, - domain: PropTypes.string.isRequired, }; const PageFour = ({ domain, intl }) => ( @@ -187,7 +186,7 @@ class OnboardingModal extends React.PureComponent { this.pages = [ <PageOne acct={me.get('acct')} domain={domain} />, <PageTwo me={me} />, - <PageThree me={me} domain={domain} />, + <PageThree me={me} />, <PageFour domain={domain} intl={intl} />, <PageSix admin={admin} domain={domain} />, ]; diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js index c622085f9..3599ab775 100644 --- a/app/javascript/mastodon/features/ui/components/video_modal.js +++ b/app/javascript/mastodon/features/ui/components/video_modal.js @@ -1,5 +1,4 @@ import React from 'react'; -import LoadingIndicator from '../../../components/loading_indicator'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; diff --git a/app/javascript/mastodon/features/ui/containers/notifications_container.js b/app/javascript/mastodon/features/ui/containers/notifications_container.js index 8bc30df35..5924197f1 100644 --- a/app/javascript/mastodon/features/ui/containers/notifications_container.js +++ b/app/javascript/mastodon/features/ui/containers/notifications_container.js @@ -1,12 +1,9 @@ import { connect } from 'react-redux'; import { NotificationStack } from 'react-notification'; -import { - dismissAlert, - clearAlerts, -} from '../../../actions/alerts'; +import { dismissAlert } from '../../../actions/alerts'; import { getAlerts } from '../../../selectors'; -const mapStateToProps = (state, props) => ({ +const mapStateToProps = state => ({ notifications: getAlerts(state), }); diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 39600607f..e48e9dbe9 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -74,9 +74,6 @@ class WrappedRoute extends React.Component { } -const noOp = () => false; - - class UI extends React.PureComponent { static propTypes = { diff --git a/app/javascript/mastodon/middleware/errors.js b/app/javascript/mastodon/middleware/errors.js index 4aca75f1e..b2c5f0898 100644 --- a/app/javascript/mastodon/middleware/errors.js +++ b/app/javascript/mastodon/middleware/errors.js @@ -1,13 +1,11 @@ import { showAlert } from '../actions/alerts'; -const defaultSuccessSuffix = 'SUCCESS'; const defaultFailSuffix = 'FAIL'; export default function errorsMiddleware() { return ({ dispatch }) => next => action => { if (action.type && !action.skipAlert) { const isFail = new RegExp(`${defaultFailSuffix}$`, 'g'); - const isSuccess = new RegExp(`${defaultSuccessSuffix}$`, 'g'); if (action.type.match(isFail)) { if (action.error.response) { diff --git a/app/javascript/mastodon/middleware/sounds.js b/app/javascript/mastodon/middleware/sounds.js index fd5a2b960..372e7c835 100644 --- a/app/javascript/mastodon/middleware/sounds.js +++ b/app/javascript/mastodon/middleware/sounds.js @@ -32,7 +32,7 @@ export default function soundsMiddleware() { ]), }; - return ({ dispatch }) => next => (action) => { + return () => next => action => { if (action.meta && action.meta.sound && soundCache[action.meta.sound]) { play(soundCache[action.meta.sound]); } diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 2413df9e2..d0b47a85c 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -20,7 +20,6 @@ import { COMPOSE_SPOILERNESS_CHANGE, COMPOSE_SPOILER_TEXT_CHANGE, COMPOSE_VISIBILITY_CHANGE, - COMPOSE_LISTABILITY_CHANGE, COMPOSE_EMOJI_INSERT, } from '../actions/compose'; import { TIMELINE_DELETE } from '../actions/timelines'; diff --git a/app/javascript/mastodon/reducers/modal.js b/app/javascript/mastodon/reducers/modal.js index 8fd9a69cd..599a2443e 100644 --- a/app/javascript/mastodon/reducers/modal.js +++ b/app/javascript/mastodon/reducers/modal.js @@ -1,5 +1,4 @@ import { MODAL_OPEN, MODAL_CLOSE } from '../actions/modal'; -import Immutable from 'immutable'; const initialState = { modalType: null, diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js index ed395427e..0a3adac05 100644 --- a/app/javascript/mastodon/reducers/search.js +++ b/app/javascript/mastodon/reducers/search.js @@ -14,60 +14,6 @@ const initialState = Immutable.Map({ results: Immutable.Map(), }); -const normalizeSuggestions = (state, value, accounts, hashtags, statuses) => { - let newSuggestions = []; - - if (accounts.length > 0) { - newSuggestions.push({ - title: 'account', - items: accounts.map(item => ({ - type: 'account', - id: item.id, - value: item.acct, - })), - }); - } - - if (value.indexOf('@') === -1 && value.indexOf(' ') === -1 || hashtags.length > 0) { - let hashtagItems = hashtags.map(item => ({ - type: 'hashtag', - id: item, - value: `#${item}`, - })); - - if (value.indexOf('@') === -1 && value.indexOf(' ') === -1 && !value.startsWith('http://') && !value.startsWith('https://') && hashtags.indexOf(value) === -1) { - hashtagItems.unshift({ - type: 'hashtag', - id: value, - value: `#${value}`, - }); - } - - if (hashtagItems.length > 0) { - newSuggestions.push({ - title: 'hashtag', - items: hashtagItems, - }); - } - } - - if (statuses.length > 0) { - newSuggestions.push({ - title: 'status', - items: statuses.map(item => ({ - type: 'status', - id: item.id, - value: item.id, - })), - }); - } - - return state.withMutations(map => { - map.set('suggestions', newSuggestions); - map.set('loaded_value', value); - }); -}; - export default function search(state = initialState, action) { switch(action.type) { case SEARCH_CHANGE: diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 2bc1c8050..1b738a16a 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -12,12 +12,6 @@ import { TIMELINE_DISCONNECT, } from '../actions/timelines'; import { - REBLOG_SUCCESS, - UNREBLOG_SUCCESS, - FAVOURITE_SUCCESS, - UNFAVOURITE_SUCCESS, -} from '../actions/interactions'; -import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS, } from '../actions/accounts'; diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index d5d736e2f..07d9a2629 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,9 +1,6 @@ import { createSelector } from 'reselect'; import Immutable from 'immutable'; -const getStatuses = state => state.get('statuses'); -const getAccounts = state => state.get('accounts'); - const getAccountBase = (state, id) => state.getIn(['accounts', id], null); const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null); const getAccountRelationship = (state, id) => state.getIn(['relationships', id], null); diff --git a/app/javascript/mastodon/store/configureStore.js b/app/javascript/mastodon/store/configureStore.js index a92d756f5..1376d4cba 100644 --- a/app/javascript/mastodon/store/configureStore.js +++ b/app/javascript/mastodon/store/configureStore.js @@ -4,7 +4,6 @@ import appReducer from '../reducers'; import loadingBarMiddleware from '../middleware/loading_bar'; import errorsMiddleware from '../middleware/errors'; import soundsMiddleware from '../middleware/sounds'; -import Immutable from 'immutable'; export default function configureStore() { return createStore(appReducer, compose(applyMiddleware( diff --git a/config/webpack/production.js b/config/webpack/production.js index 303fca81b..0d2c9acfb 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -12,6 +12,7 @@ module.exports = merge(sharedConfig, { stats: 'normal', plugins: [ + new webpack.optimize.ModuleConcatenationPlugin(), new webpack.optimize.UglifyJsPlugin({ sourceMap: true, mangle: true, diff --git a/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb new file mode 100644 index 000000000..3e74346a8 --- /dev/null +++ b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb @@ -0,0 +1,13 @@ +class AddStatusesIndexOnAccountIdId < ActiveRecord::Migration[5.1] + disable_ddl_transaction! + + def change + # Statuses queried by account_id are often sorted by id. Querying statuses + # of an account to show them in his status page is one of the most + # significant examples. + # Add this index to improve the performance in such cases. + add_index 'statuses', ['account_id', 'id'], algorithm: :concurrently, name: 'index_statuses_on_account_id_id' + + remove_index 'statuses', algorithm: :concurrently, column: 'account_id', name: 'index_statuses_on_account_id' + end +end diff --git a/db/schema.rb b/db/schema.rb index ba6c0e876..2f12c7308 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170609145826) do +ActiveRecord::Schema.define(version: 20170610000000) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -279,7 +279,7 @@ ActiveRecord::Schema.define(version: 20170609145826) do t.integer "reblogs_count", default: 0, null: false t.string "language" t.bigint "conversation_id" - t.index ["account_id"], name: "index_statuses_on_account_id" + t.index ["account_id", "id"], name: "index_statuses_on_account_id_id" t.index ["conversation_id"], name: "index_statuses_on_conversation_id" t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id" t.index ["reblog_of_id"], name: "index_statuses_on_reblog_of_id" diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 5f90e83bb..44f3e4390 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 4 + 6 end def pre diff --git a/package.json b/package.json index 4a611e685..dc08fc106 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "tiny-queue": "^0.2.1", "uuid": "^3.0.1", "uws": "^0.14.5", - "webpack": "^2.5.1", + "webpack": "^3.0.0", "webpack-bundle-analyzer": "^2.8.2", "webpack-manifest-plugin": "^1.1.0", "webpack-merge": "^4.1.0", diff --git a/spec/javascript/.eslintrc.yml b/spec/javascript/.eslintrc.yml new file mode 100644 index 000000000..6db2a46c5 --- /dev/null +++ b/spec/javascript/.eslintrc.yml @@ -0,0 +1,3 @@ +--- +env: + mocha: true diff --git a/spec/javascript/components/loading_indicator.test.js b/spec/javascript/components/loading_indicator.test.js deleted file mode 100644 index 0859dd192..000000000 --- a/spec/javascript/components/loading_indicator.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { expect } from 'chai'; -import { shallow } from 'enzyme'; -import React from 'react'; -import LoadingIndicator from '../../../app/javascript/mastodon/components/loading_indicator'; - -describe('<LoadingIndicator />', () => { - -}); diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 2496946cb..7c574eabe 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -11,6 +11,10 @@ RSpec.describe Tag, type: :model do it 'does not match URLs with hashtag-like anchors' do expect(subject.match('https://en.wikipedia.org/wiki/Ghostbusters_(song)#Lawsuit')).to be_nil end + + it 'matches #aesthetic' do + expect(subject.match('this is #aesthetic')).to_not be_nil + end end describe '.search_for' do diff --git a/storybook/config.js b/storybook/config.js index 1078059a7..87479560f 100644 --- a/storybook/config.js +++ b/storybook/config.js @@ -1,5 +1,4 @@ import { configure } from '@storybook/react'; -import React from 'react'; import { addLocaleData } from 'react-intl'; import en from 'react-intl/locale-data/en'; import '../app/javascript/styles/application.scss'; diff --git a/storybook/stories/character_counter.story.js b/storybook/stories/character_counter.story.js index 15a401a25..39d9afb56 100644 --- a/storybook/stories/character_counter.story.js +++ b/storybook/stories/character_counter.story.js @@ -1,6 +1,5 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; import CharacterCounter from 'mastodon/features/compose/components/character_counter'; storiesOf('CharacterCounter', module) diff --git a/storybook/stories/loading_indicator.story.js b/storybook/stories/loading_indicator.story.js index 3e12f61ca..6ee822758 100644 --- a/storybook/stories/loading_indicator.story.js +++ b/storybook/stories/loading_indicator.story.js @@ -1,7 +1,6 @@ import React from 'react'; import { IntlProvider } from 'react-intl'; import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; import en from 'mastodon/locales/en.json'; import LoadingIndicator from 'mastodon/components/loading_indicator'; diff --git a/streaming/index.js b/streaming/index.js index 5afdd5961..fb23be34d 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -242,7 +242,7 @@ const startWorker = (workerId) => { accountFromRequest(req, next); }; - const errorMiddleware = (err, req, res, next) => { + const errorMiddleware = (err, req, res) => { log.error(req.requestId, err.toString()); res.writeHead(err.statusCode || 500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: err.statusCode ? err.toString() : 'An unexpected error occurred' })); @@ -366,7 +366,7 @@ const startWorker = (workerId) => { } }); - ws.on('error', e => { + ws.on('error', () => { log.verbose(req.requestId, `Ending stream for ${req.accountId}`); unsubscribe(id, listener); if (closeHandler) { @@ -443,7 +443,7 @@ const startWorker = (workerId) => { } }); - const wsInterval = setInterval(() => { + setInterval(() => { wss.clients.forEach(ws => { if (ws.isAlive === false) { ws.terminate(); diff --git a/yarn.lock b/yarn.lock index 2eb1a5c75..85de4b546 100644 --- a/yarn.lock +++ b/yarn.lock @@ -192,6 +192,10 @@ ajv-keywords@^1.0.0, ajv-keywords@^1.1.1: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +ajv-keywords@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0" + ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -199,7 +203,7 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.0.0: +ajv@^5.0.0, ajv@^5.1.5: version "5.1.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.1.5.tgz#8734931b601f00d4feef7c65738d77d1b65d1f68" dependencies: @@ -3944,7 +3948,7 @@ loader-utils@^0.2.16: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.x: +loader-utils@^1.0.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.x: version "1.1.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" dependencies: @@ -6681,7 +6685,7 @@ sugarss@^1.0.0: dependencies: postcss "^6.0.0" -supports-color@3.1.2, supports-color@^3.1.0, supports-color@^3.1.1: +supports-color@3.1.2, supports-color@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" dependencies: @@ -6691,7 +6695,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.2.3: +supports-color@^3.1.0, supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -6879,10 +6883,27 @@ uglify-js@^2.8.27: optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^2.8.29: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +uglifyjs-webpack-plugin@^0.4.4: + version "0.4.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + dependencies: + source-map "^0.5.6" + uglify-js "^2.8.29" + webpack-sources "^1.0.1" + uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -7164,6 +7185,33 @@ webpack@^2.5.1: webpack-sources "^0.2.3" yargs "^6.0.0" +webpack@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.0.0.tgz#ee9bcebf21247f7153cb410168cab45e3a59d4d7" + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^5.1.5" + ajv-keywords "^2.0.0" + async "^2.1.2" + enhanced-resolve "^3.0.0" + escope "^3.6.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^3.1.0" + tapable "~0.2.5" + uglifyjs-webpack-plugin "^0.4.4" + watchpack "^1.3.1" + webpack-sources "^1.0.1" + yargs "^6.0.0" + websocket-driver@>=0.5.1: version "0.6.5" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" |