diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index c4f600c54a..4578cf6ca6 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def load_accounts
+ return [] if @account.user_hides_network? && current_account.id != @account.id
+
default_accounts.merge(paginated_follows).to_a
end
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index 90b1f7fc51..ce2bbda855 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def load_accounts
+ return [] if @account.user_hides_network? && current_account.id != @account.id
+
default_accounts.merge(paginated_follows).to_a
end
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index ac0d4c54ef..99cb3676f1 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -6,11 +6,15 @@ class FollowerAccountsController < ApplicationController
def index
respond_to do |format|
format.html do
+ next if @account.user_hides_network?
+
follows
@relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in?
end
format.json do
+ raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
+
render json: collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index 974d95c8e4..03c4b10469 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -6,11 +6,15 @@ class FollowingAccountsController < ApplicationController
def index
respond_to do |format|
format.html do
+ next if @account.user_hides_network?
+
follows
@relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
end
format.json do
+ raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
+
render json: collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 8397631388..57793d7761 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -44,6 +44,7 @@ class Settings::PreferencesController < ApplicationController
:setting_system_font_ui,
:setting_noindex,
:setting_theme,
+ :setting_hide_network,
notification_emails: %i(follow follow_request reblog favourite mention digest),
interactions: %i(must_be_follower must_be_following)
)
diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss
index b063ca52dd..93aa134cf4 100644
--- a/app/javascript/styles/mastodon/accounts.scss
+++ b/app/javascript/styles/mastodon/accounts.scss
@@ -322,6 +322,15 @@
z-index: 2;
position: relative;
+ &.empty img {
+ position: absolute;
+ opacity: 0.2;
+ height: 200px;
+ left: 0;
+ bottom: 0;
+ pointer-events: none;
+ }
+
@media screen and (max-width: 740px) {
border-radius: 0;
box-shadow: none;
@@ -438,8 +447,8 @@
font-size: 14px;
font-weight: 500;
text-align: center;
- padding: 60px 0;
- padding-top: 55px;
+ padding: 130px 0;
+ padding-top: 125px;
margin: 0 auto;
cursor: default;
}
diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss
index ba2a06954e..dd3c1b6884 100644
--- a/app/javascript/styles/mastodon/footer.scss
+++ b/app/javascript/styles/mastodon/footer.scss
@@ -4,7 +4,7 @@
font-size: 12px;
color: $darker-text-color;
- .domain {
+ .footer__domain {
font-weight: 500;
a {
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 9260a81bc2..a82f8974b7 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -28,6 +28,7 @@ class UserSettingsDecorator
user.settings['system_font_ui'] = system_font_ui_preference if change?('setting_system_font_ui')
user.settings['noindex'] = noindex_preference if change?('setting_noindex')
user.settings['theme'] = theme_preference if change?('setting_theme')
+ user.settings['hide_network'] = hide_network_preference if change?('setting_hide_network')
end
def merged_notification_emails
@@ -78,6 +79,10 @@ class UserSettingsDecorator
boolean_cast_setting 'setting_noindex'
end
+ def hide_network_preference
+ boolean_cast_setting 'setting_hide_network'
+ end
+
def theme_preference
settings['setting_theme']
end
diff --git a/app/models/account.rb b/app/models/account.rb
index 2b3ef5cdc1..72e850aa75 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -136,6 +136,7 @@ class Account < ApplicationRecord
:moderator?,
:staff?,
:locale,
+ :hides_network?,
to: :user,
prefix: true,
allow_nil: true
diff --git a/app/models/user.rb b/app/models/user.rb
index 21c217e77d..cfbae58ed3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -86,7 +86,7 @@ class User < ApplicationRecord
has_many :session_activations, dependent: :destroy
delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
- :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media,
+ :reduce_motion, :system_font_ui, :noindex, :theme, :display_sensitive_media, :hide_network,
to: :settings, prefix: :setting, allow_nil: false
attr_accessor :invite_code
@@ -219,6 +219,10 @@ class User < ApplicationRecord
settings.notification_emails['digest']
end
+ def hides_network?
+ @hides_network ||= settings.hide_network
+ end
+
def token_for_app(a)
return nil if a.nil? || a.owner != self
Doorkeeper::AccessToken
diff --git a/app/views/accounts/_follow_grid.html.haml b/app/views/accounts/_follow_grid.html.haml
index a6d0ee8176..fdcef84be2 100644
--- a/app/views/accounts/_follow_grid.html.haml
+++ b/app/views/accounts/_follow_grid.html.haml
@@ -1,5 +1,6 @@
-.accounts-grid
+.accounts-grid{ class: accounts.empty? ? 'empty' : '' }
- if accounts.empty?
+ = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
= render partial: 'accounts/nothing_here'
- else
= render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
diff --git a/app/views/accounts/_follow_grid_hidden.html.haml b/app/views/accounts/_follow_grid_hidden.html.haml
new file mode 100644
index 0000000000..e970350e63
--- /dev/null
+++ b/app/views/accounts/_follow_grid_hidden.html.haml
@@ -0,0 +1,3 @@
+.accounts-grid.empty
+ = image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
+ %p.nothing-here= t('accounts.network_hidden')
diff --git a/app/views/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml
index a24e4ea20f..65af81a5b7 100644
--- a/app/views/follower_accounts/index.html.haml
+++ b/app/views/follower_accounts/index.html.haml
@@ -7,4 +7,7 @@
= render 'accounts/header', account: @account
-= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
+- if @account.user_hides_network?
+ = render 'accounts/follow_grid_hidden'
+- else
+ = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:account)
diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml
index 67f6cfede4..8fd95a0b4d 100644
--- a/app/views/following_accounts/index.html.haml
+++ b/app/views/following_accounts/index.html.haml
@@ -7,4 +7,7 @@
= render 'accounts/header', account: @account
-= render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
+- if @account.user_hides_network?
+ = render 'accounts/follow_grid_hidden'
+- else
+ = render 'accounts/follow_grid', follows: @follows, accounts: @follows.map(&:target_account)
diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml
index be96485613..63cc3c7a7d 100644
--- a/app/views/layouts/public.html.haml
+++ b/app/views/layouts/public.html.haml
@@ -8,9 +8,9 @@
%span.single-user-login
= link_to t('auth.login'), new_user_session_path
—
- %span.domain= link_to site_hostname, about_path
+ %span.footer__domain= link_to site_hostname, about_path
- else
- %span.domain= link_to site_hostname, root_path
+ %span.footer__domain= link_to site_hostname, root_path
%span.powered-by
!= t('generic.powered_by', link: link_to('Mastodon', 'https://joinmastodon.org'))
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index fd66e13fb8..d2e8663731 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -26,6 +26,9 @@
.fields-group
= f.input :setting_noindex, as: :boolean, wrapper: :with_label
+ .fields-group
+ = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
+
%h4= t 'preferences.web'
.fields-group
diff --git a/config/locales/en.yml b/config/locales/en.yml
index c074fa5b04..0257241cf1 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -40,6 +40,7 @@ en:
following: Following
media: Media
moved_html: "%{name} has moved to %{new_profile_link}:"
+ network_hidden: This information is not available
nothing_here: There is nothing here!
people_followed_by: People whom %{name} follows
people_who_follow: People who follow %{name}
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 7d6907ff53..85597e9a78 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -15,6 +15,7 @@ en:
note:
one: 1 character left
other: %{count} characters left
+ setting_hide_network: Who you follow and who follows you will not be shown on your profile
setting_noindex: Affects your public profile and status pages
setting_theme: Affects how Mastodon looks when you're logged in from any device.
imports:
@@ -54,6 +55,7 @@ en:
setting_default_sensitive: Always mark media as sensitive
setting_delete_modal: Show confirmation dialog before deleting a toot
setting_display_sensitive_media: Always show media marked as sensitive
+ setting_hide_network: Hide your network
setting_noindex: Opt-out of search engine indexing
setting_reduce_motion: Reduce motion in animations
setting_system_font_ui: Use system's default font
diff --git a/config/settings.yml b/config/settings.yml
index dcf655008f..3581d10a2e 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -20,6 +20,7 @@ defaults: &defaults
timeline_preview: true
show_staff_badge: true
default_sensitive: false
+ hide_network: false
unfollow_modal: false
boost_modal: false
delete_modal: true