about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-09-22 00:09:21 +0200
committerEugen Rochko <eugen@zeonfederated.com>2016-09-22 00:09:21 +0200
commitbc98865c1a97a350d98c1c295f6d67ef69ba5eb5 (patch)
tree05d6e3d6c7c404a3194319ef731a9cea4a542e65
parent94525b596ac67577a6b18b6cb7405a402e409616 (diff)
API returns mentions for statuses, compose form pre-fills all relevant usernames into the form when replying
-rw-r--r--app/assets/javascripts/components/features/ui/components/compose_form.jsx8
-rw-r--r--app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx16
-rw-r--r--app/assets/javascripts/components/reducers/compose.jsx6
-rw-r--r--app/views/api/statuses/show.rabl8
4 files changed, 21 insertions, 17 deletions
diff --git a/app/assets/javascripts/components/features/ui/components/compose_form.jsx b/app/assets/javascripts/components/features/ui/components/compose_form.jsx
index 1aa0b447f..9453f22ff 100644
--- a/app/assets/javascripts/components/features/ui/components/compose_form.jsx
+++ b/app/assets/javascripts/components/features/ui/components/compose_form.jsx
@@ -32,6 +32,12 @@ const ComposeForm = React.createClass({
     this.props.onSubmit();
   },
 
+  componentDidUpdate (prevProps) {
+    if (prevProps.text !== this.props.text || prevProps.in_reply_to !== this.props.in_reply_to) {
+      this.refs.textarea.focus();
+    }
+  },
+
   render () {
     let replyArea = '';
 
@@ -43,7 +49,7 @@ const ComposeForm = React.createClass({
       <div style={{ padding: '10px' }}>
         {replyArea}
 
-        <textarea disabled={this.props.is_submitting} placeholder='What is on your mind?' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='compose-form__textarea' style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px', margin: '0' }} />
+        <textarea ref='textarea' disabled={this.props.is_submitting} placeholder='What is on your mind?' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='compose-form__textarea' style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px', margin: '0' }} />
 
         <div style={{ marginTop: '10px', overflow: 'hidden' }}>
           <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div>
diff --git a/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx b/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx
index a092a1e8e..b9c22a19d 100644
--- a/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx
+++ b/app/assets/javascripts/components/features/ui/containers/compose_form_container.jsx
@@ -1,25 +1,13 @@
 import { connect }                                          from 'react-redux';
 import ComposeForm                                          from '../components/compose_form';
 import { changeCompose, submitCompose, cancelReplyCompose } from '../../../actions/compose';
-
-function selectStatus(state) {
-  let statusId = state.getIn(['compose', 'in_reply_to'], null);
-
-  if (statusId === null) {
-    return null;
-  }
-
-  let status = state.getIn(['timelines', 'statuses', statusId]);
-  status = status.set('account', state.getIn(['timelines', 'accounts', status.get('account')]));
-
-  return status;
-};
+import { selectStatus }                                     from '../../../reducers/timelines';
 
 const mapStateToProps = function (state, props) {
   return {
     text: state.getIn(['compose', 'text']),
     is_submitting: state.getIn(['compose', 'is_submitting']),
-    in_reply_to: selectStatus(state)
+    in_reply_to: selectStatus(state, state.getIn(['compose', 'in_reply_to']))
   };
 };
 
diff --git a/app/assets/javascripts/components/reducers/compose.jsx b/app/assets/javascripts/components/reducers/compose.jsx
index 688c494c0..3974e40c6 100644
--- a/app/assets/javascripts/components/reducers/compose.jsx
+++ b/app/assets/javascripts/components/reducers/compose.jsx
@@ -23,6 +23,10 @@ const initialState = Immutable.Map({
   media_attachments: Immutable.List([])
 });
 
+function statusToTextMentions(status) {
+  return Immutable.OrderedSet([`@${status.getIn(['account', 'acct'])} `]).union(status.get('mentions').map(mention => `@${mention.get('acct')} `)).join('');
+};
+
 export default function compose(state = initialState, action) {
   switch(action.type) {
     case COMPOSE_CHANGE:
@@ -30,7 +34,7 @@ export default function compose(state = initialState, action) {
     case COMPOSE_REPLY:
       return state.withMutations(map => {
         map.set('in_reply_to', action.status.get('id'));
-        map.set('text', `@${action.status.getIn(['account', 'acct'])} `);
+        map.set('text', statusToTextMentions(action.status));
       });
     case COMPOSE_REPLY_CANCEL:
       return state.withMutations(map => {
diff --git a/app/views/api/statuses/show.rabl b/app/views/api/statuses/show.rabl
index 2f30f68cc..f06aa6e74 100644
--- a/app/views/api/statuses/show.rabl
+++ b/app/views/api/statuses/show.rabl
@@ -20,6 +20,12 @@ end
 child :media_attachments, object_root: false do
   attributes :id, :remote_url, :type
 
-  node(:url) { |media| full_asset_url(media.file.url) }
+  node(:url)         { |media| full_asset_url(media.file.url) }
   node(:preview_url) { |media| full_asset_url(media.file.url(:small)) }
 end
+
+child :mentions, object_root: false do
+  node(:url)  { |mention| TagManager.instance.url_for(mention.account) }
+  node(:acct) { |mention| mention.account.acct }
+  node(:id)   { |mention| mention.account_id }
+end