diff --git a/app/assets/images/void.png b/app/assets/images/void.png new file mode 100644 index 00000000000..7eeee75af76 Binary files /dev/null and b/app/assets/images/void.png differ diff --git a/app/assets/javascripts/components/actions/compose.jsx b/app/assets/javascripts/components/actions/compose.jsx index 4954f0f5c4f..a107b3352f3 100644 --- a/app/assets/javascripts/components/actions/compose.jsx +++ b/app/assets/javascripts/components/actions/compose.jsx @@ -1,12 +1,18 @@ import api from '../api' -export const COMPOSE_CHANGE = 'COMPOSE_CHANGE'; -export const COMPOSE_SUBMIT = 'COMPOSE_SUBMIT'; -export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST'; -export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'; -export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL'; -export const COMPOSE_REPLY = 'COMPOSE_REPLY'; -export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'; +export const COMPOSE_CHANGE = 'COMPOSE_CHANGE'; +export const COMPOSE_SUBMIT = 'COMPOSE_SUBMIT'; +export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST'; +export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'; +export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL'; +export const COMPOSE_REPLY = 'COMPOSE_REPLY'; +export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'; +export const COMPOSE_UPLOAD = 'COMPOSE_UPLOAD'; +export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'; +export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'; +export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL'; +export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS'; +export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; export function changeCompose(text) { return { @@ -34,7 +40,8 @@ export function submitCompose() { api(getState).post('/api/statuses', { status: getState().getIn(['compose', 'text'], ''), - in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null) + in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), + media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')) }).then(function (response) { dispatch(submitComposeSuccess(response.data)); }).catch(function (error) { @@ -63,3 +70,56 @@ export function submitComposeFail(error) { }; } +export function uploadCompose(files) { + return function (dispatch, getState) { + dispatch(uploadComposeRequest()); + + let data = new FormData(); + data.append('file', files[0]); + + api(getState).post('/api/media', data, { + onUploadProgress: function (e) { + dispatch(uploadComposeProgress(e.loaded, e.total)); + } + }).then(function (response) { + dispatch(uploadComposeSuccess(response.data)); + }).catch(function (error) { + dispatch(uploadComposeFail(error)); + }); + }; +} + +export function uploadComposeRequest() { + return { + type: COMPOSE_UPLOAD_REQUEST + }; +} + +export function uploadComposeProgress(loaded, total) { + return { + type: COMPOSE_UPLOAD_PROGRESS, + loaded: loaded, + total: total + }; +} + +export function uploadComposeSuccess(media) { + return { + type: COMPOSE_UPLOAD_SUCCESS, + media: media + }; +} + +export function uploadComposeFail(error) { + return { + type: COMPOSE_UPLOAD_FAIL, + error: error + }; +} + +export function undoUploadCompose(media_id) { + return { + type: COMPOSE_UPLOAD_UNDO, + media_id: media_id + }; +} diff --git a/app/assets/javascripts/components/components/button.jsx b/app/assets/javascripts/components/components/button.jsx index 1a55dd87979..6f7ace3236f 100644 --- a/app/assets/javascripts/components/components/button.jsx +++ b/app/assets/javascripts/components/components/button.jsx @@ -3,9 +3,11 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; const Button = React.createClass({ propTypes: { - text: React.PropTypes.string.isRequired, + text: React.PropTypes.string, onClick: React.PropTypes.func, - disabled: React.PropTypes.bool + disabled: React.PropTypes.bool, + block: React.PropTypes.bool, + secondary: React.PropTypes.bool }, mixins: [PureRenderMixin], @@ -18,8 +20,8 @@ const Button = React.createClass({ render () { return ( - ); } diff --git a/app/assets/javascripts/components/components/compose_form.jsx b/app/assets/javascripts/components/components/compose_form.jsx index 64141201217..40d9b7773c1 100644 --- a/app/assets/javascripts/components/components/compose_form.jsx +++ b/app/assets/javascripts/components/components/compose_form.jsx @@ -3,6 +3,7 @@ import Button from './button'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ReplyIndicator from './reply_indicator'; +import UploadButton from './upload_button'; const ComposeForm = React.createClass({ @@ -39,7 +40,7 @@ const ComposeForm = React.createClass({ } return ( -
+
{replyArea}