Limit usernames to 30 chars, statuses to 500, open account after follow form success
parent
62b384824d
commit
e9bc4a4a08
|
@ -12,7 +12,7 @@ export function changeFollow(text) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitFollow() {
|
export function submitFollow(router) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
dispatch(submitFollowRequest());
|
dispatch(submitFollowRequest());
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ export function submitFollow() {
|
||||||
uri: getState().getIn(['follow', 'text'])
|
uri: getState().getIn(['follow', 'text'])
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
dispatch(submitFollowSuccess(response.data));
|
dispatch(submitFollowSuccess(response.data));
|
||||||
|
router.push(`/accounts/${response.data.id}`);
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
dispatch(submitFollowFail(error));
|
dispatch(submitFollowFail(error));
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,6 +22,10 @@ const MediaGallery = React.createClass({
|
||||||
let bottom = 'auto';
|
let bottom = 'auto';
|
||||||
let right = 'auto';
|
let right = 'auto';
|
||||||
|
|
||||||
|
if (size === 1) {
|
||||||
|
width = 100;
|
||||||
|
}
|
||||||
|
|
||||||
if (size === 4 || (size === 3 && i > 0)) {
|
if (size === 4 || (size === 3 && i > 0)) {
|
||||||
height = 50;
|
height = 50;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ const ActionBar = React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ background: '#2f3441', display: 'flex', flexDirection: 'row', borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px 0' }}>
|
<div style={{ background: '#2f3441', display: 'flex', flexDirection: 'row', borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px 0' }}>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title='Reply' icon='reply' onClick={this.props.onReply.bind(this, status)} /></div>
|
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton title='Reply' icon='reply' onClick={() => this.props.onReply(status)} /></div>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('reblogged')} title='Reblog' icon='retweet' onClick={this.props.onReblog.bind(this, status)} /></div>
|
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('reblogged')} title='Reblog' icon='retweet' onClick={() => this.props.onReblog(status)} /></div>
|
||||||
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('favourited')} title='Favourite' icon='star' onClick={this.props.onFavourite.bind(this, status)} /></div>
|
<div style={{ flex: '1 1 auto', textAlign: 'center' }}><IconButton active={status.get('favourited')} title='Favourite' icon='star' onClick={() => this.props.onFavourite(status)} /></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,18 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
const CharacterCounter = React.createClass({
|
const CharacterCounter = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
text: React.PropTypes.string.isRequired
|
text: React.PropTypes.string.isRequired,
|
||||||
|
max: React.PropTypes.number.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const diff = this.props.max - this.props.text.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span style={{ fontSize: '16px', cursor: 'default' }}>
|
<span style={{ fontSize: '16px', cursor: 'default' }}>
|
||||||
{this.props.text.length}
|
{diff}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ const ComposeForm = React.createClass({
|
||||||
|
|
||||||
<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>
|
||||||
<div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter text={this.props.text} /></div>
|
<div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter max={500} text={this.props.text} /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,6 +3,10 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||||
|
|
||||||
const FollowForm = React.createClass({
|
const FollowForm = React.createClass({
|
||||||
|
|
||||||
|
contextTypes: {
|
||||||
|
router: React.PropTypes.object
|
||||||
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
text: React.PropTypes.string.isRequired,
|
text: React.PropTypes.string.isRequired,
|
||||||
is_submitting: React.PropTypes.bool,
|
is_submitting: React.PropTypes.bool,
|
||||||
|
@ -18,12 +22,12 @@ const FollowForm = React.createClass({
|
||||||
|
|
||||||
handleKeyUp (e) {
|
handleKeyUp (e) {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
this.props.onSubmit();
|
this.handleSubmit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSubmit () {
|
handleSubmit () {
|
||||||
this.props.onSubmit();
|
this.props.onSubmit(this.context.router);
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -15,8 +15,8 @@ const mapDispatchToProps = function (dispatch) {
|
||||||
dispatch(changeFollow(text));
|
dispatch(changeFollow(text));
|
||||||
},
|
},
|
||||||
|
|
||||||
onSubmit: function () {
|
onSubmit: function (router) {
|
||||||
dispatch(submitFollow());
|
dispatch(submitFollow(router));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Account < ApplicationRecord
|
||||||
|
|
||||||
# Local users
|
# Local users
|
||||||
has_one :user, inverse_of: :account
|
has_one :user, inverse_of: :account
|
||||||
validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i, message: 'only letters, numbers and underscores' }, uniqueness: { scope: :domain, case_sensitive: false }, if: 'local?'
|
validates :username, presence: true, format: { with: /\A[a-z0-9_]+\z/i, message: 'only letters, numbers and underscores' }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, if: 'local?'
|
||||||
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
||||||
|
|
||||||
# Avatar upload
|
# Avatar upload
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Status < ApplicationRecord
|
||||||
|
|
||||||
validates :account, presence: true
|
validates :account, presence: true
|
||||||
validates :uri, uniqueness: true, unless: 'local?'
|
validates :uri, uniqueness: true, unless: 'local?'
|
||||||
validates :text, presence: true, if: Proc.new { |s| s.local? && !s.reblog? }
|
validates :text, presence: true, length: { maximum: 500 }, if: Proc.new { |s| s.local? && !s.reblog? }
|
||||||
|
|
||||||
scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') }
|
scope :with_counters, -> { select('statuses.*, (select count(r.id) from statuses as r where r.reblog_of_id = statuses.id) as reblogs_count, (select count(f.id) from favourites as f where f.status_id = statuses.id) as favourites_count') }
|
||||||
scope :with_includes, -> { includes(:account, :media_attachments, :stream_entry, mentions: :account, reblog: [:account, mentions: :account], thread: :account) }
|
scope :with_includes, -> { includes(:account, :media_attachments, :stream_entry, mentions: :account, reblog: [:account, mentions: :account], thread: :account) }
|
||||||
|
|
Loading…
Reference in New Issue