2022-09-21 06:51:21 +09:00
import PropTypes from 'prop-types' ;
2023-05-24 00:15:17 +09:00
import { defineMessages , FormattedMessage , injectIntl } from 'react-intl' ;
2024-01-08 19:57:40 +09:00
import { createSelector } from '@reduxjs/toolkit' ;
2023-05-24 00:15:17 +09:00
import { is , List as ImmutableList , Set as ImmutableSet } from 'immutable' ;
2022-09-21 06:51:21 +09:00
import ImmutablePropTypes from 'react-immutable-proptypes' ;
2023-05-24 00:15:17 +09:00
import ImmutablePureComponent from 'react-immutable-pure-component' ;
2022-09-21 06:51:21 +09:00
import { connect } from 'react-redux' ;
2023-05-24 00:15:17 +09:00
2024-01-12 19:31:24 +09:00
import CloseIcon from '@material-symbols/svg-600/outlined/close.svg?react' ;
2023-10-25 02:45:08 +09:00
2022-09-21 06:51:21 +09:00
import { followAccount } from 'mastodon/actions/accounts' ;
2023-10-23 16:43:00 +09:00
import { Button } from 'mastodon/components/button' ;
2023-05-24 00:15:17 +09:00
import { IconButton } from 'mastodon/components/icon_button' ;
import Option from 'mastodon/features/report/components/option' ;
import { languages as preloadedLanguages } from 'mastodon/initial_state' ;
2022-09-21 06:51:21 +09:00
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 } ) ) ;
} ,
} ) ;
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 ( ) ;
2023-01-30 09:45:35 +09:00
} ;
2022-09-21 06:51:21 +09:00
renderItem ( value ) {
const language = this . props . languages . find ( language => language [ 0 ] === value ) ;
const checked = this . state . selectedLanguages . includes ( value ) ;
2022-10-03 09:56:12 +09:00
if ( ! language ) {
return null ;
}
2022-09-21 06:51:21 +09:00
return (
< Option
key = { value }
name = 'languages'
value = { value }
label = { language [ 1 ] }
checked = { checked }
onToggle = { this . handleLanguageToggle }
multiple
/ >
) ;
}
render ( ) {
const { acct , availableLanguages , selectedLanguages , intl , onClose } = this . props ;
return (
< div className = 'modal-root__modal report-dialog-modal' >
< div className = 'report-modal__target' >
2023-10-25 02:45:08 +09:00
< IconButton className = 'report-modal__close' title = { intl . formatMessage ( messages . close ) } icon = 'times' iconComponent = { CloseIcon } onClick = { onClose } size = { 20 } / >
2022-09-21 06:51:21 +09:00
< FormattedMessage id = 'subscribed_languages.target' defaultMessage = 'Change subscribed languages for {target}' values = { { target : < strong > { acct } < / strong > } } / >
< / div >
< div className = 'report-dialog-modal__container' >
< p className = 'report-dialog-modal__lead' > < FormattedMessage id = 'subscribed_languages.lead' defaultMessage = 'Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.' / > < / p >
< div >
2022-10-03 09:56:12 +09:00
{ availableLanguages . union ( selectedLanguages ) . delete ( null ) . map ( value => this . renderItem ( value ) ) }
2022-09-21 06:51:21 +09:00
< / div >
< div className = 'flex-spacer' / >
< div className = 'report-dialog-modal__actions' >
< Button disabled = { is ( this . state . selectedLanguages , this . props . selectedLanguages ) } onClick = { this . handleSubmit } > < FormattedMessage id = 'subscribed_languages.save' defaultMessage = 'Save changes' / > < / Button >
< / div >
< / div >
< / div >
) ;
}
}
2023-03-24 11:17:53 +09:00
export default connect ( mapStateToProps , mapDispatchToProps ) ( injectIntl ( SubscribedLanguagesModal ) ) ;