status_length_validator.rb 743 B

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