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 |
|
||||||
}; |
|
||||||
}; |
|
@ -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,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; |
|
||||||
} |
|
||||||
}; |
|
Loading…
Reference in new issue