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 Autosuggest from 'react-autosuggest'; | ||||||
| import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; | import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; | ||||||
| import { debounce } from 'react-decoration'; | import { debounce } from 'react-decoration'; | ||||||
|  | import UploadButtonContainer from '../containers/upload_button_container'; | ||||||
| 
 | 
 | ||||||
| const getTokenForSuggestions = (str, caretPosition) => { | const getTokenForSuggestions = (str, caretPosition) => { | ||||||
|   let word; |   let word; | ||||||
| @ -168,6 +169,7 @@ const ComposeForm = React.createClass({ | |||||||
|         <div style={{ marginTop: '10px', overflow: 'hidden' }}> |         <div style={{ marginTop: '10px', overflow: 'hidden' }}> | ||||||
|           <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={disabled} /></div> |           <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> |           <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div> | ||||||
|  |           <UploadButtonContainer style={{ paddingTop: '4px' }} /> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
| @ -1,11 +1,12 @@ | |||||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||||
| import Button          from '../../../components/button'; | import IconButton from '../../../components/icon_button'; | ||||||
| 
 | 
 | ||||||
| const UploadButton = React.createClass({ | const UploadButton = React.createClass({ | ||||||
| 
 | 
 | ||||||
|   propTypes: { |   propTypes: { | ||||||
|     disabled: React.PropTypes.bool, |     disabled: React.PropTypes.bool, | ||||||
|     onSelectFile: React.PropTypes.func.isRequired |     onSelectFile: React.PropTypes.func.isRequired, | ||||||
|  |     style: React.PropTypes.object | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   mixins: [PureRenderMixin], |   mixins: [PureRenderMixin], | ||||||
| @ -17,17 +18,18 @@ const UploadButton = React.createClass({ | |||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   handleClick () { |   handleClick () { | ||||||
|     this.refs.fileElement.click(); |     this.fileElement.click(); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   setRef (c) { | ||||||
|  |     this.fileElement = c; | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div style={this.props.style}> | ||||||
|         <Button disabled={this.props.disabled} onClick={this.handleClick} block={true}> |         <IconButton icon='photo' title='Add media' disabled={this.props.disabled} onClick={this.handleClick} size={24} /> | ||||||
|           <i className='fa fa-fw fa-photo' /> Add media |         <input ref={this.setRef} type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} /> | ||||||
|         </Button> |  | ||||||
| 
 |  | ||||||
|         <input ref='fileElement' type='file' multiple={false} onChange={this.handleChange} disabled={this.props.disabled} style={{ display: 'none' }} /> |  | ||||||
|       </div> |       </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 Drawer               from './components/drawer'; | ||||||
| import ComposeFormContainer from '../ui/containers/compose_form_container'; | import ComposeFormContainer from './containers/compose_form_container'; | ||||||
| import FollowFormContainer  from '../ui/containers/follow_form_container'; | import UploadFormContainer  from './containers/upload_form_container'; | ||||||
| import UploadFormContainer  from '../ui/containers/upload_form_container'; | import NavigationContainer  from './containers/navigation_container'; | ||||||
| import NavigationContainer  from '../ui/containers/navigation_container'; |  | ||||||
| import PureRenderMixin      from 'react-addons-pure-render-mixin'; | import PureRenderMixin      from 'react-addons-pure-render-mixin'; | ||||||
| import SuggestionsContainer from './containers/suggestions_container'; | import SuggestionsContainer from './containers/suggestions_container'; | ||||||
| import SearchContainer      from './containers/search_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 timelines             from './timelines'; | ||||||
| import meta                  from './meta'; | import meta                  from './meta'; | ||||||
| import compose               from './compose'; | import compose               from './compose'; | ||||||
| import follow                from './follow'; |  | ||||||
| import notifications         from './notifications'; | import notifications         from './notifications'; | ||||||
| import { loadingBarReducer } from 'react-redux-loading-bar'; | import { loadingBarReducer } from 'react-redux-loading-bar'; | ||||||
| import modal                 from './modal'; | import modal                 from './modal'; | ||||||
| @ -16,7 +15,6 @@ export default combineReducers({ | |||||||
|   timelines, |   timelines, | ||||||
|   meta, |   meta, | ||||||
|   compose, |   compose, | ||||||
|   follow, |  | ||||||
|   notifications, |   notifications, | ||||||
|   loadingBar: loadingBarReducer, |   loadingBar: loadingBarReducer, | ||||||
|   modal, |   modal, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user