Skip to content
This repository has been archived by the owner on Aug 2, 2020. It is now read-only.

Allow maximum toot length to be configured #32

Merged
merged 3 commits into from Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/controllers/admin/dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def index
@relay_enabled = Relay.enabled.exists?
@single_user_mode = Rails.configuration.x.single_user_mode
@registrations_enabled = Setting.open_registrations
@max_toot_chars = Setting.max_toot_chars
@deletions_enabled = Setting.open_deletion
@invites_enabled = Setting.min_invite_role == 'user'
@search_enabled = Chewy.enabled?
Expand Down
1 change: 1 addition & 0 deletions app/controllers/admin/settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SettingsController < BaseController
site_extended_description
site_terms
open_registrations
max_toot_chars
closed_registrations_message
open_deletion
timeline_preview
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def open_registrations?
Setting.open_registrations
end

def max_toot_chars
Setting.max_toot_chars
end

def open_deletion?
Setting.open_deletion
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz';
import { countableText } from '../util/counter';
import Icon from 'mastodon/components/icon';
import { maxChars } from '../../../initial_state';

const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';

Expand Down Expand Up @@ -86,7 +87,7 @@ class ComposeForm extends ImmutablePureComponent {
const { is_submitting, is_changing_upload, is_uploading, anyMedia } = this.props;
const fulltext = [this.props.spoiler_text, countableText(this.props.text)].join('');

if (is_submitting || is_uploading || is_changing_upload || length(fulltext) > 500 || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
if (is_submitting || is_uploading || is_changing_upload || length(fulltext) > maxChars || (fulltext.length !== 0 && fulltext.trim().length === 0 && !anyMedia)) {
return;
}

Expand Down Expand Up @@ -162,7 +163,7 @@ class ComposeForm extends ImmutablePureComponent {
const { intl, onPaste, showSearch, anyMedia } = this.props;
const disabled = this.props.is_submitting;
const text = [this.props.spoiler_text, countableText(this.props.text)].join('');
const disabledButton = disabled || this.props.is_uploading || this.props.is_changing_upload || length(text) > 500 || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
const disabledButton = disabled || this.props.is_uploading || this.props.is_changing_upload || length(text) > maxChars || (text.length !== 0 && text.trim().length === 0 && !anyMedia);
let publishText = '';

if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
Expand Down Expand Up @@ -214,7 +215,7 @@ class ComposeForm extends ImmutablePureComponent {
<SensitiveButtonContainer />
<SpoilerButtonContainer />
</div>
<div className='character-counter__wrapper'><CharacterCounter max={500} text={text} /></div>
<div className='character-counter__wrapper'><CharacterCounter max={maxChars} text={text} /></div>
</div>

<div className='compose-form__publish'>
Expand Down
1 change: 1 addition & 0 deletions app/javascript/mastodon/initial_state.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const boostModal = getMeta('boost_modal');
export const deleteModal = getMeta('delete_modal');
export const me = getMeta('me');
export const searchEnabled = getMeta('search_enabled');
export const maxChars = getMeta('max_toot_chars');
export const invitesEnabled = getMeta('invites_enabled');
export const version = getMeta('version');
export const mascot = getMeta('mascot');
Expand Down
2 changes: 2 additions & 0 deletions app/models/form/admin_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Form::AdminSettings
:site_extended_description=,
:site_terms,
:site_terms=,
:max_toot_chars,
:max_toot_chars=,
:open_registrations,
:open_registrations=,
:closed_registrations_message,
Expand Down
1 change: 1 addition & 0 deletions app/presenters/instance_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class InstancePresenter
:site_short_description,
:site_description,
:site_extended_description,
:max_toot_chars,
:site_terms,
to: Setting
)
Expand Down
1 change: 1 addition & 0 deletions app/serializers/initial_state_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def meta
invites_enabled: Setting.min_invite_role == 'user',
mascot: instance_presenter.mascot&.file&.url,
profile_directory: Setting.profile_directory,
max_toot_chars: instance_presenter.max_toot_chars
}

if object.current_account
Expand Down
3 changes: 1 addition & 2 deletions app/serializers/rest/instance_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
include RoutingHelper

attributes :uri, :title, :description, :email,
:version, :urls, :stats, :thumbnail,
:languages
:version, :urls, :stats, :thumbnail, :languages

has_one :contact_account, serializer: REST::AccountSerializer

Expand Down
6 changes: 2 additions & 4 deletions app/validators/status_length_validator.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# frozen_string_literal: true

class StatusLengthValidator < ActiveModel::Validator
MAX_CHARS = 500

def validate(status)
return unless status.local? && !status.reblog?

@status = status
status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?
status.errors.add(:text, I18n.t('statuses.over_character_limit', max: Setting.max_toot_chars)) if too_long?
end

private

def too_long?
countable_length > MAX_CHARS
countable_length > Setting.max_toot_chars.to_i
end

def countable_length
Expand Down
3 changes: 3 additions & 0 deletions app/views/admin/settings/edit.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
.fields-row__column.fields-row__column-6.fields-group
= f.input :site_contact_email, wrapper: :with_label, label: t('admin.settings.contact_information.email')

.fields-group
= f.input :max_toot_chars, as: :integer, wrapper: :with_label, label: t('admin.settings.max_toot_chars.title'), hint: t('admin.settings.max_toot_chars.desc_html')

.fields-group
= f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 4 }

Expand Down
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@ en:
contact_information:
email: Business e-mail
username: Contact username
max_toot_chars:
desc_html: Set maximum toot length in characters (default: 500)
title: Max Toot Size
custom_css:
desc_html: Modify the look with CSS loaded on every page
title: Custom CSS
Expand Down
1 change: 1 addition & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defaults: &defaults
site_contact_username: ''
site_contact_email: ''
open_registrations: true
max_toot_chars: 500
profile_directory: true
closed_registrations_message: ''
open_deletion: true
Expand Down