about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-09-25 15:26:56 +0200
committerEugen Rochko <eugen@zeonfederated.com>2016-09-25 15:26:56 +0200
commite9bc4a4a0822235afebbefa0c4d660b1be9ae52f (patch)
treec31007e321a90a55da1ad65cfd6a1633b8d1cc9a
parent62b384824d39fb56cb211670126b38645fdf10cc (diff)
Limit usernames to 30 chars, statuses to 500, open account after follow form success
-rw-r--r--app/assets/javascripts/components/actions/follow.jsx3
-rw-r--r--app/assets/javascripts/components/components/media_gallery.jsx4
-rw-r--r--app/assets/javascripts/components/features/status/components/action_bar.jsx6
-rw-r--r--app/assets/javascripts/components/features/ui/components/character_counter.jsx7
-rw-r--r--app/assets/javascripts/components/features/ui/components/compose_form.jsx2
-rw-r--r--app/assets/javascripts/components/features/ui/components/follow_form.jsx8
-rw-r--r--app/assets/javascripts/components/features/ui/containers/follow_form_container.jsx4
-rw-r--r--app/models/account.rb2
-rw-r--r--app/models/status.rb2
9 files changed, 25 insertions, 13 deletions
diff --git a/app/assets/javascripts/components/actions/follow.jsx b/app/assets/javascripts/components/actions/follow.jsx
index aeb786aa3..f747a3190 100644
--- a/app/assets/javascripts/components/actions/follow.jsx
+++ b/app/assets/javascripts/components/actions/follow.jsx
@@ -12,7 +12,7 @@ export function changeFollow(text) {
   };
 };
 
-export function submitFollow() {
+export function submitFollow(router) {
   return function (dispatch, getState) {
     dispatch(submitFollowRequest());
 
@@ -20,6 +20,7 @@ export function submitFollow() {
       uri: getState().getIn(['follow', 'text'])
     }).then(function (response) {
       dispatch(submitFollowSuccess(response.data));
+      router.push(`/accounts/${response.data.id}`);
     }).catch(function (error) {
       dispatch(submitFollowFail(error));
     });
diff --git a/app/assets/javascripts/components/components/media_gallery.jsx b/app/assets/javascripts/components/components/media_gallery.jsx
index 20f9a3d87..432de9074 100644
--- a/app/assets/javascripts/components/components/media_gallery.jsx
+++ b/app/assets/javascripts/components/components/media_gallery.jsx
@@ -22,6 +22,10 @@ const MediaGallery = React.createClass({
       let bottom = 'auto';
       let right  = 'auto';
 
+      if (size === 1) {
+        width = 100;
+      }
+      
       if (size === 4 || (size === 3 && i > 0)) {
         height = 50;
       }
diff --git a/app/assets/javascripts/components/features/status/components/action_bar.jsx b/app/assets/javascripts/components/features/status/components/action_bar.jsx
index 51332dc95..65c107edc 100644
--- a/app/assets/javascripts/components/features/status/components/action_bar.jsx
+++ b/app/assets/javascripts/components/features/status/components/action_bar.jsx
@@ -18,9 +18,9 @@ const ActionBar = React.createClass({
 
     return (
       <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 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('favourited')} title='Favourite' icon='star' onClick={this.props.onFavourite.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(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>
     );
   }
diff --git a/app/assets/javascripts/components/features/ui/components/character_counter.jsx b/app/assets/javascripts/components/features/ui/components/character_counter.jsx
index dd9218844..f0c1b7c8d 100644
--- a/app/assets/javascripts/components/features/ui/components/character_counter.jsx
+++ b/app/assets/javascripts/components/features/ui/components/character_counter.jsx
@@ -3,15 +3,18 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
 const CharacterCounter = React.createClass({
 
   propTypes: {
-    text: React.PropTypes.string.isRequired
+    text: React.PropTypes.string.isRequired,
+    max: React.PropTypes.number.isRequired
   },
 
   mixins: [PureRenderMixin],
 
   render () {
+    const diff = this.props.max - this.props.text.length;
+
     return (
       <span style={{ fontSize: '16px', cursor: 'default' }}>
-        {this.props.text.length}
+        {diff}
       </span>
     );
   }
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 9453f22ff..5542b4fb4 100644
--- a/app/assets/javascripts/components/features/ui/components/compose_form.jsx
+++ b/app/assets/javascripts/components/features/ui/components/compose_form.jsx
@@ -53,7 +53,7 @@ const ComposeForm = React.createClass({
 
         <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', 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>
     );
diff --git a/app/assets/javascripts/components/features/ui/components/follow_form.jsx b/app/assets/javascripts/components/features/ui/components/follow_form.jsx
index a9d73a9a1..ec108fdb2 100644
--- a/app/assets/javascripts/components/features/ui/components/follow_form.jsx
+++ b/app/assets/javascripts/components/features/ui/components/follow_form.jsx
@@ -3,6 +3,10 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
 
 const FollowForm = React.createClass({
 
+  contextTypes: {
+    router: React.PropTypes.object
+  },
+
   propTypes: {
     text: React.PropTypes.string.isRequired,
     is_submitting: React.PropTypes.bool,
@@ -18,12 +22,12 @@ const FollowForm = React.createClass({
 
   handleKeyUp (e) {
     if (e.keyCode === 13) {
-      this.props.onSubmit();
+      this.handleSubmit();
     }
   },
 
   handleSubmit () {
-    this.props.onSubmit();
+    this.props.onSubmit(this.context.router);
   },
 
   render () {
diff --git a/app/assets/javascripts/components/features/ui/containers/follow_form_container.jsx b/app/assets/javascripts/components/features/ui/containers/follow_form_container.jsx
index a21c1291b..05cfb7c1d 100644
--- a/app/assets/javascripts/components/features/ui/containers/follow_form_container.jsx
+++ b/app/assets/javascripts/components/features/ui/containers/follow_form_container.jsx
@@ -15,8 +15,8 @@ const mapDispatchToProps = function (dispatch) {
       dispatch(changeFollow(text));
     },
 
-    onSubmit: function () {
-      dispatch(submitFollow());
+    onSubmit: function (router) {
+      dispatch(submitFollow(router));
     }
   }
 };
diff --git a/app/models/account.rb b/app/models/account.rb
index 25316c9a4..16db2d719 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -6,7 +6,7 @@ class Account < ApplicationRecord
 
   # Local users
   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?'
 
   # Avatar upload
diff --git a/app/models/status.rb b/app/models/status.rb
index ae5c4b496..cbcde69f4 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -15,7 +15,7 @@ class Status < ApplicationRecord
 
   validates :account, presence: true
   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_includes, -> { includes(:account, :media_attachments, :stream_entry, mentions: :account, reblog: [:account, mentions: :account], thread: :account) }