Merge branch 'master' into glitch-soc/merge-upstream
Conflicts: - `app/javascript/mastodon/features/compose/components/poll_form.js`: Upstream bumped poll option character limit, but we already had a higher one, kept ours. - `app/validators/poll_validator.rb`: Upstream bumped poll option character limit, but we already had a higher one, kept ours. - `config/initializers/content_security_policy.rb`: Upstream added a rule, the way we compute ours is different, but that added rule has been ported. - `package.json`: No real conflict, dependency update. Performed the same update. - `yarn.lock`: No real conflict, dependency update. Performed the same update.
This commit is contained in:
commit
f3eff922a3
14
Gemfile
14
Gemfile
@ -69,7 +69,7 @@ gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b
|
|||||||
gem 'nokogiri', '~> 1.10'
|
gem 'nokogiri', '~> 1.10'
|
||||||
gem 'nsa', '~> 0.2'
|
gem 'nsa', '~> 0.2'
|
||||||
gem 'oj', '~> 3.10'
|
gem 'oj', '~> 3.10'
|
||||||
gem 'ox', '~> 2.12'
|
gem 'ox', '~> 2.13'
|
||||||
gem 'parslet'
|
gem 'parslet'
|
||||||
gem 'parallel', '~> 1.19'
|
gem 'parallel', '~> 1.19'
|
||||||
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
|
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
|
||||||
@ -94,7 +94,7 @@ gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
|||||||
gem 'stoplight', '~> 2.2.0'
|
gem 'stoplight', '~> 2.2.0'
|
||||||
gem 'strong_migrations', '~> 0.6'
|
gem 'strong_migrations', '~> 0.6'
|
||||||
gem 'tty-command', '~> 0.9', require: false
|
gem 'tty-command', '~> 0.9', require: false
|
||||||
gem 'tty-prompt', '~> 0.20', require: false
|
gem 'tty-prompt', '~> 0.21', require: false
|
||||||
gem 'twitter-text', '~> 1.14'
|
gem 'twitter-text', '~> 1.14'
|
||||||
gem 'tzinfo-data', '~> 1.2019'
|
gem 'tzinfo-data', '~> 1.2019'
|
||||||
gem 'webpacker', '~> 4.2'
|
gem 'webpacker', '~> 4.2'
|
||||||
@ -112,7 +112,7 @@ group :development, :test do
|
|||||||
gem 'i18n-tasks', '~> 0.9', require: false
|
gem 'i18n-tasks', '~> 0.9', require: false
|
||||||
gem 'pry-byebug', '~> 3.8'
|
gem 'pry-byebug', '~> 3.8'
|
||||||
gem 'pry-rails', '~> 0.3'
|
gem 'pry-rails', '~> 0.3'
|
||||||
gem 'rspec-rails', '~> 3.9'
|
gem 'rspec-rails', '~> 4.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production, :test do
|
group :production, :test do
|
||||||
@ -122,19 +122,19 @@ end
|
|||||||
group :test do
|
group :test do
|
||||||
gem 'capybara', '~> 3.31'
|
gem 'capybara', '~> 3.31'
|
||||||
gem 'climate_control', '~> 0.2'
|
gem 'climate_control', '~> 0.2'
|
||||||
gem 'faker', '~> 2.10'
|
gem 'faker', '~> 2.11'
|
||||||
gem 'microformats', '~> 4.2'
|
gem 'microformats', '~> 4.2'
|
||||||
gem 'rails-controller-testing', '~> 1.0'
|
gem 'rails-controller-testing', '~> 1.0'
|
||||||
gem 'rspec-sidekiq', '~> 3.0'
|
gem 'rspec-sidekiq', '~> 3.0'
|
||||||
gem 'simplecov', '~> 0.18', require: false
|
gem 'simplecov', '~> 0.18', require: false
|
||||||
gem 'webmock', '~> 3.8'
|
gem 'webmock', '~> 3.8'
|
||||||
gem 'parallel_tests', '~> 2.30'
|
gem 'parallel_tests', '~> 2.32'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'active_record_query_trace', '~> 1.7'
|
gem 'active_record_query_trace', '~> 1.7'
|
||||||
gem 'annotate', '~> 3.0'
|
gem 'annotate', '~> 3.0'
|
||||||
gem 'better_errors', '~> 2.5'
|
gem 'better_errors', '~> 2.6'
|
||||||
gem 'binding_of_caller', '~> 0.7'
|
gem 'binding_of_caller', '~> 0.7'
|
||||||
gem 'bullet', '~> 6.1'
|
gem 'bullet', '~> 6.1'
|
||||||
gem 'letter_opener', '~> 1.7'
|
gem 'letter_opener', '~> 1.7'
|
||||||
@ -142,7 +142,7 @@ group :development do
|
|||||||
gem 'memory_profiler'
|
gem 'memory_profiler'
|
||||||
gem 'rubocop', '~> 0.79', require: false
|
gem 'rubocop', '~> 0.79', require: false
|
||||||
gem 'rubocop-rails', '~> 2.4', require: false
|
gem 'rubocop-rails', '~> 2.4', require: false
|
||||||
gem 'brakeman', '~> 4.7', require: false
|
gem 'brakeman', '~> 4.8', require: false
|
||||||
gem 'bundler-audit', '~> 0.6', require: false
|
gem 'bundler-audit', '~> 0.6', require: false
|
||||||
|
|
||||||
gem 'capistrano', '~> 3.12'
|
gem 'capistrano', '~> 3.12'
|
||||||
|
66
Gemfile.lock
66
Gemfile.lock
@ -108,7 +108,7 @@ GEM
|
|||||||
aws-sigv4 (1.1.1)
|
aws-sigv4 (1.1.1)
|
||||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||||
bcrypt (3.1.12)
|
bcrypt (3.1.12)
|
||||||
better_errors (2.5.1)
|
better_errors (2.6.0)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubi (>= 1.0.0)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
@ -116,9 +116,9 @@ GEM
|
|||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
blurhash (0.1.4)
|
blurhash (0.1.4)
|
||||||
ffi (~> 1.10.0)
|
ffi (~> 1.10.0)
|
||||||
bootsnap (1.4.5)
|
bootsnap (1.4.6)
|
||||||
msgpack (~> 1.0)
|
msgpack (~> 1.0)
|
||||||
brakeman (4.7.2)
|
brakeman (4.8.0)
|
||||||
browser (4.0.0)
|
browser (4.0.0)
|
||||||
builder (3.2.4)
|
builder (3.2.4)
|
||||||
bullet (6.1.0)
|
bullet (6.1.0)
|
||||||
@ -166,7 +166,7 @@ GEM
|
|||||||
cocaine (0.5.8)
|
cocaine (0.5.8)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
concurrent-ruby (1.1.5)
|
concurrent-ruby (1.1.6)
|
||||||
connection_pool (2.2.2)
|
connection_pool (2.2.2)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
@ -218,7 +218,7 @@ GEM
|
|||||||
tzinfo
|
tzinfo
|
||||||
excon (0.71.0)
|
excon (0.71.0)
|
||||||
fabrication (2.21.0)
|
fabrication (2.21.0)
|
||||||
faker (2.10.1)
|
faker (2.11.0)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
faraday (0.17.3)
|
faraday (0.17.3)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
@ -299,19 +299,19 @@ GEM
|
|||||||
terminal-table (>= 1.5.1)
|
terminal-table (>= 1.5.1)
|
||||||
idn-ruby (0.1.0)
|
idn-ruby (0.1.0)
|
||||||
ipaddress (0.8.3)
|
ipaddress (0.8.3)
|
||||||
iso-639 (0.2.8)
|
iso-639 (0.3.5)
|
||||||
jaro_winkler (1.5.4)
|
jaro_winkler (1.5.4)
|
||||||
jmespath (1.4.0)
|
jmespath (1.4.0)
|
||||||
json (2.3.0)
|
json (2.3.0)
|
||||||
json-canonicalization (0.2.0)
|
json-canonicalization (0.2.0)
|
||||||
json-ld (3.1.1)
|
json-ld (3.1.2)
|
||||||
htmlentities (~> 4.3)
|
htmlentities (~> 4.3)
|
||||||
json-canonicalization (~> 0.2)
|
json-canonicalization (~> 0.2)
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
multi_json (~> 1.14)
|
multi_json (~> 1.14)
|
||||||
rack (~> 2.0)
|
rack (~> 2.0)
|
||||||
rdf (~> 3.1)
|
rdf (~> 3.1)
|
||||||
json-ld-preloaded (3.1.1)
|
json-ld-preloaded (3.1.2)
|
||||||
json-ld (~> 3.1)
|
json-ld (~> 3.1)
|
||||||
rdf (~> 3.1)
|
rdf (~> 3.1)
|
||||||
jsonapi-renderer (0.2.2)
|
jsonapi-renderer (0.2.2)
|
||||||
@ -365,7 +365,7 @@ GEM
|
|||||||
mini_mime (1.0.2)
|
mini_mime (1.0.2)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
minitest (5.14.0)
|
minitest (5.14.0)
|
||||||
msgpack (1.3.1)
|
msgpack (1.3.3)
|
||||||
multi_json (1.14.1)
|
multi_json (1.14.1)
|
||||||
multipart-post (2.1.1)
|
multipart-post (2.1.1)
|
||||||
necromancer (0.5.1)
|
necromancer (0.5.1)
|
||||||
@ -383,7 +383,7 @@ GEM
|
|||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
sidekiq (>= 3.5)
|
sidekiq (>= 3.5)
|
||||||
statsd-ruby (~> 1.4, >= 1.4.0)
|
statsd-ruby (~> 1.4, >= 1.4.0)
|
||||||
oj (3.10.3)
|
oj (3.10.5)
|
||||||
omniauth (1.9.1)
|
omniauth (1.9.1)
|
||||||
hashie (>= 3.4.6)
|
hashie (>= 3.4.6)
|
||||||
rack (>= 1.6.2, < 3)
|
rack (>= 1.6.2, < 3)
|
||||||
@ -395,7 +395,7 @@ GEM
|
|||||||
omniauth (~> 1.3, >= 1.3.2)
|
omniauth (~> 1.3, >= 1.3.2)
|
||||||
ruby-saml (~> 1.7)
|
ruby-saml (~> 1.7)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ox (2.12.1)
|
ox (2.13.2)
|
||||||
paperclip (6.0.0)
|
paperclip (6.0.0)
|
||||||
activemodel (>= 4.2.0)
|
activemodel (>= 4.2.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
@ -406,7 +406,7 @@ GEM
|
|||||||
av (~> 0.9.0)
|
av (~> 0.9.0)
|
||||||
paperclip (>= 2.5.2)
|
paperclip (>= 2.5.2)
|
||||||
parallel (1.19.1)
|
parallel (1.19.1)
|
||||||
parallel_tests (2.30.1)
|
parallel_tests (2.32.0)
|
||||||
parallel
|
parallel
|
||||||
parser (2.7.0.5)
|
parser (2.7.0.5)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
@ -414,7 +414,7 @@ GEM
|
|||||||
pastel (0.7.3)
|
pastel (0.7.3)
|
||||||
equatable (~> 0.6)
|
equatable (~> 0.6)
|
||||||
tty-color (~> 0.5)
|
tty-color (~> 0.5)
|
||||||
pg (1.2.2)
|
pg (1.2.3)
|
||||||
pghero (2.4.1)
|
pghero (2.4.1)
|
||||||
activerecord (>= 5)
|
activerecord (>= 5)
|
||||||
pkg-config (1.4.1)
|
pkg-config (1.4.1)
|
||||||
@ -531,14 +531,14 @@ GEM
|
|||||||
rspec-mocks (3.9.1)
|
rspec-mocks (3.9.1)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.9.0)
|
rspec-support (~> 3.9.0)
|
||||||
rspec-rails (3.9.1)
|
rspec-rails (4.0.0)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 4.2)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 4.2)
|
||||||
railties (>= 3.0)
|
railties (>= 4.2)
|
||||||
rspec-core (~> 3.9.0)
|
rspec-core (~> 3.9)
|
||||||
rspec-expectations (~> 3.9.0)
|
rspec-expectations (~> 3.9)
|
||||||
rspec-mocks (~> 3.9.0)
|
rspec-mocks (~> 3.9)
|
||||||
rspec-support (~> 3.9.0)
|
rspec-support (~> 3.9)
|
||||||
rspec-sidekiq (3.0.3)
|
rspec-sidekiq (3.0.3)
|
||||||
rspec-core (~> 3.0, >= 3.0.0)
|
rspec-core (~> 3.0, >= 3.0.0)
|
||||||
sidekiq (>= 2.4.0)
|
sidekiq (>= 2.4.0)
|
||||||
@ -577,7 +577,7 @@ GEM
|
|||||||
sidekiq (>= 3)
|
sidekiq (>= 3)
|
||||||
thwait
|
thwait
|
||||||
tilt (>= 1.4.0)
|
tilt (>= 1.4.0)
|
||||||
sidekiq-unique-jobs (6.0.20)
|
sidekiq-unique-jobs (6.0.21)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||||
sidekiq (>= 4.0, < 7.0)
|
sidekiq (>= 4.0, < 7.0)
|
||||||
thor (~> 0)
|
thor (~> 0)
|
||||||
@ -616,11 +616,11 @@ GEM
|
|||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
thwait (0.1.0)
|
thwait (0.1.0)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
tty-color (0.5.0)
|
tty-color (0.5.1)
|
||||||
tty-command (0.9.0)
|
tty-command (0.9.0)
|
||||||
pastel (~> 0.7.0)
|
pastel (~> 0.7.0)
|
||||||
tty-cursor (0.7.0)
|
tty-cursor (0.7.1)
|
||||||
tty-prompt (0.20.0)
|
tty-prompt (0.21.0)
|
||||||
necromancer (~> 0.5.0)
|
necromancer (~> 0.5.0)
|
||||||
pastel (~> 0.7.0)
|
pastel (~> 0.7.0)
|
||||||
tty-reader (~> 0.7.0)
|
tty-reader (~> 0.7.0)
|
||||||
@ -628,7 +628,7 @@ GEM
|
|||||||
tty-cursor (~> 0.7)
|
tty-cursor (~> 0.7)
|
||||||
tty-screen (~> 0.7)
|
tty-screen (~> 0.7)
|
||||||
wisper (~> 2.0.0)
|
wisper (~> 2.0.0)
|
||||||
tty-screen (0.7.0)
|
tty-screen (0.7.1)
|
||||||
twitter-text (1.14.7)
|
twitter-text (1.14.7)
|
||||||
unf (~> 0.1.0)
|
unf (~> 0.1.0)
|
||||||
tzinfo (1.2.6)
|
tzinfo (1.2.6)
|
||||||
@ -669,11 +669,11 @@ DEPENDENCIES
|
|||||||
addressable (~> 2.7)
|
addressable (~> 2.7)
|
||||||
annotate (~> 3.0)
|
annotate (~> 3.0)
|
||||||
aws-sdk-s3 (~> 1.61)
|
aws-sdk-s3 (~> 1.61)
|
||||||
better_errors (~> 2.5)
|
better_errors (~> 2.6)
|
||||||
binding_of_caller (~> 0.7)
|
binding_of_caller (~> 0.7)
|
||||||
blurhash (~> 0.1)
|
blurhash (~> 0.1)
|
||||||
bootsnap (~> 1.4)
|
bootsnap (~> 1.4)
|
||||||
brakeman (~> 4.7)
|
brakeman (~> 4.8)
|
||||||
browser
|
browser
|
||||||
bullet (~> 6.1)
|
bullet (~> 6.1)
|
||||||
bundler-audit (~> 0.6)
|
bundler-audit (~> 0.6)
|
||||||
@ -696,7 +696,7 @@ DEPENDENCIES
|
|||||||
dotenv-rails (~> 2.7)
|
dotenv-rails (~> 2.7)
|
||||||
e2mmap (~> 0.1.0)
|
e2mmap (~> 0.1.0)
|
||||||
fabrication (~> 2.21)
|
fabrication (~> 2.21)
|
||||||
faker (~> 2.10)
|
faker (~> 2.11)
|
||||||
fast_blank (~> 1.0)
|
fast_blank (~> 1.0)
|
||||||
fastimage
|
fastimage
|
||||||
fog-core (<= 2.1.0)
|
fog-core (<= 2.1.0)
|
||||||
@ -734,11 +734,11 @@ DEPENDENCIES
|
|||||||
omniauth (~> 1.9)
|
omniauth (~> 1.9)
|
||||||
omniauth-cas (~> 1.1)
|
omniauth-cas (~> 1.1)
|
||||||
omniauth-saml (~> 1.10)
|
omniauth-saml (~> 1.10)
|
||||||
ox (~> 2.12)
|
ox (~> 2.13)
|
||||||
paperclip (~> 6.0)
|
paperclip (~> 6.0)
|
||||||
paperclip-av-transcoder (~> 0.6)
|
paperclip-av-transcoder (~> 0.6)
|
||||||
parallel (~> 1.19)
|
parallel (~> 1.19)
|
||||||
parallel_tests (~> 2.30)
|
parallel_tests (~> 2.32)
|
||||||
parslet
|
parslet
|
||||||
pg (~> 1.2)
|
pg (~> 1.2)
|
||||||
pghero (~> 2.4)
|
pghero (~> 2.4)
|
||||||
@ -763,7 +763,7 @@ DEPENDENCIES
|
|||||||
redis-namespace (~> 1.7)
|
redis-namespace (~> 1.7)
|
||||||
redis-rails (~> 5.0)
|
redis-rails (~> 5.0)
|
||||||
rqrcode (~> 1.1)
|
rqrcode (~> 1.1)
|
||||||
rspec-rails (~> 3.9)
|
rspec-rails (~> 4.0)
|
||||||
rspec-sidekiq (~> 3.0)
|
rspec-sidekiq (~> 3.0)
|
||||||
rubocop (~> 0.79)
|
rubocop (~> 0.79)
|
||||||
rubocop-rails (~> 2.4)
|
rubocop-rails (~> 2.4)
|
||||||
@ -785,7 +785,7 @@ DEPENDENCIES
|
|||||||
thor (~> 0.20)
|
thor (~> 0.20)
|
||||||
thwait (~> 0.1.0)
|
thwait (~> 0.1.0)
|
||||||
tty-command (~> 0.9)
|
tty-command (~> 0.9)
|
||||||
tty-prompt (~> 0.20)
|
tty-prompt (~> 0.21)
|
||||||
twitter-text (~> 1.14)
|
twitter-text (~> 1.14)
|
||||||
tzinfo-data (~> 1.2019)
|
tzinfo-data (~> 1.2019)
|
||||||
webmock (~> 3.8)
|
webmock (~> 3.8)
|
||||||
|
@ -7,6 +7,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||||||
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy]
|
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy]
|
||||||
before_action :require_user!, except: [:show, :context]
|
before_action :require_user!, except: [:show, :context]
|
||||||
before_action :set_status, only: [:show, :context]
|
before_action :set_status, only: [:show, :context]
|
||||||
|
before_action :set_thread, only: [:create]
|
||||||
|
|
||||||
override_rate_limit_headers :create, family: :statuses
|
override_rate_limit_headers :create, family: :statuses
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||||||
def create
|
def create
|
||||||
@status = PostStatusService.new.call(current_user.account,
|
@status = PostStatusService.new.call(current_user.account,
|
||||||
text: status_params[:status],
|
text: status_params[:status],
|
||||||
thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
|
thread: @thread,
|
||||||
media_ids: status_params[:media_ids],
|
media_ids: status_params[:media_ids],
|
||||||
sensitive: status_params[:sensitive],
|
sensitive: status_params[:sensitive],
|
||||||
spoiler_text: status_params[:spoiler_text],
|
spoiler_text: status_params[:spoiler_text],
|
||||||
@ -70,6 +71,12 @@ class Api::V1::StatusesController < Api::BaseController
|
|||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_thread
|
||||||
|
@thread = status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id])
|
||||||
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404
|
||||||
|
end
|
||||||
|
|
||||||
def status_params
|
def status_params
|
||||||
params.permit(
|
params.permit(
|
||||||
:status,
|
:status,
|
||||||
|
@ -29,6 +29,6 @@ class Settings::ImportsController < Settings::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def import_params
|
def import_params
|
||||||
params.require(:import).permit(:data, :type)
|
params.require(:import).permit(:data, :type, :mode)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -396,6 +396,7 @@ export function fetchFollowersFail(id, error) {
|
|||||||
type: FOLLOWERS_FETCH_FAIL,
|
type: FOLLOWERS_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -482,6 +483,7 @@ export function fetchFollowingFail(id, error) {
|
|||||||
type: FOLLOWING_FETCH_FAIL,
|
type: FOLLOWING_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -571,6 +573,7 @@ export function fetchRelationshipsFail(error) {
|
|||||||
type: RELATIONSHIPS_FETCH_FAIL,
|
type: RELATIONSHIPS_FETCH_FAIL,
|
||||||
error,
|
error,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
|
skipNotFound: true,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function showAlertForError(error) {
|
export function showAlertForError(error, skipNotFound = false) {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
const { data, status, statusText, headers } = error.response;
|
const { data, status, statusText, headers } = error.response;
|
||||||
|
|
||||||
if (status === 404 || status === 410) {
|
if (skipNotFound && (status === 404 || status === 410)) {
|
||||||
// Skip these errors as they are reflected in the UI
|
// Skip these errors as they are reflected in the UI
|
||||||
return { type: ALERT_NOOP };
|
return { type: ALERT_NOOP };
|
||||||
}
|
}
|
||||||
|
@ -27,4 +27,5 @@ export const fetchAccountIdentityProofsFail = (accountId, err) => ({
|
|||||||
type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
|
type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
|
||||||
accountId,
|
accountId,
|
||||||
err,
|
err,
|
||||||
|
skipNotFound: true,
|
||||||
});
|
});
|
||||||
|
@ -149,6 +149,7 @@ export function expandTimelineFail(timeline, error, isLoadingMore) {
|
|||||||
timeline,
|
timeline,
|
||||||
error,
|
error,
|
||||||
skipLoading: !isLoadingMore,
|
skipLoading: !isLoadingMore,
|
||||||
|
skipNotFound: timeline.startsWith('account:'),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,8 +76,9 @@ class ColumnHeader extends React.PureComponent {
|
|||||||
|
|
||||||
handlePin = () => {
|
handlePin = () => {
|
||||||
if (!this.props.pinned) {
|
if (!this.props.pinned) {
|
||||||
this.historyBack();
|
this.context.router.history.replace('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onPin();
|
this.props.onPin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,15 +127,7 @@ class Poll extends ImmutablePureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={option.get('title')}>
|
<li key={option.get('title')}>
|
||||||
{showResults && (
|
<label className={classNames('poll__option', { selectable: !showResults })}>
|
||||||
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
|
|
||||||
{({ width }) =>
|
|
||||||
<span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
|
|
||||||
}
|
|
||||||
</Motion>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<label className={classNames('poll__text', { selectable: !showResults })}>
|
|
||||||
<input
|
<input
|
||||||
name='vote-options'
|
name='vote-options'
|
||||||
type={poll.get('multiple') ? 'checkbox' : 'radio'}
|
type={poll.get('multiple') ? 'checkbox' : 'radio'}
|
||||||
@ -157,12 +149,26 @@ class Poll extends ImmutablePureComponent {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showResults && <span className='poll__number'>
|
{showResults && <span className='poll__number'>
|
||||||
{!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
|
|
||||||
{Math.round(percent)}%
|
{Math.round(percent)}%
|
||||||
</span>}
|
</span>}
|
||||||
|
|
||||||
<span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
|
<span
|
||||||
|
className='poll__option__text'
|
||||||
|
dangerouslySetInnerHTML={{ __html: titleEmojified }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{!!voted && <span className='poll__voted'>
|
||||||
|
<Icon id='check' className='poll__voted__mark' title={intl.formatMessage(messages.voted)} />
|
||||||
|
</span>}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
{showResults && (
|
||||||
|
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
|
||||||
|
{({ width }) =>
|
||||||
|
<span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
|
||||||
|
}
|
||||||
|
</Motion>
|
||||||
|
)}
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -432,16 +432,10 @@ class Status extends ImmutablePureComponent {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} collapsable onCollapsedToggle={this.handleCollapsedToggle} />
|
<StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} showThread={showThread} onExpandedToggle={this.handleExpandedToggle} collapsable onCollapsedToggle={this.handleCollapsedToggle} />
|
||||||
|
|
||||||
{media}
|
{media}
|
||||||
|
|
||||||
{showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) && (
|
|
||||||
<button className='status__content__read-more-button' onClick={this.handleClick}>
|
|
||||||
<FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<StatusActionBar status={status} account={account} {...other} />
|
<StatusActionBar status={status} account={account} {...other} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +20,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
expanded: PropTypes.bool,
|
expanded: PropTypes.bool,
|
||||||
|
showThread: PropTypes.bool,
|
||||||
onExpandedToggle: PropTypes.func,
|
onExpandedToggle: PropTypes.func,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
collapsable: PropTypes.bool,
|
collapsable: PropTypes.bool,
|
||||||
@ -181,6 +182,7 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
|
|
||||||
const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
|
const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
|
||||||
const renderReadMore = this.props.onClick && status.get('collapsed');
|
const renderReadMore = this.props.onClick && status.get('collapsed');
|
||||||
|
const renderViewThread = this.props.showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']);
|
||||||
|
|
||||||
const content = { __html: status.get('contentHtml') };
|
const content = { __html: status.get('contentHtml') };
|
||||||
const spoilerContent = { __html: status.get('spoilerHtml') };
|
const spoilerContent = { __html: status.get('spoilerHtml') };
|
||||||
@ -195,6 +197,12 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
directionStyle.direction = 'rtl';
|
directionStyle.direction = 'rtl';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showThreadButton = (
|
||||||
|
<button className='status__content__read-more-button' onClick={this.props.onClick}>
|
||||||
|
<FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
const readMoreButton = (
|
const readMoreButton = (
|
||||||
<button className='status__content__read-more-button' onClick={this.props.onClick} key='read-more'>
|
<button className='status__content__read-more-button' onClick={this.props.onClick} key='read-more'>
|
||||||
<FormattedMessage id='status.read_more' defaultMessage='Read more' /><Icon id='angle-right' fixedWidth />
|
<FormattedMessage id='status.read_more' defaultMessage='Read more' /><Icon id='angle-right' fixedWidth />
|
||||||
@ -229,6 +237,8 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
<div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
|
<div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
|
||||||
|
|
||||||
{!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
|
{renderViewThread && showThreadButton}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (this.props.onClick) {
|
} else if (this.props.onClick) {
|
||||||
@ -237,6 +247,8 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
<div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
|
<div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
|
||||||
|
|
||||||
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
|
{renderViewThread && showThreadButton}
|
||||||
</div>,
|
</div>,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -251,6 +263,8 @@ export default class StatusContent extends React.PureComponent {
|
|||||||
<div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
|
<div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
|
||||||
|
|
||||||
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
|
||||||
|
|
||||||
|
{renderViewThread && showThreadButton}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ class Option extends React.PureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<label className='poll__text editable'>
|
<label className='poll__option editable'>
|
||||||
<span
|
<span
|
||||||
className={classNames('poll__input', { checkbox: isPollMultiple })}
|
className={classNames('poll__input', { checkbox: isPollMultiple })}
|
||||||
onClick={this.handleToggleMultiple}
|
onClick={this.handleToggleMultiple}
|
||||||
|
@ -160,7 +160,7 @@ class Conversation extends ImmutablePureComponent {
|
|||||||
return (
|
return (
|
||||||
<HotKeys handlers={handlers}>
|
<HotKeys handlers={handlers}>
|
||||||
<div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex='0'>
|
<div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex='0'>
|
||||||
<div className='conversation__avatar'>
|
<div className='conversation__avatar' onClick={this.handleClick} role='presentation'>
|
||||||
<AvatarComposite accounts={accounts} size={48} />
|
<AvatarComposite accounts={accounts} size={48} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ export default function errorsMiddleware() {
|
|||||||
const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
|
const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
|
||||||
|
|
||||||
if (action.type.match(isFail)) {
|
if (action.type.match(isFail)) {
|
||||||
dispatch(showAlertForError(action.error));
|
dispatch(showAlertForError(action.error, action.skipNotFound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,6 @@ export default function compose(state = initialState, action) {
|
|||||||
});
|
});
|
||||||
case COMPOSE_SPOILERNESS_CHANGE:
|
case COMPOSE_SPOILERNESS_CHANGE:
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
map.set('spoiler_text', '');
|
|
||||||
map.set('spoiler', !state.get('spoiler'));
|
map.set('spoiler', !state.get('spoiler'));
|
||||||
map.set('idempotencyKey', uuid());
|
map.set('idempotencyKey', uuid());
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.compose-form__autosuggest-wrapper,
|
.compose-form__autosuggest-wrapper,
|
||||||
.poll__text input[type="text"],
|
.poll__option input[type="text"],
|
||||||
.compose-form .spoiler-input__input,
|
.compose-form .spoiler-input__input,
|
||||||
.compose-form__poll-wrapper select,
|
.compose-form__poll-wrapper select,
|
||||||
.search__input,
|
.search__input,
|
||||||
|
@ -1028,13 +1028,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.display-name {
|
.display-name {
|
||||||
|
color: $light-text-color;
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
color: $inverted-text-color;
|
color: $inverted-text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
|
||||||
color: $light-text-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status__content {
|
.status__content {
|
||||||
@ -1333,7 +1331,6 @@
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
float: left;
|
float: left;
|
||||||
@ -6570,6 +6567,7 @@ noscript {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__unread {
|
&__unread {
|
||||||
|
@ -8,20 +8,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__chart {
|
&__chart {
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 100%;
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: darken($ui-primary-color, 14%);
|
display: block;
|
||||||
|
background: darken($ui-primary-color, 5%);
|
||||||
|
height: 5px;
|
||||||
|
min-width: 1%;
|
||||||
|
|
||||||
&.leading {
|
&.leading {
|
||||||
background: $ui-highlight-color;
|
background: $ui-highlight-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__text {
|
&__option {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 6px 0;
|
padding: 6px 0;
|
||||||
@ -29,6 +27,13 @@
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
display: inline-block;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: calc(100% - 45px - 25px);
|
||||||
|
}
|
||||||
|
|
||||||
input[type=radio],
|
input[type=radio],
|
||||||
input[type=checkbox] {
|
input[type=checkbox] {
|
||||||
display: none;
|
display: none;
|
||||||
@ -112,19 +117,18 @@
|
|||||||
|
|
||||||
&__number {
|
&__number {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 52px;
|
width: 45px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding: 0 10px;
|
flex: 0 0 45px;
|
||||||
padding-left: 8px;
|
|
||||||
text-align: right;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
flex: 0 0 52px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__vote__mark {
|
&__voted {
|
||||||
float: left;
|
padding: 0 5px;
|
||||||
line-height: 18px;
|
display: inline-block;
|
||||||
|
|
||||||
|
&__mark {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__footer {
|
&__footer {
|
||||||
@ -199,7 +203,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.poll__text {
|
.poll__option {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
width: calc(100% - (23px + 6px));
|
width: calc(100% - (23px + 6px));
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
|
@ -64,7 +64,8 @@ class ImportService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def import_relationships!(action, undo_action, overwrite_scope, limit, extra_fields = {})
|
def import_relationships!(action, undo_action, overwrite_scope, limit, extra_fields = {})
|
||||||
items = @data.take(limit).map { |row| [row['Account address']&.strip, Hash[extra_fields.map { |key, header| [key, row[header]&.strip] }]] }.reject { |(id, _)| id.blank? }
|
local_domain_suffix = "@#{Rails.configuration.x.local_domain}"
|
||||||
|
items = @data.take(limit).map { |row| [row['Account address']&.strip&.delete_suffix(local_domain_suffix), Hash[extra_fields.map { |key, header| [key, row[header]&.strip] }]] }.reject { |(id, _)| id.blank? }
|
||||||
|
|
||||||
if @import.overwrite?
|
if @import.overwrite?
|
||||||
presence_hash = items.each_with_object({}) { |(id, extra), mapping| mapping[id] = [true, extra] }
|
presence_hash = items.each_with_object({}) { |(id, extra), mapping| mapping[id] = [true, extra] }
|
||||||
|
@ -10,10 +10,10 @@ class SearchService < BaseService
|
|||||||
@resolve = options[:resolve] || false
|
@resolve = options[:resolve] || false
|
||||||
|
|
||||||
default_results.tap do |results|
|
default_results.tap do |results|
|
||||||
next if @query.blank?
|
next if @query.blank? || @limit.zero?
|
||||||
|
|
||||||
if url_query?
|
if url_query?
|
||||||
results.merge!(url_resource_results) unless url_resource.nil? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym)
|
results.merge!(url_resource_results) unless url_resource.nil? || @offset.positive? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym)
|
||||||
elsif @query.present?
|
elsif @query.present?
|
||||||
results[:accounts] = perform_accounts_search! if account_searchable?
|
results[:accounts] = perform_accounts_search! if account_searchable?
|
||||||
results[:statuses] = perform_statuses_search! if full_text_searchable?
|
results[:statuses] = perform_statuses_search! if full_text_searchable?
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
%li
|
%li
|
||||||
- if show_results
|
- if show_results
|
||||||
- percent = total_votes_count > 0 ? 100 * option.votes_count / total_votes_count : 0
|
- percent = total_votes_count > 0 ? 100 * option.votes_count / total_votes_count : 0
|
||||||
%span.poll__chart{ style: "width: #{percent}%" }
|
%label.poll__option><
|
||||||
|
|
||||||
%label.poll__text><
|
|
||||||
%span.poll__number><
|
%span.poll__number><
|
||||||
- if own_votes.include?(index)
|
- if own_votes.include?(index)
|
||||||
%i.poll__vote__mark.fa.fa-check
|
%i.poll__voted__mark.fa.fa-check
|
||||||
= percent.round
|
= percent.round
|
||||||
= Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
|
= Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
|
||||||
|
|
||||||
|
%span.poll__chart{ style: "width: #{percent}%" }
|
||||||
- else
|
- else
|
||||||
%label.poll__text><
|
%label.poll__option><
|
||||||
%span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
|
%span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
|
||||||
= Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
|
= Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
|
||||||
.poll__footer
|
.poll__footer
|
||||||
|
@ -4,7 +4,7 @@ class ActivityPub::DistributePollUpdateWorker
|
|||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
include Payloadable
|
include Payloadable
|
||||||
|
|
||||||
sidekiq_options queue: 'push', unique: :until_executed, retry: 0
|
sidekiq_options queue: 'push', lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform(status_id)
|
def perform(status_id)
|
||||||
@status = Status.find(status_id)
|
@status = Status.find(status_id)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class ActivityPub::SynchronizeFeaturedCollectionWorker
|
class ActivityPub::SynchronizeFeaturedCollectionWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', unique: :until_executed
|
sidekiq_options queue: 'pull', lock: :until_executed
|
||||||
|
|
||||||
def perform(account_id)
|
def perform(account_id)
|
||||||
ActivityPub::FetchFeaturedCollectionService.new.call(Account.find(account_id))
|
ActivityPub::FetchFeaturedCollectionService.new.call(Account.find(account_id))
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AfterRemoteFollowRequestWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', retry: 5
|
|
||||||
|
|
||||||
def perform(follow_request_id); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AfterRemoteFollowWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', retry: 5
|
|
||||||
|
|
||||||
def perform(follow_id); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class NotificationWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push', retry: 5
|
|
||||||
|
|
||||||
def perform(xml, source_account_id, target_account_id); end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class PollExpirationNotifyWorker
|
class PollExpirationNotifyWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed
|
sidekiq_options lock: :until_executed
|
||||||
|
|
||||||
def perform(poll_id)
|
def perform(poll_id)
|
||||||
poll = Poll.find(poll_id)
|
poll = Poll.find(poll_id)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ProcessingWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options backtrace: true
|
|
||||||
|
|
||||||
def perform(account_id, body); end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class PublishScheduledStatusWorker
|
class PublishScheduledStatusWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed
|
sidekiq_options lock: :until_executed
|
||||||
|
|
||||||
def perform(scheduled_status_id)
|
def perform(scheduled_status_id)
|
||||||
scheduled_status = ScheduledStatus.find(scheduled_status_id)
|
scheduled_status = ScheduledStatus.find(scheduled_status_id)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::ConfirmationWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push', retry: false
|
|
||||||
|
|
||||||
def perform(subscription_id, mode, secret = nil, lease_seconds = nil); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::DeliveryWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push', retry: 3, dead: false
|
|
||||||
|
|
||||||
def perform(subscription_id, payload); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::DistributionWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push'
|
|
||||||
|
|
||||||
def perform(stream_entry_ids); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::RawDistributionWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push'
|
|
||||||
|
|
||||||
def perform(xml, source_account_id); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::SubscribeWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push', retry: 10, unique: :until_executed, dead: false
|
|
||||||
|
|
||||||
def perform(account_id); end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Pubsubhubbub::UnsubscribeWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'push', retry: false, unique: :until_executed, dead: false
|
|
||||||
|
|
||||||
def perform(account_id); end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class RegenerationWorker
|
class RegenerationWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed
|
sidekiq_options lock: :until_executed
|
||||||
|
|
||||||
def perform(account_id, _ = :home)
|
def perform(account_id, _ = :home)
|
||||||
account = Account.find(account_id)
|
account = Account.find(account_id)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class RemoteProfileUpdateWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options queue: 'pull'
|
|
||||||
|
|
||||||
def perform(account_id, body, resubscribe); end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class ResolveAccountWorker
|
class ResolveAccountWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', unique: :until_executed
|
sidekiq_options queue: 'pull', lock: :until_executed
|
||||||
|
|
||||||
def perform(uri)
|
def perform(uri)
|
||||||
ResolveAccountService.new.call(uri)
|
ResolveAccountService.new.call(uri)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class SalmonWorker
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options backtrace: true
|
|
||||||
|
|
||||||
def perform(account_id, body); end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::BackupCleanupScheduler
|
class Scheduler::BackupCleanupScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
old_backups.reorder(nil).find_each(&:destroy!)
|
old_backups.reorder(nil).find_each(&:destroy!)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::DoorkeeperCleanupScheduler
|
class Scheduler::DoorkeeperCleanupScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
|
Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::EmailScheduler
|
class Scheduler::EmailScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
FREQUENCY = 7.days.freeze
|
FREQUENCY = 7.days.freeze
|
||||||
SIGN_IN_OFFSET = 1.day.freeze
|
SIGN_IN_OFFSET = 1.day.freeze
|
||||||
|
@ -4,7 +4,7 @@ class Scheduler::FeedCleanupScheduler
|
|||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
include Redisable
|
include Redisable
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
clean_home_feeds!
|
clean_home_feeds!
|
||||||
|
@ -5,7 +5,7 @@ class Scheduler::IpCleanupScheduler
|
|||||||
|
|
||||||
RETENTION_PERIOD = 1.year
|
RETENTION_PERIOD = 1.year
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
time_ago = RETENTION_PERIOD.ago
|
time_ago = RETENTION_PERIOD.ago
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::MediaCleanupScheduler
|
class Scheduler::MediaCleanupScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
unattached_media.find_each(&:destroy)
|
unattached_media.find_each(&:destroy)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::PgheroScheduler
|
class Scheduler::PgheroScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
PgHero.capture_space_stats
|
PgHero.capture_space_stats
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::ScheduledStatusesScheduler
|
class Scheduler::ScheduledStatusesScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
publish_scheduled_statuses!
|
publish_scheduled_statuses!
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Scheduler::SubscriptionsCleanupScheduler
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
|
||||||
|
|
||||||
def perform; end
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Scheduler::SubscriptionsScheduler
|
|
||||||
include Sidekiq::Worker
|
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
|
||||||
|
|
||||||
def perform; end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::TrendingTagsScheduler
|
class Scheduler::TrendingTagsScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
TrendingTags.update! if Setting.trends
|
TrendingTags.update! if Setting.trends
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Scheduler::UserCleanupScheduler
|
class Scheduler::UserCleanupScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options unique: :until_executed, retry: 0
|
sidekiq_options lock: :until_executed, retry: 0
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
|
User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class VerifyAccountLinksWorker
|
class VerifyAccountLinksWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', retry: false, unique: :until_executed
|
sidekiq_options queue: 'pull', retry: false, lock: :until_executed
|
||||||
|
|
||||||
def perform(account_id)
|
def perform(account_id)
|
||||||
account = Account.find(account_id)
|
account = Account.find(account_id)
|
||||||
|
@ -37,6 +37,7 @@ if Rails.env.production?
|
|||||||
p.style_src :self, :unsafe_inline, assets_host
|
p.style_src :self, :unsafe_inline, assets_host
|
||||||
p.media_src :self, :data, *data_hosts
|
p.media_src :self, :data, *data_hosts
|
||||||
p.frame_src :self, :https
|
p.frame_src :self, :https
|
||||||
|
p.child_src :self, :blob, assets_host
|
||||||
p.worker_src :self, :blob, assets_host
|
p.worker_src :self, :blob, assets_host
|
||||||
p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
|
p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
|
||||||
p.manifest_src :self, assets_host
|
p.manifest_src :self, assets_host
|
||||||
|
@ -42,6 +42,7 @@ class Rack::Attack
|
|||||||
/auth/sign_in
|
/auth/sign_in
|
||||||
/auth
|
/auth
|
||||||
/auth/password
|
/auth/password
|
||||||
|
/auth/confirmation
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
||||||
|
@ -13,6 +13,11 @@ Sidekiq.configure_server do |config|
|
|||||||
config.server_middleware do |chain|
|
config.server_middleware do |chain|
|
||||||
chain.add SidekiqErrorHandler
|
chain.add SidekiqErrorHandler
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.death_handlers << lambda do |job, _ex|
|
||||||
|
digest = job['lock_digest']
|
||||||
|
SidekiqUniqueJobs::Digests.delete_by_digest(digest) if digest
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Sidekiq.configure_client do |config|
|
Sidekiq.configure_client do |config|
|
||||||
|
@ -1093,6 +1093,8 @@ en:
|
|||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'contained a disallowed hashtag: %{tags}'
|
one: 'contained a disallowed hashtag: %{tags}'
|
||||||
other: 'contained the disallowed hashtags: %{tags}'
|
other: 'contained the disallowed hashtags: %{tags}'
|
||||||
|
errors:
|
||||||
|
in_reply_not_found: The status you are trying to reply to does not appear to exist.
|
||||||
language_detection: Automatically detect language
|
language_detection: Automatically detect language
|
||||||
open_in_web: Open in web
|
open_in_web: Open in web
|
||||||
over_character_limit: character limit of %{max} exceeded
|
over_character_limit: character limit of %{max} exceeded
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'sidekiq/web'
|
require 'sidekiq_unique_jobs/web'
|
||||||
require 'sidekiq-scheduler/web'
|
require 'sidekiq-scheduler/web'
|
||||||
|
|
||||||
Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base]
|
Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base]
|
||||||
|
@ -115,7 +115,7 @@ module Mastodon
|
|||||||
when :filesystem
|
when :filesystem
|
||||||
require 'find'
|
require 'find'
|
||||||
|
|
||||||
root_path = ENV.fetch('RAILS_ROOT_PATH', File.join(':rails_root', 'public', 'system')).gsub(':rails_root', Rails.root.to_s)
|
root_path = ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')).gsub(':rails_root', Rails.root.to_s)
|
||||||
|
|
||||||
Find.find(File.join(*[root_path, prefix].compact)) do |path|
|
Find.find(File.join(*[root_path, prefix].compact)) do |path|
|
||||||
next if File.directory?(path)
|
next if File.directory?(path)
|
||||||
|
18
package.json
18
package.json
@ -65,17 +65,17 @@
|
|||||||
"@babel/plugin-proposal-decorators": "^7.8.3",
|
"@babel/plugin-proposal-decorators": "^7.8.3",
|
||||||
"@babel/plugin-transform-react-inline-elements": "^7.9.0",
|
"@babel/plugin-transform-react-inline-elements": "^7.9.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.9.0",
|
"@babel/plugin-transform-runtime": "^7.9.0",
|
||||||
"@babel/preset-env": "^7.8.3",
|
"@babel/preset-env": "^7.9.0",
|
||||||
"@babel/preset-react": "^7.8.3",
|
"@babel/preset-react": "^7.9.4",
|
||||||
"@babel/runtime": "^7.8.4",
|
"@babel/runtime": "^7.8.4",
|
||||||
"@clusterws/cws": "^0.17.3",
|
"@clusterws/cws": "^0.17.3",
|
||||||
"@gamestdio/websocket": "^0.3.2",
|
"@gamestdio/websocket": "^0.3.2",
|
||||||
"array-includes": "^3.1.1",
|
"array-includes": "^3.1.1",
|
||||||
"arrow-key-navigation": "^1.1.0",
|
"arrow-key-navigation": "^1.1.0",
|
||||||
"atrament": "0.2.4",
|
"atrament": "0.2.4",
|
||||||
"autoprefixer": "^9.7.4",
|
"autoprefixer": "^9.7.5",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.1.0",
|
||||||
"babel-plugin-lodash": "^3.3.4",
|
"babel-plugin-lodash": "^3.3.4",
|
||||||
"babel-plugin-preval": "^5.0.0",
|
"babel-plugin-preval": "^5.0.0",
|
||||||
"babel-plugin-react-intl": "^3.4.1",
|
"babel-plugin-react-intl": "^3.4.1",
|
||||||
@ -127,7 +127,7 @@
|
|||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"punycode": "^2.1.0",
|
"punycode": "^2.1.0",
|
||||||
"@rails/ujs": "^6.0.2",
|
"@rails/ujs": "^6.0.2",
|
||||||
"react": "^16.12.0",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.0",
|
"react-dom": "^16.13.0",
|
||||||
"react-hotkeys": "^1.1.4",
|
"react-hotkeys": "^1.1.4",
|
||||||
"react-immutable-proptypes": "^2.2.0",
|
"react-immutable-proptypes": "^2.2.0",
|
||||||
@ -157,13 +157,13 @@
|
|||||||
"sass": "^1.26.3",
|
"sass": "^1.26.3",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"stacktrace-js": "^2.0.2",
|
"stacktrace-js": "^2.0.2",
|
||||||
"stringz": "^2.0.0",
|
"stringz": "^2.1.0",
|
||||||
"substring-trie": "^1.0.2",
|
"substring-trie": "^1.0.2",
|
||||||
"terser-webpack-plugin": "^2.3.5",
|
"terser-webpack-plugin": "^2.3.5",
|
||||||
"tesseract.js": "^2.0.0-alpha.16",
|
"tesseract.js": "^2.0.0-alpha.16",
|
||||||
"throng": "^4.0.0",
|
"throng": "^4.0.0",
|
||||||
"tiny-queue": "^0.2.1",
|
"tiny-queue": "^0.2.1",
|
||||||
"uuid": "^3.4.0",
|
"uuid": "^7.0.2",
|
||||||
"wavesurfer.js": "^3.3.1",
|
"wavesurfer.js": "^3.3.1",
|
||||||
"webpack": "^4.42.1",
|
"webpack": "^4.42.1",
|
||||||
"webpack-assets-manifest": "^3.1.1",
|
"webpack-assets-manifest": "^3.1.1",
|
||||||
@ -174,7 +174,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.0.3",
|
"babel-eslint": "^10.0.3",
|
||||||
"babel-jest": "^25.1.0",
|
"babel-jest": "^25.2.4",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
"enzyme-adapter-react-16": "^1.15.2",
|
"enzyme-adapter-react-16": "^1.15.2",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
@ -188,6 +188,6 @@
|
|||||||
"react-test-renderer": "^16.13.0",
|
"react-test-renderer": "^16.13.0",
|
||||||
"sass-lint": "^1.13.1",
|
"sass-lint": "^1.13.1",
|
||||||
"webpack-dev-server": "^3.10.3",
|
"webpack-dev-server": "^3.10.3",
|
||||||
"yargs": "^15.1.0"
|
"yargs": "^15.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +91,6 @@ RSpec.describe ImportService, type: :service do
|
|||||||
|
|
||||||
let(:csv) { attachment_fixture('mute-imports.txt') }
|
let(:csv) { attachment_fixture('mute-imports.txt') }
|
||||||
|
|
||||||
before do
|
|
||||||
allow(NotificationWorker).to receive(:perform_async)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when no accounts are followed' do
|
describe 'when no accounts are followed' do
|
||||||
let(:import) { Import.create(account: account, type: 'following', data: csv) }
|
let(:import) { Import.create(account: account, type: 'following', data: csv) }
|
||||||
it 'follows the listed accounts, including boosts' do
|
it 'follows the listed accounts, including boosts' do
|
||||||
@ -135,10 +131,6 @@ RSpec.describe ImportService, type: :service do
|
|||||||
|
|
||||||
let(:csv) { attachment_fixture('new-following-imports.txt') }
|
let(:csv) { attachment_fixture('new-following-imports.txt') }
|
||||||
|
|
||||||
before do
|
|
||||||
allow(NotificationWorker).to receive(:perform_async)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'when no accounts are followed' do
|
describe 'when no accounts are followed' do
|
||||||
let(:import) { Import.create(account: account, type: 'following', data: csv) }
|
let(:import) { Import.create(account: account, type: 'following', data: csv) }
|
||||||
it 'follows the listed accounts, respecting boosts' do
|
it 'follows the listed accounts, respecting boosts' do
|
||||||
|
Loading…
Reference in New Issue
Block a user