Prevent selection of unacceptable Content-Type files (#2910)
* Prevent selection of unacceptable Content-Type files * replace hard code * media_attachments accept content-types in initial state
This commit is contained in:
		
							parent
							
								
									7140def5c9
								
							
						
					
					
						commit
						459bbfa4b2
					
				| @ -2,11 +2,19 @@ import React from 'react'; | |||||||
| import IconButton from '../../../components/icon_button'; | import IconButton from '../../../components/icon_button'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { defineMessages, injectIntl } from 'react-intl'; | import { defineMessages, injectIntl } from 'react-intl'; | ||||||
|  | import { connect } from 'react-redux'; | ||||||
| 
 | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   upload: { id: 'upload_button.label', defaultMessage: 'Add media' } |   upload: { id: 'upload_button.label', defaultMessage: 'Add media' } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const makeMapStateToProps = () => { | ||||||
|  |   const mapStateToProps = (state, props) => ({ | ||||||
|  |     acceptContentTypes: state.getIn(['media_attachments', 'accept_content_types']).toArray(), | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   return mapStateToProps; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| const iconStyle = { | const iconStyle = { | ||||||
|   height: null, |   height: null, | ||||||
| @ -38,12 +46,21 @@ class UploadButton extends React.PureComponent { | |||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
| 
 | 
 | ||||||
|     const { intl, resetFileKey, disabled } = this.props; |     const { intl, resetFileKey, disabled, acceptContentTypes } = this.props; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div className='compose-form__upload-button'> |       <div className='compose-form__upload-button'> | ||||||
|         <IconButton icon='camera' title={intl.formatMessage(messages.upload)} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle}/> |         <IconButton icon='camera' title={intl.formatMessage(messages.upload)} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle}/> | ||||||
|         <input key={resetFileKey} ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={disabled} style={{ display: 'none' }} /> |         <input | ||||||
|  |           key={resetFileKey} | ||||||
|  |           ref={this.setRef} | ||||||
|  |           type='file' | ||||||
|  |           multiple={false} | ||||||
|  |           accept={ acceptContentTypes.join(',')} | ||||||
|  |           onChange={this.handleChange} | ||||||
|  |           disabled={disabled} | ||||||
|  |           style={{ display: 'none' }} | ||||||
|  |         /> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| @ -55,7 +72,8 @@ UploadButton.propTypes = { | |||||||
|   onSelectFile: PropTypes.func.isRequired, |   onSelectFile: PropTypes.func.isRequired, | ||||||
|   style: PropTypes.object, |   style: PropTypes.object, | ||||||
|   resetFileKey: PropTypes.number, |   resetFileKey: PropTypes.number, | ||||||
|  |   acceptContentTypes: PropTypes.arrayOf(PropTypes.string).isRequired, | ||||||
|   intl: PropTypes.object.isRequired |   intl: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default injectIntl(UploadButton); | export default connect(makeMapStateToProps)(injectIntl(UploadButton)); | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ import user_lists from './user_lists'; | |||||||
| import accounts from './accounts'; | import accounts from './accounts'; | ||||||
| import accounts_counters from './accounts_counters'; | import accounts_counters from './accounts_counters'; | ||||||
| import statuses from './statuses'; | import statuses from './statuses'; | ||||||
|  | import media_attachments from './media_attachments'; | ||||||
| import relationships from './relationships'; | import relationships from './relationships'; | ||||||
| import search from './search'; | import search from './search'; | ||||||
| import notifications from './notifications'; | import notifications from './notifications'; | ||||||
| @ -28,6 +29,7 @@ export default combineReducers({ | |||||||
|   status_lists, |   status_lists, | ||||||
|   accounts, |   accounts, | ||||||
|   accounts_counters, |   accounts_counters, | ||||||
|  |   media_attachments, | ||||||
|   statuses, |   statuses, | ||||||
|   relationships, |   relationships, | ||||||
|   search, |   search, | ||||||
|  | |||||||
							
								
								
									
										15
									
								
								app/javascript/mastodon/reducers/media_attachments.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/javascript/mastodon/reducers/media_attachments.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | import { STORE_HYDRATE } from '../actions/store'; | ||||||
|  | import Immutable from 'immutable'; | ||||||
|  | 
 | ||||||
|  | const initialState = Immutable.Map({ | ||||||
|  |   accept_content_types: [], | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export default function meta(state = initialState, action) { | ||||||
|  |   switch(action.type) { | ||||||
|  |   case STORE_HYDRATE: | ||||||
|  |     return state.merge(action.state.get('media_attachments')); | ||||||
|  |   default: | ||||||
|  |     return state; | ||||||
|  |   } | ||||||
|  | }; | ||||||
| @ -27,4 +27,10 @@ node(:accounts) do | |||||||
|   store |   store | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | node(:media_attachments) do | ||||||
|  |   { | ||||||
|  |     accept_content_types: MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES | ||||||
|  |   } | ||||||
|  | end | ||||||
|  | 
 | ||||||
| node(:settings) { @web_settings } | node(:settings) { @web_settings } | ||||||
|  | |||||||
| @ -7,8 +7,8 @@ | |||||||
|   .fields-group |   .fields-group | ||||||
|     = f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', counter: "<span class=\"name-counter\">#{30 - @account.display_name.size}</span>").html_safe |     = f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', counter: "<span class=\"name-counter\">#{30 - @account.display_name.size}</span>").html_safe | ||||||
|     = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', counter: "<span class=\"note-counter\">#{160 - @account.note.size}</span>").html_safe |     = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', counter: "<span class=\"note-counter\">#{160 - @account.note.size}</span>").html_safe | ||||||
|     = f.input :avatar, wrapper: :with_label, hint: t('simple_form.hints.defaults.avatar') |     = f.input :avatar, wrapper: :with_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar') | ||||||
|     = f.input :header, wrapper: :with_label, hint: t('simple_form.hints.defaults.header') |     = f.input :header, wrapper: :with_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header') | ||||||
| 
 | 
 | ||||||
|   = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked') |   = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked') | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user