This commit is contained in:
Baptiste Lemoine 2020-08-03 11:37:47 +02:00
commit 79f60e91c3
23 changed files with 639 additions and 754 deletions

View File

@ -27,7 +27,7 @@ plugins:
enabled: true
eslint:
enabled: true
channel: eslint-6
channel: eslint-7
rubocop:
enabled: true
channel: rubocop-0-82

View File

@ -3,7 +3,7 @@ Changelog
All notable changes to this project will be documented in this file.
## Unreleased
## [3.2.0] - 2020-07-27
### Added
- Add `SMTP_SSL` environment variable ([OmmyZhang](https://github.com/tootsuite/mastodon/pull/14309))
@ -29,7 +29,7 @@ All notable changes to this project will be documented in this file.
- New REST API: `POST /api/v1/accounts/:id/note` with `comment` param
- The Relationship entity in REST API has a new `note` attribute
- Add Helm chart ([dunn](https://github.com/tootsuite/mastodon/pull/14090), [dunn](https://github.com/tootsuite/mastodon/pull/14256), [dunn](https://github.com/tootsuite/mastodon/pull/14245))
- **Add customizable thumbnails for audio and video attachments** ([Gargron](https://github.com/tootsuite/mastodon/pull/14145), [Gargron](https://github.com/tootsuite/mastodon/pull/14244), [Gargron](https://github.com/tootsuite/mastodon/pull/14273), [Gargron](https://github.com/tootsuite/mastodon/pull/14203), [ThibG](https://github.com/tootsuite/mastodon/pull/14255), [ThibG](https://github.com/tootsuite/mastodon/pull/14306))
- **Add customizable thumbnails for audio and video attachments** ([Gargron](https://github.com/tootsuite/mastodon/pull/14145), [Gargron](https://github.com/tootsuite/mastodon/pull/14244), [Gargron](https://github.com/tootsuite/mastodon/pull/14273), [Gargron](https://github.com/tootsuite/mastodon/pull/14203), [ThibG](https://github.com/tootsuite/mastodon/pull/14255), [ThibG](https://github.com/tootsuite/mastodon/pull/14306), [noellabo](https://github.com/tootsuite/mastodon/pull/14358), [noellabo](https://github.com/tootsuite/mastodon/pull/14357))
- Metadata (album, artist, etc) is no longer stripped from audio files
- Album art is automatically extracted from audio files
- Thumbnail can be manually uploaded for both audio and video attachments
@ -37,6 +37,7 @@ All notable changes to this project will be documented in this file.
- On `POST /api/v1/media` and `POST /api/v2/media`
- And on `PUT /api/v1/media/:id`
- ActivityPub representation of media attachments represents custom thumbnails with an `icon` attribute
- The Media Attachment entity in REST API now has a `preview_remote_url` to its `preview_url`, equivalent to `remote_url` to its `url`
- **Add color extraction for thumbnails** ([Gargron](https://github.com/tootsuite/mastodon/pull/14209), [ThibG](https://github.com/tootsuite/mastodon/pull/14264))
- The `meta` attribute on the Media Attachment entity in REST API can now have a `colors` attribute which in turn contains three hex colors: `background`, `foreground`, and `accent`
- The background color is chosen from the most dominant color around the edges of the thumbnail
@ -48,6 +49,9 @@ All notable changes to this project will be documented in this file.
- Add `tootctl email_domain_blocks` ([tateisu](https://github.com/tootsuite/mastodon/pull/13589), [Gargron](https://github.com/tootsuite/mastodon/pull/14147))
- Add "Add new domain block" to header of federation page in admin UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13934))
- Add ability to keep emoji picker open with ctrl+click in web UI ([bclindner](https://github.com/tootsuite/mastodon/pull/13896), [noellabo](https://github.com/tootsuite/mastodon/pull/14096))
- Add custom icon for private boosts in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14380))
- Add support for Create and Update activities that don't inline objects in ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/14359))
- Add support for Undo activities that don't inline activities in ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/14346))
### Changed
@ -59,9 +63,9 @@ All notable changes to this project will be documented in this file.
- Some websites may not render OpenGraph tags into HTML if that's not the case
- Change behaviour to carry blocks over when someone migrates their followers ([ThibG](https://github.com/tootsuite/mastodon/pull/14144))
- Change volume control and download buttons in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14122))
- **Change design of audio players in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/14095), [ThibG](https://github.com/tootsuite/mastodon/pull/14281), [Gargron](https://github.com/tootsuite/mastodon/pull/14282), [ThibG](https://github.com/tootsuite/mastodon/pull/14118), [Gargron](https://github.com/tootsuite/mastodon/pull/14199))
- **Change design of audio players in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/14095), [ThibG](https://github.com/tootsuite/mastodon/pull/14281), [Gargron](https://github.com/tootsuite/mastodon/pull/14282), [ThibG](https://github.com/tootsuite/mastodon/pull/14118), [Gargron](https://github.com/tootsuite/mastodon/pull/14199), [ThibG](https://github.com/tootsuite/mastodon/pull/14338))
- Change reply filter to never filter own toots in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14128))
- Change boost button to no longer serve as visibility indicator in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/14132))
- Change boost button to no longer serve as visibility indicator in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/14132), [ThibG](https://github.com/tootsuite/mastodon/pull/14373))
- Change contrast of flash messages ([cchoi12](https://github.com/tootsuite/mastodon/pull/13892))
- Change wording from "Hide media" to "Hide image/images" in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13834))
- Change appearence of settings pages to be more consistent ([ariasuni](https://github.com/tootsuite/mastodon/pull/13938))
@ -69,6 +73,7 @@ All notable changes to this project will be documented in this file.
- Change how badly contrasting emoji are rendered in web UI ([leo60228](https://github.com/tootsuite/mastodon/pull/13773), [ThibG](https://github.com/tootsuite/mastodon/pull/13772), [mfmfuyu](https://github.com/tootsuite/mastodon/pull/14020), [ThibG](https://github.com/tootsuite/mastodon/pull/14015))
- Change structure of unavailable content section on about page ([ariasuni](https://github.com/tootsuite/mastodon/pull/13930))
- Change behaviour to accept ActivityPub activities relayed through group actor ([noellabo](https://github.com/tootsuite/mastodon/pull/14279))
- Change amount of processing retries for ActivityPub activities ([noellabo](https://github.com/tootsuite/mastodon/pull/14355))
### Removed
@ -84,13 +89,18 @@ All notable changes to this project will be documented in this file.
### Fixed
- Fix `following` param not working when exact match is found in account search ([noellabo](https://github.com/tootsuite/mastodon/pull/14394))
- Fix sometimes occuring duplicate mention notifications ([noellabo](https://github.com/tootsuite/mastodon/pull/14378))
- Fix RSS feeds not being cachable ([ThibG](https://github.com/tootsuite/mastodon/pull/14368))
- Fix lack of locking around processing of Announce activities in ActivityPub ([noellabo](https://github.com/tootsuite/mastodon/pull/14365))
- Fix boosted toots from blocked account not being retroactively removed from TL ([ThibG](https://github.com/tootsuite/mastodon/pull/14339))
- Fix large shortened numbers (like 1.2K) using incorrect pluralization ([Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/14061))
- Fix streaming server trying to use empty password to connect to Redis when `REDIS_PASSWORD` is given but blank ([ThibG](https://github.com/tootsuite/mastodon/pull/14135))
- Fix being unable to unboost posts when blocked by their author ([ThibG](https://github.com/tootsuite/mastodon/pull/14308))
- Fix account domain block not properly unfollowing accounts from domain ([Gargron](https://github.com/tootsuite/mastodon/pull/14304))
- Fix removing a domain allow wiping known accounts in open federation mode ([ThibG](https://github.com/tootsuite/mastodon/pull/14298))
- Fix blocks and mutes pagination in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14275))
- Fix new posts pushing down origin of opened dropdown in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14271))
- Fix new posts pushing down origin of opened dropdown in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14271), [ThibG](https://github.com/tootsuite/mastodon/pull/14348))
- Fix timeline markers not being saved sometimes ([ThibG](https://github.com/tootsuite/mastodon/pull/13887), [ThibG](https://github.com/tootsuite/mastodon/pull/13889), [ThibG](https://github.com/tootsuite/mastodon/pull/14155))
- Fix CSV uploads being rejected ([noellabo](https://github.com/tootsuite/mastodon/pull/13835))
- Fix incompatibility with ElasticSearch 7.x ([noellabo](https://github.com/tootsuite/mastodon/pull/13828))
@ -112,7 +122,7 @@ All notable changes to this project will be documented in this file.
- Use circuit breakers to stop hitting unresponsive servers
- Avoid hitting servers that are already known to be generally unavailable
- Fix filters ignoring media descriptions ([BenLubar](https://github.com/tootsuite/mastodon/pull/13837))
- Fix soem actions on custom emojis leading to cryptic errors in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13951))
- Fix some actions on custom emojis leading to cryptic errors in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13951))
- Fix ActivityPub serialization of replies when some of them are URIs ([ThibG](https://github.com/tootsuite/mastodon/pull/13957))
- Fix `rake mastodon:setup` choking on environment variables containing `%` ([ThibG](https://github.com/tootsuite/mastodon/pull/13940))
- Fix account redirect confirmation message talking about moved followers ([ThibG](https://github.com/tootsuite/mastodon/pull/13950))
@ -132,7 +142,7 @@ All notable changes to this project will be documented in this file.
- Fix unapproved users being able to view profiles when in limited-federation mode *and* requiring approval for sign-ups ([ThibG](https://github.com/tootsuite/mastodon/pull/14093))
- Fix initial audio volume not corresponding to what's displayed in audio player in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14057))
- Fix timelines sometimes jumping when closing modals in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14019))
- Fix memory usage of downloading remote files ([Gargron](https://github.com/tootsuite/mastodon/pull/14184), [Gargron](https://github.com/tootsuite/mastodon/pull/14181))
- Fix memory usage of downloading remote files ([Gargron](https://github.com/tootsuite/mastodon/pull/14184), [Gargron](https://github.com/tootsuite/mastodon/pull/14181), [noellabo](https://github.com/tootsuite/mastodon/pull/14356))
- Don't read entire file (up to 40 MB) into memory
- Read and write it to temp file in small chunks
- Fix inconsistent account header padding in web UI ([trwnh](https://github.com/tootsuite/mastodon/pull/14179))

22
Gemfile
View File

@ -11,16 +11,16 @@ gem 'sprockets', '~> 3.7.2'
gem 'thor', '~> 0.20'
gem 'rack', '~> 2.2.3'
gem 'thwait', '~> 0.1.0'
gem 'thwait', '~> 0.2.0'
gem 'e2mmap', '~> 0.1.0'
gem 'hamlit-rails', '~> 0.2'
gem 'pg', '~> 1.2'
gem 'makara', '~> 0.4'
gem 'pghero', '~> 2.5'
gem 'pghero', '~> 2.6'
gem 'dotenv-rails', '~> 2.7'
gem 'aws-sdk-s3', '~> 1.73', require: false
gem 'aws-sdk-s3', '~> 1.75', require: false
gem 'fog-core', '<= 2.1.0'
gem 'fog-openstack', '~> 0.3', require: false
gem 'paperclip', '~> 6.0'
@ -74,7 +74,7 @@ gem 'oj', '~> 3.10'
gem 'ox', '~> 2.13'
gem 'parslet'
gem 'parallel', '~> 1.19'
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
gem 'posix-spawn'
gem 'pundit', '~> 2.1'
gem 'premailer-rails'
gem 'rack-attack', '~> 6.3'
@ -86,16 +86,16 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
gem 'rqrcode', '~> 1.1'
gem 'ruby-progressbar', '~> 1.10'
gem 'sanitize', '~> 5.2'
gem 'sidekiq', '~> 6.0'
gem 'sidekiq', '~> 6.1'
gem 'sidekiq-scheduler', '~> 3.0'
gem 'sidekiq-unique-jobs', '~> 6.0'
gem 'sidekiq-bulk', '~>0.2.0'
gem 'simple-navigation', '~> 4.1'
gem 'simple_form', '~> 5.0'
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
gem 'stoplight', '~> 2.2.0'
gem 'strong_migrations', '~> 0.6'
gem 'tty-prompt', '~> 0.21', require: false
gem 'stoplight', '~> 2.2.1'
gem 'strong_migrations', '~> 0.7'
gem 'tty-prompt', '~> 0.22', require: false
gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2020'
gem 'webpacker', '~> 5.1'
@ -127,7 +127,7 @@ group :test do
gem 'rspec-sidekiq', '~> 3.1'
gem 'simplecov', '~> 0.18', require: false
gem 'webmock', '~> 3.8'
gem 'parallel_tests', '~> 3.0'
gem 'parallel_tests', '~> 3.1'
gem 'rspec_junit_formatter', '~> 0.4'
end
@ -146,8 +146,8 @@ group :development do
gem 'bundler-audit', '~> 0.7', require: false
gem 'capistrano', '~> 3.14'
gem 'capistrano-rails', '~> 1.5'
gem 'capistrano-rbenv', '~> 2.1'
gem 'capistrano-rails', '~> 1.6'
gem 'capistrano-rbenv', '~> 2.2'
gem 'capistrano-yarn', '~> 2.0'
gem 'stackprof'

View File

@ -6,13 +6,6 @@ GIT
health_check (4.0.0.pre)
rails (>= 4.0)
GIT
remote: https://github.com/rtomayko/posix-spawn
revision: 58465d2e213991f8afb13b984854a49fcdcc980c
ref: 58465d2e213991f8afb13b984854a49fcdcc980c
specs:
posix-spawn (0.3.13)
GIT
remote: https://github.com/tmm1/http_parser.rb
revision: 54b17ba8c7d8d20a16dfc65d1775241833219cf2
@ -92,8 +85,8 @@ GEM
av (0.9.0)
cocaine (~> 0.5.3)
aws-eventstream (1.1.0)
aws-partitions (1.340.0)
aws-sdk-core (3.103.0)
aws-partitions (1.345.0)
aws-sdk-core (3.104.3)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
@ -101,13 +94,13 @@ GEM
aws-sdk-kms (1.36.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.74.0)
aws-sdk-core (~> 3, >= 3.102.1)
aws-sdk-s3 (1.75.0)
aws-sdk-core (~> 3, >= 3.104.1)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
bcrypt (3.1.13)
bcrypt (3.1.15)
better_errors (2.7.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
@ -116,7 +109,7 @@ GEM
debug_inspector (>= 0.0.1)
blurhash (0.1.4)
ffi (~> 1.10.0)
bootsnap (1.4.6)
bootsnap (1.4.7)
msgpack (~> 1.0)
brakeman (4.8.2)
browser (4.2.0)
@ -133,12 +126,12 @@ GEM
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
capistrano-bundler (1.6.0)
capistrano-bundler (2.0.1)
capistrano (~> 3.1)
capistrano-rails (1.5.0)
capistrano-rails (1.6.1)
capistrano (~> 3.1)
capistrano-bundler (~> 1.1)
capistrano-rbenv (2.1.6)
capistrano-bundler (>= 1.1, < 3)
capistrano-rbenv (2.2.0)
capistrano (~> 3.1)
sshkit (~> 1.3)
capistrano-yarn (2.0.2)
@ -197,10 +190,10 @@ GEM
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.4.0)
railties (>= 5)
dotenv (2.7.5)
dotenv-rails (2.7.5)
dotenv (= 2.7.5)
railties (>= 3.2, < 6.1)
dotenv (2.7.6)
dotenv-rails (2.7.6)
dotenv (= 2.7.6)
railties (>= 3.2)
e2mmap (0.1.0)
ed25519 (1.2.4)
elasticsearch (7.8.0)
@ -213,7 +206,6 @@ GEM
faraday (~> 1)
multi_json
encryptor (3.0.0)
equatable (0.6.1)
erubi (1.9.0)
et-orbi (1.2.4)
tzinfo
@ -224,7 +216,7 @@ GEM
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
fast_blank (1.0.0)
fastimage (2.1.7)
fastimage (2.2.0)
ffi (1.10.0)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
@ -286,7 +278,7 @@ GEM
httplog (1.4.3)
rack (>= 1.0)
rainbow (>= 2.0.0)
i18n (1.8.3)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.31)
activesupport (>= 4.0.2)
@ -366,9 +358,8 @@ GEM
mini_portile2 (2.4.0)
minitest (5.14.1)
msgpack (1.3.3)
multi_json (1.14.1)
multi_json (1.15.0)
multipart-post (2.1.1)
necromancer (0.5.1)
net-ldap (0.16.2)
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
@ -383,7 +374,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.10.6)
oj (3.10.8)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@ -396,7 +387,7 @@ GEM
ruby-saml (~> 1.9)
orm_adapter (0.5.0)
ox (2.13.2)
paperclip (6.1.0)
paperclip (6.0.0)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
mime-types
@ -406,19 +397,19 @@ GEM
av (~> 0.9.0)
paperclip (>= 2.5.2)
parallel (1.19.2)
parallel_tests (3.0.0)
parallel_tests (3.1.0)
parallel
parser (2.7.1.4)
ast (~> 2.4.1)
parslet (2.0.0)
pastel (0.7.4)
equatable (~> 0.6)
pastel (0.8.0)
tty-color (~> 0.5)
pg (1.2.3)
pghero (2.6.0)
activerecord (>= 5)
pkg-config (1.4.1)
premailer (1.11.1)
posix-spawn (0.3.15)
premailer (1.12.1)
addressable
css_parser (>= 1.6.0)
htmlentities (>= 4.0.0)
@ -474,7 +465,7 @@ GEM
rails-i18n (5.1.3)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
rails-settings-cached (0.7.2)
rails-settings-cached (0.6.6)
rails (>= 4.2.0)
railties (5.2.4.3)
actionpack (= 5.2.4.3)
@ -543,16 +534,16 @@ GEM
rspec-support (3.9.3)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.87.1)
rubocop (0.86.0)
parallel (~> 1.10)
parser (>= 2.7.1.1)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.1.0, < 1.0)
rubocop-ast (>= 0.0.3, < 1.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.1.0)
rubocop-ast (0.2.0)
parser (>= 2.7.0.1)
rubocop-rails (2.6.0)
activesupport (>= 4.2.0)
@ -569,7 +560,7 @@ GEM
nokogiri (>= 1.8.0)
nokogumbo (~> 2.0)
semantic_range (2.3.0)
sidekiq (6.1.0)
sidekiq (6.1.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
@ -607,10 +598,10 @@ GEM
net-ssh (>= 2.8.0)
stackprof (0.2.15)
statsd-ruby (1.4.0)
stoplight (2.2.0)
stoplight (2.2.1)
streamio-ffmpeg (3.0.2)
multi_json (~> 1.8)
strong_migrations (0.6.8)
strong_migrations (0.7.1)
activerecord (>= 5)
temple (0.8.2)
terminal-table (1.8.0)
@ -619,19 +610,19 @@ GEM
climate_control (>= 0.0.3, < 1.0)
thor (0.20.3)
thread_safe (0.3.6)
thwait (0.1.0)
thwait (0.2.0)
e2mmap
tilt (2.0.10)
tty-color (0.5.1)
tty-cursor (0.7.1)
tty-prompt (0.21.0)
necromancer (~> 0.5.0)
pastel (~> 0.7.0)
tty-reader (~> 0.7.0)
tty-reader (0.7.0)
tty-prompt (0.22.0)
pastel (~> 0.8)
tty-reader (~> 0.8)
tty-reader (0.8.0)
tty-cursor (~> 0.7)
tty-screen (~> 0.7)
wisper (~> 2.0.0)
tty-screen (0.8.0)
tty-screen (~> 0.8)
wisper (~> 2.0)
tty-screen (0.8.1)
twitter-text (1.14.7)
unf (~> 0.1.0)
tzinfo (1.2.7)
@ -654,10 +645,10 @@ GEM
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
webpush (1.0.0)
webpush (0.3.8)
hkdf (~> 0.2)
jwt (~> 2.0)
websocket-driver (0.7.2)
websocket-driver (0.7.3)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
wisper (2.0.1)
@ -672,7 +663,7 @@ DEPENDENCIES
active_record_query_trace (~> 1.7)
addressable (~> 2.7)
annotate (~> 3.1)
aws-sdk-s3 (~> 1.73)
aws-sdk-s3 (~> 1.75)
better_errors (~> 2.7)
binding_of_caller (~> 0.7)
blurhash (~> 0.1)
@ -682,8 +673,8 @@ DEPENDENCIES
bullet (~> 6.1)
bundler-audit (~> 0.7)
capistrano (~> 3.14)
capistrano-rails (~> 1.5)
capistrano-rbenv (~> 2.1)
capistrano-rails (~> 1.6)
capistrano-rbenv (~> 2.2)
capistrano-yarn (~> 2.0)
capybara (~> 3.33)
charlock_holmes (~> 0.7.7)
@ -744,12 +735,12 @@ DEPENDENCIES
paperclip (~> 6.0)
paperclip-av-transcoder (~> 0.6)
parallel (~> 1.19)
parallel_tests (~> 3.0)
parallel_tests (~> 3.1)
parslet
pg (~> 1.2)
pghero (~> 2.5)
pghero (~> 2.6)
pkg-config (~> 1.4)
posix-spawn!
posix-spawn
premailer-rails
private_address_check (~> 0.5)
pry-byebug (~> 3.9)
@ -775,7 +766,7 @@ DEPENDENCIES
rubocop-rails (~> 2.6)
ruby-progressbar (~> 1.10)
sanitize (~> 5.2)
sidekiq (~> 6.0)
sidekiq (~> 6.1)
sidekiq-bulk (~> 0.2.0)
sidekiq-scheduler (~> 3.0)
sidekiq-unique-jobs (~> 6.0)
@ -785,12 +776,12 @@ DEPENDENCIES
sprockets (~> 3.7.2)
sprockets-rails (~> 3.2)
stackprof
stoplight (~> 2.2.0)
stoplight (~> 2.2.1)
streamio-ffmpeg (~> 3.0)
strong_migrations (~> 0.6)
strong_migrations (~> 0.7)
thor (~> 0.20)
thwait (~> 0.1.0)
tty-prompt (~> 0.21)
thwait (~> 0.2.0)
tty-prompt (~> 0.22)
twitter-text (~> 1.14)
tzinfo-data (~> 1.2020)
webmock (~> 3.8)

View File

@ -71,10 +71,9 @@ const refreshHomeTimelineAndNotification = (dispatch, done) => {
dispatch(fetchAnnouncements(done))))));
};
export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
export const connectUserTimelineStream = (accountId) => connectTimelineStream(`account:${accountId}`, 'user');
export const connectCommunityStream = ({ onlyMedia } = {}) => connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);
export const connectPublicStream = ({ onlyMedia, onlyRemote } = {}) => connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`);
export const connectHashtagStream = (id, tag, local, accept) => connectTimelineStream(`hashtag:${id}${local ? ':local' : ''}`, `hashtag${local ? ':local' : ''}&tag=${tag}`, null, accept);
export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);
export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
export const connectCommunityStream = ({ onlyMedia } = {}) => connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`);
export const connectPublicStream = ({ onlyMedia, onlyRemote } = {}) => connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`);
export const connectHashtagStream = (id, tag, local, accept) => connectTimelineStream(`hashtag:${id}${local ? ':local' : ''}`, `hashtag${local ? ':local' : ''}&tag=${tag}`, null, accept);
export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`);

View File

@ -66,6 +66,16 @@ class Header extends ImmutablePureComponent {
identity_props: ImmutablePropTypes.list,
onFollow: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,
onDirect: PropTypes.func.isRequired,
onReport: PropTypes.func.isRequired,
onReblogToggle: PropTypes.func.isRequired,
onMute: PropTypes.func.isRequired,
onBlockDomain: PropTypes.func.isRequired,
onUnblockDomain: PropTypes.func.isRequired,
onEndorseToggle: PropTypes.func.isRequired,
onAddToList: PropTypes.func.isRequired,
onEditAccountNote: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
domain: PropTypes.string.isRequired,
};

View File

@ -23,7 +23,6 @@ export default class Header extends ImmutablePureComponent {
onUnblockDomain: PropTypes.func.isRequired,
onEndorseToggle: PropTypes.func.isRequired,
onAddToList: PropTypes.func.isRequired,
onEditAccountNote: PropTypes.func.isRequired,
hideTabs: PropTypes.bool,
domain: PropTypes.string.isRequired,
};

View File

@ -16,7 +16,7 @@ import { fetchAccountIdentityProofs } from '../../actions/identity_proofs';
import MissingIndicator from 'mastodon/components/missing_indicator';
import TimelineHint from 'mastodon/components/timeline_hint';
import { me } from 'mastodon/initial_state';
import { connectUserTimelineStream } from '../../actions/streaming';
import { connectTimeline, disconnectTimeline } from 'mastodon/actions/timelines';
const emptyList = ImmutableList();
@ -63,41 +63,48 @@ class AccountTimeline extends ImmutablePureComponent {
};
componentWillMount () {
const { params: { accountId }, withReplies } = this.props;
const { params: { accountId }, withReplies, dispatch } = this.props;
this.props.dispatch(fetchAccount(accountId));
this.props.dispatch(fetchAccountIdentityProofs(accountId));
dispatch(fetchAccount(accountId));
dispatch(fetchAccountIdentityProofs(accountId));
if (!withReplies) {
this.props.dispatch(expandAccountFeaturedTimeline(accountId));
dispatch(expandAccountFeaturedTimeline(accountId));
}
this.props.dispatch(expandAccountTimeline(accountId, { withReplies }));
}
dispatch(expandAccountTimeline(accountId, { withReplies }));
componentDidMount () {
if (this.props.params.accountId === me) {
this.disconnect = this.props.dispatch(connectUserTimelineStream(me));
if (accountId === me) {
dispatch(connectTimeline(`account:${me}`));
}
}
componentWillReceiveProps (nextProps) {
const { dispatch } = this.props;
if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
this.props.dispatch(fetchAccount(nextProps.params.accountId));
this.props.dispatch(fetchAccountIdentityProofs(nextProps.params.accountId));
dispatch(fetchAccount(nextProps.params.accountId));
dispatch(fetchAccountIdentityProofs(nextProps.params.accountId));
if (!nextProps.withReplies) {
this.props.dispatch(expandAccountFeaturedTimeline(nextProps.params.accountId));
dispatch(expandAccountFeaturedTimeline(nextProps.params.accountId));
}
this.props.dispatch(expandAccountTimeline(nextProps.params.accountId, { withReplies: nextProps.params.withReplies }));
dispatch(expandAccountTimeline(nextProps.params.accountId, { withReplies: nextProps.params.withReplies }));
}
if (nextProps.params.accountId === me && this.props.params.accountId !== me) {
dispatch(connectTimeline(`account:${me}`));
} else if (this.props.params.accountId === me && nextProps.params.accountId !== me) {
dispatch(disconnectTimeline(`account:${me}`));
}
}
componentWillUnmount () {
if (this.disconnect) {
this.disconnect();
this.disconnect = null;
const { dispatch, params: { accountId } } = this.props;
if (accountId === me) {
dispatch(disconnectTimeline(`account:${me}`));
}
}

View File

@ -115,6 +115,10 @@ class Audio extends React.PureComponent {
}
togglePlay = () => {
if (!this.audioContext) {
this._initAudioContext();
}
if (this.state.paused) {
this.setState({ paused: false }, () => this.audio.play());
} else {
@ -133,10 +137,6 @@ class Audio extends React.PureComponent {
handlePlay = () => {
this.setState({ paused: false });
if (this.canvas && !this.audioContext) {
this._initAudioContext();
}
if (this.audioContext && this.audioContext.state === 'suspended') {
this.audioContext.resume();
}
@ -269,8 +269,9 @@ class Audio extends React.PureComponent {
}
_initAudioContext () {
const context = new AudioContext();
const source = context.createMediaElementSource(this.audio);
const AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
const source = context.createMediaElementSource(this.audio);
this.visualizer.setAudioContext(context, source);
source.connect(context.destination);

View File

@ -5,7 +5,22 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { me } from '../../../initial_state';
const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i;
const HASHTAG_SEPARATORS = "_\\u00b7\\u200c";
const ALPHA = '\\p{L}\\p{M}';
const WORD = '\\p{L}\\p{M}\\p{N}\\p{Pc}';
const APPROX_HASHTAG_RE = new RegExp(
'(?:^|[^\\/\\)\\w])#((' +
'[' + WORD + '_]' +
'[' + WORD + HASHTAG_SEPARATORS + ']*' +
'[' + ALPHA + HASHTAG_SEPARATORS + ']' +
'[' + WORD + HASHTAG_SEPARATORS +']*' +
'[' + WORD + '_]' +
')|(' +
'[' + WORD + '_]*' +
'[' + ALPHA + ']' +
'[' + WORD + '_]*' +
'))', 'iu'
);
const mapStateToProps = state => ({
needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']),

View File

@ -15,5 +15,8 @@ button.icon-button i.fa-retweet {
}
button.icon-button.disabled i.fa-retweet {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='209' width='22'><path d='M 18.972656 1.2011719 C 18.829825 1.1881782 18.685932 1.2302188 18.572266 1.3300781 L 15.990234 3.5996094 C 15.58109 3.6070661 15.297269 3.609375 14.730469 3.609375 L 7.0996094 3.609375 L 9.4199219 6.4609375 L 9.4492188 6.5195312 L 12.664062 6.5195312 L 6.5761719 11.867188 C 6.5674697 11.818249 6.5507813 11.773891 6.5507812 11.720703 L 6.5507812 9.0195312 L 9.0507812 9.0195312 C 9.4207813 9.0495313 9.6792188 8.54 9.4492188 8.25 L 5.5 3.3496094 C 5.38 3.1796094 5.1607031 3.1003906 4.9707031 3.1503906 L 4.9707031 3.1601562 C 4.8707031 3.1901563 4.8 3.2598438 4.75 3.3398438 L 0.80078125 8.2402344 C 0.60078125 8.5402344 0.8292187 9.0190625 1.1992188 9.0390625 L 3.5996094 9.0390625 L 3.5996094 11.720703 C 3.5996094 13.045739 3.5690668 13.895038 3.6503906 14.4375 L 2.6152344 15.347656 C 2.3879011 15.547375 2.3754917 15.901081 2.5859375 16.140625 L 3.1464844 16.78125 C 3.3569308 17.020794 3.7101667 17.053234 3.9375 16.853516 L 19.892578 2.8359375 C 20.119911 2.6362188 20.134275 2.282513 19.923828 2.0429688 L 19.361328 1.4023438 C 19.256105 1.282572 19.115488 1.2141655 18.972656 1.2011719 z M 18.410156 6.7753906 L 15.419922 9.4042969 L 15.419922 9.9394531 L 14.810547 9.9394531 L 13.148438 11.400391 L 16.539062 15.640625 C 16.719062 15.890625 17.140313 15.890625 17.320312 15.640625 L 21.259766 10.740234 C 21.519766 10.460234 21.260625 9.9094531 20.890625 9.9394531 L 18.400391 9.9394531 L 18.400391 7.2402344 C 18.400391 7.0470074 18.407711 6.9489682 18.410156 6.7753906 z M 11.966797 12.439453 L 8.6679688 15.339844 L 14.919922 15.339844 L 12.619141 12.5 C 12.589141 12.48 12.590313 12.459453 12.570312 12.439453 L 11.966797 12.439453 z' fill='#{hex-color(darken($action-button-color, 13%))}' stroke-width='0'/></svg>");
&,
&:hover {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='209' width='22'><path d='M 18.972656 1.2011719 C 18.829825 1.1881782 18.685932 1.2302188 18.572266 1.3300781 L 15.990234 3.5996094 C 15.58109 3.6070661 15.297269 3.609375 14.730469 3.609375 L 7.0996094 3.609375 L 9.4199219 6.4609375 L 9.4492188 6.5195312 L 12.664062 6.5195312 L 6.5761719 11.867188 C 6.5674697 11.818249 6.5507813 11.773891 6.5507812 11.720703 L 6.5507812 9.0195312 L 9.0507812 9.0195312 C 9.4207813 9.0495313 9.6792188 8.54 9.4492188 8.25 L 5.5 3.3496094 C 5.38 3.1796094 5.1607031 3.1003906 4.9707031 3.1503906 L 4.9707031 3.1601562 C 4.8707031 3.1901563 4.8 3.2598438 4.75 3.3398438 L 0.80078125 8.2402344 C 0.60078125 8.5402344 0.8292187 9.0190625 1.1992188 9.0390625 L 3.5996094 9.0390625 L 3.5996094 11.720703 C 3.5996094 13.045739 3.5690668 13.895038 3.6503906 14.4375 L 2.6152344 15.347656 C 2.3879011 15.547375 2.3754917 15.901081 2.5859375 16.140625 L 3.1464844 16.78125 C 3.3569308 17.020794 3.7101667 17.053234 3.9375 16.853516 L 19.892578 2.8359375 C 20.119911 2.6362188 20.134275 2.282513 19.923828 2.0429688 L 19.361328 1.4023438 C 19.256105 1.282572 19.115488 1.2141655 18.972656 1.2011719 z M 18.410156 6.7753906 L 15.419922 9.4042969 L 15.419922 9.9394531 L 14.810547 9.9394531 L 13.148438 11.400391 L 16.539062 15.640625 C 16.719062 15.890625 17.140313 15.890625 17.320312 15.640625 L 21.259766 10.740234 C 21.519766 10.460234 21.260625 9.9094531 20.890625 9.9394531 L 18.400391 9.9394531 L 18.400391 7.2402344 C 18.400391 7.0470074 18.407711 6.9489682 18.410156 6.7753906 z M 11.966797 12.439453 L 8.6679688 15.339844 L 14.919922 15.339844 L 12.619141 12.5 C 12.589141 12.48 12.590313 12.459453 12.570312 12.439453 L 11.966797 12.439453 z' fill='#{hex-color(darken($action-button-color, 13%))}' stroke-width='0'/></svg>");
}
}

View File

@ -4,7 +4,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
def perform
return reject_follow_for_relay if relay_follow?
return follow_request_from_object.reject! unless follow_request_from_object.nil?
return UnfollowService.new.call(follow_from_object.target_account, @account) unless follow_from_object.nil?
return UnfollowService.new.call(follow_from_object.account, @account) unless follow_from_object.nil?
case @object['type']
when 'Follow'

View File

@ -27,7 +27,7 @@ class AccountSearchService < BaseService
return @exact_match if defined?(@exact_match)
@exact_match = begin
match = begin
if options[:resolve]
ResolveAccountService.new.call(query)
elsif domain_is_local?
@ -36,6 +36,10 @@ class AccountSearchService < BaseService
Account.find_remote(query_username, query_domain)
end
end
match = nil if !match.nil? && !account.nil? && options[:following] && !account.following?(match)
@exact_match = match
end
def search_results

View File

@ -29,11 +29,11 @@
- if !status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small), blurhash: video.blurhash, sensitive: status.sensitive?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: status.sensitive?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
- elsif status.media_attachments.first.audio?
- audio = status.media_attachments.first
= react_component :audio, src: audio.file.url(:original), poster: audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url, backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 670, height: 380, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
= react_component :audio, src: full_asset_url(audio.file.url(:original)), poster: full_asset_url(audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url), backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 670, height: 380, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
- else
= react_component :media_gallery, height: 380, sensitive: status.sensitive?, standalone: true, autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do

View File

@ -35,11 +35,11 @@
- if !status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small), blurhash: video.blurhash, sensitive: status.sensitive?, width: 610, height: 343, inline: true, alt: video.description do
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: status.sensitive?, width: 610, height: 343, inline: true, alt: video.description do
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
- elsif status.media_attachments.first.audio?
- audio = status.media_attachments.first
= react_component :audio, src: audio.file.url(:original), poster: audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url, backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 610, height: 343, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
= react_component :audio, src: full_asset_url(audio.file.url(:original)), poster: full_asset_url(audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url), backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 610, height: 343, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
- else
= react_component :media_gallery, height: 343, sensitive: status.sensitive?, autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do

View File

@ -4,7 +4,7 @@ image:
repository: tootsuite/mastodon
pullPolicy: Always
# https://hub.docker.com/r/tootsuite/mastodon/tags
tag: v3.1.5
tag: v3.2.0
# alternatively, use `latest` for the latest release or `edge` for the image
# built from the most recent commit
#

View File

@ -17,7 +17,7 @@ module Mastodon
end
def flags
'rc1'
''
end
def suffix

View File

@ -5,6 +5,7 @@ require 'mime/types/columnar'
module Paperclip
class ColorExtractor < Paperclip::Processor
MIN_CONTRAST = 3.0
ACCENT_MIN_CONTRAST = 2.0
FREQUENCY_THRESHOLD = 0.01
def make
@ -26,8 +27,9 @@ module Paperclip
foreground_palette.each do |color|
distance = ColorDiff.between(background_color, color)
contrast = w3c_contrast(background_color, color)
if distance > max_distance
if distance > max_distance && contrast >= ACCENT_MIN_CONTRAST
max_distance = distance
max_distance_color = color
end
@ -77,8 +79,8 @@ module Paperclip
private
def w3c_contrast(color1, color2)
luminance1 = (0.2126 * color1.r + 0.7152 * color1.g + 0.0722 * color1.b) + 0.05
luminance2 = (0.2126 * color2.r + 0.7152 * color2.g + 0.0722 * color2.b) + 0.05
luminance1 = color1.to_xyz.y * 0.01 + 0.05
luminance2 = color2.to_xyz.y * 0.01 + 0.05
if luminance1 > luminance2
luminance1 / luminance2

View File

@ -19,7 +19,7 @@ module Paperclip
@original_filename = filename_from_content_disposition || filename_from_path || 'data'
@size = @target.response.content_length
@tempfile = copy_to_tempfile(@target)
@content_type = @target.response.mime_type || ContentTypeDetector.new(@tempfile.path).detect
@content_type = ContentTypeDetector.new(@tempfile.path).detect
end
def copy_to_tempfile(source)

View File

@ -59,11 +59,11 @@
},
"private": true,
"dependencies": {
"@babel/core": "^7.10.3",
"@babel/core": "^7.10.5",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.10.3",
"@babel/plugin-proposal-decorators": "^7.10.5",
"@babel/plugin-transform-react-inline-elements": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.10.5",
"@babel/preset-env": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@babel/runtime": "^7.8.4",
@ -72,7 +72,7 @@
"@rails/ujs": "^6.0.3",
"array-includes": "^3.1.1",
"arrow-key-navigation": "^1.2.0",
"autoprefixer": "^9.8.0",
"autoprefixer": "^9.8.5",
"axios": "^0.19.2",
"babel-loader": "^8.1.0",
"babel-plugin-lodash": "^3.3.4",
@ -138,14 +138,14 @@
"react-motion": "^0.5.2",
"react-notification": "^6.8.5",
"react-overlays": "^0.9.1",
"react-redux": "^7.2.0",
"react-redux": "^7.2.1",
"react-redux-loading-bar": "^4.0.8",
"react-router-dom": "^4.1.1",
"react-router-scroll-4": "^1.0.0-beta.1",
"react-select": "^3.1.0",
"react-sparklines": "^1.7.0",
"react-swipeable-views": "^0.13.9",
"react-textarea-autosize": "^8.1.1",
"react-textarea-autosize": "^8.2.0",
"react-toggle": "^4.1.1",
"redis": "^3.0.2",
"redux": "^4.0.5",
@ -155,7 +155,7 @@
"requestidlecallback": "^0.3.0",
"reselect": "^4.0.0",
"rimraf": "^3.0.2",
"sass": "^1.26.8",
"sass": "^1.26.10",
"sass-loader": "^8.0.2",
"stacktrace-js": "^2.0.2",
"stringz": "^2.1.0",
@ -165,7 +165,7 @@
"throng": "^4.0.0",
"tiny-queue": "^0.2.1",
"uuid": "^8.2.0",
"webpack": "^4.43.0",
"webpack": "^4.44.0",
"webpack-assets-manifest": "^3.1.1",
"webpack-bundle-analyzer": "^3.8.0",
"webpack-cli": "^3.3.12",
@ -174,21 +174,21 @@
},
"devDependencies": {
"@testing-library/jest-dom": "^5.11.0",
"@testing-library/react": "^10.4.3",
"@testing-library/react": "^10.4.7",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.1.0",
"eslint": "^6.8.0",
"eslint-plugin-import": "~2.21.2",
"eslint": "^7.5.0",
"eslint-plugin-import": "~2.22.0",
"eslint-plugin-jsx-a11y": "~6.3.1",
"eslint-plugin-promise": "~4.2.1",
"eslint-plugin-react": "~7.20.0",
"eslint-plugin-react": "~7.20.4",
"jest": "^26.0.1",
"raf": "^3.4.1",
"react-intl-translations-manager": "^5.0.3",
"react-test-renderer": "^16.13.1",
"sass-lint": "^1.13.1",
"webpack-dev-server": "^3.11.0",
"yargs": "^15.4.0"
"yargs": "^15.4.1"
},
"resolutions": {
"kind-of": "^6.0.3"

View File

@ -18,6 +18,7 @@ RSpec.describe ActivityPub::Activity::Create do
stub_request(:get, 'http://example.com/attachment.png').to_return(request_fixture('avatar.txt'))
stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png'))
stub_request(:get, 'http://example.com/emojib.png').to_return(body: attachment_fixture('emojo.png'), headers: { 'Content-Type' => 'application/octet-stream' })
end
describe '#perform' do
@ -451,6 +452,32 @@ RSpec.describe ActivityPub::Activity::Create do
end
end
context 'with emojis served with invalid content-type' do
let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum :tinkong:',
tag: [
{
type: 'Emoji',
icon: {
url: 'http://example.com/emojib.png',
},
name: 'tinkong',
},
],
}
end
it 'creates status' do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.emojis.map(&:shortcode)).to include('tinkong')
end
end
context 'with emojis missing name' do
let(:object_json) do
{

View File

@ -3,6 +3,14 @@ require 'rails_helper'
RSpec.describe ActivityPub::Activity::Reject do
let(:sender) { Fabricate(:account) }
let(:recipient) { Fabricate(:account) }
let(:object_json) do
{
id: 'bar',
type: 'Follow',
actor: ActivityPub::TagManager.instance.uri_for(recipient),
object: ActivityPub::TagManager.instance.uri_for(sender),
}
end
let(:json) do
{
@ -10,29 +18,105 @@ RSpec.describe ActivityPub::Activity::Reject do
id: 'foo',
type: 'Reject',
actor: ActivityPub::TagManager.instance.uri_for(sender),
object: {
id: 'bar',
type: 'Follow',
actor: ActivityPub::TagManager.instance.uri_for(recipient),
object: ActivityPub::TagManager.instance.uri_for(sender),
},
object: object_json,
}.with_indifferent_access
end
describe '#perform' do
subject { described_class.new(json, sender) }
before do
Fabricate(:follow_request, account: recipient, target_account: sender)
subject.perform
context 'rejecting a pending follow request by target' do
before do
Fabricate(:follow_request, account: recipient, target_account: sender)
subject.perform
end
it 'does not create a follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'removes the follow request' do
expect(recipient.requested?(sender)).to be false
end
end
it 'does not create a follow relationship' do
expect(recipient.following?(sender)).to be false
context 'rejecting a pending follow request by uri' do
before do
Fabricate(:follow_request, account: recipient, target_account: sender, uri: 'bar')
subject.perform
end
it 'does not create a follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'removes the follow request' do
expect(recipient.requested?(sender)).to be false
end
end
it 'removes the follow request' do
expect(recipient.requested?(sender)).to be false
context 'rejecting a pending follow request by uri only' do
let(:object_json) { 'bar' }
before do
Fabricate(:follow_request, account: recipient, target_account: sender, uri: 'bar')
subject.perform
end
it 'does not create a follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'removes the follow request' do
expect(recipient.requested?(sender)).to be false
end
end
context 'rejecting an existing follow relationship by target' do
before do
Fabricate(:follow, account: recipient, target_account: sender)
subject.perform
end
it 'removes the follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'does not create a follow request' do
expect(recipient.requested?(sender)).to be false
end
end
context 'rejecting an existing follow relationship by uri' do
before do
Fabricate(:follow, account: recipient, target_account: sender, uri: 'bar')
subject.perform
end
it 'removes the follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'does not create a follow request' do
expect(recipient.requested?(sender)).to be false
end
end
context 'rejecting an existing follow relationship by uri only' do
let(:object_json) { 'bar' }
before do
Fabricate(:follow, account: recipient, target_account: sender, uri: 'bar')
subject.perform
end
it 'removes the follow relationship' do
expect(recipient.following?(sender)).to be false
end
it 'does not create a follow request' do
expect(recipient.requested?(sender)).to be false
end
end
end

937
yarn.lock

File diff suppressed because it is too large Load Diff