Skip to content
Snippets Groups Projects
Commit e9bc4a4a authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Limit usernames to 30 chars, statuses to 500, open account after follow form success

parent 62b38482
No related branches found
No related tags found
No related merge requests found
...@@ -12,7 +12,7 @@ export function changeFollow(text) { ...@@ -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() { ...@@ -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({ ...@@ -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({ ...@@ -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'; ...@@ -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({ ...@@ -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'; ...@@ -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({ ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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) }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment