Making upload button into a smaller icon button
This commit is contained in:
		
							parent
							
								
									d42ed78aa4
								
							
						
					
					
						commit
						50d3083cbd
					
				| @ -1,48 +0,0 @@ | ||||
| import api from '../api' | ||||
| 
 | ||||
| export const FOLLOW_CHANGE         = 'FOLLOW_CHANGE'; | ||||
| export const FOLLOW_SUBMIT_REQUEST = 'FOLLOW_SUBMIT_REQUEST'; | ||||
| export const FOLLOW_SUBMIT_SUCCESS = 'FOLLOW_SUBMIT_SUCCESS'; | ||||
| export const FOLLOW_SUBMIT_FAIL    = 'FOLLOW_SUBMIT_FAIL'; | ||||
| 
 | ||||
| export function changeFollow(text) { | ||||
|   return { | ||||
|     type: FOLLOW_CHANGE, | ||||
|     text: text | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function submitFollow(router) { | ||||
|   return function (dispatch, getState) { | ||||
|     dispatch(submitFollowRequest()); | ||||
| 
 | ||||
|     api(getState).post('/api/v1/follows', { | ||||
|       uri: getState().getIn(['follow', 'text']) | ||||
|     }).then(function (response) { | ||||
|       dispatch(submitFollowSuccess(response.data)); | ||||
|       router.push(`/accounts/${response.data.id}`); | ||||
|     }).catch(function (error) { | ||||
|       dispatch(submitFollowFail(error)); | ||||
|     }); | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function submitFollowRequest() { | ||||
|   return { | ||||
|     type: FOLLOW_SUBMIT_REQUEST | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function submitFollowSuccess(account) { | ||||
|   return { | ||||
|     type: FOLLOW_SUBMIT_SUCCESS, | ||||
|     account: account | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export function submitFollowFail(error) { | ||||
|   return { | ||||
|     type: FOLLOW_SUBMIT_FAIL, | ||||
|     error: error | ||||
|   }; | ||||
| }; | ||||
| @ -7,6 +7,7 @@ import UploadButton from './upload_button'; | ||||
| import Autosuggest from 'react-autosuggest'; | ||||
| import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; | ||||
| import { debounce } from 'react-decoration'; | ||||
| import UploadButtonContainer from '../containers/upload_button_container'; | ||||
| 
 | ||||
| const getTokenForSuggestions = (str, caretPosition) => { | ||||
|   let word; | ||||
| @ -168,6 +169,7 @@ const ComposeForm = React.createClass({ | ||||
|         <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||
|           <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={disabled} /></div> | ||||
|           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div> | ||||
|           <UploadButtonContainer style={{ paddingTop: '4px' }} /> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
| @ -1,11 +1,12 @@ | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import Button          from '../../../components/button'; | ||||
| import IconButton from '../../../components/icon_button'; | ||||
| 
 | ||||
| const UploadButton = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     disabled: React.PropTypes.bool, | ||||
|     onSelectFile: React.PropTypes.func.isRequired | ||||
|     onSelectFile: React.PropTypes.func.isRequired, | ||||
|     style: React.PropTypes.object | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| @ -17,17 +18,18 @@ const UploadButton = React.createClass({ | ||||
|   }, | ||||
| 
 | ||||
|   handleClick () { | ||||
|     this.refs.fileElement.click(); | ||||
|     this.fileElement.click(); | ||||
|   }, | ||||
| 
 | ||||
|   setRef (c) { | ||||
|     this.fileElement = c; | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     return ( | ||||
|       <div> | ||||
|         <Button disabled={this.props.disabled} onClick={this.handleClick} block={true}> | ||||
|           <i className='fa fa-fw fa-photo' /> Add media | ||||
|         </Button> | ||||
| 
 | ||||
|         <input ref='fileElement' type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} /> | ||||
|       <div style={this.props.style}> | ||||
|         <IconButton icon='photo' title='Add media' disabled={this.props.disabled} onClick={this.handleClick} size={24} /> | ||||
|         <input ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} /> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| @ -0,0 +1,34 @@ | ||||
| import PureRenderMixin    from 'react-addons-pure-render-mixin'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import IconButton         from '../../../components/icon_button'; | ||||
| 
 | ||||
| const UploadForm = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     media: ImmutablePropTypes.list.isRequired, | ||||
|     is_uploading: React.PropTypes.bool, | ||||
|     onSelectFile: React.PropTypes.func.isRequired, | ||||
|     onRemoveFile: React.PropTypes.func.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   render () { | ||||
|     const uploads = this.props.media.map(attachment => ( | ||||
|       <div key={attachment.get('id')} style={{ borderRadius: '4px', marginBottom: '10px' }} className='transparent-background'> | ||||
|         <div style={{ width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}> | ||||
|           <IconButton icon='times' title='Undo' size={36} onClick={this.props.onRemoveFile.bind(this, attachment.get('id'))} /> | ||||
|         </div> | ||||
|       </div> | ||||
|     )); | ||||
| 
 | ||||
|     return ( | ||||
|       <div style={{ marginBottom: '20px', padding: '10px', overflow: 'hidden' }}> | ||||
|         {uploads} | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default UploadForm; | ||||
| @ -0,0 +1,17 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import UploadButton from '../components/upload_button'; | ||||
| import { uploadCompose } from '../../../actions/compose'; | ||||
| 
 | ||||
| const mapStateToProps = state => ({ | ||||
|   disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => m.get('type') === 'video')), | ||||
| }); | ||||
| 
 | ||||
| const mapDispatchToProps = dispatch => ({ | ||||
| 
 | ||||
|   onSelectFile (files) { | ||||
|     dispatch(uploadCompose(files)); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default connect(mapStateToProps, mapDispatchToProps)(UploadButton); | ||||
| @ -0,0 +1,17 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import UploadForm from '../components/upload_form'; | ||||
| import { undoUploadCompose } from '../../../actions/compose'; | ||||
| 
 | ||||
| const mapStateToProps = (state, props) => ({ | ||||
|   media: state.getIn(['compose', 'media_attachments']), | ||||
| }); | ||||
| 
 | ||||
| const mapDispatchToProps = dispatch => ({ | ||||
| 
 | ||||
|   onRemoveFile (media_id) { | ||||
|     dispatch(undoUploadCompose(media_id)); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default connect(mapStateToProps, mapDispatchToProps)(UploadForm); | ||||
| @ -1,8 +1,7 @@ | ||||
| import Drawer               from '../ui/components/drawer'; | ||||
| import ComposeFormContainer from '../ui/containers/compose_form_container'; | ||||
| import FollowFormContainer  from '../ui/containers/follow_form_container'; | ||||
| import UploadFormContainer  from '../ui/containers/upload_form_container'; | ||||
| import NavigationContainer  from '../ui/containers/navigation_container'; | ||||
| import Drawer               from './components/drawer'; | ||||
| import ComposeFormContainer from './containers/compose_form_container'; | ||||
| import UploadFormContainer  from './containers/upload_form_container'; | ||||
| import NavigationContainer  from './containers/navigation_container'; | ||||
| import PureRenderMixin      from 'react-addons-pure-render-mixin'; | ||||
| import SuggestionsContainer from './containers/suggestions_container'; | ||||
| import SearchContainer      from './containers/search_container'; | ||||
|  | ||||
| @ -1,44 +0,0 @@ | ||||
| import IconButton      from '../../../components/icon_button'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| 
 | ||||
| const FollowForm = React.createClass({ | ||||
| 
 | ||||
|   contextTypes: { | ||||
|     router: React.PropTypes.object | ||||
|   }, | ||||
| 
 | ||||
|   propTypes: { | ||||
|     text: React.PropTypes.string.isRequired, | ||||
|     is_submitting: React.PropTypes.bool, | ||||
|     onChange: React.PropTypes.func.isRequired, | ||||
|     onSubmit: React.PropTypes.func.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   handleChange (e) { | ||||
|     this.props.onChange(e.target.value); | ||||
|   }, | ||||
| 
 | ||||
|   handleKeyUp (e) { | ||||
|     if (e.keyCode === 13) { | ||||
|       this.handleSubmit(); | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   handleSubmit () { | ||||
|     this.props.onSubmit(this.context.router); | ||||
|   }, | ||||
| 
 | ||||
|   render () { | ||||
|     return ( | ||||
|       <div style={{ display: 'flex', lineHeight: '20px', padding: '10px', background: '#373b4a' }}> | ||||
|         <input autoComplete='off' type='text' disabled={this.props.is_submitting} placeholder='username@domain' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='follow-form__input' style={{ flex: '1 1 auto', boxSizing: 'border-box', display: 'block', border: 'none', padding: '10px', fontFamily: 'Roboto', color: '#282c37', fontSize: '14px', margin: '0' }} /> | ||||
|         <div style={{ padding: '10px', paddingRight: '0' }}><IconButton title='Follow' size={20} icon='user-plus' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default FollowForm; | ||||
| @ -1,43 +0,0 @@ | ||||
| import PureRenderMixin    from 'react-addons-pure-render-mixin'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import UploadButton       from './upload_button'; | ||||
| import IconButton         from '../../../components/icon_button'; | ||||
| 
 | ||||
| const UploadForm = React.createClass({ | ||||
| 
 | ||||
|   propTypes: { | ||||
|     media: ImmutablePropTypes.list.isRequired, | ||||
|     is_uploading: React.PropTypes.bool, | ||||
|     onSelectFile: React.PropTypes.func.isRequired, | ||||
|     onRemoveFile: React.PropTypes.func.isRequired | ||||
|   }, | ||||
| 
 | ||||
|   mixins: [PureRenderMixin], | ||||
| 
 | ||||
|   render () { | ||||
|     let uploads = this.props.media.map(function (attachment) { | ||||
|       return ( | ||||
|         <div key={attachment.get('id')} style={{ borderRadius: '4px', marginBottom: '10px' }} className='transparent-background'> | ||||
|           <div style={{ width: '100%', height: '100px', borderRadius: '4px', background: `url(${attachment.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }}> | ||||
|             <IconButton icon='times' title='Undo' size={36} onClick={() => this.props.onRemoveFile(attachment.get('id'))} /> | ||||
|           </div> | ||||
|         </div> | ||||
|       ); | ||||
|     }.bind(this)); | ||||
| 
 | ||||
|     const noMoreAllowed = (this.props.media.some(m => m.get('type') === 'video')) || (this.props.media.size > 3); | ||||
| 
 | ||||
|     return ( | ||||
|       <div style={{ marginBottom: '20px', padding: '10px', paddingTop: '0' }}> | ||||
|         <UploadButton onSelectFile={this.props.onSelectFile} disabled={this.props.is_uploading || noMoreAllowed } /> | ||||
| 
 | ||||
|         <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||
|           {uploads} | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
| export default UploadForm; | ||||
| @ -1,24 +0,0 @@ | ||||
| import { connect }                    from 'react-redux'; | ||||
| import FollowForm                     from '../components/follow_form'; | ||||
| import { changeFollow, submitFollow } from '../../../actions/follow'; | ||||
| 
 | ||||
| const mapStateToProps = function (state, props) { | ||||
|   return { | ||||
|     text: state.getIn(['follow', 'text']), | ||||
|     is_submitting: state.getIn(['follow', 'is_submitting']) | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const mapDispatchToProps = function (dispatch) { | ||||
|   return { | ||||
|     onChange: function (text) { | ||||
|       dispatch(changeFollow(text)); | ||||
|     }, | ||||
| 
 | ||||
|     onSubmit: function (router) { | ||||
|       dispatch(submitFollow(router)); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export default connect(mapStateToProps, mapDispatchToProps)(FollowForm); | ||||
| @ -1,25 +0,0 @@ | ||||
| import { connect }                          from 'react-redux'; | ||||
| import UploadForm                           from '../components/upload_form'; | ||||
| import { uploadCompose, undoUploadCompose } from '../../../actions/compose'; | ||||
| 
 | ||||
| const mapStateToProps = function (state, props) { | ||||
|   return { | ||||
|     media: state.getIn(['compose', 'media_attachments']), | ||||
|     progress: state.getIn(['compose', 'progress']), | ||||
|     is_uploading: state.getIn(['compose', 'is_uploading']) | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const mapDispatchToProps = function (dispatch) { | ||||
|   return { | ||||
|     onSelectFile: function (files) { | ||||
|       dispatch(uploadCompose(files)); | ||||
|     }, | ||||
| 
 | ||||
|     onRemoveFile: function (media_id) { | ||||
|       dispatch(undoUploadCompose(media_id)); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export default connect(mapStateToProps, mapDispatchToProps)(UploadForm); | ||||
| @ -1,29 +0,0 @@ | ||||
| import { | ||||
|   FOLLOW_CHANGE, | ||||
|   FOLLOW_SUBMIT_REQUEST, | ||||
|   FOLLOW_SUBMIT_SUCCESS, | ||||
|   FOLLOW_SUBMIT_FAIL | ||||
| } from '../actions/follow'; | ||||
| import Immutable from 'immutable'; | ||||
| 
 | ||||
| const initialState = Immutable.Map({ | ||||
|   text: '', | ||||
|   is_submitting: false | ||||
| }); | ||||
| 
 | ||||
| export default function follow(state = initialState, action) { | ||||
|   switch(action.type) { | ||||
|     case FOLLOW_CHANGE: | ||||
|       return state.set('text', action.text); | ||||
|     case FOLLOW_SUBMIT_REQUEST: | ||||
|       return state.set('is_submitting', true); | ||||
|     case FOLLOW_SUBMIT_SUCCESS: | ||||
|       return state.withMutations(map => { | ||||
|         map.set('text', '').set('is_submitting', false); | ||||
|       }); | ||||
|     case FOLLOW_SUBMIT_FAIL: | ||||
|       return state.set('is_submitting', false); | ||||
|     default: | ||||
|       return state; | ||||
|   } | ||||
| }; | ||||
| @ -2,7 +2,6 @@ import { combineReducers }   from 'redux-immutable'; | ||||
| import timelines             from './timelines'; | ||||
| import meta                  from './meta'; | ||||
| import compose               from './compose'; | ||||
| import follow                from './follow'; | ||||
| import notifications         from './notifications'; | ||||
| import { loadingBarReducer } from 'react-redux-loading-bar'; | ||||
| import modal                 from './modal'; | ||||
| @ -16,7 +15,6 @@ export default combineReducers({ | ||||
|   timelines, | ||||
|   meta, | ||||
|   compose, | ||||
|   follow, | ||||
|   notifications, | ||||
|   loadingBar: loadingBarReducer, | ||||
|   modal, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user