From 54d9a9c18a74a1ec766d8f611ad3ee11ab4c5422 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Sat, 27 Aug 2022 22:17:27 +0900 Subject: Fix react warning on notifications column (#1832) --- .../flavours/glitch/features/notifications/index.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index 075e729b1..2682dd29b 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -283,13 +283,14 @@ class Notifications extends React.PureComponent { if (canMarkAsRead) { extraButtons.push( + , ); } @@ -306,13 +307,14 @@ class Notifications extends React.PureComponent { extraButtons.push( + , ); const notifCleaningDrawer = ( @@ -323,6 +325,12 @@ class Notifications extends React.PureComponent { ); + const extraButton = ( + <> + {extraButtons} + + ); + return ( -- cgit From 7a02c1d9bab8ba004eea54a907782a949ecb3493 Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 28 Aug 2022 22:21:55 +0200 Subject: Add regexp filter field to public timeline column settings (#1834) * Add regexp filter field to public timeline column settings This has accidentally been removed while porting an upstream change years ago. * Remove dead code * Fix regexp filter not working for local and public TLs when using non-default settings --- .../public_timeline/components/column_settings.js | 17 ++++++++++++++--- .../features/ui/containers/status_list_container.js | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/public_timeline/components/column_settings.js b/app/javascript/flavours/glitch/features/public_timeline/components/column_settings.js index e92681065..cfe821cfc 100644 --- a/app/javascript/flavours/glitch/features/public_timeline/components/column_settings.js +++ b/app/javascript/flavours/glitch/features/public_timeline/components/column_settings.js @@ -1,8 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { injectIntl, FormattedMessage } from 'react-intl'; -import SettingToggle from '../../notifications/components/setting_toggle'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import SettingText from 'flavours/glitch/components/setting_text'; +import SettingToggle from 'flavours/glitch/features/notifications/components/setting_toggle'; + +const messages = defineMessages({ + filter_regex: { id: 'home.column_settings.filter_regex', defaultMessage: 'Filter out by regular expressions' }, +}); export default @injectIntl class ColumnSettings extends React.PureComponent { @@ -15,7 +20,7 @@ class ColumnSettings extends React.PureComponent { }; render () { - const { settings, onChange } = this.props; + const { settings, onChange, intl } = this.props; return (
@@ -24,6 +29,12 @@ class ColumnSettings extends React.PureComponent { } /> {!settings.getIn(['other', 'onlyRemote']) && } />}
+ + + +
+ +
); } diff --git a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js index bd2d2eb4e..0828e3cb0 100644 --- a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js +++ b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js @@ -6,8 +6,20 @@ import { createSelector } from 'reselect'; import { debounce } from 'lodash'; import { me } from 'flavours/glitch/util/initial_state'; +const normalizeTimelineId = timelineId => { + if (timelineId.startsWith('public:')) { + return 'public'; + } + + if (timelineId.startsWith('community:')) { + return 'community'; + } + + return timelineId; +}; + const getRegex = createSelector([ - (state, { type }) => state.getIn(['settings', type, 'regex', 'body']), + (state, { type }) => state.getIn(['settings', normalizeTimelineId(type), 'regex', 'body']), ], (rawRegex) => { let regex = null; @@ -20,13 +32,11 @@ const getRegex = createSelector([ }); const makeGetStatusIds = (pending = false) => createSelector([ - (state, { type }) => state.getIn(['settings', type], ImmutableMap()), + (state, { type }) => state.getIn(['settings', normalizeTimelineId(type)], ImmutableMap()), (state, { type }) => state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList()), (state) => state.get('statuses'), getRegex, ], (columnSettings, statusIds, statuses, regex) => { - const rawRegex = columnSettings.getIn(['regex', 'body'], '').trim(); - return statusIds.filter(id => { if (id === null) return true; -- cgit From 0495302f1ca811e5ed48ed49b2d291fc119e9dc6 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 30 Aug 2022 10:57:27 +0200 Subject: Fix local settings navigation (#1836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The “filters” page was removed, but not from the navigation, which would offset everything. --- .../features/local_settings/navigation/index.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/local_settings/navigation/index.js b/app/javascript/flavours/glitch/features/local_settings/navigation/index.js index ab3a554bf..d085a606c 100644 --- a/app/javascript/flavours/glitch/features/local_settings/navigation/index.js +++ b/app/javascript/flavours/glitch/features/local_settings/navigation/index.js @@ -61,34 +61,27 @@ class LocalSettingsNavigation extends React.PureComponent { active={index === 3} index={3} onNavigate={onNavigate} - icon='filter' - title={intl.formatMessage(messages.filters)} - /> - Date: Fri, 2 Sep 2022 11:57:06 +0200 Subject: Fix regexp filtering in pinned community/public TLs (#1840) --- .../flavours/glitch/components/status_list.js | 1 + .../glitch/features/community_timeline/index.js | 4 ++++ .../flavours/glitch/features/home_timeline/index.js | 3 +++ .../glitch/features/public_timeline/index.js | 4 ++++ .../features/ui/containers/status_list_container.js | 20 ++++---------------- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/components/status_list.js b/app/javascript/flavours/glitch/components/status_list.js index 9095e087e..ac255f4ac 100644 --- a/app/javascript/flavours/glitch/components/status_list.js +++ b/app/javascript/flavours/glitch/components/status_list.js @@ -25,6 +25,7 @@ export default class StatusList extends ImmutablePureComponent { alwaysPrepend: PropTypes.bool, emptyMessage: PropTypes.node, timelineId: PropTypes.string.isRequired, + regex: PropTypes.string, }; static defaultProps = { diff --git a/app/javascript/flavours/glitch/features/community_timeline/index.js b/app/javascript/flavours/glitch/features/community_timeline/index.js index 7341f9702..64030e195 100644 --- a/app/javascript/flavours/glitch/features/community_timeline/index.js +++ b/app/javascript/flavours/glitch/features/community_timeline/index.js @@ -19,11 +19,13 @@ const mapStateToProps = (state, { columnId }) => { const columns = state.getIn(['settings', 'columns']); const index = columns.findIndex(c => c.get('uuid') === uuid); const onlyMedia = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']); + const regex = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'regex', 'body']) : state.getIn(['settings', 'community', 'regex', 'body']); const timelineState = state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`]); return { hasUnread: !!timelineState && timelineState.get('unread') > 0, onlyMedia, + regex, }; }; @@ -46,6 +48,7 @@ class CommunityTimeline extends React.PureComponent { hasUnread: PropTypes.bool, multiColumn: PropTypes.bool, onlyMedia: PropTypes.bool, + regex: PropTypes.string, }; handlePin = () => { @@ -127,6 +130,7 @@ class CommunityTimeline extends React.PureComponent { onLoadMore={this.handleLoadMore} emptyMessage={} bindToDocument={!multiColumn} + regex={this.props.regex} />
); diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.js b/app/javascript/flavours/glitch/features/home_timeline/index.js index 19551d6b8..51e932307 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/index.js +++ b/app/javascript/flavours/glitch/features/home_timeline/index.js @@ -26,6 +26,7 @@ const mapStateToProps = state => ({ hasAnnouncements: !state.getIn(['announcements', 'items']).isEmpty(), unreadAnnouncements: state.getIn(['announcements', 'items']).count(item => !item.get('read')), showAnnouncements: state.getIn(['announcements', 'show']), + regex: state.getIn(['settings', 'home', 'regex', 'body']), }); export default @connect(mapStateToProps) @@ -42,6 +43,7 @@ class HomeTimeline extends React.PureComponent { hasAnnouncements: PropTypes.bool, unreadAnnouncements: PropTypes.number, showAnnouncements: PropTypes.bool, + regex: PropTypes.string, }; handlePin = () => { @@ -154,6 +156,7 @@ class HomeTimeline extends React.PureComponent { timelineId='home' emptyMessage={ }} />} bindToDocument={!multiColumn} + regex={this.props.regex} /> ); diff --git a/app/javascript/flavours/glitch/features/public_timeline/index.js b/app/javascript/flavours/glitch/features/public_timeline/index.js index 848049965..9f31cf922 100644 --- a/app/javascript/flavours/glitch/features/public_timeline/index.js +++ b/app/javascript/flavours/glitch/features/public_timeline/index.js @@ -21,6 +21,7 @@ const mapStateToProps = (state, { columnId }) => { const onlyMedia = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'public', 'other', 'onlyMedia']); const onlyRemote = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyRemote']) : state.getIn(['settings', 'public', 'other', 'onlyRemote']); const allowLocalOnly = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'allowLocalOnly']) : state.getIn(['settings', 'public', 'other', 'allowLocalOnly']); + const regex = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'regex', 'body']) : state.getIn(['settings', 'public', 'regex', 'body']); const timelineState = state.getIn(['timelines', `public${onlyMedia ? ':media' : ''}`]); return { @@ -28,6 +29,7 @@ const mapStateToProps = (state, { columnId }) => { onlyMedia, onlyRemote, allowLocalOnly, + regex, }; }; @@ -52,6 +54,7 @@ class PublicTimeline extends React.PureComponent { onlyMedia: PropTypes.bool, onlyRemote: PropTypes.bool, allowLocalOnly: PropTypes.bool, + regex: PropTypes.string, }; handlePin = () => { @@ -133,6 +136,7 @@ class PublicTimeline extends React.PureComponent { scrollKey={`public_timeline-${columnId}`} emptyMessage={} bindToDocument={!multiColumn} + regex={this.props.regex} /> ); diff --git a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js index 0828e3cb0..53c3b8f39 100644 --- a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js +++ b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js @@ -6,20 +6,8 @@ import { createSelector } from 'reselect'; import { debounce } from 'lodash'; import { me } from 'flavours/glitch/util/initial_state'; -const normalizeTimelineId = timelineId => { - if (timelineId.startsWith('public:')) { - return 'public'; - } - - if (timelineId.startsWith('community:')) { - return 'community'; - } - - return timelineId; -}; - const getRegex = createSelector([ - (state, { type }) => state.getIn(['settings', normalizeTimelineId(type), 'regex', 'body']), + (state, { regex }) => regex, ], (rawRegex) => { let regex = null; @@ -32,7 +20,7 @@ const getRegex = createSelector([ }); const makeGetStatusIds = (pending = false) => createSelector([ - (state, { type }) => state.getIn(['settings', normalizeTimelineId(type)], ImmutableMap()), + (state, { type }) => state.getIn(['settings', type], ImmutableMap()), (state, { type }) => state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList()), (state) => state.get('statuses'), getRegex, @@ -70,8 +58,8 @@ const makeMapStateToProps = () => { const getStatusIds = makeGetStatusIds(); const getPendingStatusIds = makeGetStatusIds(true); - const mapStateToProps = (state, { timelineId }) => ({ - statusIds: getStatusIds(state, { type: timelineId }), + const mapStateToProps = (state, { timelineId, regex }) => ({ + statusIds: getStatusIds(state, { type: timelineId, regex }), isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true), isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false), hasMore: state.getIn(['timelines', timelineId, 'hasMore']), -- cgit From e18ba67727efc0160dd49348f0e38c106d50d7af Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 2 Oct 2022 18:23:14 +0200 Subject: [Glitch] Add privacy icons to report modal Port d2f7e30a283a1dca1f7974884ac0c237b93903ad to glitch-soc --- .../flavours/glitch/features/report/components/status_check_box.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/report/components/status_check_box.js b/app/javascript/flavours/glitch/features/report/components/status_check_box.js index 76bf0eb85..2231fc0ce 100644 --- a/app/javascript/flavours/glitch/features/report/components/status_check_box.js +++ b/app/javascript/flavours/glitch/features/report/components/status_check_box.js @@ -7,6 +7,7 @@ import DisplayName from 'flavours/glitch/components/display_name'; import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp'; import Option from './option'; import MediaAttachments from 'flavours/glitch/components/media_attachments'; +import VisibilityIcon from 'flavours/glitch/components/status_visibility_icon'; export default class StatusCheckBox extends React.PureComponent { @@ -36,7 +37,7 @@ export default class StatusCheckBox extends React.PureComponent { -
·
+
·
} /> -- cgit From d25de7f01ee04498c13a433f6c3044fa50392dc0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 29 Sep 2022 06:22:12 +0200 Subject: [Glitch] Change path of privacy policy page Port 36f4c32a38ed85e5e658b34d36eac40a6147bc0c to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/features/ui/components/link_footer.js | 4 ++-- app/javascript/flavours/glitch/util/backend_links.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/ui/components/link_footer.js b/app/javascript/flavours/glitch/features/ui/components/link_footer.js index 3abdaad4b..d91f9b8c4 100644 --- a/app/javascript/flavours/glitch/features/ui/components/link_footer.js +++ b/app/javascript/flavours/glitch/features/ui/components/link_footer.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Link } from 'react-router-dom'; import { limitedFederationMode, version, repository, source_url } from 'flavours/glitch/util/initial_state'; -import { signOutLink, securityLink } from 'flavours/glitch/util/backend_links'; +import { signOutLink, securityLink, privacyPolicyLink } from 'flavours/glitch/util/backend_links'; import { logOut } from 'flavours/glitch/util/log_out'; import { openModal } from 'flavours/glitch/actions/modal'; import { PERMISSION_INVITE_USERS } from 'flavours/glitch/permissions'; @@ -55,7 +55,7 @@ class LinkFooter extends React.PureComponent { {!!securityLink &&
  • ·
  • } {!limitedFederationMode &&
  • ·
  • }
  • ·
  • -
  • ·
  • +
  • ·
  • ·
  • ·
  • diff --git a/app/javascript/flavours/glitch/util/backend_links.js b/app/javascript/flavours/glitch/util/backend_links.js index 5b2dd8dbf..d0ae63419 100644 --- a/app/javascript/flavours/glitch/util/backend_links.js +++ b/app/javascript/flavours/glitch/util/backend_links.js @@ -1,7 +1,7 @@ export const preferencesLink = '/settings/preferences'; export const profileLink = '/settings/profile'; export const signOutLink = '/auth/sign_out'; -export const termsLink = '/terms'; +export const privacyPolicyLink = '/privacy-policy'; export const accountAdminLink = (id) => `/admin/accounts/${id}`; export const statusAdminLink = (account_id, status_id) => `/admin/accounts/${account_id}/statuses?id=${status_id}`; export const filterEditLink = (id) => `/filters/${id}/edit`; -- cgit From f416e36f0fb68379cbb0cd019c5a8f435f9ab988 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 20 Sep 2022 23:51:21 +0200 Subject: [Glitch] Add ability to filter followed accounts' posts by language Port 50948b46aabc0756d85bc6641f0bd3bcc09bf7d4 to glitch-soc Signed-off-by: Claire --- .../glitch/features/account/components/header.js | 5 + .../features/account_timeline/components/header.js | 6 + .../containers/header_container.js | 8 +- .../features/subscribed_languages_modal/index.js | 121 +++++++++++++++++++++ .../glitch/features/ui/components/modal_root.js | 2 + 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js (limited to 'app/javascript/flavours/glitch/features') diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 53170b7a6..cc2a7d4d4 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -51,6 +51,7 @@ const messages = defineMessages({ add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, add_account_note: { id: 'account.add_account_note', defaultMessage: 'Add note for @{name}' }, + languages: { id: 'account.languages', defaultMessage: 'Change subscribed languages' }, }); const dateFormatOptions = { @@ -85,6 +86,7 @@ class Header extends ImmutablePureComponent { onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, onEditAccountNote: PropTypes.func.isRequired, + onChangeLanguages: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, domain: PropTypes.string.isRequired, hidden: PropTypes.bool, @@ -215,6 +217,9 @@ class Header extends ImmutablePureComponent { } else { menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); } + + menu.push({ text: intl.formatMessage(messages.languages), action: this.props.onChangeLanguages }); + menu.push(null); } menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle }); diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/header.js b/app/javascript/flavours/glitch/features/account_timeline/components/header.js index 645ff29ea..783d318f9 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/header.js +++ b/app/javascript/flavours/glitch/features/account_timeline/components/header.js @@ -23,6 +23,7 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain: PropTypes.func.isRequired, onEndorseToggle: PropTypes.func.isRequired, onAddToList: PropTypes.func.isRequired, + onChangeLanguages: PropTypes.func.isRequired, hideTabs: PropTypes.bool, domain: PropTypes.string.isRequired, hidden: PropTypes.bool, @@ -92,6 +93,10 @@ export default class Header extends ImmutablePureComponent { this.props.onEditAccountNote(this.props.account); } + handleChangeLanguages = () => { + this.props.onChangeLanguages(this.props.account); + } + render () { const { account, hidden, hideTabs } = this.props; @@ -118,6 +123,7 @@ export default class Header extends ImmutablePureComponent { onEndorseToggle={this.handleEndorseToggle} onAddToList={this.handleAddToList} onEditAccountNote={this.handleEditAccountNote} + onChangeLanguages={this.handleChangeLanguages} domain={this.props.domain} hidden={hidden} /> diff --git a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js index 3fa7c1448..dc8b2d55a 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js +++ b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js @@ -130,12 +130,18 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch(unblockDomain(domain)); }, - onAddToList(account){ + onAddToList (account) { dispatch(openModal('LIST_ADDER', { accountId: account.get('id'), })); }, + onChangeLanguages (account) { + dispatch(openModal('SUBSCRIBED_LANGUAGES', { + accountId: account.get('id'), + })); + }, + }); export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header)); diff --git a/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js new file mode 100644 index 000000000..55404c184 --- /dev/null +++ b/app/javascript/flavours/glitch/features/subscribed_languages_modal/index.js @@ -0,0 +1,121 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { is, List as ImmutableList, Set as ImmutableSet } from 'immutable'; +import { languages as preloadedLanguages } from 'flavours/glitch/util/initial_state'; +import Option from 'flavours/glitch/features/report/components/option'; +import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import IconButton from 'flavours/glitch/components/icon_button'; +import Button from 'flavours/glitch/components/button'; +import { followAccount } from 'flavours/glitch/actions/accounts'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + +const getAccountLanguages = createSelector([ + (state, accountId) => state.getIn(['timelines', `account:${accountId}`, 'items'], ImmutableList()), + state => state.get('statuses'), +], (statusIds, statuses) => + new ImmutableSet(statusIds.map(statusId => statuses.get(statusId)).filter(status => !status.get('reblog')).map(status => status.get('language')))); + +const mapStateToProps = (state, { accountId }) => ({ + acct: state.getIn(['accounts', accountId, 'acct']), + availableLanguages: getAccountLanguages(state, accountId), + selectedLanguages: ImmutableSet(state.getIn(['relationships', accountId, 'languages']) || ImmutableList()), +}); + +const mapDispatchToProps = (dispatch, { accountId }) => ({ + + onSubmit (languages) { + dispatch(followAccount(accountId, { languages })); + }, + +}); + +export default @connect(mapStateToProps, mapDispatchToProps) +@injectIntl +class SubscribedLanguagesModal extends ImmutablePureComponent { + + static propTypes = { + accountId: PropTypes.string.isRequired, + acct: PropTypes.string.isRequired, + availableLanguages: ImmutablePropTypes.setOf(PropTypes.string), + selectedLanguages: ImmutablePropTypes.setOf(PropTypes.string), + onClose: PropTypes.func.isRequired, + languages: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)), + intl: PropTypes.object.isRequired, + submit: PropTypes.func.isRequired, + }; + + static defaultProps = { + languages: preloadedLanguages, + }; + + state = { + selectedLanguages: this.props.selectedLanguages, + }; + + handleLanguageToggle = (value, checked) => { + const { selectedLanguages } = this.state; + + if (checked) { + this.setState({ selectedLanguages: selectedLanguages.add(value) }); + } else { + this.setState({ selectedLanguages: selectedLanguages.delete(value) }); + } + }; + + handleSubmit = () => { + this.props.onSubmit(this.state.selectedLanguages.toArray()); + this.props.onClose(); + } + + renderItem (value) { + const language = this.props.languages.find(language => language[0] === value); + const checked = this.state.selectedLanguages.includes(value); + + return ( +