diff --git a/.nvmrc b/.nvmrc index 48ef2c10ba..d4c3d320cc 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.9 +20.10 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 030f311101..bc66bc4add 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -45,48 +45,6 @@ Metrics/PerceivedComplexity: RSpec/ExampleLength: Max: 22 -RSpec/LetSetup: - Exclude: - - 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb' - - 'spec/controllers/api/v1/filters_controller_spec.rb' - - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb' - - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb' - - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb' - - 'spec/controllers/auth/confirmations_controller_spec.rb' - - 'spec/controllers/auth/passwords_controller_spec.rb' - - 'spec/controllers/auth/sessions_controller_spec.rb' - - 'spec/controllers/follower_accounts_controller_spec.rb' - - 'spec/controllers/following_accounts_controller_spec.rb' - - 'spec/controllers/oauth/authorized_applications_controller_spec.rb' - - 'spec/controllers/oauth/tokens_controller_spec.rb' - - 'spec/controllers/settings/imports_controller_spec.rb' - - 'spec/lib/activitypub/activity/delete_spec.rb' - - 'spec/lib/vacuum/applications_vacuum_spec.rb' - - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb' - - 'spec/models/account_spec.rb' - - 'spec/models/account_statuses_cleanup_policy_spec.rb' - - 'spec/models/canonical_email_block_spec.rb' - - 'spec/models/status_spec.rb' - - 'spec/models/user_spec.rb' - - 'spec/services/account_statuses_cleanup_service_spec.rb' - - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb' - - 'spec/services/activitypub/fetch_remote_status_service_spec.rb' - - 'spec/services/activitypub/process_account_service_spec.rb' - - 'spec/services/activitypub/process_collection_service_spec.rb' - - 'spec/services/batched_remove_status_service_spec.rb' - - 'spec/services/block_domain_service_spec.rb' - - 'spec/services/bulk_import_service_spec.rb' - - 'spec/services/delete_account_service_spec.rb' - - 'spec/services/import_service_spec.rb' - - 'spec/services/notify_service_spec.rb' - - 'spec/services/remove_status_service_spec.rb' - - 'spec/services/report_service_spec.rb' - - 'spec/services/resolve_account_service_spec.rb' - - 'spec/services/suspend_account_service_spec.rb' - - 'spec/services/unallow_domain_service_spec.rb' - - 'spec/services/unsuspend_account_service_spec.rb' - - 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb' - RSpec/MultipleExpectations: Max: 8 diff --git a/Gemfile.lock b/Gemfile.lock index 3b33402b22..9b78ca733e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -131,20 +131,20 @@ GEM attr_required (1.0.1) awrence (1.2.1) aws-eventstream (1.3.0) - aws-partitions (1.857.0) - aws-sdk-core (3.188.0) - aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (1.860.0) + aws-sdk-core (3.189.0) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.73.0) + aws-sdk-kms (1.74.0) aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.140.0) - aws-sdk-core (~> 3, >= 3.188.0) + aws-sdk-s3 (1.141.0) + aws-sdk-core (~> 3, >= 3.189.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.6) - aws-sigv4 (1.7.0) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) azure-storage-blob (2.0.3) azure-storage-common (~> 2.0) @@ -220,7 +220,7 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) date (3.3.4) - debug (1.9.0) + debug (1.9.1) irb (~> 1.10) reline (>= 0.3.8) debug_inspector (1.1.0) @@ -376,8 +376,8 @@ GEM rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) idn-ruby (0.1.5) - io-console (0.6.0) - irb (1.10.1) + io-console (0.7.1) + irb (1.11.0) rdoc reline (>= 0.3.8) jmespath (1.6.2) @@ -540,7 +540,7 @@ GEM activesupport (>= 7.0.0) rack railties (>= 7.0.0) - psych (5.1.1.1) + psych (5.1.2) stringio public_suffix (5.0.4) puma (6.4.0) @@ -614,7 +614,7 @@ GEM link_header (~> 0.0, >= 0.0.8) rdf-normalize (0.6.1) rdf (~> 3.2) - rdoc (6.6.1) + rdoc (6.6.2) psych (>= 4.0.0) redcarpet (3.6.0) redis (4.8.1) diff --git a/app/controllers/admin/follow_recommendations_controller.rb b/app/controllers/admin/follow_recommendations_controller.rb index 841e3cc7fb..a54e41bd8c 100644 --- a/app/controllers/admin/follow_recommendations_controller.rb +++ b/app/controllers/admin/follow_recommendations_controller.rb @@ -8,7 +8,7 @@ module Admin authorize :follow_recommendation, :show? @form = Form::AccountBatch.new - @accounts = filtered_follow_recommendations + @accounts = filtered_follow_recommendations.page(params[:page]) end def update diff --git a/app/controllers/api/v1/suggestions_controller.rb b/app/controllers/api/v1/suggestions_controller.rb index 9737ae5cb6..9ba1cef63c 100644 --- a/app/controllers/api/v1/suggestions_controller.rb +++ b/app/controllers/api/v1/suggestions_controller.rb @@ -3,22 +3,23 @@ class Api::V1::SuggestionsController < Api::BaseController include Authorization - before_action -> { doorkeeper_authorize! :read } + before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index + before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index before_action :require_user! + before_action :set_suggestions def index - suggestions = suggestions_source.get(current_account, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT)) - render json: suggestions.map(&:account), each_serializer: REST::AccountSerializer + render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i).map(&:account), each_serializer: REST::AccountSerializer end def destroy - suggestions_source.remove(current_account, params[:id]) + @suggestions.remove(params[:id]) render_empty end private - def suggestions_source - AccountSuggestions::PastInteractionsSource.new + def set_suggestions + @suggestions = AccountSuggestions.new(current_account) end end diff --git a/app/controllers/api/v2/suggestions_controller.rb b/app/controllers/api/v2/suggestions_controller.rb index 35eb276c01..8516796e86 100644 --- a/app/controllers/api/v2/suggestions_controller.rb +++ b/app/controllers/api/v2/suggestions_controller.rb @@ -3,17 +3,23 @@ class Api::V2::SuggestionsController < Api::BaseController include Authorization - before_action -> { doorkeeper_authorize! :read } + before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index + before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index before_action :require_user! before_action :set_suggestions def index - render json: @suggestions, each_serializer: REST::SuggestionSerializer + render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i), each_serializer: REST::SuggestionSerializer + end + + def destroy + @suggestions.remove(params[:id]) + render_empty end private def set_suggestions - @suggestions = AccountSuggestions.get(current_account, limit_param(DEFAULT_ACCOUNTS_LIMIT)) + @suggestions = AccountSuggestions.new(current_account) end end diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index 29b46cb43d..97f68c2217 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -35,6 +35,8 @@ import FollowRequestNoteContainer from '../containers/follow_request_note_contai const messages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, follow: { id: 'account.follow', defaultMessage: 'Follow' }, + followBack: { id: 'account.follow_back', defaultMessage: 'Follow back' }, + mutual: { id: 'account.mutual', defaultMessage: 'Mutual' }, cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Withdraw follow request' }, requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' }, unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, @@ -82,6 +84,20 @@ const titleFromAccount = account => { return `${prefix} (@${acct})`; }; +const messageForFollowButton = relationship => { + if(!relationship) return messages.follow; + + if (relationship.get('following') && relationship.get('followed_by')) { + return messages.mutual; + } else if (!relationship.get('following') && relationship.get('followed_by')) { + return messages.followBack; + } else if (relationship.get('following')) { + return messages.unfollow; + } else { + return messages.follow; + } +}; + const dateFormatOptions = { month: 'short', day: 'numeric', @@ -253,9 +269,7 @@ class Header extends ImmutablePureComponent { let info = []; let menu = []; - if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { - info.push(); - } else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) { + if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) { info.push(); } @@ -281,7 +295,7 @@ class Header extends ImmutablePureComponent { } else if (account.getIn(['relationship', 'requested'])) { actionBtn =