diff --git a/.rubocop.yml b/.rubocop.yml
index 8dc2d1c47..dfda150f9 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -70,6 +70,8 @@ Metrics/AbcSize:
Max: 115
Exclude:
- 'lib/mastodon/*_cli.rb'
+ AllowedMethods:
+ - process_update
Metrics/BlockLength:
Max: 55
@@ -92,6 +94,8 @@ Metrics/CyclomaticComplexity:
Max: 25
Exclude:
- 'lib/mastodon/*_cli.rb'
+ AllowedMethods:
+ - process_update
Layout/LineLength:
AllowURI: true
@@ -113,6 +117,8 @@ Metrics/ParameterLists:
Metrics/PerceivedComplexity:
Max: 25
+ AllowedMethods:
+ - process_update
Naming/MemoizedInstanceVariableName:
Enabled: false
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 3aea517a8..4be581ca3 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -57,6 +57,7 @@ class Settings::PreferencesController < Settings::BaseController
:setting_trends,
:setting_crop_images,
:setting_always_send_emails,
+ :setting_expand_usernames,
notification_emails: %i(follow follow_request reblog favourite mention report pending_account trending_tag appeal),
interactions: %i(must_be_follower must_be_following must_be_following_dm)
)
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 5737144f0..e16bac854 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -6,7 +6,12 @@ import Permalink from './permalink';
import classnames from 'classnames';
import PollContainer from 'mastodon/containers/poll_container';
import Icon from 'mastodon/components/icon';
-import { autoPlayGif, languages as preloadedLanguages, translationEnabled } from 'mastodon/initial_state';
+import {
+ autoPlayGif,
+ languages as preloadedLanguages,
+ translationEnabled,
+ expandUsernames,
+} from 'mastodon/initial_state';
const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top)
@@ -96,6 +101,14 @@ class StatusContent extends React.PureComponent {
if (mention) {
link.addEventListener('click', this.onMentionClick.bind(this, mention), false);
link.setAttribute('title', mention.get('acct'));
+ // Hometown: make remote usernames
+ if (expandUsernames) {
+ if (mention.get('acct') === mention.get('username')) {
+ link.innerHTML = `@${mention.get('username')}`;
+ } else {
+ link.innerHTML = `@${mention.get('acct')}`;
+ }
+ }
} else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
} else {
@@ -254,7 +267,9 @@ class StatusContent extends React.PureComponent {
const mentionLinks = status.get('mentions').map(item => (
- @{item.get('username')}
+ @
+ {expandUsernames ? item.get('acct') : item.get('username')}
+
)).reduce((aggregate, item) => [...aggregate, item, ' '], []);
@@ -277,7 +292,7 @@ class StatusContent extends React.PureComponent {
{!hidden && poll}
{!hidden && translateButton}
-
+ ,
];
if (status.get('activity_pub_type') === 'Article' && !this.props.expanded) {
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index 1bc47690a..e72a4d44f 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -111,6 +111,8 @@ export const disabledAccountId = getMeta('disabled_account_id');
export const displayMedia = getMeta('display_media');
export const domain = getMeta('domain');
export const expandSpoilers = getMeta('expand_spoilers');
+// Hometown: expand usernames
+export const expandUsernames = getMeta('expand_usernames');
export const forceSingleColumn = !getMeta('advanced_layout');
export const limitedFederationMode = getMeta('limited_federation_mode');
export const mascot = getMeta('mascot');
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index d529de5a9..f079f542f 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -25,6 +25,7 @@ class UserSettingsDecorator
user.settings['boost_modal'] = boost_modal_preference if change?('setting_boost_modal')
user.settings['delete_modal'] = delete_modal_preference if change?('setting_delete_modal')
user.settings['auto_play_gif'] = auto_play_gif_preference if change?('setting_auto_play_gif')
+ user.settings['expand_usernames'] = expand_usernames_preference if change?('setting_expand_usernames')
user.settings['display_media'] = display_media_preference if change?('setting_display_media')
user.settings['expand_spoilers'] = expand_spoilers_preference if change?('setting_expand_spoilers')
user.settings['reduce_motion'] = reduce_motion_preference if change?('setting_reduce_motion')
@@ -83,6 +84,10 @@ class UserSettingsDecorator
boolean_cast_setting 'setting_auto_play_gif'
end
+ def expand_usernames_preference
+ boolean_cast_setting 'setting_expand_usernames'
+ end
+
def display_media_preference
settings['setting_display_media']
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 29aff60ec..d5a81588f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -135,7 +135,7 @@ class User < ApplicationRecord
:reduce_motion, :system_font_ui, :noindex, :norss, :theme, :display_media,
:expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
:advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images,
- :disable_swiping, :default_federation, :always_send_emails,
+ :disable_swiping, :default_federation, :always_send_emails, :expand_usernames,
to: :settings, prefix: :setting, allow_nil: false
delegate :can?, to: :role
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 190df2e23..dfa68b8a0 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -44,6 +44,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:boost_modal] = object.current_account.user.setting_boost_modal
store[:delete_modal] = object.current_account.user.setting_delete_modal
store[:auto_play_gif] = object.current_account.user.setting_auto_play_gif
+ store[:expand_usernames] = object.current_account.user.setting_expand_usernames
store[:display_media] = object.current_account.user.setting_display_media
store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
store[:reduce_motion] = object.current_account.user.setting_reduce_motion
@@ -76,11 +77,11 @@ class InitialStateSerializer < ActiveModel::Serializer
store = {}
if object.current_account
- store[:me] = object.current_account.id.to_s
- store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy
- store[:default_sensitive] = object.current_account.user.setting_default_sensitive
+ store[:me] = object.current_account.id.to_s
+ store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy
+ store[:default_sensitive] = object.current_account.user.setting_default_sensitive
store[:default_federation] = object.current_account.user.setting_default_federation
- store[:default_language] = object.current_account.user.preferred_posting_language
+ store[:default_language] = object.current_account.user.preferred_posting_language
end
store[:text] = object.text if object.text
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
index 9e3964f21..49775b8c2 100644
--- a/app/views/settings/preferences/appearance/show.html.haml
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -32,6 +32,7 @@
= f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
= f.input :setting_disable_swiping, as: :boolean, wrapper: :with_label
= f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label
+ = f.input :setting_expand_usernames, as: :boolean, wrapper: :with_label
%h4= t 'appearance.toot_layout'
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index abfb2b623..76fcd1242 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -205,6 +205,7 @@ en:
setting_display_media_hide_all: Hide all
setting_display_media_show_all: Show all
setting_expand_spoilers: Always expand posts marked with content warnings
+ setting_expand_usernames: Show full username (including domain) for remote users
setting_hide_network: Hide your social graph
setting_noindex: Opt-out of search engine indexing for your profile page
setting_norss: Opt-out of an RSS feed for your public posts
diff --git a/config/settings.yml b/config/settings.yml
index cd1de06b4..ee01130d0 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -24,6 +24,7 @@ defaults: &defaults
auto_play_gif: false
display_media: 'default'
expand_spoilers: false
+ expand_usernames: true
preview_sensitive_media: false
reduce_motion: false
disable_swiping: false
diff --git a/spec/lib/settings/scoped_settings_spec.rb b/spec/lib/settings/scoped_settings_spec.rb
index 7566685b4..3faf3f41e 100644
--- a/spec/lib/settings/scoped_settings_spec.rb
+++ b/spec/lib/settings/scoped_settings_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Settings::ScopedSettings do
let(:object) { Fabricate(:user) }
let(:scoped_setting) { described_class.new(object) }
let(:val) { 'whatever' }
- let(:methods) { %i(auto_play_gif default_sensitive unfollow_modal boost_modal delete_modal reduce_motion system_font_ui noindex theme) }
+ let(:methods) { %i(auto_play_gif expand_usernames default_sensitive unfollow_modal boost_modal delete_modal reduce_motion system_font_ui noindex theme) }
describe '.initialize' do
it 'sets @object' do
diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb
index 462c5b124..1bb44d380 100644
--- a/spec/lib/user_settings_decorator_spec.rb
+++ b/spec/lib/user_settings_decorator_spec.rb
@@ -63,6 +63,13 @@ describe UserSettingsDecorator do
expect(user.settings['auto_play_gif']).to eq false
end
+ it 'updates the user settings value for username expansion' do
+ values = { 'setting_expand_usernames' => '0'}
+
+ settings.update(values)
+ expect(user.settings['expand_usernames'].to eq false)
+ end
+
it 'updates the user settings value for system font in UI' do
values = { 'setting_system_font_ui' => '0' }