You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

37 lines
835 B

  1. # frozen_string_literal: true
  2. class StatusLengthValidator < ActiveModel::Validator
  3. MAX_CHARS = 5000
  4. URL_PLACEHOLDER_CHARS = 23
  5. URL_PLACEHOLDER = "\1#{'x' * URL_PLACEHOLDER_CHARS}"
  6. def validate(status)
  7. return unless status.local? && !status.reblog?
  8. @status = status
  9. status.errors.add(:text, I18n.t('statuses.over_character_limit', max: MAX_CHARS)) if too_long?
  10. end
  11. private
  12. def too_long?
  13. countable_length > MAX_CHARS
  14. end
  15. def countable_length
  16. total_text.mb_chars.grapheme_length
  17. end
  18. def total_text
  19. [@status.spoiler_text, countable_text].join
  20. end
  21. def countable_text
  22. return '' if @status.text.nil?
  23. @status.text.dup.tap do |new_text|
  24. new_text.gsub!(FetchLinkCardService::URL_PATTERN, URL_PLACEHOLDER)
  25. new_text.gsub!(Account::MENTION_RE, '@\2')
  26. end
  27. end
  28. end