Add preference to hide following/followers lists (#7532)
* Add preference to hide following/followers lists - Public pages - ActivityPub collections (does not return pages but does give total) - REST API (unless it's your own) (does not federate) Fix #6901 * Add preference * Add delegation * Fix issue * Fix issuegh/stable
parent
919eef3098
commit
1e02dc8715
|
@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_accounts
|
def load_accounts
|
||||||
|
return [] if @account.user_hides_network? && current_account.id != @account.id
|
||||||
|
|
||||||
default_accounts.merge(paginated_follows).to_a
|
default_accounts.merge(paginated_follows).to_a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_accounts
|
def load_accounts
|
||||||
|
return [] if @account.user_hides_network? && current_account.id != @account.id
|
||||||
|
|
||||||
default_accounts.merge(paginated_follows).to_a
|
default_accounts.merge(paginated_follows).to_a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,15 @@ class FollowerAccountsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
next if @account.user_hides_network?
|
||||||
|
|
||||||
follows
|
follows
|
||||||
@relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in?
|
@relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in?
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
|
raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
|
||||||
|
|
||||||
render json: collection_presenter,
|
render json: collection_presenter,
|
||||||
serializer: ActivityPub::CollectionSerializer,
|
serializer: ActivityPub::CollectionSerializer,
|
||||||
adapter: ActivityPub::Adapter,
|
adapter: ActivityPub::Adapter,
|
||||||
|
|
|
@ -6,11 +6,15 @@ class FollowingAccountsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
next if @account.user_hides_network?
|
||||||
|
|
||||||
follows
|
follows
|
||||||
@relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
|
@relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
|
raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
|
||||||
|
|
||||||
render json: collection_presenter,
|
render json: collection_presenter,
|
||||||
serializer: ActivityPub::CollectionSerializer,
|
serializer: ActivityPub::CollectionSerializer,
|
||||||
adapter: ActivityPub::Adapter,
|
adapter: ActivityPub::Adapter,
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Settings::PreferencesController < ApplicationController
|
||||||
:setting_system_font_ui,
|
:setting_system_font_ui,
|
||||||
:setting_noindex,
|
:setting_noindex,
|
||||||
:setting_theme,
|
:setting_theme,
|
||||||
|
:setting_hide_network,
|
||||||
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||||
interactions: %i(must_be_follower must_be_following)
|
interactions: %i(must_be_follower must_be_following)
|
||||||
)
|
)
|
||||||
|
|
|
@ -322,6 +322,15 @@
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&.empty img {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.2;
|
||||||
|
height: 200px;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 740px) {
|
@media screen and (max-width: 740px) {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
@ -438,8 +447,8 @@
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 60px 0;
|
padding: 130px 0;
|
||||||
padding-top: 55px;
|
padding-top: 125px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
|
|
||||||
.domain {
|
.footer__domain {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -28,6 +28,7 @@ class UserSettingsDecorator
|
||||||
user.settings['system_font_ui'] = system_font_ui_preference if change?('setting_system_font_ui')
|
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['noindex'] = noindex_preference if change?('setting_noindex')
|
||||||
user.settings['theme'] = theme_preference if change?('setting_theme')
|
user.settings['theme'] = theme_preference if change?('setting_theme')
|
||||||
|
user.settings['hide_network'] = hide_network_preference if change?('setting_hide_network')
|
||||||
end
|
end
|
||||||
|
|
||||||
def merged_notification_emails
|
def merged_notification_emails
|
||||||
|
@ -78,6 +79,10 @@ class UserSettingsDecorator
|
||||||
boolean_cast_setting 'setting_noindex'
|
boolean_cast_setting 'setting_noindex'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hide_network_preference
|
||||||
|
boolean_cast_setting 'setting_hide_network'
|
||||||
|
end
|
||||||
|
|
||||||
def theme_preference
|
def theme_preference
|
||||||
settings['setting_theme']
|
settings['setting_theme']
|
||||||
end
|
end
|
||||||
|
|
|
@ -136,6 +136,7 @@ class Account < ApplicationRecord
|
||||||
:moderator?,
|
:moderator?,
|
||||||
:staff?,
|
:staff?,
|
||||||
:locale,
|
:locale,
|
||||||
|
:hides_network?,
|
||||||
to: :user,
|
to: :user,
|
||||||
prefix: true,
|
prefix: true,
|
||||||
allow_nil: true
|
allow_nil: true
|
||||||
|
|
|
@ -86,7 +86,7 @@ class User < ApplicationRecord
|
||||||
has_many :session_activations, dependent: :destroy
|
has_many :session_activations, dependent: :destroy
|
||||||
|
|
||||||
delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
|
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
|
to: :settings, prefix: :setting, allow_nil: false
|
||||||
|
|
||||||
attr_accessor :invite_code
|
attr_accessor :invite_code
|
||||||
|
@ -219,6 +219,10 @@ class User < ApplicationRecord
|
||||||
settings.notification_emails['digest']
|
settings.notification_emails['digest']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hides_network?
|
||||||
|
@hides_network ||= settings.hide_network
|
||||||
|
end
|
||||||
|
|
||||||
def token_for_app(a)
|
def token_for_app(a)
|
||||||
return nil if a.nil? || a.owner != self
|
return nil if a.nil? || a.owner != self
|
||||||
Doorkeeper::AccessToken
|
Doorkeeper::AccessToken
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
.accounts-grid
|
.accounts-grid{ class: accounts.empty? ? 'empty' : '' }
|
||||||
- if accounts.empty?
|
- if accounts.empty?
|
||||||
|
= image_tag asset_pack_path('elephant_ui_greeting.svg'), alt: '', role: 'presentational'
|
||||||
= render partial: 'accounts/nothing_here'
|
= render partial: 'accounts/nothing_here'
|
||||||
- else
|
- else
|
||||||
= render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
|
= render partial: 'accounts/grid_card', collection: accounts, as: :account, cached: !user_signed_in?
|
||||||
|
|
|
@ -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')
|
|
@ -7,4 +7,7 @@
|
||||||
|
|
||||||
= render 'accounts/header', account: @account
|
= 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)
|
||||||
|
|
|
@ -7,4 +7,7 @@
|
||||||
|
|
||||||
= render 'accounts/header', account: @account
|
= 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)
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
%span.single-user-login
|
%span.single-user-login
|
||||||
= link_to t('auth.login'), new_user_session_path
|
= 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
|
- else
|
||||||
%span.domain= link_to site_hostname, root_path
|
%span.footer__domain= link_to site_hostname, root_path
|
||||||
%span.powered-by
|
%span.powered-by
|
||||||
!= t('generic.powered_by', link: link_to('Mastodon', 'https://joinmastodon.org'))
|
!= t('generic.powered_by', link: link_to('Mastodon', 'https://joinmastodon.org'))
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :setting_noindex, as: :boolean, wrapper: :with_label
|
= 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'
|
%h4= t 'preferences.web'
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
|
|
|
@ -40,6 +40,7 @@ en:
|
||||||
following: Following
|
following: Following
|
||||||
media: Media
|
media: Media
|
||||||
moved_html: "%{name} has moved to %{new_profile_link}:"
|
moved_html: "%{name} has moved to %{new_profile_link}:"
|
||||||
|
network_hidden: This information is not available
|
||||||
nothing_here: There is nothing here!
|
nothing_here: There is nothing here!
|
||||||
people_followed_by: People whom %{name} follows
|
people_followed_by: People whom %{name} follows
|
||||||
people_who_follow: People who follow %{name}
|
people_who_follow: People who follow %{name}
|
||||||
|
|
|
@ -15,6 +15,7 @@ en:
|
||||||
note:
|
note:
|
||||||
one: <span class="note-counter">1</span> character left
|
one: <span class="note-counter">1</span> character left
|
||||||
other: <span class="note-counter">%{count}</span> characters left
|
other: <span class="note-counter">%{count}</span> 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_noindex: Affects your public profile and status pages
|
||||||
setting_theme: Affects how Mastodon looks when you're logged in from any device.
|
setting_theme: Affects how Mastodon looks when you're logged in from any device.
|
||||||
imports:
|
imports:
|
||||||
|
@ -54,6 +55,7 @@ en:
|
||||||
setting_default_sensitive: Always mark media as sensitive
|
setting_default_sensitive: Always mark media as sensitive
|
||||||
setting_delete_modal: Show confirmation dialog before deleting a toot
|
setting_delete_modal: Show confirmation dialog before deleting a toot
|
||||||
setting_display_sensitive_media: Always show media marked as sensitive
|
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_noindex: Opt-out of search engine indexing
|
||||||
setting_reduce_motion: Reduce motion in animations
|
setting_reduce_motion: Reduce motion in animations
|
||||||
setting_system_font_ui: Use system's default font
|
setting_system_font_ui: Use system's default font
|
||||||
|
|
|
@ -20,6 +20,7 @@ defaults: &defaults
|
||||||
timeline_preview: true
|
timeline_preview: true
|
||||||
show_staff_badge: true
|
show_staff_badge: true
|
||||||
default_sensitive: false
|
default_sensitive: false
|
||||||
|
hide_network: false
|
||||||
unfollow_modal: false
|
unfollow_modal: false
|
||||||
boost_modal: false
|
boost_modal: false
|
||||||
delete_modal: true
|
delete_modal: true
|
||||||
|
|
Reference in New Issue