diff --git a/.env.production.sample b/.env.production.sample
index 91fcce6ac45..27de27de493 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -134,3 +134,6 @@ STREAMING_CLUSTER_NUM=1
# If you use Docker, you may want to assign UID/GID manually.
# UID=1000
# GID=1000
+
+# Maximum allowed character count
+# MAX_TOOT_CHARS=500
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 13a41f23f87..aaca4549329 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -19,6 +19,9 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz';
import { countableText } from '../util/counter';
import ComposeAttachOptions from '../../../../glitch/components/compose/attach_options/index';
+import initialState from '../../../initial_state';
+
+const maxChars = initialState.max_toot_chars;
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
@@ -205,7 +208,7 @@ export default class ComposeForm extends ImmutablePureComponent {
}
}
- const submitDisabled = disabled || this.props.is_uploading || length(text) > 500 || (text.length !== 0 && text.trim().length === 0);
+ const submitDisabled = disabled || this.props.is_uploading || length(text) > maxChars || (text.length !== 0 && text.trim().length === 0);
return (
@@ -255,7 +258,7 @@ export default class ComposeForm extends ImmutablePureComponent {
-
+
{
showSideArm ?
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 787c5add33c..9dfa019f59d 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -2,10 +2,15 @@
class InitialStateSerializer < ActiveModel::Serializer
attributes :meta, :compose, :accounts,
- :media_attachments, :settings, :push_subscription
+ :media_attachments, :settings, :push_subscription,
+ :max_toot_chars
has_many :custom_emojis, serializer: REST::CustomEmojiSerializer
+ def max_toot_chars
+ StatusLengthValidator::MAX_CHARS
+ end
+
def custom_emojis
CustomEmoji.local.where(disabled: false)
end
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index 2898011fd8a..abbacc37476 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -4,7 +4,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
include RoutingHelper
attributes :uri, :title, :description, :email,
- :version, :urls, :stats, :thumbnail
+ :version, :urls, :stats, :thumbnail, :max_toot_chars
def uri
Rails.configuration.x.local_domain
@@ -30,6 +30,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
full_asset_url(instance_presenter.thumbnail.file.url) if instance_presenter.thumbnail
end
+ def max_toot_chars
+ StatusLengthValidator::MAX_CHARS
+ end
+
def stats
{
user_count: instance_presenter.user_count,
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index 2ce5d1ee999..79d17742a90 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class StatusLengthValidator < ActiveModel::Validator
- MAX_CHARS = 512
+ MAX_CHARS = (ENV['MAX_TOOT_CHARS'] || 500).to_i
def validate(status)
return unless status.local? && !status.reblog?