From 3fd6ab99e69e736e10c7022f07dfa34b60a4e54d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 5 Jul 2019 02:14:56 +0200 Subject: [PATCH 1/6] Remove deprecated REST API `GET /api/v1/timelines/direct` (#11212) --- .../api/v1/timelines/direct_controller.rb | 63 ------------------- app/models/status.rb | 41 ------------ config/routes.rb | 1 - .../v1/timelines/direct_controller_spec.rb | 17 ----- spec/models/status_spec.rb | 50 --------------- 5 files changed, 172 deletions(-) delete mode 100644 app/controllers/api/v1/timelines/direct_controller.rb delete mode 100644 spec/controllers/api/v1/timelines/direct_controller_spec.rb diff --git a/app/controllers/api/v1/timelines/direct_controller.rb b/app/controllers/api/v1/timelines/direct_controller.rb deleted file mode 100644 index d8a76d153..000000000 --- a/app/controllers/api/v1/timelines/direct_controller.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Timelines::DirectController < Api::BaseController - before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show] - before_action :require_user!, only: [:show] - after_action :insert_pagination_headers, unless: -> { @statuses.empty? } - - respond_to :json - - def show - @statuses = load_statuses - render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) - end - - private - - def load_statuses - cached_direct_statuses - end - - def cached_direct_statuses - cache_collection direct_statuses, Status - end - - def direct_statuses - direct_timeline_statuses - end - - def direct_timeline_statuses - # this query requires built in pagination. - Status.as_direct_timeline( - current_account, - limit_param(DEFAULT_STATUSES_LIMIT), - params[:max_id], - params[:since_id], - true # returns array of cache_ids object - ) - end - - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_params(core_params) - params.permit(:local, :limit).merge(core_params) - end - - def next_path - api_v1_timelines_direct_url pagination_params(max_id: pagination_max_id) - end - - def prev_path - api_v1_timelines_direct_url pagination_params(since_id: pagination_since_id) - end - - def pagination_max_id - @statuses.last.id - end - - def pagination_since_id - @statuses.first.id - end -end diff --git a/app/models/status.rb b/app/models/status.rb index fb9bbc9a9..2258e2d07 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -280,47 +280,6 @@ class Status < ApplicationRecord where(account: [account] + account.following).where(visibility: [:public, :unlisted, :private]) end - def as_direct_timeline(account, limit = 20, max_id = nil, since_id = nil, cache_ids = false) - # direct timeline is mix of direct message from_me and to_me. - # 2 queries are executed with pagination. - # constant expression using arel_table is required for partial index - - # _from_me part does not require any timeline filters - query_from_me = where(account_id: account.id) - .where(Status.arel_table[:visibility].eq(3)) - .limit(limit) - .order('statuses.id DESC') - - # _to_me part requires mute and block filter. - # FIXME: may we check mutes.hide_notifications? - query_to_me = Status - .joins(:mentions) - .merge(Mention.where(account_id: account.id)) - .where(Status.arel_table[:visibility].eq(3)) - .limit(limit) - .order('mentions.status_id DESC') - .not_excluded_by_account(account) - - if max_id.present? - query_from_me = query_from_me.where('statuses.id < ?', max_id) - query_to_me = query_to_me.where('mentions.status_id < ?', max_id) - end - - if since_id.present? - query_from_me = query_from_me.where('statuses.id > ?', since_id) - query_to_me = query_to_me.where('mentions.status_id > ?', since_id) - end - - if cache_ids - # returns array of cache_ids object that have id and updated_at - (query_from_me.cache_ids.to_a + query_to_me.cache_ids.to_a).uniq(&:id).sort_by(&:id).reverse.take(limit) - else - # returns ActiveRecord.Relation - items = (query_from_me.select(:id).to_a + query_to_me.select(:id).to_a).uniq(&:id).sort_by(&:id).reverse.take(limit) - Status.where(id: items.map(&:id)) - end - end - def as_public_timeline(account = nil, local_only = false) query = timeline_scope(local_only).without_replies diff --git a/config/routes.rb b/config/routes.rb index 764db8db2..29db54a32 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -299,7 +299,6 @@ Rails.application.routes.draw do end namespace :timelines do - resource :direct, only: :show, controller: :direct resource :home, only: :show, controller: :home resource :public, only: :show, controller: :public resources :tag, only: :show diff --git a/spec/controllers/api/v1/timelines/direct_controller_spec.rb b/spec/controllers/api/v1/timelines/direct_controller_spec.rb deleted file mode 100644 index a22c2cbea..000000000 --- a/spec/controllers/api/v1/timelines/direct_controller_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::Timelines::DirectController, type: :controller do - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } - - describe 'GET #show' do - it 'returns 200' do - allow(controller).to receive(:doorkeeper_token) { token } - get :show - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index e8cf18af9..a8c567414 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -339,56 +339,6 @@ RSpec.describe Status, type: :model do end end - describe '.as_direct_timeline' do - let(:account) { Fabricate(:account) } - let(:followed) { Fabricate(:account) } - let(:not_followed) { Fabricate(:account) } - - before do - Fabricate(:follow, account: account, target_account: followed) - - @self_public_status = Fabricate(:status, account: account, visibility: :public) - @self_direct_status = Fabricate(:status, account: account, visibility: :direct) - @followed_public_status = Fabricate(:status, account: followed, visibility: :public) - @followed_direct_status = Fabricate(:status, account: followed, visibility: :direct) - @not_followed_direct_status = Fabricate(:status, account: not_followed, visibility: :direct) - - @results = Status.as_direct_timeline(account) - end - - it 'does not include public statuses from self' do - expect(@results).to_not include(@self_public_status) - end - - it 'includes direct statuses from self' do - expect(@results).to include(@self_direct_status) - end - - it 'does not include public statuses from followed' do - expect(@results).to_not include(@followed_public_status) - end - - it 'does not include direct statuses not mentioning recipient from followed' do - expect(@results).to_not include(@followed_direct_status) - end - - it 'does not include direct statuses not mentioning recipient from non-followed' do - expect(@results).to_not include(@not_followed_direct_status) - end - - it 'includes direct statuses mentioning recipient from followed' do - Fabricate(:mention, account: account, status: @followed_direct_status) - results2 = Status.as_direct_timeline(account) - expect(results2).to include(@followed_direct_status) - end - - it 'includes direct statuses mentioning recipient from non-followed' do - Fabricate(:mention, account: account, status: @not_followed_direct_status) - results2 = Status.as_direct_timeline(account) - expect(results2).to include(@not_followed_direct_status) - end - end - describe '.as_public_timeline' do it 'only includes statuses with public visibility' do public_status = Fabricate(:status, visibility: :public) From 30f5bcf3e749be9651ed39a07b893f70605f8a39 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 5 Jul 2019 02:15:13 +0200 Subject: [PATCH 2/6] Remove deprecated REST API `POST /api/v1/notifications/dismiss?id=:id` (#11214) --- config/routes.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 29db54a32..1f97dea4c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -351,7 +351,6 @@ Rails.application.routes.draw do resources :notifications, only: [:index, :show] do collection do post :clear - post :dismiss # Deprecated end member do From 0c1b1069c96d3452d43d922a737c522d10e4747b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 5 Jul 2019 02:15:24 +0200 Subject: [PATCH 3/6] Remove deprecated REST API `GET /api/v1/statuses/:id/card` (#11213) --- app/controllers/api/v1/statuses_controller.rb | 14 ++------------ config/routes.rb | 1 - .../controllers/api/v1/statuses_controller_spec.rb | 14 -------------- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index b0e134554..71a505c26 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -5,8 +5,8 @@ class Api::V1::StatusesController < Api::BaseController before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :destroy] before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy] - before_action :require_user!, except: [:show, :context, :card] - before_action :set_status, only: [:show, :context, :card] + before_action :require_user!, except: [:show, :context] + before_action :set_status, only: [:show, :context] respond_to :json @@ -33,16 +33,6 @@ class Api::V1::StatusesController < Api::BaseController render json: @context, serializer: REST::ContextSerializer, relationships: StatusRelationshipsPresenter.new(statuses, current_user&.account_id) end - def card - @card = @status.preview_cards.first - - if @card.nil? - render_empty - else - render json: @card, serializer: REST::PreviewCardSerializer - end - end - def create @status = PostStatusService.new.call(current_user.account, text: status_params[:status], diff --git a/config/routes.rb b/config/routes.rb index 1f97dea4c..9ab5ba7f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -294,7 +294,6 @@ Rails.application.routes.draw do member do get :context - get :card end end diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb index 8bc3b0c67..9ff5fcd3b 100644 --- a/spec/controllers/api/v1/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/statuses_controller_spec.rb @@ -91,13 +91,6 @@ RSpec.describe Api::V1::StatusesController, type: :controller do expect(response).to have_http_status(404) end end - - describe 'GET #card' do - it 'returns http unautharized' do - get :card, params: { id: status.id } - expect(response).to have_http_status(404) - end - end end context 'with a public status' do @@ -120,13 +113,6 @@ RSpec.describe Api::V1::StatusesController, type: :controller do expect(response).to have_http_status(200) end end - - describe 'GET #card' do - it 'returns http success' do - get :card, params: { id: status.id } - expect(response).to have_http_status(200) - end - end end end end From ed544f3166a2a726a22736ee53d43c29d0f44773 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 5 Jul 2019 22:03:00 +0200 Subject: [PATCH 4/6] Fix HTTP requests to IPv6 hosts (#11240) --- app/lib/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index af49d6c77..e25b9026c 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -191,7 +191,7 @@ class Request begin raise Mastodon::HostValidationError if PrivateAddressCheck.private_address?(IPAddr.new(address.to_s)) - sock = ::Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, 0) + sock = ::Socket.new(address.is_a?(Resolv::IPv6) ? ::Socket::AF_INET6 : ::Socket::AF_INET, ::Socket::SOCK_STREAM, 0) sockaddr = ::Socket.pack_sockaddr_in(port, address.to_s) sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) From ae003d54f956fa2cbb422b04519b3a3e602652c3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 6 Jul 2019 13:54:32 +0200 Subject: [PATCH 5/6] Fix option to send e-mail notification about account action always being true (#11242) --- app/models/admin/account_action.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb index 84c3f880d..bdbd342fb 100644 --- a/app/models/admin/account_action.rb +++ b/app/models/admin/account_action.rb @@ -17,10 +17,13 @@ class Admin::AccountAction :type, :text, :report_id, - :warning_preset_id, - :send_email_notification + :warning_preset_id - attr_reader :warning + attr_reader :warning, :send_email_notification + + def send_email_notification=(value) + @send_email_notification = ActiveModel::Type::Boolean.new.cast(value) + end def save! ApplicationRecord.transaction do From c07cca4727041ea5a5721acbc603d4bfb45a15a6 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 6 Jul 2019 18:18:08 +0200 Subject: [PATCH 6/6] Only scroll to the compose form if it's not horizontally in the viewport (#11246) Avoids jumping the scroll around vertically when giving it focus and editing long toots. --- .../mastodon/features/compose/components/compose_form.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 1f476397f..47e189251 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -117,7 +117,10 @@ class ComposeForm extends ImmutablePureComponent { handleFocus = () => { if (this.composeForm && !this.props.singleColumn) { - this.composeForm.scrollIntoView(); + const { left, right } = this.composeForm.getBoundingClientRect(); + if (left < 0 || right > (window.innerWidth || document.documentElement.clientWidth)) { + this.composeForm.scrollIntoView(); + } } }