diff options
20 files changed, 69 insertions, 17 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 21209cf12..81b8f8985 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -69,12 +69,12 @@ class AccountsController < ApplicationController default_statuses.tap do |statuses| statuses.merge!(hashtag_scope) if tag_requested? statuses.merge!(only_media_scope) if media_requested? - statuses.merge!(no_replies_scope) unless (current_account&.id == @account.id) && replies_requested? + statuses.merge!(no_replies_scope) unless (current_account&.id == @account.id || @account.show_replies?) && replies_requested? end end def default_statuses - visibility_scopes = user_signed_in? ? [:public, :unlisted] : :public + visibility_scopes = user_signed_in? || @account.show_unlisted? ? [:public, :unlisted] : :public @account.statuses.not_local_only.where(visibility: visibility_scopes) end diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb index e25a4bc07..4d4f5e364 100644 --- a/app/controllers/activitypub/outboxes_controller.rb +++ b/app/controllers/activitypub/outboxes_controller.rb @@ -49,7 +49,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController def set_statuses return unless page_requested? - @statuses = @account.statuses.permitted_for(@account, signed_request_account) + @statuses = @account.statuses.permitted_for(@account, signed_request_account, user_signed_in: known_visitor?) @statuses = @statuses.paginate_by_id(LIMIT, params_slice(:max_id, :min_id, :since_id)) @statuses = cache_collection(@statuses, Status) end @@ -61,4 +61,8 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController def page_params { page: true, max_id: params[:max_id], min_id: params[:min_id] }.compact end + + def known_visitor? + user_signed_in? || (signed_request_account.present? && signed_request_account.following?(@account)) + end end diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index dbafc3cc2..3c8187a99 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -21,7 +21,9 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController private def account_params - params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :require_dereference, fields_attributes: [:name, :value]) + params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, + :require_dereference, :show_replies, :show_unlisted, + fields_attributes: [:name, :value]) end def user_settings_params diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb index 8a7a3a04d..4735fea8c 100644 --- a/app/controllers/api/v1/accounts/statuses_controller.rb +++ b/app/controllers/api/v1/accounts/statuses_controller.rb @@ -29,7 +29,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses statuses.merge!(only_media_scope) if truthy_param?(:only_media) - statuses.merge!(no_replies_scope) if (current_account&.id != @account.id) || truthy_param?(:exclude_replies) + statuses.merge!(no_replies_scope) if (current_account&.id != @account.id && !@account.show_replies?) || truthy_param?(:exclude_replies) statuses.merge!(no_reblogs_scope) if truthy_param?(:exclude_reblogs) statuses.merge!(hashtag_scope) if params[:tagged].present? @@ -37,7 +37,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController end def permitted_account_statuses - @account.statuses.permitted_for(@account, current_account) + @account.statuses.permitted_for(@account, current_account, user_signed_in: user_signed_in?) end def only_media_scope diff --git a/app/controllers/settings/profiles_controller.rb b/app/controllers/settings/profiles_controller.rb index 33d93a233..d6e3c9863 100644 --- a/app/controllers/settings/profiles_controller.rb +++ b/app/controllers/settings/profiles_controller.rb @@ -23,7 +23,9 @@ class Settings::ProfilesController < Settings::BaseController private def account_params - params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :require_dereference, fields_attributes: [:name, :value]) + params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, + :require_dereference, :show_replies, :show_unlisted, + fields_attributes: [:name, :value]) end def set_account diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index 021c75c76..3a6029b96 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -674,6 +674,7 @@ class Status extends ImmutablePureComponent { const selectorAttribs = { 'data-status-by': `@${status.getIn(['account', 'acct'])}`, 'data-nest-level': status.get('nest_level'), + 'data-nest-deep': status.get('nest_level') >= 15, }; if (prepend && account) { diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/header.js b/app/javascript/flavours/glitch/features/account_timeline/components/header.js index d7edd43ab..527352497 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/header.js +++ b/app/javascript/flavours/glitch/features/account_timeline/components/header.js @@ -125,7 +125,8 @@ export default class Header extends ImmutablePureComponent { {!hideTabs && ( <div className='account__section-headline'> <NavLink exact to={`/accounts/${account.get('id')}`}><FormattedMessage id='account.posts' defaultMessage='Toots' /></NavLink> - { account.get('id') === me && (<NavLink exact to={`/accounts/${account.get('id')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Toots with replies' /></NavLink>) } + { (account.get('id') === me || account.get('show_replies')) && + (<NavLink exact to={`/accounts/${account.get('id')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Toots with replies' /></NavLink>) } <NavLink exact to={`/accounts/${account.get('id')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink> </div> )} diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 6ecce7fe9..ef46ae4ae 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -10,6 +10,8 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base direct_message: { 'litepub': 'http://litepub.social/ns#', 'directMessage': 'litepub:directMessage' }, edited: { 'mp' => 'http://the.monsterpit.net/ns#', 'edited' => 'mp:edited' }, require_dereference: { 'mp' => 'http://the.monsterpit.net/ns#', 'requireDereference' => 'mp:requireDereference' }, + show_replies: { 'mp' => 'http://the.monsterpit.net/ns#', 'showReplies' => 'mp:showReplies' }, + show_unlisted: { 'mp' => 'http://the.monsterpit.net/ns#', 'showUnlisted' => 'mp:showUnlisted' }, manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' }, sensitive: { 'sensitive' => 'as:sensitive' }, hashtag: { 'Hashtag' => 'as:Hashtag' }, diff --git a/app/models/account.rb b/app/models/account.rb index 48e6e8532..8b384f212 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -51,6 +51,8 @@ # header_storage_schema_version :integer # devices_url :string # require_dereference :boolean default(FALSE), not null +# show_replies :boolean default(TRUE), not null +# show_unlisted :boolean default(TRUE), not null # class Account < ApplicationRecord diff --git a/app/models/status.rb b/app/models/status.rb index bee7d1e67..54023c24c 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -390,8 +390,8 @@ class Status < ApplicationRecord end end - def permitted_for(target_account, account) - visibility = [:public, :unlisted] + def permitted_for(target_account, account, user_signed_in: false) + visibility = user_signed_in || target_account.show_unlisted? ? [:public, :unlisted] : :public if account.nil? where(visibility: visibility).not_local_only @@ -402,7 +402,7 @@ class Status < ApplicationRecord else # followers can see followers-only stuff, but also things they are mentioned in. # non-followers can see everything that isn't private/direct, but can see stuff they are mentioned in. - visibility.push(:private) if account.following?(target_account) + visibility.push(:private) if account.following?(target_account) && (user_signed_in || target_account.show_unlisted?) scope = left_outer_joins(:reblog) diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index f3ed70490..5a63d15ea 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -24,8 +24,8 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer attribute :moved_to, if: :moved? attribute :also_known_as, if: :also_known_as? - context_extensions :require_dereference - attribute :require_dereference + context_extensions :require_dereference, :show_replies + attributes :require_dereference, :show_replies, :show_unlisted class EndpointsSerializer < ActivityPub::Serializer include RoutingHelper diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index bc941d3e7..e425c34a0 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -7,7 +7,7 @@ class REST::AccountSerializer < ActiveModel::Serializer :note, :url, :avatar, :avatar_static, :header, :header_static, :followers_count, :following_count, :statuses_count, :last_status_at - attribute :require_dereference + attributes :require_dereference, :show_replies, :show_unlisted has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested? has_many :emojis, serializer: REST::CustomEmojiSerializer diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 56c70cfa0..2a5980c79 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -87,6 +87,8 @@ class ActivityPub::ProcessAccountService < BaseService @account.actor_type = actor_type @account.discoverable = @json['discoverable'] || false @account.require_dereference = @json['requireDereference'] || false + @account.show_replies = @json['showReplies'] || true + @account.show_unlisted = @json['showUnlisted'] || true end def set_fetchable_attributes! diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml index ef84f7304..b1f237618 100644 --- a/app/views/accounts/show.html.haml +++ b/app/views/accounts/show.html.haml @@ -26,6 +26,8 @@ .account__section-headline = active_link_to t('accounts.posts_tab_heading'), short_account_url(@account) + - if @account.show_replies? + = active_link_to t('accounts.posts_with_replies'), short_account_with_replies_url(@account) = active_link_to t('accounts.media'), short_account_media_url(@account) - if user_signed_in? && @account.blocking?(current_account) diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index d2f6dc9ba..828b3ee4c 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -28,13 +28,25 @@ .fields-group = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot') + + %h4= t 'settings.profiles.privacy' + + %p.hint= t 'settings.profiles.privacy_html' - if Setting.profile_directory .fields-group - = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable'), recommended: true + = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable') + + .fields-group + = f.input :show_replies, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.show_replies') + .fields-group + = f.input :show_unlisted, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.show_unlisted') + %h4= t 'settings.profiles.advanced_privacy' + %p.hint= t 'settings.profiles.advanced_privacy_html' + .fields-group = f.input :require_dereference, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.require_dereference_html') diff --git a/config/locales/en-MP.yml b/config/locales/en-MP.yml index 534552c73..eb5b82067 100644 --- a/config/locales/en-MP.yml +++ b/config/locales/en-MP.yml @@ -111,7 +111,10 @@ en-MP: settings: monsterfork: Monsterfork profiles: + privacy: Privacy + privacy_html: These options allow you to adjust how much information is visible on your public profile on Monsterpit. <strong>Be aware that other servers you send your roars to have their own profile systems and may not honor these options. You will need to use <em>followers-only</em> or <em>direct</em> privacy for roars you do not want displayed in other servers' public profiles.</strong> advanced_privacy: Advanced privacy + advanced_privacy_html: These options can increase your privacy at the expense of compatability with other servers. <strong>They can potentially cause roars to not be delivered to some of your followers. Only enable them if you're fully aware of their side effects.</strong> user_mailer: warning: explanation: diff --git a/config/locales/simple_form.en-MP.yml b/config/locales/simple_form.en-MP.yml index 55097c519..376ea7f9d 100644 --- a/config/locales/simple_form.en-MP.yml +++ b/config/locales/simple_form.en-MP.yml @@ -26,7 +26,8 @@ en-MP: setting_default_language: The language of your roars can be detected automatically, but it's not always accurate setting_show_application: The application you use to toot will be displayed in the detailed view of your roars setting_skin: Reskins the selected UI flavour - invite_request: + show_replies: Disable if you'd prefer your replies not be a part of your public profile + show_unlisted: Disable if you'd prefer to only show unlisted roars on your profile page to visitors who are logged-in or are your followers. text: This helps us determine if registrations are made in sincerity and prevent spam. It is only visible to admins. user: chosen_languages: When checked, only roars in selected languages will be displayed in public timelines @@ -47,6 +48,8 @@ en-MP: setting_favourite_modal: Show confirmation dialog before admiring (applies to Glitch flavour only) setting_show_application: Disclose application used to send roars setting_use_pending_items: Relax mode + show_replies: Show replies on profile + show_unlisted: Show unlisted roars to anonymous visitors invite_request: text: "Introduce yourself and let the admins know what brings you to Monsterpit." notification_emails: diff --git a/db/migrate/20200719024610_add_show_replies_to_accounts.rb b/db/migrate/20200719024610_add_show_replies_to_accounts.rb new file mode 100644 index 000000000..ac6c5906b --- /dev/null +++ b/db/migrate/20200719024610_add_show_replies_to_accounts.rb @@ -0,0 +1,7 @@ +class AddShowRepliesToAccounts < ActiveRecord::Migration[5.2] + def change + safety_assured do + add_column :accounts, :show_replies, :boolean, null: false, default: true + end + end +end diff --git a/db/migrate/20200719033609_add_show_unlisted_to_accounts.rb b/db/migrate/20200719033609_add_show_unlisted_to_accounts.rb new file mode 100644 index 000000000..a9bb16720 --- /dev/null +++ b/db/migrate/20200719033609_add_show_unlisted_to_accounts.rb @@ -0,0 +1,7 @@ +class AddShowUnlistedToAccounts < ActiveRecord::Migration[5.2] + def change + safety_assured do + add_column :accounts, :show_unlisted, :boolean, null: false, default: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index beec07767..9618dc7d4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_07_18_011317) do +ActiveRecord::Schema.define(version: 2020_07_19_033609) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -183,6 +183,8 @@ ActiveRecord::Schema.define(version: 2020_07_18_011317) do t.integer "header_storage_schema_version" t.string "devices_url" t.boolean "require_dereference", default: false, null: false + t.boolean "show_replies", default: true, null: false + t.boolean "show_unlisted", default: true, null: false t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id" |