forked from cybrespace/mastodon
		
	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 issue
This commit is contained in:
		
							parent
							
								
									919eef3098
								
							
						
					
					
						commit
						1e02dc8715
					
				
					 19 changed files with 58 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
  font-size: 12px;
 | 
			
		||||
  color: $darker-text-color;
 | 
			
		||||
 | 
			
		||||
  .domain {
 | 
			
		||||
  .footer__domain {
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
 | 
			
		||||
    a {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,6 +136,7 @@ class Account < ApplicationRecord
 | 
			
		|||
           :moderator?,
 | 
			
		||||
           :staff?,
 | 
			
		||||
           :locale,
 | 
			
		||||
           :hides_network?,
 | 
			
		||||
           to: :user,
 | 
			
		||||
           prefix: true,
 | 
			
		||||
           allow_nil: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								app/views/accounts/_follow_grid_hidden.html.haml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/views/accounts/_follow_grid_hidden.html.haml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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/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/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
 | 
			
		||||
        = 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'))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@ en:
 | 
			
		|||
        note:
 | 
			
		||||
          one: <span class="note-counter">1</span> character 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_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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue