@ -2,6 +2,7 @@
import PropTypes from 'prop-types' ;
import PropTypes from 'prop-types' ;
import React from 'react' ;
import React from 'react' ;
import ImmutablePropTypes from 'react-immutable-proptypes' ;
import ImmutablePropTypes from 'react-immutable-proptypes' ;
import { defineMessages } from 'react-intl' ;
const APPROX _HASHTAG _RE = /(?:^|[^\/\)\w])#(\S+)/i ;
const APPROX _HASHTAG _RE = /(?:^|[^\/\)\w])#(\S+)/i ;
@ -49,6 +50,13 @@ import { assignHandlers } from 'flavours/glitch/util/react_helpers';
import { wrap } from 'flavours/glitch/util/redux_helpers' ;
import { wrap } from 'flavours/glitch/util/redux_helpers' ;
import { privacyPreference } from 'flavours/glitch/util/privacy_preference' ;
import { privacyPreference } from 'flavours/glitch/util/privacy_preference' ;
const messages = defineMessages ( {
missingDescriptionMessage : { id : 'confirmations.missing_media_description.message' ,
defaultMessage : 'At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.' } ,
missingDescriptionConfirm : { id : 'confirmations.missing_media_description.confirm' ,
defaultMessage : 'Send anyway' } ,
} ) ;
// State mapping.
// State mapping.
function mapStateToProps ( state ) {
function mapStateToProps ( state ) {
const spoilersAlwaysOn = state . getIn ( [ 'local_settings' , 'always_show_spoilers_field' ] ) ;
const spoilersAlwaysOn = state . getIn ( [ 'local_settings' , 'always_show_spoilers_field' ] ) ;
@ -93,11 +101,12 @@ function mapStateToProps (state) {
text : state . getIn ( [ 'compose' , 'text' ] ) ,
text : state . getIn ( [ 'compose' , 'text' ] ) ,
anyMedia : state . getIn ( [ 'compose' , 'media_attachments' ] ) . size > 0 ,
anyMedia : state . getIn ( [ 'compose' , 'media_attachments' ] ) . size > 0 ,
spoilersAlwaysOn : spoilersAlwaysOn ,
spoilersAlwaysOn : spoilersAlwaysOn ,
mediaDescriptionConfirmation : state . getIn ( [ 'local_settings' , 'confirm_missing_media_description' ] ) ,
} ;
} ;
} ;
} ;
// Dispatch mapping.
// Dispatch mapping.
const mapDispatchToProps = ( dispatch ) => ( {
const mapDispatchToProps = ( dispatch , { intl } ) => ( {
onCancelReply ( ) {
onCancelReply ( ) {
dispatch ( cancelReplyCompose ( ) ) ;
dispatch ( cancelReplyCompose ( ) ) ;
} ,
} ,
@ -149,6 +158,13 @@ const mapDispatchToProps = (dispatch) => ({
onSelectSuggestion ( position , token , suggestion ) {
onSelectSuggestion ( position , token , suggestion ) {
dispatch ( selectComposeSuggestion ( position , token , suggestion ) ) ;
dispatch ( selectComposeSuggestion ( position , token , suggestion ) ) ;
} ,
} ,
onMediaDescriptionConfirm ( ) {
dispatch ( openModal ( 'CONFIRM' , {
message : intl . formatMessage ( messages . missingDescriptionMessage ) ,
confirm : intl . formatMessage ( messages . missingDescriptionConfirm ) ,
onConfirm : ( ) => dispatch ( submitCompose ( ) ) ,
} ) ) ;
} ,
onSubmit ( ) {
onSubmit ( ) {
dispatch ( submitCompose ( ) ) ;
dispatch ( submitCompose ( ) ) ;
} ,
} ,
@ -212,8 +228,11 @@ const handlers = {
onSubmit ,
onSubmit ,
isSubmitting ,
isSubmitting ,
isUploading ,
isUploading ,
media ,
anyMedia ,
anyMedia ,
text ,
text ,
mediaDescriptionConfirmation ,
onMediaDescriptionConfirm ,
} = this . props ;
} = this . props ;
// If something changes inside the textarea, then we update the
// If something changes inside the textarea, then we update the
@ -227,8 +246,15 @@ const handlers = {
return ;
return ;
}
}
// Submits the status.
// Submit unless there are media with missing descriptions
if ( onSubmit ) {
if ( mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media . some ( item => ! item . get ( 'description' ) ) ) {
const firstWithoutDescription = media . findIndex ( item => ! item . get ( 'description' ) ) ;
const inputs = document . querySelectorAll ( '.composer--upload_form--item input' ) ;
if ( inputs . length == media . size && firstWithoutDescription !== - 1 ) {
inputs [ firstWithoutDescription ] . focus ( ) ;
}
onMediaDescriptionConfirm ( ) ;
} else if ( onSubmit ) {
onSubmit ( ) ;
onSubmit ( ) ;
}
}
} ,
} ,
@ -495,6 +521,9 @@ Composer.propTypes = {
suggestionToken : PropTypes . string ,
suggestionToken : PropTypes . string ,
suggestions : ImmutablePropTypes . list ,
suggestions : ImmutablePropTypes . list ,
text : PropTypes . string ,
text : PropTypes . string ,
anyMedia : PropTypes . bool ,
spoilersAlwaysOn : PropTypes . bool ,
mediaDescriptionConfirmation : PropTypes . bool ,
// Dispatch props.
// Dispatch props.
onCancelReply : PropTypes . func ,
onCancelReply : PropTypes . func ,
@ -517,8 +546,7 @@ Composer.propTypes = {
onUndoUpload : PropTypes . func ,
onUndoUpload : PropTypes . func ,
onUnmount : PropTypes . func ,
onUnmount : PropTypes . func ,
onUpload : PropTypes . func ,
onUpload : PropTypes . func ,
anyMedia : PropTypes . bool ,
onMediaDescriptionConfirm : PropTypes . func ,
spoilersAlwaysOn : PropTypes . bool ,
} ;
} ;
// Connecting and export.
// Connecting and export.