API returns mentions for statuses, compose form pre-fills all relevant usernames into the form when replying
This commit is contained in:
parent
94525b596a
commit
bc98865c1a
4 changed files with 21 additions and 17 deletions
|
@ -32,6 +32,12 @@ const ComposeForm = React.createClass({
|
||||||
this.props.onSubmit();
|
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 () {
|
render () {
|
||||||
let replyArea = '';
|
let replyArea = '';
|
||||||
|
|
||||||
|
@ -43,7 +49,7 @@ const ComposeForm = React.createClass({
|
||||||
<div style={{ padding: '10px' }}>
|
<div style={{ padding: '10px' }}>
|
||||||
{replyArea}
|
{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={{ marginTop: '10px', overflow: 'hidden' }}>
|
||||||
<div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div>
|
<div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div>
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ComposeForm from '../components/compose_form';
|
import ComposeForm from '../components/compose_form';
|
||||||
import { changeCompose, submitCompose, cancelReplyCompose } from '../../../actions/compose';
|
import { changeCompose, submitCompose, cancelReplyCompose } from '../../../actions/compose';
|
||||||
|
import { selectStatus } from '../../../reducers/timelines';
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = function (state, props) {
|
const mapStateToProps = function (state, props) {
|
||||||
return {
|
return {
|
||||||
text: state.getIn(['compose', 'text']),
|
text: state.getIn(['compose', 'text']),
|
||||||
is_submitting: state.getIn(['compose', 'is_submitting']),
|
is_submitting: state.getIn(['compose', 'is_submitting']),
|
||||||
in_reply_to: selectStatus(state)
|
in_reply_to: selectStatus(state, state.getIn(['compose', 'in_reply_to']))
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ const initialState = Immutable.Map({
|
||||||
media_attachments: Immutable.List([])
|
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) {
|
export default function compose(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case COMPOSE_CHANGE:
|
case COMPOSE_CHANGE:
|
||||||
|
@ -30,7 +34,7 @@ export default function compose(state = initialState, action) {
|
||||||
case COMPOSE_REPLY:
|
case COMPOSE_REPLY:
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
map.set('in_reply_to', action.status.get('id'));
|
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:
|
case COMPOSE_REPLY_CANCEL:
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
|
|
|
@ -20,6 +20,12 @@ end
|
||||||
child :media_attachments, object_root: false do
|
child :media_attachments, object_root: false do
|
||||||
attributes :id, :remote_url, :type
|
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)) }
|
node(:preview_url) { |media| full_asset_url(media.file.url(:small)) }
|
||||||
end
|
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
|
||||||
|
|
Loading…
Reference in a new issue