forked from fedi/mastodon
Fix reblogs of reblogs in UI, add follow form in UI
This commit is contained in:
parent
f24cb32e99
commit
d0e2733f63
|
@ -6,41 +6,41 @@ export const FOLLOW_SUBMIT_REQUEST = 'FOLLOW_SUBMIT_REQUEST';
|
||||||
export const FOLLOW_SUBMIT_SUCCESS = 'FOLLOW_SUBMIT_SUCCESS';
|
export const FOLLOW_SUBMIT_SUCCESS = 'FOLLOW_SUBMIT_SUCCESS';
|
||||||
export const FOLLOW_SUBMIT_FAIL = 'FOLLOW_SUBMIT_FAIL';
|
export const FOLLOW_SUBMIT_FAIL = 'FOLLOW_SUBMIT_FAIL';
|
||||||
|
|
||||||
export function followChange(text) {
|
export function changeFollow(text) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_CHANGE,
|
type: FOLLOW_CHANGE,
|
||||||
text: text
|
text: text
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function followSubmit() {
|
export function submitFollow() {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
dispatch(followSubmitRequest());
|
dispatch(submitFollowRequest());
|
||||||
|
|
||||||
api(getState).post('/api/follows', {
|
api(getState).post('/api/follows', {
|
||||||
uri: getState().getIn(['follow', 'text'])
|
uri: getState().getIn(['follow', 'text'])
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
dispatch(followSubmitSuccess(response.data));
|
dispatch(submitFollowSuccess(response.data));
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
dispatch(followSubmitFail(error));
|
dispatch(submitFollowFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function followSubmitRequest() {
|
export function submitFollowRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_SUBMIT_REQUEST
|
type: FOLLOW_SUBMIT_REQUEST
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function followSubmitSuccess(account) {
|
export function submitFollowSuccess(account) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_SUBMIT_SUCCESS,
|
type: FOLLOW_SUBMIT_SUCCESS,
|
||||||
account: account
|
account: account
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function followSubmitFail(error) {
|
export function submitFollowFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_SUBMIT_FAIL,
|
type: FOLLOW_SUBMIT_FAIL,
|
||||||
error: error
|
error: error
|
||||||
|
|
|
@ -4,7 +4,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ReplyIndicator from './reply_indicator';
|
import ReplyIndicator from './reply_indicator';
|
||||||
|
|
||||||
const ComposerDrawer = React.createClass({
|
const ComposeForm = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
text: React.PropTypes.string.isRequired,
|
text: React.PropTypes.string.isRequired,
|
||||||
|
@ -39,10 +39,10 @@ const ComposerDrawer = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '280px', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '10px' }}>
|
<div style={{ marginBottom: '30px', 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-drawer__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 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>
|
||||||
|
@ -54,4 +54,4 @@ const ComposerDrawer = React.createClass({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ComposerDrawer;
|
export default ComposeForm;
|
17
app/assets/javascripts/components/components/drawer.jsx
Normal file
17
app/assets/javascripts/components/components/drawer.jsx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
|
const Drawer = React.createClass({
|
||||||
|
|
||||||
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div style={{ width: '280px', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '0', display: 'flex', flexDirection: 'column' }}>
|
||||||
|
{this.props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Drawer;
|
40
app/assets/javascripts/components/components/follow_form.jsx
Normal file
40
app/assets/javascripts/components/components/follow_form.jsx
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import IconButton from './icon_button';
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
|
const FollowForm = React.createClass({
|
||||||
|
|
||||||
|
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.props.onSubmit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit () {
|
||||||
|
this.props.onSubmit();
|
||||||
|
},
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', lineHeight: '20px', padding: '10px', background: '#373b4a' }}>
|
||||||
|
<input 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,6 +1,8 @@
|
||||||
import ColumnsArea from './columns_area';
|
import ColumnsArea from './columns_area';
|
||||||
import ComposerDrawerContainer from '../containers/composer_drawer_container';
|
import Drawer from './drawer';
|
||||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
import ComposeFormContainer from '../containers/compose_form_container';
|
||||||
|
import FollowFormContainer from '../containers/follow_form_container';
|
||||||
|
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
const Frontend = React.createClass({
|
const Frontend = React.createClass({
|
||||||
|
|
||||||
|
@ -9,7 +11,14 @@ const Frontend = React.createClass({
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div style={{ flex: '0 0 auto', display: 'flex', width: '100%', height: '100%', background: '#1a1c23' }}>
|
<div style={{ flex: '0 0 auto', display: 'flex', width: '100%', height: '100%', background: '#1a1c23' }}>
|
||||||
<ComposerDrawerContainer />
|
<Drawer>
|
||||||
|
<div style={{ flex: '1 1 auto' }}>
|
||||||
|
<ComposeFormContainer />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FollowFormContainer />
|
||||||
|
</Drawer>
|
||||||
|
|
||||||
<ColumnsArea />
|
<ColumnsArea />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ComposerDrawer from '../components/composer_drawer';
|
import ComposeForm from '../components/compose_form';
|
||||||
import { changeCompose, submitCompose, cancelReplyCompose } from '../actions/compose';
|
import { changeCompose, submitCompose, cancelReplyCompose } from '../actions/compose';
|
||||||
|
|
||||||
const mapStateToProps = function (state, props) {
|
const mapStateToProps = function (state, props) {
|
||||||
|
@ -26,4 +26,4 @@ const mapDispatchToProps = function (dispatch) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(ComposerDrawer);
|
export default connect(mapStateToProps, mapDispatchToProps)(ComposeForm);
|
|
@ -0,0 +1,24 @@
|
||||||
|
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 () {
|
||||||
|
dispatch(submitFollow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(FollowForm);
|
|
@ -9,6 +9,8 @@ function updateMatchingStatuses(state, needle, callback) {
|
||||||
return list.map(function (status) {
|
return list.map(function (status) {
|
||||||
if (status.get('id') === needle.get('id')) {
|
if (status.get('id') === needle.get('id')) {
|
||||||
return callback(status);
|
return callback(status);
|
||||||
|
} else if (status.getIn(['reblog', 'id'], null) === needle.get('id')) {
|
||||||
|
return status.set('reblog', callback(status.get('reblog')));
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-drawer__textarea {
|
.compose-form__textarea, .follow-form__input {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
|
|
|
@ -59,11 +59,11 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def favourited?(status)
|
def favourited?(status)
|
||||||
(status.reblog? ? status.reblog : status).favourites.where(account: self).count == 1
|
(status.reblog? ? status.reblog : status).favourites.where(account: self).count > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def reblogged?(status)
|
def reblogged?(status)
|
||||||
(status.reblog? ? status.reblog : status).reblogs.where(account: self).count == 1
|
(status.reblog? ? status.reblog : status).reblogs.where(account: self).count > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def keypair
|
def keypair
|
||||||
|
|
Loading…
Reference in a new issue