mirror of
https://github.com/mastodon/mastodon.git
synced 2024-11-21 12:05:07 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
529a2edded
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
@ -35,6 +35,10 @@ SMTP_PORT=587
|
||||
SMTP_LOGIN=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_FROM_ADDRESS=notifications@example.com
|
||||
#SMTP_AUTH_METHOD=plain
|
||||
#SMTP_OPENSSL_VERIFY_MODE=peer
|
||||
#SMTP_ENABLE_STARTTLS_AUTO=true
|
||||
|
||||
|
||||
# Optional asset host for multi-server setups
|
||||
# CDN_HOST=assets.example.com
|
||||
|
30
.eslintignore
Normal file
30
.eslintignore
Normal file
@ -0,0 +1,30 @@
|
||||
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
||||
#
|
||||
# If you find yourself ignoring temporary files generated by your text editor
|
||||
# or operating system, you probably want to add a global ignore instead:
|
||||
# git config --global core.excludesfile '~/.gitignore_global'
|
||||
|
||||
# Ignore bundler config.
|
||||
/.bundle
|
||||
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
/db/*.sqlite3-journal
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*
|
||||
!/log/.keep
|
||||
/tmp
|
||||
coverage
|
||||
public/system
|
||||
public/assets
|
||||
.env
|
||||
.env.production
|
||||
node_modules/
|
||||
neo4j/
|
||||
|
||||
# Ignore Vagrant files
|
||||
.vagrant/
|
||||
|
||||
# Ignore Capistrano customizations
|
||||
config/deploy/*
|
@ -1 +1 @@
|
||||
2.3.1
|
||||
2.4.1
|
||||
|
@ -16,7 +16,7 @@ addons:
|
||||
postgresql: 9.4
|
||||
|
||||
rvm:
|
||||
- 2.3.1
|
||||
- 2.4.1
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM ruby:2.3.1-alpine
|
||||
FROM ruby:2.4.1-alpine
|
||||
|
||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||
description="A GNU Social-compatible microblogging server"
|
||||
|
5
Gemfile
5
Gemfile
@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby '2.3.1'
|
||||
ruby '2.4.1'
|
||||
|
||||
gem 'rails', '~> 5.0.2'
|
||||
gem 'sass-rails', '~> 5.0'
|
||||
@ -32,6 +32,7 @@ gem 'htmlentities'
|
||||
gem 'http'
|
||||
gem 'http_accept_language'
|
||||
gem 'httplog'
|
||||
gem 'kaminari'
|
||||
gem 'link_header'
|
||||
gem 'nokogiri'
|
||||
gem 'oj'
|
||||
@ -52,7 +53,6 @@ gem 'simple_form'
|
||||
gem 'statsd-instrument'
|
||||
gem 'twitter-text'
|
||||
gem 'tzinfo-data'
|
||||
gem 'will_paginate'
|
||||
|
||||
gem 'react-rails'
|
||||
gem 'browserify-rails'
|
||||
@ -68,6 +68,7 @@ end
|
||||
|
||||
group :test do
|
||||
gem 'faker'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'rspec-sidekiq'
|
||||
gem 'simplecov', require: false
|
||||
gem 'webmock'
|
||||
|
206
Gemfile.lock
206
Gemfile.lock
@ -24,7 +24,7 @@ GEM
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_record_query_trace (1.5.3)
|
||||
active_record_query_trace (1.5.4)
|
||||
activejob (5.0.2)
|
||||
activesupport (= 5.0.2)
|
||||
globalid (>= 0.3.6)
|
||||
@ -39,7 +39,7 @@ GEM
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.0)
|
||||
addressable (2.5.1)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
airbrussh (1.1.2)
|
||||
sshkit (>= 1.6.1, != 1.7.0)
|
||||
@ -47,17 +47,17 @@ GEM
|
||||
ast (2.3.0)
|
||||
attr_encrypted (3.0.3)
|
||||
encryptor (~> 3.0.0)
|
||||
autoprefixer-rails (6.5.0.2)
|
||||
autoprefixer-rails (6.7.7.1)
|
||||
execjs
|
||||
av (0.9.0)
|
||||
cocaine (~> 0.5.3)
|
||||
aws-sdk (2.6.28)
|
||||
aws-sdk-resources (= 2.6.28)
|
||||
aws-sdk-core (2.6.28)
|
||||
aws-sdk (2.9.6)
|
||||
aws-sdk-resources (= 2.9.6)
|
||||
aws-sdk-core (2.9.6)
|
||||
aws-sigv4 (~> 1.0)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-resources (2.6.28)
|
||||
aws-sdk-core (= 2.6.28)
|
||||
aws-sdk-resources (2.9.6)
|
||||
aws-sdk-core (= 2.9.6)
|
||||
aws-sigv4 (1.0.0)
|
||||
babel-source (5.8.35)
|
||||
babel-transpiler (0.7.0)
|
||||
@ -78,12 +78,11 @@ GEM
|
||||
railties (>= 4.0.0, < 5.1)
|
||||
sprockets (>= 3.6.0)
|
||||
builder (3.2.3)
|
||||
bullet (5.3.0)
|
||||
bullet (5.5.1)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.10.0)
|
||||
capistrano (3.7.2)
|
||||
capistrano (3.8.0)
|
||||
airbrussh (>= 1.0.0)
|
||||
capistrano-harrow
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (>= 1.9.0)
|
||||
@ -92,8 +91,7 @@ GEM
|
||||
sshkit (~> 1.2)
|
||||
capistrano-faster-assets (1.0.2)
|
||||
capistrano (>= 3.1)
|
||||
capistrano-harrow (0.5.3)
|
||||
capistrano-rails (1.2.2)
|
||||
capistrano-rails (1.2.3)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rbenv (2.1.0)
|
||||
@ -119,7 +117,7 @@ GEM
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
debug_inspector (0.0.2)
|
||||
devise (4.2.0)
|
||||
devise (4.2.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 5.1)
|
||||
@ -131,16 +129,16 @@ GEM
|
||||
devise (~> 4.0)
|
||||
railties
|
||||
rotp (~> 2.0)
|
||||
diff-lcs (1.2.5)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
domain_name (0.5.20161129)
|
||||
domain_name (0.5.20170404)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
doorkeeper (4.2.0)
|
||||
doorkeeper (4.2.5)
|
||||
railties (>= 4.2)
|
||||
dotenv (2.1.1)
|
||||
dotenv-rails (2.1.1)
|
||||
dotenv (= 2.1.1)
|
||||
railties (>= 4.0, < 5.1)
|
||||
dotenv (2.2.0)
|
||||
dotenv-rails (2.2.0)
|
||||
dotenv (= 2.2.0)
|
||||
railties (>= 3.2, < 5.1)
|
||||
easy_translate (0.5.0)
|
||||
json
|
||||
thread
|
||||
@ -148,14 +146,14 @@ GEM
|
||||
encryptor (3.0.0)
|
||||
erubis (2.7.0)
|
||||
execjs (2.7.0)
|
||||
fabrication (2.15.2)
|
||||
faker (1.6.6)
|
||||
fabrication (2.16.1)
|
||||
faker (1.7.3)
|
||||
i18n (~> 0.5)
|
||||
fast_blank (1.0.0)
|
||||
font-awesome-rails (4.6.3.1)
|
||||
font-awesome-rails (4.7.0.1)
|
||||
railties (>= 3.2, < 5.1)
|
||||
fuubar (2.1.1)
|
||||
rspec (~> 3.0)
|
||||
fuubar (2.2.0)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
globalid (0.3.7)
|
||||
activesupport (>= 4.1.0)
|
||||
@ -163,20 +161,20 @@ GEM
|
||||
addressable (~> 2.4)
|
||||
http (~> 2.0)
|
||||
nokogiri (~> 1.6)
|
||||
hamlit (2.7.2)
|
||||
temple (~> 0.7.6)
|
||||
hamlit (2.8.1)
|
||||
temple (>= 0.8.0)
|
||||
thor
|
||||
tilt
|
||||
hamlit-rails (0.1.0)
|
||||
hamlit-rails (0.2.0)
|
||||
actionpack (>= 4.0.1)
|
||||
activesupport (>= 4.0.1)
|
||||
hamlit (>= 1.2.0)
|
||||
railties (>= 4.0.1)
|
||||
hashdiff (0.3.0)
|
||||
hashdiff (0.3.2)
|
||||
highline (1.7.8)
|
||||
hiredis (0.6.1)
|
||||
htmlentities (4.3.4)
|
||||
http (2.1.0)
|
||||
http (2.2.1)
|
||||
addressable (~> 2.3)
|
||||
http-cookie (~> 1.0)
|
||||
http-form_data (~> 1.0.1)
|
||||
@ -186,10 +184,10 @@ GEM
|
||||
http-form_data (1.0.1)
|
||||
http_accept_language (2.1.0)
|
||||
http_parser.rb (0.6.0)
|
||||
httplog (0.3.2)
|
||||
httplog (0.99.2)
|
||||
colorize
|
||||
i18n (0.8.1)
|
||||
i18n-tasks (0.9.6)
|
||||
i18n-tasks (0.9.13)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
easy_translate (>= 0.5.0)
|
||||
@ -197,19 +195,31 @@ GEM
|
||||
highline (>= 1.7.3)
|
||||
i18n
|
||||
parser (>= 2.2.3.0)
|
||||
term-ansicolor (>= 1.3.2)
|
||||
rainbow (~> 2.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
jmespath (1.3.1)
|
||||
jquery-rails (4.1.1)
|
||||
jquery-rails (4.3.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json (2.0.3)
|
||||
kaminari (1.0.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.0.1)
|
||||
kaminari-activerecord (= 1.0.1)
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-actionview (1.0.1)
|
||||
actionview
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-activerecord (1.0.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-core (1.0.1)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.4.1)
|
||||
launchy (~> 2.2)
|
||||
letter_opener_web (1.3.0)
|
||||
letter_opener_web (1.3.1)
|
||||
actionmailer (>= 3.2)
|
||||
letter_opener (~> 1.0)
|
||||
railties (>= 3.2)
|
||||
@ -231,11 +241,11 @@ GEM
|
||||
minitest (5.10.1)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (4.0.1)
|
||||
net-ssh (4.1.0)
|
||||
nio4r (2.0.0)
|
||||
nokogiri (1.7.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
oj (2.17.3)
|
||||
oj (2.18.5)
|
||||
orm_adapter (0.5.0)
|
||||
ostatus2 (1.0.2)
|
||||
addressable (~> 2.4)
|
||||
@ -251,26 +261,26 @@ GEM
|
||||
paperclip-av-transcoder (0.6.4)
|
||||
av (~> 0.9.0)
|
||||
paperclip (>= 2.5.2)
|
||||
parser (2.3.1.2)
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
pg (0.18.4)
|
||||
pghero (1.6.2)
|
||||
pg (0.20.0)
|
||||
pghero (1.6.4)
|
||||
activerecord
|
||||
powerpack (0.1.1)
|
||||
pry (0.10.4)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
pry-rails (0.3.4)
|
||||
pry (>= 0.9.10)
|
||||
public_suffix (2.0.4)
|
||||
puma (3.6.0)
|
||||
pry-rails (0.3.6)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (2.0.5)
|
||||
puma (3.8.2)
|
||||
rabl (0.13.1)
|
||||
activesupport (>= 2.3.14)
|
||||
rack (2.0.1)
|
||||
rack-attack (5.0.1)
|
||||
rack
|
||||
rack-cors (0.4.0)
|
||||
rack-cors (0.4.1)
|
||||
rack-protection (1.5.3)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
@ -288,6 +298,10 @@ GEM
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 5.0.2)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.1)
|
||||
actionpack (~> 5.x)
|
||||
actionview (~> 5.x)
|
||||
activesupport (~> 5.x)
|
||||
rails-dom-testing (2.0.2)
|
||||
activesupport (>= 4.2.0, < 6.0)
|
||||
nokogiri (~> 1.6)
|
||||
@ -306,42 +320,37 @@ GEM
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.1.0)
|
||||
rainbow (2.2.1)
|
||||
rake (12.0.0)
|
||||
react-rails (1.10.0)
|
||||
react-rails (1.11.0)
|
||||
babel-transpiler (>= 0.7.0)
|
||||
coffee-script-source (~> 1.8)
|
||||
connection_pool
|
||||
execjs
|
||||
railties (>= 3.2)
|
||||
tilt
|
||||
redis (3.3.2)
|
||||
redis-actionpack (5.0.0)
|
||||
actionpack (>= 4.0.0, < 6)
|
||||
redis-rack (~> 2.0.0.pre)
|
||||
redis-store (~> 1.2.0.pre)
|
||||
redis-activesupport (5.0.1)
|
||||
redis (3.3.3)
|
||||
redis-actionpack (5.0.1)
|
||||
actionpack (>= 4.0, < 6)
|
||||
redis-rack (>= 1, < 3)
|
||||
redis-store (>= 1.1.0, < 1.4.0)
|
||||
redis-activesupport (5.0.2)
|
||||
activesupport (>= 3, < 6)
|
||||
redis-store (~> 1.2.0)
|
||||
redis-rack (2.0.0)
|
||||
rack (~> 2.0)
|
||||
redis-store (~> 1.2.0)
|
||||
redis-rails (5.0.1)
|
||||
redis-actionpack (~> 5.0.0)
|
||||
redis-activesupport (~> 5.0.0)
|
||||
redis-store (~> 1.2.0)
|
||||
redis-store (1.2.0)
|
||||
redis-store (~> 1.3.0)
|
||||
redis-rack (2.0.1)
|
||||
rack (>= 2.0, < 3)
|
||||
redis-store (>= 1.2, < 1.4)
|
||||
redis-rails (5.0.2)
|
||||
redis-actionpack (>= 5.0, < 6)
|
||||
redis-activesupport (>= 5.0, < 6)
|
||||
redis-store (>= 1.2, < 2)
|
||||
redis-store (1.3.0)
|
||||
redis (>= 2.2)
|
||||
responders (2.3.0)
|
||||
railties (>= 4.2.0, < 5.1)
|
||||
rotp (2.1.2)
|
||||
rqrcode (0.10.1)
|
||||
chunky_png (~> 1.0)
|
||||
rspec (3.5.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-core (3.5.2)
|
||||
rspec-core (3.5.4)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
@ -349,7 +358,7 @@ GEM
|
||||
rspec-mocks (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.1)
|
||||
rspec-rails (3.5.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
@ -357,40 +366,40 @@ GEM
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-sidekiq (2.2.0)
|
||||
rspec (~> 3.0, >= 3.0.0)
|
||||
rspec-sidekiq (3.0.0)
|
||||
rspec-core (~> 3.0, >= 3.0.0)
|
||||
sidekiq (>= 2.4.0)
|
||||
rspec-support (3.5.0)
|
||||
rubocop (0.42.0)
|
||||
parser (>= 2.3.1.1, < 3.0)
|
||||
rubocop (0.48.1)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-oembed (0.10.1)
|
||||
ruby-oembed (0.12.0)
|
||||
ruby-progressbar (1.8.1)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.4.22)
|
||||
sass (3.4.23)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
sidekiq (4.2.7)
|
||||
sidekiq (4.2.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (~> 3.2, >= 3.2.1)
|
||||
sidekiq-unique-jobs (4.0.18)
|
||||
sidekiq (>= 2.6)
|
||||
sidekiq-unique-jobs (5.0.0)
|
||||
sidekiq (>= 4.0)
|
||||
thor
|
||||
simple-navigation (4.0.3)
|
||||
simple-navigation (4.0.5)
|
||||
activesupport (>= 2.3.2)
|
||||
simple_form (3.2.1)
|
||||
simple_form (3.4.0)
|
||||
actionpack (> 4, < 5.1)
|
||||
activemodel (> 4, < 5.1)
|
||||
simplecov (0.12.0)
|
||||
simplecov (0.14.1)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
@ -403,43 +412,39 @@ GEM
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sshkit (1.11.5)
|
||||
sshkit (1.13.1)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
statsd-instrument (2.1.2)
|
||||
temple (0.7.7)
|
||||
term-ansicolor (1.4.0)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.7.0)
|
||||
unicode-display_width (~> 1.1)
|
||||
temple (0.8.0)
|
||||
terminal-table (1.7.3)
|
||||
unicode-display_width (~> 1.1.1)
|
||||
thor (0.19.4)
|
||||
thread (0.2.2)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.6)
|
||||
tins (1.12.0)
|
||||
tilt (2.0.7)
|
||||
twitter-text (1.14.5)
|
||||
unf (~> 0.1.0)
|
||||
tzinfo (1.2.2)
|
||||
tzinfo (1.2.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2017.2)
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (3.0.1)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.2)
|
||||
unicode-display_width (1.1.0)
|
||||
unicode-display_width (1.1.3)
|
||||
uniform_notifier (1.10.0)
|
||||
warden (1.2.6)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webmock (2.1.0)
|
||||
webmock (2.3.2)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
will_paginate (3.1.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@ -478,6 +483,7 @@ DEPENDENCIES
|
||||
httplog
|
||||
i18n-tasks (~> 0.9.6)
|
||||
jquery-rails
|
||||
kaminari
|
||||
letter_opener
|
||||
letter_opener_web
|
||||
link_header
|
||||
@ -497,6 +503,7 @@ DEPENDENCIES
|
||||
rack-cors
|
||||
rack-timeout
|
||||
rails (~> 5.0.2)
|
||||
rails-controller-testing
|
||||
rails-settings-cached
|
||||
rails_12factor
|
||||
react-rails
|
||||
@ -518,10 +525,9 @@ DEPENDENCIES
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
webmock
|
||||
will_paginate
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.3.1p112
|
||||
ruby 2.4.1p111
|
||||
|
||||
BUNDLED WITH
|
||||
1.14.5
|
||||
1.14.6
|
||||
|
@ -67,7 +67,7 @@ Consult the example configuration file, `.env.production.sample` for the full li
|
||||
|
||||
[![](https://images.microbadger.com/badges/version/gargron/mastodon.svg)](https://microbadger.com/images/gargron/mastodon "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/image/gargron/mastodon.svg)](https://microbadger.com/images/gargron/mastodon "Get your own image badge on microbadger.com")
|
||||
|
||||
The project now includes a `Dockerfile` and a `docker-compose.yml`. You need to turn `.env.production.sample` into `.env.production` with all the variables set before you can:
|
||||
The project now includes a `Dockerfile` and a `docker-compose.yml` file (which requires at least docker-compose version `1.10.0`). You need to turn `.env.production.sample` into `.env.production` with all the variables set before you can:
|
||||
|
||||
docker-compose build
|
||||
|
||||
|
8
Vagrantfile
vendored
8
Vagrantfile
vendored
@ -46,12 +46,12 @@ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
|
||||
export PATH="$HOME/.rbenv/bin::$PATH"
|
||||
eval "$(rbenv init -)"
|
||||
|
||||
echo "Compiling Ruby 2.3.1: warning, this takes a while!!!"
|
||||
rbenv install 2.3.1
|
||||
rbenv global 2.3.1
|
||||
|
||||
cd /vagrant
|
||||
|
||||
echo "Compiling Ruby $(cat .ruby-version): warning, this takes a while!!!"
|
||||
rbenv install $(cat .ruby-version)
|
||||
rbenv global $(cat .ruby-version)
|
||||
|
||||
# Configure database
|
||||
sudo -u postgres createuser -U postgres vagrant -s
|
||||
sudo -u postgres createdb -U postgres mastodon_development
|
||||
|
12
app.json
12
app.json
@ -79,6 +79,18 @@
|
||||
"SMTP_FROM_ADDRESS": {
|
||||
"description": "Address to send emails from",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_AUTH_METHOD": {
|
||||
"description": "Authentication method to use with SMTP server. Default is 'plain'.",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_OPENSSL_VERIFY_MODE": {
|
||||
"description": "SMTP server certificate verification mode. Defaults is 'peer'.",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_ENABLE_STARTTLS_AUTO": {
|
||||
"description": "Enable STARTTLS if SMTP server supports it? Default is true.",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"buildpacks": [
|
||||
|
@ -61,6 +61,8 @@ export function refreshNotifications() {
|
||||
params.since_id = ids.first().get('id');
|
||||
}
|
||||
|
||||
params.exclude_types = getState().getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
|
||||
|
||||
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
|
||||
@ -105,11 +107,11 @@ export function expandNotifications() {
|
||||
|
||||
dispatch(expandNotificationsRequest());
|
||||
|
||||
api(getState).get(url, {
|
||||
params: {
|
||||
limit: 5
|
||||
}
|
||||
}).then(response => {
|
||||
const params = {};
|
||||
|
||||
params.exclude_types = getState().getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
|
||||
|
||||
api(getState).get(url, params).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
|
||||
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
|
||||
|
@ -65,7 +65,7 @@ const Account = React.createClass({
|
||||
<div className='account'>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
||||
<div style={{ float: 'left', marginLeft: '12px', marginRight: '10px' }}><Avatar src={account.get('avatar')} size={36} /></div>
|
||||
<div style={{ float: 'left', marginLeft: '12px', marginRight: '10px' }}><Avatar src={account.get('avatar')} staticSrc={status.getIn(['account', 'avatar_static'])} size={36} /></div>
|
||||
<DisplayName account={account} />
|
||||
</Permalink>
|
||||
|
||||
|
@ -1,103 +1,18 @@
|
||||
import PureRenderMixin from 'react-addons-pure-render-mixin';
|
||||
|
||||
// From: http://stackoverflow.com/a/18320662
|
||||
const resample = (canvas, width, height, resize_canvas) => {
|
||||
let width_source = canvas.width;
|
||||
let height_source = canvas.height;
|
||||
width = Math.round(width);
|
||||
height = Math.round(height);
|
||||
|
||||
let ratio_w = width_source / width;
|
||||
let ratio_h = height_source / height;
|
||||
let ratio_w_half = Math.ceil(ratio_w / 2);
|
||||
let ratio_h_half = Math.ceil(ratio_h / 2);
|
||||
|
||||
let ctx = canvas.getContext("2d");
|
||||
let img = ctx.getImageData(0, 0, width_source, height_source);
|
||||
let img2 = ctx.createImageData(width, height);
|
||||
let data = img.data;
|
||||
let data2 = img2.data;
|
||||
|
||||
for (let j = 0; j < height; j++) {
|
||||
for (let i = 0; i < width; i++) {
|
||||
let x2 = (i + j * width) * 4;
|
||||
let weight = 0;
|
||||
let weights = 0;
|
||||
let weights_alpha = 0;
|
||||
let gx_r = 0;
|
||||
let gx_g = 0;
|
||||
let gx_b = 0;
|
||||
let gx_a = 0;
|
||||
let center_y = (j + 0.5) * ratio_h;
|
||||
let yy_start = Math.floor(j * ratio_h);
|
||||
let yy_stop = Math.ceil((j + 1) * ratio_h);
|
||||
|
||||
for (let yy = yy_start; yy < yy_stop; yy++) {
|
||||
let dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
|
||||
let center_x = (i + 0.5) * ratio_w;
|
||||
let w0 = dy * dy; //pre-calc part of w
|
||||
let xx_start = Math.floor(i * ratio_w);
|
||||
let xx_stop = Math.ceil((i + 1) * ratio_w);
|
||||
|
||||
for (let xx = xx_start; xx < xx_stop; xx++) {
|
||||
let dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
|
||||
let w = Math.sqrt(w0 + dx * dx);
|
||||
|
||||
if (w >= 1) {
|
||||
// pixel too far
|
||||
continue;
|
||||
}
|
||||
|
||||
// hermite filter
|
||||
weight = 2 * w * w * w - 3 * w * w + 1;
|
||||
let pos_x = 4 * (xx + yy * width_source);
|
||||
|
||||
// alpha
|
||||
gx_a += weight * data[pos_x + 3];
|
||||
weights_alpha += weight;
|
||||
|
||||
// colors
|
||||
if (data[pos_x + 3] < 255)
|
||||
weight = weight * data[pos_x + 3] / 250;
|
||||
|
||||
gx_r += weight * data[pos_x];
|
||||
gx_g += weight * data[pos_x + 1];
|
||||
gx_b += weight * data[pos_x + 2];
|
||||
weights += weight;
|
||||
}
|
||||
}
|
||||
|
||||
data2[x2] = gx_r / weights;
|
||||
data2[x2 + 1] = gx_g / weights;
|
||||
data2[x2 + 2] = gx_b / weights;
|
||||
data2[x2 + 3] = gx_a / weights_alpha;
|
||||
}
|
||||
}
|
||||
|
||||
// clear and resize canvas
|
||||
if (resize_canvas === true) {
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
} else {
|
||||
ctx.clearRect(0, 0, width_source, height_source);
|
||||
}
|
||||
|
||||
// draw
|
||||
ctx.putImageData(img2, 0, 0);
|
||||
};
|
||||
|
||||
const Avatar = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
src: React.PropTypes.string.isRequired,
|
||||
staticSrc: React.PropTypes.string,
|
||||
size: React.PropTypes.number.isRequired,
|
||||
style: React.PropTypes.object,
|
||||
animated: React.PropTypes.bool
|
||||
animate: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getDefaultProps () {
|
||||
return {
|
||||
animated: true
|
||||
animate: false
|
||||
};
|
||||
},
|
||||
|
||||
@ -117,38 +32,30 @@ const Avatar = React.createClass({
|
||||
this.setState({ hovering: false });
|
||||
},
|
||||
|
||||
handleLoad () {
|
||||
this.canvas.width = this.image.naturalWidth;
|
||||
this.canvas.height = this.image.naturalHeight;
|
||||
this.canvas.getContext('2d').drawImage(this.image, 0, 0);
|
||||
|
||||
resample(this.canvas, this.props.size * window.devicePixelRatio, this.props.size * window.devicePixelRatio, true);
|
||||
},
|
||||
|
||||
setImageRef (c) {
|
||||
this.image = c;
|
||||
},
|
||||
|
||||
setCanvasRef (c) {
|
||||
this.canvas = c;
|
||||
},
|
||||
|
||||
render () {
|
||||
const { src, size, staticSrc, animate } = this.props;
|
||||
const { hovering } = this.state;
|
||||
|
||||
if (this.props.animated) {
|
||||
return (
|
||||
<div style={{ ...this.props.style, width: `${this.props.size}px`, height: `${this.props.size}px` }}>
|
||||
<img src={this.props.src} width={this.props.size} height={this.props.size} alt='' style={{ borderRadius: '4px' }} />
|
||||
</div>
|
||||
);
|
||||
const style = {
|
||||
...this.props.style,
|
||||
width: `${size}px`,
|
||||
height: `${size}px`,
|
||||
backgroundSize: `${size}px ${size}px`
|
||||
};
|
||||
|
||||
if (hovering || animate) {
|
||||
style.backgroundImage = `url(${src})`;
|
||||
} else {
|
||||
style.backgroundImage = `url(${staticSrc})`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} style={{ ...this.props.style, width: `${this.props.size}px`, height: `${this.props.size}px`, position: 'relative' }}>
|
||||
<img ref={this.setImageRef} onLoad={this.handleLoad} src={this.props.src} width={this.props.size} height={this.props.size} alt='' style={{ position: 'absolute', top: '0', left: '0', opacity: hovering ? '1' : '0', borderRadius: '4px' }} />
|
||||
<canvas ref={this.setCanvasRef} style={{ borderRadius: '4px', width: this.props.size, height: this.props.size, opacity: hovering ? '0' : '1' }} />
|
||||
</div>
|
||||
<div
|
||||
className='avatar'
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ const Status = React.createClass({
|
||||
|
||||
<a onClick={this.handleAccountClick.bind(this, status.getIn(['account', 'id']))} href={status.getIn(['account', 'url'])} className='status__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px' }}>
|
||||
<div className='status__avatar' style={{ position: 'absolute', left: '10px', top: '10px', width: '48px', height: '48px' }}>
|
||||
<Avatar src={status.getIn(['account', 'avatar'])} size={48} />
|
||||
<Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
|
||||
</div>
|
||||
|
||||
<DisplayName account={status.get('account')} />
|
||||
|
@ -36,6 +36,7 @@ const StatusContent = React.createClass({
|
||||
|
||||
if (mention) {
|
||||
link.addEventListener('click', this.onMentionClick.bind(this, mention), false);
|
||||
link.setAttribute('title', mention.get('acct'));
|
||||
} else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
|
||||
link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
|
||||
} else if (media) {
|
||||
@ -91,7 +92,7 @@ const StatusContent = React.createClass({
|
||||
const { status } = this.props;
|
||||
const { hidden } = this.state;
|
||||
|
||||
const content = { __html: emojify(status.get('content')) };
|
||||
const content = { __html: emojify(status.get('content')).replace(/\n/g, '') };
|
||||
const spoilerContent = { __html: emojify(escapeTextContentForBrowser(status.get('spoiler_text', ''))) };
|
||||
const directionStyle = { direction: 'ltr' };
|
||||
|
||||
@ -125,7 +126,7 @@ const StatusContent = React.createClass({
|
||||
<div style={{ display: hidden ? 'none' : 'block', ...directionStyle }} dangerouslySetInnerHTML={content} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
} else if (this.props.onClick) {
|
||||
return (
|
||||
<div
|
||||
className='status__content'
|
||||
@ -135,6 +136,14 @@ const StatusContent = React.createClass({
|
||||
dangerouslySetInnerHTML={content}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
className='status__content'
|
||||
style={{ ...directionStyle }}
|
||||
dangerouslySetInnerHTML={content}
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
const AutosuggestAccount = ({ account }) => (
|
||||
<div style={{ overflow: 'hidden' }} className='autosuggest-account'>
|
||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar src={account.get('avatar')} size={18} /></div>
|
||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar src={account.get('avatar')} staticSrc={status.getIn(['account', 'avatar_static'])} size={18} /></div>
|
||||
<DisplayName account={account} />
|
||||
</div>
|
||||
);
|
||||
|
@ -83,11 +83,23 @@ const ComposeForm = React.createClass({
|
||||
this.props.onChangeSpoilerText(e.target.value);
|
||||
},
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
// If this is the update where we've finished uploading,
|
||||
// save the last caret position so we can restore it below!
|
||||
if (!nextProps.is_uploading && this.props.is_uploading) {
|
||||
this._restoreCaret = this.autosuggestTextarea.textarea.selectionStart;
|
||||
}
|
||||
},
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
if (this.props.focusDate !== prevProps.focusDate) {
|
||||
// If replying to zero or one users, places the cursor at the end of the textbox.
|
||||
// If replying to more than one user, selects any usernames past the first;
|
||||
// this provides a convenient shortcut to drop everyone else from the conversation.
|
||||
// This statement does several things:
|
||||
// - If we're beginning a reply, and,
|
||||
// - Replying to zero or one users, places the cursor at the end of the textbox.
|
||||
// - Replying to more than one user, selects any usernames past the first;
|
||||
// this provides a convenient shortcut to drop everyone else from the conversation.
|
||||
// - If we've just finished uploading an image, and have a saved caret position,
|
||||
// restores the cursor to that position after the text changes!
|
||||
if (this.props.focusDate !== prevProps.focusDate || (prevProps.is_uploading && !this.props.is_uploading && typeof this._restoreCaret === 'number')) {
|
||||
let selectionEnd, selectionStart;
|
||||
|
||||
if (this.props.preselectDate !== prevProps.preselectDate) {
|
||||
@ -118,7 +130,7 @@ const ComposeForm = React.createClass({
|
||||
|
||||
render () {
|
||||
const { intl, needsPrivacyWarning, mentionedDomains, onPaste } = this.props;
|
||||
const disabled = this.props.is_submitting || this.props.is_uploading;
|
||||
const disabled = this.props.is_submitting;
|
||||
|
||||
let publishText = '';
|
||||
let privacyWarning = '';
|
||||
|
@ -17,7 +17,7 @@ const NavigationBar = React.createClass({
|
||||
render () {
|
||||
return (
|
||||
<div className='navigation-bar'>
|
||||
<Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`} style={{ textDecoration: 'none' }}><Avatar src={this.props.account.get('avatar')} size={40} /></Permalink>
|
||||
<Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`} style={{ textDecoration: 'none' }}><Avatar src={this.props.account.get('avatar')} animate size={40} /></Permalink>
|
||||
|
||||
<div style={{ flex: '1 1 auto', marginLeft: '8px' }}>
|
||||
<strong style={{ fontWeight: '500', display: 'block' }}>{this.props.account.get('acct')}</strong>
|
||||
|
@ -50,7 +50,7 @@ const ReplyIndicator = React.createClass({
|
||||
<div style={{ float: 'right', lineHeight: '24px' }}><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} /></div>
|
||||
|
||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name' style={{ display: 'block', maxWidth: '100%', paddingRight: '25px', textDecoration: 'none', overflow: 'hidden', lineHeight: '24px' }}>
|
||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={status.getIn(['account', 'avatar'])} /></div>
|
||||
<div style={{ float: 'left', marginRight: '5px' }}><Avatar size={24} src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} /></div>
|
||||
<DisplayName account={status.get('account')} />
|
||||
</a>
|
||||
</div>
|
||||
|
@ -33,7 +33,7 @@ const AccountAuthorize = ({ intl, account, onAuthorize, onReject }) => {
|
||||
<div>
|
||||
<div style={outerStyle}>
|
||||
<Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name' style={{ display: 'block', overflow: 'hidden', marginBottom: '15px' }}>
|
||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={account.get('avatar')} size={48} /></div>
|
||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={account.get('avatar')} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} /></div>
|
||||
<DisplayName account={account} />
|
||||
</Permalink>
|
||||
|
||||
|
@ -4,16 +4,6 @@ const messages = defineMessages({
|
||||
clear: { id: 'notifications.clear', defaultMessage: 'Clear notifications' }
|
||||
});
|
||||
|
||||
const iconStyle = {
|
||||
fontSize: '16px',
|
||||
padding: '15px',
|
||||
position: 'absolute',
|
||||
right: '48px',
|
||||
top: '0',
|
||||
cursor: 'pointer',
|
||||
zIndex: '2'
|
||||
};
|
||||
|
||||
const ClearColumnButton = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
@ -25,7 +15,7 @@ const ClearColumnButton = React.createClass({
|
||||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<div title={intl.formatMessage(messages.clear)} className='column-icon' tabIndex='0' style={iconStyle} onClick={this.props.onClick}>
|
||||
<div title={intl.formatMessage(messages.clear)} className='column-icon column-icon-clear' tabIndex='0' onClick={this.props.onClick}>
|
||||
<i className='fa fa-eraser' />
|
||||
</div>
|
||||
);
|
||||
|
@ -21,7 +21,7 @@ const Notification = React.createClass({
|
||||
|
||||
renderFollow (account, link) {
|
||||
return (
|
||||
<div className='notification'>
|
||||
<div className='notification notification-follow'>
|
||||
<div className='notification__message'>
|
||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
||||
<i className='fa fa-fw fa-user-plus' />
|
||||
@ -41,7 +41,7 @@ const Notification = React.createClass({
|
||||
|
||||
renderFavourite (notification, link) {
|
||||
return (
|
||||
<div className='notification'>
|
||||
<div className='notification notification-favourite'>
|
||||
<div className='notification__message'>
|
||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
||||
<i className='fa fa-fw fa-star' style={{ color: '#ca8f04' }} />
|
||||
@ -57,7 +57,7 @@ const Notification = React.createClass({
|
||||
|
||||
renderReblog (notification, link) {
|
||||
return (
|
||||
<div className='notification'>
|
||||
<div className='notification notification-reblog'>
|
||||
<div className='notification__message'>
|
||||
<div style={{ position: 'absolute', 'left': '-26px'}}>
|
||||
<i className='fa fa-fw fa-retweet' />
|
||||
@ -76,7 +76,7 @@ const Notification = React.createClass({
|
||||
const account = notification.get('account');
|
||||
const displayName = account.get('display_name').length > 0 ? account.get('display_name') : account.get('username');
|
||||
const displayNameHTML = { __html: emojify(escapeTextContentForBrowser(displayName)) };
|
||||
const link = <Permalink className='notification__display-name' style={linkStyle} href={account.get('url')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHTML} />;
|
||||
const link = <Permalink className='notification__display-name' style={linkStyle} href={account.get('url')} title={account.get('acct')} to={`/accounts/${account.get('id')}`} dangerouslySetInnerHTML={displayNameHTML} />;
|
||||
|
||||
switch(notification.get('type')) {
|
||||
case 'follow':
|
||||
|
@ -54,7 +54,7 @@ const DetailedStatus = React.createClass({
|
||||
return (
|
||||
<div style={{ padding: '14px 10px' }} className='detailed-status'>
|
||||
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name' style={{ display: 'block', overflow: 'hidden', marginBottom: '15px' }}>
|
||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={status.getIn(['account', 'avatar'])} size={48} /></div>
|
||||
<div style={{ float: 'left', marginRight: '10px' }}><Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} /></div>
|
||||
<DisplayName account={status.get('account')} />
|
||||
</a>
|
||||
|
||||
|
@ -72,6 +72,7 @@
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
flex-direction: row;
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.details-counters {
|
||||
@ -83,7 +84,7 @@
|
||||
.counter {
|
||||
width: 80px;
|
||||
color: $color3;
|
||||
padding: 0 10px;
|
||||
padding: 5px 10px 0px;
|
||||
margin-bottom: 10px;
|
||||
border-right: 1px solid $color3;
|
||||
cursor: default;
|
||||
@ -173,7 +174,7 @@
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
|
||||
a, .current, .next_page, .previous_page, .gap {
|
||||
a, .current, .page, .gap {
|
||||
font-size: 14px;
|
||||
color: $color5;
|
||||
font-weight: 500;
|
||||
@ -193,12 +194,12 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.previous_page, .next_page {
|
||||
.prev, .next {
|
||||
text-transform: uppercase;
|
||||
color: $color2;
|
||||
}
|
||||
|
||||
.previous_page {
|
||||
.prev {
|
||||
float: left;
|
||||
padding-left: 0;
|
||||
|
||||
@ -208,7 +209,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.next_page {
|
||||
.next {
|
||||
float: right;
|
||||
padding-right: 0;
|
||||
|
||||
@ -226,11 +227,11 @@
|
||||
@media screen and (max-width: 360px) {
|
||||
padding: 30px 20px;
|
||||
|
||||
a, .current, .next_page, .previous_page, .gap {
|
||||
a, .current, .next, .prev, .gap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.next_page, .previous_page {
|
||||
.next, .prev {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
@import 'variables';
|
||||
|
||||
.app-body{
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
}
|
||||
|
||||
.button {
|
||||
@ -49,6 +49,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.column-icon-clear {
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
right: 48px;
|
||||
top: 0;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.column-icon-clear {
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
@ -149,6 +165,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
border-radius: 4px;
|
||||
background: transparent no-repeat;
|
||||
background-position: 50%;
|
||||
background-clip: padding-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lightbox .icon-button {
|
||||
color: $color1;
|
||||
}
|
||||
@ -714,15 +738,7 @@ a.status__content__spoiler-link {
|
||||
|
||||
@media screen and (min-width: 360px) {
|
||||
.columns-area {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.column:first-child, .drawer:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.column:last-child, .drawer:last-child {
|
||||
margin-right: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -730,9 +746,12 @@ a.status__content__spoiler-link {
|
||||
width: 330px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
background: $color1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> .scrollable {
|
||||
background: $color1;
|
||||
}
|
||||
}
|
||||
|
||||
.ui {
|
||||
@ -764,6 +783,58 @@ a.status__content__spoiler-link {
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
|
||||
.column, .drawer {
|
||||
flex: 1 1 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 360px) {
|
||||
.tabs-bar {
|
||||
margin: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.column, .drawer {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.columns-area {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.search__input, .autosuggest-textarea__textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.columns-area {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.column, .drawer {
|
||||
flex: 0 0 auto;
|
||||
padding: 10px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 2560px) {
|
||||
.columns-area {
|
||||
justify-content: center;
|
||||
@ -823,38 +894,6 @@ a.status__content__spoiler-link {
|
||||
}
|
||||
}
|
||||
|
||||
.column, .drawer {
|
||||
margin: 10px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
flex: 0 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.column:first-child, .drawer:first-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.column:last-child, .drawer:last-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.column, .drawer {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.columns-area {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.search__input, .autosuggest-textarea__textarea {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs-bar {
|
||||
display: flex;
|
||||
background: lighten($color1, 8%);
|
||||
@ -895,27 +934,6 @@ a.status__content__spoiler-link {
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 360px) {
|
||||
.columns-area {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.tabs-bar {
|
||||
margin: 10px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.columns-area {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.tabs-bar__link {
|
||||
span {
|
||||
@ -1379,12 +1397,15 @@ button.active i.fa-retweet {
|
||||
|
||||
.empty-column-indicator {
|
||||
color: lighten($color1, 20%);
|
||||
background: $color1;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
padding-top: 100px;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
cursor: default;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
color: $color4;
|
||||
@ -1412,7 +1433,7 @@ button.active i.fa-retweet {
|
||||
.emoji-dialog {
|
||||
width: 280px;
|
||||
height: 220px;
|
||||
background: $color2;
|
||||
background: darken($color3, 10%);
|
||||
box-sizing: border-box;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
|
@ -35,11 +35,11 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def followers
|
||||
@followers = @account.followers.order('follows.created_at desc').paginate(page: params[:page], per_page: 12)
|
||||
@followers = @account.followers.order('follows.created_at desc').page(params[:page]).per(12)
|
||||
end
|
||||
|
||||
def following
|
||||
@following = @account.following.order('follows.created_at desc').paginate(page: params[:page], per_page: 12)
|
||||
@following = @account.following.order('follows.created_at desc').page(params[:page]).per(12)
|
||||
end
|
||||
|
||||
private
|
||||
@ -53,7 +53,7 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def webfinger_account_url
|
||||
webfinger_url(resource: "acct:#{@account.acct}@#{Rails.configuration.x.local_domain}")
|
||||
webfinger_url(resource: @account.to_webfinger_s)
|
||||
end
|
||||
|
||||
def check_account_suspension
|
||||
|
@ -1,51 +1,50 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::AccountsController < ApplicationController
|
||||
before_action :require_admin!
|
||||
before_action :set_account, except: :index
|
||||
module Admin
|
||||
class AccountsController < BaseController
|
||||
before_action :set_account, except: :index
|
||||
|
||||
layout 'admin'
|
||||
def index
|
||||
@accounts = Account.alphabetic.page(params[:page])
|
||||
|
||||
def index
|
||||
@accounts = Account.alphabetic.paginate(page: params[:page], per_page: 40)
|
||||
@accounts = @accounts.local if params[:local].present?
|
||||
@accounts = @accounts.remote if params[:remote].present?
|
||||
@accounts = @accounts.where(domain: params[:by_domain]) if params[:by_domain].present?
|
||||
@accounts = @accounts.silenced if params[:silenced].present?
|
||||
@accounts = @accounts.recent if params[:recent].present?
|
||||
@accounts = @accounts.suspended if params[:suspended].present?
|
||||
end
|
||||
|
||||
@accounts = @accounts.local if params[:local].present?
|
||||
@accounts = @accounts.remote if params[:remote].present?
|
||||
@accounts = @accounts.where(domain: params[:by_domain]) if params[:by_domain].present?
|
||||
@accounts = @accounts.silenced if params[:silenced].present?
|
||||
@accounts = @accounts.recent if params[:recent].present?
|
||||
@accounts = @accounts.suspended if params[:suspended].present?
|
||||
end
|
||||
def show; end
|
||||
|
||||
def show; end
|
||||
def suspend
|
||||
Admin::SuspensionWorker.perform_async(@account.id)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def suspend
|
||||
Admin::SuspensionWorker.perform_async(@account.id)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
def unsuspend
|
||||
@account.update(suspended: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def unsuspend
|
||||
@account.update(suspended: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
def silence
|
||||
@account.update(silenced: true)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def silence
|
||||
@account.update(silenced: true)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
def unsilence
|
||||
@account.update(silenced: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def unsilence
|
||||
@account.update(silenced: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
private
|
||||
|
||||
private
|
||||
def set_account
|
||||
@account = Account.find(params[:id])
|
||||
end
|
||||
|
||||
def set_account
|
||||
@account = Account.find(params[:id])
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:silenced, :suspended)
|
||||
def account_params
|
||||
params.require(:account).permit(:silenced, :suspended)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
9
app/controllers/admin/base_controller.rb
Normal file
9
app/controllers/admin/base_controller.rb
Normal file
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class BaseController < ApplicationController
|
||||
before_action :require_admin!
|
||||
|
||||
layout 'admin'
|
||||
end
|
||||
end
|
@ -1,32 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::DomainBlocksController < ApplicationController
|
||||
before_action :require_admin!
|
||||
module Admin
|
||||
class DomainBlocksController < BaseController
|
||||
def index
|
||||
@blocks = DomainBlock.page(params[:page])
|
||||
end
|
||||
|
||||
layout 'admin'
|
||||
def new
|
||||
@domain_block = DomainBlock.new
|
||||
end
|
||||
|
||||
def index
|
||||
@blocks = DomainBlock.paginate(page: params[:page], per_page: 40)
|
||||
end
|
||||
def create
|
||||
@domain_block = DomainBlock.new(resource_params)
|
||||
|
||||
def new
|
||||
@domain_block = DomainBlock.new
|
||||
end
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
redirect_to admin_domain_blocks_path, notice: 'Domain block is now being processed'
|
||||
else
|
||||
render action: :new
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@domain_block = DomainBlock.new(resource_params)
|
||||
private
|
||||
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
redirect_to admin_domain_blocks_path, notice: 'Domain block is now being processed'
|
||||
else
|
||||
render action: :new
|
||||
def resource_params
|
||||
params.require(:domain_block).permit(:domain, :severity)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:domain_block).permit(:domain, :severity)
|
||||
end
|
||||
end
|
||||
|
@ -1,11 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::PubsubhubbubController < ApplicationController
|
||||
before_action :require_admin!
|
||||
|
||||
layout 'admin'
|
||||
|
||||
def index
|
||||
@subscriptions = Subscription.order('id desc').includes(:account).paginate(page: params[:page], per_page: 40)
|
||||
module Admin
|
||||
class PubsubhubbubController < BaseController
|
||||
def index
|
||||
@subscriptions = Subscription.order('id desc').includes(:account).page(params[:page])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,45 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::ReportsController < ApplicationController
|
||||
before_action :require_admin!
|
||||
before_action :set_report, except: [:index]
|
||||
module Admin
|
||||
class ReportsController < BaseController
|
||||
before_action :set_report, except: [:index]
|
||||
|
||||
layout 'admin'
|
||||
def index
|
||||
@reports = Report.includes(:account, :target_account).order('id desc').page(params[:page])
|
||||
@reports = params[:action_taken].present? ? @reports.resolved : @reports.unresolved
|
||||
end
|
||||
|
||||
def index
|
||||
@reports = Report.includes(:account, :target_account).order('id desc').paginate(page: params[:page], per_page: 40)
|
||||
@reports = params[:action_taken].present? ? @reports.resolved : @reports.unresolved
|
||||
end
|
||||
def show
|
||||
@statuses = Status.where(id: @report.status_ids)
|
||||
end
|
||||
|
||||
def show
|
||||
@statuses = Status.where(id: @report.status_ids)
|
||||
end
|
||||
def resolve
|
||||
@report.update(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def resolve
|
||||
@report.update(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
def suspend
|
||||
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||
Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def suspend
|
||||
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||
Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
def silence
|
||||
@report.target_account.update(silenced: true)
|
||||
Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def silence
|
||||
@report.target_account.update(silenced: true)
|
||||
Report.unresolved.where(target_account: @report.target_account).update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
def remove
|
||||
RemovalWorker.perform_async(params[:status_id])
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def remove
|
||||
RemovalWorker.perform_async(params[:status_id])
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
private
|
||||
|
||||
private
|
||||
|
||||
def set_report
|
||||
@report = Report.find(params[:id])
|
||||
def set_report
|
||||
@report = Report.find(params[:id])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,35 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::SettingsController < ApplicationController
|
||||
before_action :require_admin!
|
||||
|
||||
layout 'admin'
|
||||
|
||||
def index
|
||||
@settings = Setting.all_as_records
|
||||
end
|
||||
|
||||
def update
|
||||
@setting = Setting.where(var: params[:id]).first_or_initialize(var: params[:id])
|
||||
value = settings_params[:value]
|
||||
|
||||
# Special cases
|
||||
value = value == 'true' if @setting.var == 'open_registrations'
|
||||
|
||||
if @setting.value != value
|
||||
@setting.value = value
|
||||
@setting.save
|
||||
module Admin
|
||||
class SettingsController < BaseController
|
||||
def index
|
||||
@settings = Setting.all_as_records
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to admin_settings_path }
|
||||
format.json { respond_with_bip(@setting) }
|
||||
def update
|
||||
@setting = Setting.where(var: params[:id]).first_or_initialize(var: params[:id])
|
||||
value = settings_params[:value]
|
||||
|
||||
# Special cases
|
||||
value = value == 'true' if @setting.var == 'open_registrations'
|
||||
|
||||
if @setting.value != value
|
||||
@setting.value = value
|
||||
@setting.save
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to admin_settings_path }
|
||||
format.json { respond_with_bip(@setting) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def settings_params
|
||||
params.require(:setting).permit(:value)
|
||||
def settings_params
|
||||
params.require(:setting).permit(:value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -9,7 +9,7 @@ class Api::V1::NotificationsController < ApiController
|
||||
DEFAULT_NOTIFICATIONS_LIMIT = 15
|
||||
|
||||
def index
|
||||
@notifications = Notification.where(account: current_account).browserable.paginate_by_max_id(limit_param(DEFAULT_NOTIFICATIONS_LIMIT), params[:max_id], params[:since_id])
|
||||
@notifications = Notification.where(account: current_account).browserable(exclude_types).paginate_by_max_id(limit_param(DEFAULT_NOTIFICATIONS_LIMIT), params[:max_id], params[:since_id])
|
||||
@notifications = cache_collection(@notifications, Notification)
|
||||
statuses = @notifications.select { |n| !n.target_status.nil? }.map(&:target_status)
|
||||
|
||||
@ -32,7 +32,13 @@ class Api::V1::NotificationsController < ApiController
|
||||
|
||||
private
|
||||
|
||||
def exclude_types
|
||||
val = params.permit(exclude_types: [])[:exclude_types] || []
|
||||
val = [val] unless val.is_a?(Enumerable)
|
||||
val
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
params.permit(:limit, exclude_types: []).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
@ -25,7 +25,7 @@ class RemoteFollowController < ApplicationController
|
||||
|
||||
session[:remote_follow] = @remote_follow.acct
|
||||
|
||||
redirect_to Addressable::Template.new(redirect_url_link.template).expand(uri: "#{@account.username}@#{Rails.configuration.x.local_domain}").to_s
|
||||
redirect_to Addressable::Template.new(redirect_url_link.template).expand(uri: @account.to_webfinger_s).to_s
|
||||
else
|
||||
render :new
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ class Settings::ExportsController < ApplicationController
|
||||
def accounts_list_to_csv(list)
|
||||
CSV.generate do |csv|
|
||||
list.each do |account|
|
||||
csv << [(account.local? ? "#{account.username}@#{Rails.configuration.x.local_domain}" : account.acct)]
|
||||
csv << [(account.local? ? account.local_username_and_domain : account.acct)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ class XrdController < ApplicationController
|
||||
|
||||
def webfinger
|
||||
@account = Account.find_local!(username_from_resource)
|
||||
@canonical_account_uri = "acct:#{@account.username}@#{Rails.configuration.x.local_domain}"
|
||||
@canonical_account_uri = @account.to_webfinger_s
|
||||
@magic_key = pem_to_magic_key(@account.keypair.public_key)
|
||||
|
||||
respond_to do |format|
|
||||
|
@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module AccountsHelper
|
||||
def pagination_options
|
||||
{
|
||||
previous_label: safe_join([fa_icon('chevron-left'), t('pagination.prev')], ' '),
|
||||
next_label: safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '),
|
||||
inner_window: 1,
|
||||
outer_window: 0,
|
||||
}
|
||||
end
|
||||
end
|
@ -160,7 +160,7 @@ module AtomBuilderHelper
|
||||
object_type xml, :person
|
||||
uri xml, TagManager.instance.uri_for(account)
|
||||
name xml, account.username
|
||||
email xml, account.local? ? "#{account.acct}@#{Rails.configuration.x.local_domain}" : account.acct
|
||||
email xml, account.local? ? account.local_username_and_domain : account.acct
|
||||
summary xml, account.note
|
||||
link_alternate xml, TagManager.instance.url_for(account)
|
||||
link_avatar xml, account
|
||||
|
@ -20,7 +20,7 @@ class AtomSerializer
|
||||
append_element(author, 'activity:object-type', TagManager::TYPES[:person])
|
||||
append_element(author, 'uri', uri)
|
||||
append_element(author, 'name', account.username)
|
||||
append_element(author, 'email', account.local? ? "#{account.acct}@#{Rails.configuration.x.local_domain}" : account.acct)
|
||||
append_element(author, 'email', account.local? ? account.local_username_and_domain : account.acct)
|
||||
append_element(author, 'summary', account.note)
|
||||
append_element(author, 'link', nil, rel: :alternate, type: 'text/html', href: TagManager.instance.url_for(account))
|
||||
append_element(author, 'link', nil, rel: :avatar, type: account.avatar_content_type, 'media:width': 120, 'media:height': 120, href: full_asset_url(account.avatar.url(:original)))
|
||||
|
@ -66,7 +66,7 @@ class FeedManager
|
||||
timeline_key = key(:home, into_account.id)
|
||||
oldest_home_score = redis.zrange(timeline_key, 0, 0, with_scores: true)&.first&.last&.to_i || 0
|
||||
|
||||
from_account.statuses.select('id').where('id > ?', oldest_home_score).find_in_batches do |statuses|
|
||||
from_account.statuses.select('id').where('id > ?', oldest_home_score).reorder(nil).find_in_batches do |statuses|
|
||||
redis.pipelined do
|
||||
statuses.each do |status|
|
||||
redis.zrem(timeline_key, status.id)
|
||||
|
@ -15,7 +15,6 @@ class Formatter
|
||||
html = status.text
|
||||
html = encode(html)
|
||||
html = simple_format(html, {}, sanitize: false)
|
||||
html = html.gsub(/\n/, '')
|
||||
html = link_urls(html)
|
||||
html = link_mentions(html, status.mentions)
|
||||
html = link_hashtags(html)
|
||||
|
@ -12,12 +12,12 @@ class Account < ApplicationRecord
|
||||
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
||||
|
||||
# Avatar upload
|
||||
has_attached_file :avatar, styles: { original: '120x120#' }, convert_options: { all: '-quality 80 -strip' }
|
||||
has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' }
|
||||
validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES
|
||||
validates_attachment_size :avatar, less_than: 2.megabytes
|
||||
|
||||
# Header upload
|
||||
has_attached_file :header, styles: { original: '700x335#' }, convert_options: { all: '-quality 80 -strip' }
|
||||
has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-quality 80 -strip' }
|
||||
validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES
|
||||
validates_attachment_size :header, less_than: 2.megabytes
|
||||
|
||||
@ -120,6 +120,14 @@ class Account < ApplicationRecord
|
||||
local? ? username : "#{username}@#{domain}"
|
||||
end
|
||||
|
||||
def local_username_and_domain
|
||||
"#{username}@#{Rails.configuration.x.local_domain}"
|
||||
end
|
||||
|
||||
def to_webfinger_s
|
||||
"acct:#{local_username_and_domain}"
|
||||
end
|
||||
|
||||
def subscribed?
|
||||
!subscription_expires_at.blank?
|
||||
end
|
||||
@ -150,6 +158,22 @@ class Account < ApplicationRecord
|
||||
save!
|
||||
end
|
||||
|
||||
def avatar_original_url
|
||||
avatar.url(:original)
|
||||
end
|
||||
|
||||
def avatar_static_url
|
||||
avatar_content_type == 'image/gif' ? avatar.url(:static) : avatar_original_url
|
||||
end
|
||||
|
||||
def header_original_url
|
||||
header.url(:original)
|
||||
end
|
||||
|
||||
def header_static_url
|
||||
header_content_type == 'image/gif' ? header.url(:static) : header_original_url
|
||||
end
|
||||
|
||||
def avatar_remote_url=(url)
|
||||
parsed_url = URI.parse(url)
|
||||
|
||||
@ -284,6 +308,18 @@ class Account < ApplicationRecord
|
||||
def follow_mapping(query, field)
|
||||
query.pluck(field).inject({}) { |mapping, id| mapping[id] = true; mapping }
|
||||
end
|
||||
|
||||
def avatar_styles(file)
|
||||
styles = { original: '120x120#' }
|
||||
styles[:static] = { format: 'png' } if file.content_type == 'image/gif'
|
||||
styles
|
||||
end
|
||||
|
||||
def header_styles(file)
|
||||
styles = { original: '700x335#' }
|
||||
styles[:static] = { format: 'png' } if file.content_type == 'image/gif'
|
||||
styles
|
||||
end
|
||||
end
|
||||
|
||||
before_create do
|
||||
|
@ -16,10 +16,17 @@ class Notification < ApplicationRecord
|
||||
|
||||
validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] }
|
||||
|
||||
TYPE_CLASS_MAP = {
|
||||
mention: 'Mention',
|
||||
reblog: 'Status',
|
||||
follow: 'Follow',
|
||||
follow_request: 'FollowRequest',
|
||||
favourite: 'Favourite',
|
||||
}.freeze
|
||||
|
||||
STATUS_INCLUDES = [:account, :stream_entry, :media_attachments, :tags, mentions: :account, reblog: [:stream_entry, :account, :media_attachments, :tags, mentions: :account]].freeze
|
||||
|
||||
scope :cache_ids, -> { select(:id, :updated_at, :activity_type, :activity_id) }
|
||||
scope :browserable, -> { where.not(activity_type: ['FollowRequest']) }
|
||||
|
||||
cache_associated :from_account, status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account
|
||||
|
||||
@ -28,12 +35,7 @@ class Notification < ApplicationRecord
|
||||
end
|
||||
|
||||
def type
|
||||
case activity_type
|
||||
when 'Status'
|
||||
:reblog
|
||||
else
|
||||
activity_type.underscore.to_sym
|
||||
end
|
||||
@type ||= TYPE_CLASS_MAP.invert[activity_type].to_sym
|
||||
end
|
||||
|
||||
def target_status
|
||||
@ -50,6 +52,11 @@ class Notification < ApplicationRecord
|
||||
end
|
||||
|
||||
class << self
|
||||
def browserable(types = [])
|
||||
types.concat([:follow_request])
|
||||
where.not(activity_type: activity_types_from_types(types))
|
||||
end
|
||||
|
||||
def reload_stale_associations!(cached_items)
|
||||
account_ids = cached_items.map(&:from_account_id).uniq
|
||||
accounts = Account.where(id: account_ids).map { |a| [a.id, a] }.to_h
|
||||
@ -58,6 +65,12 @@ class Notification < ApplicationRecord
|
||||
item.from_account = accounts[item.from_account_id]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def activity_types_from_types(types)
|
||||
types.map { |type| TYPE_CLASS_MAP[type.to_sym] }.compact
|
||||
end
|
||||
end
|
||||
|
||||
after_initialize :set_from_account
|
||||
|
@ -9,4 +9,4 @@
|
||||
- else
|
||||
= render partial: 'grid_card', collection: @followers, as: :account, cached: true
|
||||
|
||||
= will_paginate @followers, pagination_options
|
||||
= paginate @followers
|
||||
|
@ -9,4 +9,4 @@
|
||||
- else
|
||||
= render partial: 'grid_card', collection: @following, as: :account, cached: true
|
||||
|
||||
= will_paginate @following, pagination_options
|
||||
= paginate @following
|
||||
|
@ -31,4 +31,4 @@
|
||||
|
||||
.pagination
|
||||
- if @statuses.size == 20
|
||||
= link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), short_account_url(@account, max_id: @statuses.last.id), class: 'next_page', rel: 'next'
|
||||
= link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), short_account_url(@account, max_id: @statuses.last.id), class: 'next', rel: 'next'
|
||||
|
@ -46,4 +46,4 @@
|
||||
= table_link_to 'globe', 'Public', TagManager.instance.url_for(account)
|
||||
= table_link_to 'pencil', 'Edit', admin_account_path(account.id)
|
||||
|
||||
= will_paginate @accounts, pagination_options
|
||||
= paginate @accounts
|
||||
|
@ -13,5 +13,5 @@
|
||||
%samp= block.domain
|
||||
%td= block.severity
|
||||
|
||||
= will_paginate @blocks, pagination_options
|
||||
= paginate @blocks
|
||||
= link_to 'Add new', new_admin_domain_block_path, class: 'button'
|
||||
|
@ -26,4 +26,4 @@
|
||||
- else
|
||||
= l subscription.last_successful_delivery_at
|
||||
|
||||
= will_paginate @subscriptions, pagination_options
|
||||
= paginate @subscriptions
|
||||
|
@ -29,4 +29,4 @@
|
||||
%td= truncate(report.comment, length: 30, separator: ' ')
|
||||
%td= table_link_to 'circle', 'View', admin_report_path(report)
|
||||
|
||||
= will_paginate @reports, pagination_options
|
||||
= paginate @reports
|
||||
|
@ -4,8 +4,9 @@ attributes :id, :username, :acct, :display_name, :locked, :created_at
|
||||
|
||||
node(:note) { |account| Formatter.instance.simplified_format(account) }
|
||||
node(:url) { |account| TagManager.instance.url_for(account) }
|
||||
node(:avatar) { |account| full_asset_url(account.avatar.url(:original)) }
|
||||
node(:header) { |account| full_asset_url(account.header.url(:original)) }
|
||||
node(:followers_count) { |account| defined?(@followers_counts_map) ? (@followers_counts_map[account.id] || 0) : account.followers_count }
|
||||
node(:following_count) { |account| defined?(@following_counts_map) ? (@following_counts_map[account.id] || 0) : account.following_count }
|
||||
node(:statuses_count) { |account| defined?(@statuses_counts_map) ? (@statuses_counts_map[account.id] || 0) : account.statuses_count }
|
||||
node(:avatar) { |account| full_asset_url(account.avatar_original_url) }
|
||||
node(:avatar_static) { |account| full_asset_url(account.avatar_static_url) }
|
||||
node(:header) { |account| full_asset_url(account.header_original_url) }
|
||||
node(:header_static) { |account| full_asset_url(account.header_static_url) }
|
||||
|
||||
attributes :followers_count, :following_count, :statuses_count
|
||||
|
9
app/views/kaminari/_next_page.html.haml
Normal file
9
app/views/kaminari/_next_page.html.haml
Normal file
@ -0,0 +1,9 @@
|
||||
-# Link to the "Next" page
|
||||
-# available local variables
|
||||
-# url: url to the next page
|
||||
-# current_page: a page object for the currently displayed page
|
||||
-# total_pages: total number of pages
|
||||
-# per_page: number of items to fetch per page
|
||||
-# remote: data-remote
|
||||
%span.next
|
||||
= link_to_unless current_page.last?, safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), url, rel: 'next', remote: remote
|
16
app/views/kaminari/_paginator.html.haml
Normal file
16
app/views/kaminari/_paginator.html.haml
Normal file
@ -0,0 +1,16 @@
|
||||
-# The container tag
|
||||
-# available local variables
|
||||
-# current_page: a page object for the currently displayed page
|
||||
-# total_pages: total number of pages
|
||||
-# per_page: number of items to fetch per page
|
||||
-# remote: data-remote
|
||||
-# paginator: the paginator that renders the pagination tags inside
|
||||
= paginator.render do
|
||||
%nav.pagination
|
||||
= prev_page_tag unless current_page.first?
|
||||
- each_page do |page|
|
||||
- if page.display_tag?
|
||||
= page_tag page
|
||||
- elsif !page.was_truncated?
|
||||
= gap_tag
|
||||
= next_page_tag unless current_page.last?
|
9
app/views/kaminari/_prev_page.html.haml
Normal file
9
app/views/kaminari/_prev_page.html.haml
Normal file
@ -0,0 +1,9 @@
|
||||
-# Link to the "Previous" page
|
||||
-# available local variables
|
||||
-# url: url to the previous page
|
||||
-# current_page: a page object for the currently displayed page
|
||||
-# total_pages: total number of pages
|
||||
-# per_page: number of items to fetch per page
|
||||
-# remote: data-remote
|
||||
%span.prev
|
||||
= link_to_unless current_page.first?, safe_join([fa_icon('chevron-left'), t('pagination.prev')], ' '), url, rel: 'prev', remote: remote
|
@ -1,2 +1,5 @@
|
||||
.landing-strip
|
||||
= t('landing_strip_html', name: display_name(account), domain: Rails.configuration.x.local_domain, sign_up_path: new_user_registration_path)
|
||||
= t('landing_strip_html',
|
||||
name: content_tag(:span, display_name(account), class: :emojify),
|
||||
domain: Rails.configuration.x.local_domain,
|
||||
sign_up_path: new_user_registration_path)
|
||||
|
@ -13,7 +13,7 @@
|
||||
= fa_icon('retweet fw')
|
||||
%span
|
||||
= link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do
|
||||
%strong= display_name(status.account)
|
||||
%strong.emojify= display_name(status.account)
|
||||
= t('stream_entries.reblogged')
|
||||
|
||||
= render partial: centered ? 'stream_entries/detailed_status' : 'stream_entries/simple_status', locals: { status: status.proper }
|
||||
|
@ -15,4 +15,4 @@
|
||||
|
||||
- if @statuses.size == 20
|
||||
.pagination
|
||||
= link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), tag_url(@tag, max_id: @statuses.last.id), class: 'next_page', rel: 'next'
|
||||
= link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), tag_url(@tag, max_id: @statuses.last.id), class: 'next', rel: 'next'
|
||||
|
@ -99,7 +99,9 @@ Rails.application.configure do
|
||||
:user_name => ENV['SMTP_LOGIN'],
|
||||
:password => ENV['SMTP_PASSWORD'],
|
||||
:domain => ENV['SMTP_DOMAIN'] || config.x.local_domain,
|
||||
:authentication => :plain,
|
||||
:authentication => ENV['SMTP_AUTH_METHOD'] || :plain,
|
||||
:openssl_verify_mode => ENV['SMTP_OPENSSL_VERIFY_MODE'] || 'peer',
|
||||
:enable_starttls_auto => ENV['SMTP_ENABLE_STARTTLS_AUTO'] || true,
|
||||
}
|
||||
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
|
@ -33,7 +33,7 @@ search:
|
||||
|
||||
ignore_unused:
|
||||
- 'activerecord.attributes.*'
|
||||
- '{devise,will_paginate,doorkeeper}.*'
|
||||
- '{devise,pagination,doorkeeper}.*'
|
||||
- '{datetime,time}.*'
|
||||
- 'simple_form.{yes,no}'
|
||||
- 'simple_form.{placeholders,hints,labels}.*'
|
||||
|
@ -74,7 +74,8 @@ Devise.setup do |config|
|
||||
# It will change confirmation, password recovery and other workflows
|
||||
# to behave the same regardless if the e-mail provided was right or wrong.
|
||||
# Does not affect registerable.
|
||||
# config.paranoid = true
|
||||
# See : https://github.com/plataformatec/devise/wiki/How-To:-Using-paranoid-mode,-avoid-user-enumeration-on-registerable
|
||||
config.paranoid = true
|
||||
|
||||
# By default Devise will store the user in session. You can skip storage for
|
||||
# particular strategies by setting this option.
|
||||
|
@ -1,3 +1,5 @@
|
||||
HttpLog.options[:logger] = Rails.logger
|
||||
HttpLog.options[:color] = { color: :yellow }
|
||||
HttpLog.options[:compact_log] = true
|
||||
HttpLog.configure do |config|
|
||||
config.logger = Rails.logger
|
||||
config.color = { color: :yellow }
|
||||
config.compact_log = true
|
||||
end
|
||||
|
7
config/initializers/kaminari_config.rb
Normal file
7
config/initializers/kaminari_config.rb
Normal file
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
Kaminari.configure do |config|
|
||||
config.default_per_page = 40
|
||||
config.window = 1
|
||||
config.left = 3
|
||||
config.right = 1
|
||||
end
|
0
config/initializers/pagination.rb
Normal file
0
config/initializers/pagination.rb
Normal file
@ -88,5 +88,3 @@ de:
|
||||
default: "%d.%m.%Y %H:%M"
|
||||
users:
|
||||
invalid_email: Inkorrekte E-mail-Addresse
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -126,6 +126,7 @@ en:
|
||||
pagination:
|
||||
next: Next
|
||||
prev: Prev
|
||||
truncate: "…"
|
||||
remote_follow:
|
||||
acct: Enter your username@domain you want to follow from
|
||||
missing_resource: Could not find the required redirect URL for your account
|
||||
@ -169,5 +170,3 @@ en:
|
||||
users:
|
||||
invalid_email: The e-mail address is invalid
|
||||
invalid_otp_token: Invalid two-factor code
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -160,5 +160,3 @@ eo:
|
||||
users:
|
||||
invalid_email: La retpoŝt-adreso ne estas valida
|
||||
invalid_otp_token: La dufaktora aŭtentigila kodo ne estas valida
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -51,5 +51,3 @@ es:
|
||||
settings:
|
||||
edit_profile: Editar perfil
|
||||
preferences: Preferencias
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -160,5 +160,3 @@ fi:
|
||||
users:
|
||||
invalid_email: Virheellinen sähköposti
|
||||
invalid_otp_token: Virheellinen kaksivaihe tunnistus koodi
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -167,5 +167,3 @@ fr:
|
||||
users:
|
||||
invalid_email: L'adresse courriel est invalide
|
||||
invalid_otp_token: Le code d'authentification à deux facteurs est invalide
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -51,5 +51,3 @@ hu:
|
||||
settings:
|
||||
edit_profile: Profil szerkesztése
|
||||
preferences: Beállítások
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -160,5 +160,3 @@
|
||||
users:
|
||||
invalid_email: E-post addressen er ugyldig
|
||||
invalid_otp_token: Ugyldig two-faktor kode
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -51,5 +51,3 @@ pt:
|
||||
settings:
|
||||
edit_profile: Editar perfil
|
||||
preferences: Preferências
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -161,5 +161,3 @@ ru:
|
||||
users:
|
||||
invalid_email: Введенный e-mail неверен
|
||||
invalid_otp_token: Введен неверный код
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -51,5 +51,3 @@ uk:
|
||||
settings:
|
||||
edit_profile: Редагувати профіль
|
||||
preferences: Налаштування
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -150,5 +150,3 @@ zh-CN:
|
||||
users:
|
||||
invalid_email: 无效的邮箱
|
||||
invalid_otp_token: 无效的两步验证码
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
@ -1,11 +1,20 @@
|
||||
version: '2'
|
||||
services:
|
||||
|
||||
db:
|
||||
restart: always
|
||||
image: postgres:alpine
|
||||
### Uncomment to enable DB persistance
|
||||
# volumes:
|
||||
# - ./postgres:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
restart: always
|
||||
image: redis:alpine
|
||||
### Uncomment to enable REDIS persistance
|
||||
# volumes:
|
||||
# - ./redis:/data
|
||||
|
||||
web:
|
||||
restart: always
|
||||
build: .
|
||||
@ -19,6 +28,7 @@ services:
|
||||
volumes:
|
||||
- ./public/assets:/mastodon/public/assets
|
||||
- ./public/system:/mastodon/public/system
|
||||
|
||||
streaming:
|
||||
restart: always
|
||||
build: .
|
||||
@ -29,6 +39,7 @@ services:
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
|
||||
sidekiq:
|
||||
restart: always
|
||||
build: .
|
||||
|
@ -34,10 +34,19 @@ server {
|
||||
keepalive_timeout 70;
|
||||
sendfile on;
|
||||
client_max_body_size 0;
|
||||
gzip off;
|
||||
|
||||
root /home/mastodon/live/public;
|
||||
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
|
||||
|
||||
location / {
|
||||
@ -49,7 +58,7 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
|
||||
proxy_set_header Proxy "";
|
||||
proxy_pass_header Server;
|
||||
|
||||
proxy_pass http://localhost:3000;
|
||||
@ -67,6 +76,7 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Proxy "";
|
||||
|
||||
proxy_pass http://localhost:4000;
|
||||
proxy_buffering off;
|
||||
@ -121,7 +131,7 @@ It is recommended to use rbenv (exclusively from the `mastodon` user) to install
|
||||
[2]: https://github.com/rbenv/ruby-build#installation
|
||||
[3]: https://github.com/rbenv/ruby-build/wiki#suggested-build-environment
|
||||
|
||||
Then once `rbenv` is ready, run `rbenv install 2.3.1` to install the Ruby version for Mastodon.
|
||||
Then once `rbenv` is ready, run `rbenv install 2.4.1` to install the Ruby version for Mastodon.
|
||||
|
||||
## Git
|
||||
|
||||
|
@ -14,5 +14,6 @@ Some people have started working on apps for the Mastodon API. Here is a list of
|
||||
|Tooter|Chrome|<https://github.com/ineffyble/tooter>|[@effy@mastodon.social](https://mastodon.social/users/effy)|
|
||||
|tootstream|CLI|<https://github.com/magicalraccoon/tootstream>|[@Raccoon@mastodon.social](https://mastodon.social/users/Raccoon)|
|
||||
|HackerNewsBot|CLI|<https://github.com/raymestalez/mastodon-hnbot>|[@rayalez@hackertribe.io](https://hackertribe.io/users/rayalez)|
|
||||
|Mastodon.tools|Wordpress, web browser, social network|<https://github.com/davidlibeau/mastodon-tools>|[@David@mastodon.xyz](https://mastodon.xyz/users/David)|
|
||||
|
||||
If you have a project like this, let me know so I can add it to the list!
|
||||
|
@ -76,7 +76,7 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz)
|
||||
| [mastodon.fun](https://mastodon.fun/)|Mastodon for everyone ! |Yes|Yes|
|
||||
| [oulipo.social](https://oulipo.social/)|An Oulipo Mastodon in which that fifth symbol in Latin script is taboo|Yes|No|
|
||||
| [indigo.zone](https://indigo.zone)|Open Registrations, General Purpose|Yes|No|
|
||||
| [mastodon.cloud](https://mastodon.cloud)|An open Mastodon instance with people from all around the world|Yes|Yes|
|
||||
| [mst3k.interlinked.me](https://mst3k.interlinked.me)|Open registrations, general purpose|Yes|Yes|
|
||||
|
||||
|
||||
We are no longer maintaining this list as instances are popping up too quickly for using GitHub to be a tenable system for tracking them. Please standby while we work on another solution
|
||||
|
@ -362,15 +362,15 @@ Returns an empty object.
|
||||
|
||||
#### Reblogging/unreblogging a status:
|
||||
|
||||
POST /api/vi/statuses/:id/reblog
|
||||
POST /api/vi/statuses/:id/unreblog
|
||||
POST /api/v1/statuses/:id/reblog
|
||||
POST /api/v1/statuses/:id/unreblog
|
||||
|
||||
Returns the target [Status](#status).
|
||||
|
||||
#### Favouriting/unfavouriting a status:
|
||||
|
||||
POST /api/vi/statuses/:id/favourite
|
||||
POST /api/vi/statuses/:id/unfavourite
|
||||
POST /api/v1/statuses/:id/favourite
|
||||
POST /api/v1/statuses/:id/unfavourite
|
||||
|
||||
Returns the target [Status](#status).
|
||||
|
||||
|
@ -13,10 +13,13 @@ namespace :mastodon do
|
||||
desc 'Manually confirms a user with associated user email address stored in USER_EMAIL environment variable.'
|
||||
task confirm_email: :environment do
|
||||
email = ENV.fetch('USER_EMAIL')
|
||||
user = User.where(email: email)
|
||||
user.update(confirmed_at: Time.now.utc)
|
||||
|
||||
puts "User #{email} confirmed."
|
||||
user = User.where(email: email).first
|
||||
if user
|
||||
user.update(confirmed_at: Time.now.utc)
|
||||
puts "User #{email} confirmed."
|
||||
else
|
||||
abort "User #{email} not found."
|
||||
end
|
||||
end
|
||||
|
||||
namespace :media do
|
||||
@ -89,5 +92,17 @@ namespace :mastodon do
|
||||
|
||||
Rails.logger.debug 'Done!'
|
||||
end
|
||||
|
||||
desc 'Generate static versions of GIF avatars/headers'
|
||||
task add_static_avatars: :environment do
|
||||
Rails.logger.debug 'Generating static avatars/headers for GIF ones...'
|
||||
|
||||
Account.unscoped.where(avatar_content_type: 'image/gif').or(Account.unscoped.where(header_content_type: 'image/gif')).find_each do |account|
|
||||
account.avatar.reprocess!
|
||||
account.header.reprocess!
|
||||
end
|
||||
|
||||
Rails.logger.debug 'Done!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -72,5 +72,10 @@
|
||||
"webpack": "^2.2.1",
|
||||
"websocket.js": "^0.1.7",
|
||||
"ws": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^7.2.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-plugin-react": "^6.10.3"
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,18 @@
|
||||
"description": "Address to send emails from",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_AUTH_METHOD": {
|
||||
"description": "Authentication method to use with SMTP server. Default is 'plain'.",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_OPENSSL_VERIFY_MODE": {
|
||||
"description": "SMTP server certificate verification mode. Defaults is 'peer'.",
|
||||
"required": false
|
||||
},
|
||||
"SMTP_ENABLE_STARTTLS_AUTO": {
|
||||
"description": "Enable STARTTLS if SMTP server supports it? Default is true.",
|
||||
"required": false
|
||||
},
|
||||
"BUILDPACK_URL": {
|
||||
"description": "Internal scalingo configuration",
|
||||
"required": true,
|
||||
|
14
spec/controllers/admin/reports_controller_spec.rb
Normal file
14
spec/controllers/admin/reports_controller_spec.rb
Normal file
@ -0,0 +1,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::ReportsController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
sign_in Fabricate(:user, admin: true), scope: :user
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
14
spec/controllers/admin/settings_controller_spec.rb
Normal file
14
spec/controllers/admin/settings_controller_spec.rb
Normal file
@ -0,0 +1,14 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Admin::SettingsController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
before do
|
||||
sign_in Fabricate(:user, admin: true), scope: :user
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
@ -5,15 +5,71 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do
|
||||
|
||||
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
|
||||
let(:token) { double acceptable?: true, resource_owner_id: user.id }
|
||||
let(:other) { Fabricate(:user, account: Fabricate(:account, username: 'bob')) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(:success)
|
||||
before do
|
||||
status = PostStatusService.new.call(user.account, 'Test')
|
||||
@reblog = ReblogService.new.call(other.account, status)
|
||||
@mention = PostStatusService.new.call(other.account, 'Hello @alice')
|
||||
@favourite = FavouriteService.new.call(other.account, status)
|
||||
@follow = FollowService.new.call(other.account, 'alice')
|
||||
end
|
||||
|
||||
describe 'with no options' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'includes reblog' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@reblog.id)
|
||||
end
|
||||
|
||||
it 'includes mention' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@mention.mentions.first.id)
|
||||
end
|
||||
|
||||
it 'includes favourite' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@favourite.id)
|
||||
end
|
||||
|
||||
it 'includes follow' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@follow.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with excluded mentions' do
|
||||
before do
|
||||
get :index, params: { exclude_types: ['mention'] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'includes reblog' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@reblog.id)
|
||||
end
|
||||
|
||||
it 'excludes mention' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to_not include(@mention.mentions.first.id)
|
||||
end
|
||||
|
||||
it 'includes favourite' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@favourite.id)
|
||||
end
|
||||
|
||||
it 'includes follow' do
|
||||
expect(assigns(:notifications).map(&:activity_id)).to include(@follow.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ RSpec.describe XrdController, type: :controller do
|
||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it 'returns http success when account can be found' do
|
||||
get :webfinger, params: { resource: "acct:#{alice.username}@#{Rails.configuration.x.local_domain}" }
|
||||
get :webfinger, params: { resource: alice.to_webfinger_s }
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
|
BIN
spec/fixtures/files/avatar.gif
vendored
Normal file
BIN
spec/fixtures/files/avatar.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
@ -1,5 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountsHelper, type: :helper do
|
||||
|
||||
end
|
@ -6,16 +6,10 @@ import Avatar from '../../../app/assets/javascripts/components/components/avatar
|
||||
describe('<Avatar />', () => {
|
||||
const src = '/path/to/image.jpg';
|
||||
const size = 100;
|
||||
const wrapper = render(<Avatar src={src} size={size} />);
|
||||
const wrapper = render(<Avatar src={src} animate size={size} />);
|
||||
|
||||
it('renders an img element with the given src', () => {
|
||||
expect(wrapper.find('img')).to.have.attr('src', `${src}`);
|
||||
});
|
||||
|
||||
it('renders an img element of the given size', () => {
|
||||
['width', 'height'].map((attr) => {
|
||||
expect(wrapper.find('img')).to.have.attr(attr, `${size}`);
|
||||
});
|
||||
it('renders a div element with the given src as background', () => {
|
||||
expect(wrapper.find('div')).to.have.style('background-image', `url(${src})`);
|
||||
});
|
||||
|
||||
it('renders a div element of the given size', () => {
|
||||
|
@ -54,6 +54,30 @@ RSpec.describe Account, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Local domain user methods' do
|
||||
around do |example|
|
||||
before = Rails.configuration.x.local_domain
|
||||
example.run
|
||||
Rails.configuration.x.local_domain = before
|
||||
end
|
||||
|
||||
describe '#to_webfinger_s' do
|
||||
it 'returns a webfinger string for the account' do
|
||||
Rails.configuration.x.local_domain = 'example.com'
|
||||
|
||||
expect(subject.to_webfinger_s).to eq 'acct:alice@example.com'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#local_username_and_domain' do
|
||||
it 'returns the username and local domain for the account' do
|
||||
Rails.configuration.x.local_domain = 'example.com'
|
||||
|
||||
expect(subject.local_username_and_domain).to eq 'alice@example.com'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#acct' do
|
||||
it 'returns username for local users' do
|
||||
expect(subject.acct).to eql 'alice'
|
||||
@ -397,4 +421,24 @@ RSpec.describe Account, type: :model do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'static avatars' do
|
||||
describe 'when GIF' do
|
||||
it 'creates a png static style' do
|
||||
subject.avatar = attachment_fixture('avatar.gif')
|
||||
subject.save
|
||||
|
||||
expect(subject.avatar_static_url).to_not eq subject.avatar_original_url
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when non-GIF' do
|
||||
it 'does not create extra static style' do
|
||||
subject.avatar = attachment_fixture('attachment.jpg')
|
||||
subject.save
|
||||
|
||||
expect(subject.avatar_static_url).to eq subject.avatar_original_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -87,21 +87,24 @@ const setRequestId = (req, res, next) => {
|
||||
const accountFromToken = (token, req, next) => {
|
||||
pgPool.connect((err, client, done) => {
|
||||
if (err) {
|
||||
return next(err)
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
|
||||
client.query('SELECT oauth_access_tokens.resource_owner_id, users.account_id FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 LIMIT 1', [token], (err, result) => {
|
||||
done()
|
||||
|
||||
if (err) {
|
||||
return next(err)
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
err = new Error('Invalid access token')
|
||||
err.statusCode = 401
|
||||
|
||||
return next(err)
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
|
||||
req.accountId = result.rows[0].account_id
|
||||
@ -113,7 +116,8 @@ const accountFromToken = (token, req, next) => {
|
||||
|
||||
const authenticationMiddleware = (req, res, next) => {
|
||||
if (req.method === 'OPTIONS') {
|
||||
return next()
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
const authorization = req.get('Authorization')
|
||||
@ -122,7 +126,8 @@ const authenticationMiddleware = (req, res, next) => {
|
||||
const err = new Error('Missing access token')
|
||||
err.statusCode = 401
|
||||
|
||||
return next(err)
|
||||
next(err)
|
||||
return
|
||||
}
|
||||
|
||||
const token = authorization.replace(/^Bearer /, '')
|
||||
|
486
yarn.lock
486
yarn.lock
@ -140,6 +140,12 @@ acorn-globals@^3.1.0:
|
||||
dependencies:
|
||||
acorn "^4.0.4"
|
||||
|
||||
acorn-jsx@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
|
||||
dependencies:
|
||||
acorn "^3.0.4"
|
||||
|
||||
acorn@^1.0.3:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014"
|
||||
@ -148,7 +154,7 @@ acorn@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7"
|
||||
|
||||
acorn@^3.0.0:
|
||||
acorn@^3.0.0, acorn@^3.0.4:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
|
||||
|
||||
@ -156,6 +162,10 @@ acorn@^4.0.3, acorn@^4.0.4:
|
||||
version "4.0.11"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0"
|
||||
|
||||
acorn@^5.0.1:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
|
||||
|
||||
airbnb-js-shims@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-1.0.1.tgz#7d5a7d772c8c6fdeb624ea3cef62506091b180b5"
|
||||
@ -169,7 +179,7 @@ airbnb-js-shims@^1.0.1:
|
||||
string.prototype.padend "^3.0.0"
|
||||
string.prototype.padstart "^3.0.0"
|
||||
|
||||
ajv-keywords@^1.1.1:
|
||||
ajv-keywords@^1.0.0, ajv-keywords@^1.1.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
|
||||
|
||||
@ -196,6 +206,10 @@ amdefine@>=0.0.4:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.0.tgz#fd17474700cb5cc9c2b709f0be9d23ce3c198c33"
|
||||
|
||||
ansi-escapes@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
|
||||
|
||||
ansi-html@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e"
|
||||
@ -284,10 +298,27 @@ array-reduce@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
||||
|
||||
array-union@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
|
||||
dependencies:
|
||||
array-uniq "^1.0.1"
|
||||
|
||||
array-uniq@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
|
||||
|
||||
array-unique@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
|
||||
|
||||
array.prototype.find@^2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90"
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
es-abstract "^1.7.0"
|
||||
|
||||
arrify@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||
@ -424,7 +455,7 @@ babel-code-frame@^6.11.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^2.0.0"
|
||||
|
||||
babel-code-frame@^6.22.0:
|
||||
babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
|
||||
dependencies:
|
||||
@ -480,6 +511,15 @@ babel-core@^6.11.4:
|
||||
slash "^1.0.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
babel-eslint@^7.2.1:
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.1.tgz#079422eb73ba811e3ca0865ce87af29327f8c52f"
|
||||
dependencies:
|
||||
babel-code-frame "^6.22.0"
|
||||
babel-traverse "^6.23.1"
|
||||
babel-types "^6.23.0"
|
||||
babylon "^6.16.1"
|
||||
|
||||
babel-generator@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.22.0.tgz#d642bf4961911a8adc7c692b0c9297f325cda805"
|
||||
@ -1302,6 +1342,10 @@ babylon@^6.15.0:
|
||||
version "6.15.0"
|
||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e"
|
||||
|
||||
babylon@^6.16.1:
|
||||
version "6.16.1"
|
||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
|
||||
|
||||
babylon@~5.8.3:
|
||||
version "5.8.38"
|
||||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd"
|
||||
@ -1586,6 +1630,16 @@ cached-path-relative@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7"
|
||||
|
||||
caller-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
|
||||
dependencies:
|
||||
callsites "^0.2.0"
|
||||
|
||||
callsites@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
|
||||
|
||||
camelcase-keys@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
|
||||
@ -1639,7 +1693,7 @@ chai@^3.5.0:
|
||||
deep-eql "^0.1.3"
|
||||
type-detect "^1.0.0"
|
||||
|
||||
chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
dependencies:
|
||||
@ -1695,6 +1749,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1:
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
|
||||
circular-json@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
|
||||
|
||||
clap@^1.0.9:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.1.tgz#a8a93e0bfb7581ac199c4f001a5525a724ce696d"
|
||||
@ -1705,6 +1763,16 @@ classnames@^2.1.2, classnames@^2.2.3, classnames@~2.2:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
|
||||
|
||||
cli-cursor@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
|
||||
dependencies:
|
||||
restore-cursor "^1.0.1"
|
||||
|
||||
cli-width@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
|
||||
|
||||
cliui@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
|
||||
@ -1824,7 +1892,7 @@ concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
concat-stream@^1.4.7, concat-stream@~1.5.0, concat-stream@~1.5.1:
|
||||
concat-stream@^1.4.7, concat-stream@^1.5.2, concat-stream@~1.5.0, concat-stream@~1.5.1:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
|
||||
dependencies:
|
||||
@ -2085,6 +2153,12 @@ currently-unhandled@^0.4.1:
|
||||
dependencies:
|
||||
array-find-index "^1.0.1"
|
||||
|
||||
d@1:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
|
||||
dependencies:
|
||||
es5-ext "^0.10.9"
|
||||
|
||||
d@^0.1.1, d@~0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309"
|
||||
@ -2140,6 +2214,18 @@ defined@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||
|
||||
del@^2.0.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
|
||||
dependencies:
|
||||
globby "^5.0.0"
|
||||
is-path-cwd "^1.0.0"
|
||||
is-path-in-cwd "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
@ -2197,6 +2283,13 @@ diffie-hellman@^5.0.0:
|
||||
miller-rabin "^4.0.0"
|
||||
randombytes "^2.0.0"
|
||||
|
||||
doctrine@^1.2.2:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
doctrine@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
|
||||
@ -2377,6 +2470,15 @@ es-abstract@^1.3.2, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1:
|
||||
is-callable "^1.1.3"
|
||||
is-regex "^1.0.3"
|
||||
|
||||
es-abstract@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
|
||||
dependencies:
|
||||
es-to-primitive "^1.1.1"
|
||||
function-bind "^1.1.0"
|
||||
is-callable "^1.1.3"
|
||||
is-regex "^1.0.3"
|
||||
|
||||
es-to-primitive@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
|
||||
@ -2385,6 +2487,13 @@ es-to-primitive@^1.1.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.1"
|
||||
|
||||
es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
|
||||
version "0.10.15"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6"
|
||||
dependencies:
|
||||
es6-iterator "2"
|
||||
es6-symbol "~3.1"
|
||||
|
||||
es5-ext@^0.10.7, es5-ext@~0.10.11, es5-ext@~0.10.2:
|
||||
version "0.10.12"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047"
|
||||
@ -2404,10 +2513,39 @@ es6-iterator@2:
|
||||
es5-ext "^0.10.7"
|
||||
es6-symbol "3"
|
||||
|
||||
es6-iterator@^2.0.1, es6-iterator@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.14"
|
||||
es6-symbol "^3.1"
|
||||
|
||||
es6-map@^0.1.3:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
es6-iterator "~2.0.1"
|
||||
es6-set "~0.1.5"
|
||||
es6-symbol "~3.1.1"
|
||||
event-emitter "~0.3.5"
|
||||
|
||||
es6-promise@^3.2.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
|
||||
|
||||
es6-set@~0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
es6-iterator "~2.0.1"
|
||||
es6-symbol "3.1.1"
|
||||
event-emitter "~0.3.5"
|
||||
|
||||
es6-shim@^0.35.1:
|
||||
version "0.35.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.1.tgz#a23524009005b031ab4a352ac196dfdfd1144ab7"
|
||||
@ -2419,6 +2557,22 @@ es6-symbol@3, es6-symbol@^3.0.2, es6-symbol@~3.1:
|
||||
d "~0.1.1"
|
||||
es5-ext "~0.10.11"
|
||||
|
||||
es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
es6-weak-map@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.14"
|
||||
es6-iterator "^2.0.1"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
escape-html@^1.0.3, escape-html@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
@ -2438,6 +2592,72 @@ escodegen@^1.6.1:
|
||||
optionalDependencies:
|
||||
source-map "~0.2.0"
|
||||
|
||||
escope@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
|
||||
dependencies:
|
||||
es6-map "^0.1.3"
|
||||
es6-weak-map "^2.0.1"
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-plugin-react@^6.10.3:
|
||||
version "6.10.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78"
|
||||
dependencies:
|
||||
array.prototype.find "^2.0.1"
|
||||
doctrine "^1.2.2"
|
||||
has "^1.0.1"
|
||||
jsx-ast-utils "^1.3.4"
|
||||
object.assign "^4.0.4"
|
||||
|
||||
eslint@^3.19.0:
|
||||
version "3.19.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
|
||||
dependencies:
|
||||
babel-code-frame "^6.16.0"
|
||||
chalk "^1.1.3"
|
||||
concat-stream "^1.5.2"
|
||||
debug "^2.1.1"
|
||||
doctrine "^2.0.0"
|
||||
escope "^3.6.0"
|
||||
espree "^3.4.0"
|
||||
esquery "^1.0.0"
|
||||
estraverse "^4.2.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^2.0.0"
|
||||
glob "^7.0.3"
|
||||
globals "^9.14.0"
|
||||
ignore "^3.2.0"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^0.12.0"
|
||||
is-my-json-valid "^2.10.0"
|
||||
is-resolvable "^1.0.0"
|
||||
js-yaml "^3.5.1"
|
||||
json-stable-stringify "^1.0.0"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.0.0"
|
||||
mkdirp "^0.5.0"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.2"
|
||||
path-is-inside "^1.0.1"
|
||||
pluralize "^1.2.1"
|
||||
progress "^1.1.8"
|
||||
require-uncached "^1.0.2"
|
||||
shelljs "^0.7.5"
|
||||
strip-bom "^3.0.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
table "^3.7.8"
|
||||
text-table "~0.2.0"
|
||||
user-home "^2.0.0"
|
||||
|
||||
espree@^3.4.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2"
|
||||
dependencies:
|
||||
acorn "^5.0.1"
|
||||
acorn-jsx "^3.0.0"
|
||||
|
||||
esprima@^2.6.0, esprima@^2.7.1:
|
||||
version "2.7.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
||||
@ -2446,10 +2666,31 @@ esprima@~3.1.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||
|
||||
esquery@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
|
||||
dependencies:
|
||||
estraverse "^4.0.0"
|
||||
|
||||
esrecurse@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220"
|
||||
dependencies:
|
||||
estraverse "~4.1.0"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
estraverse@^1.9.1:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
|
||||
|
||||
estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
|
||||
|
||||
estraverse@~4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2"
|
||||
|
||||
esutils@^2.0.0, esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
@ -2458,6 +2699,13 @@ etag@~1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8"
|
||||
|
||||
event-emitter@~0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
events@^1.0.0, events@^1.1.1, events@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
|
||||
@ -2478,6 +2726,10 @@ exenv@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.0.tgz#3835f127abf075bfe082d0aed4484057c78e3c89"
|
||||
|
||||
exit-hook@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
|
||||
|
||||
expand-brackets@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
|
||||
@ -2559,6 +2811,20 @@ fbjs@^0.8.1, fbjs@^0.8.4:
|
||||
promise "^7.1.1"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
figures@^1.3.5:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
|
||||
dependencies:
|
||||
escape-string-regexp "^1.0.5"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
file-entry-cache@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
|
||||
dependencies:
|
||||
flat-cache "^1.2.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
file-loader@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.9.0.tgz#1d2daddd424ce6d1b07cfe3f79731bed3617ab42"
|
||||
@ -2604,6 +2870,15 @@ find-up@^1.0.0:
|
||||
path-exists "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
flat-cache@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
|
||||
dependencies:
|
||||
circular-json "^0.3.1"
|
||||
del "^2.0.2"
|
||||
graceful-fs "^4.1.2"
|
||||
write "^0.2.1"
|
||||
|
||||
flatten@1.0.2, flatten@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
@ -2815,10 +3090,21 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@~7.1.1:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^9.0.0:
|
||||
globals@^9.0.0, globals@^9.14.0:
|
||||
version "9.14.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-9.14.0.tgz#8859936af0038741263053b39d0e76ca241e4034"
|
||||
|
||||
globby@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
|
||||
dependencies:
|
||||
array-union "^1.0.1"
|
||||
arrify "^1.0.0"
|
||||
glob "^7.0.3"
|
||||
object-assign "^4.0.1"
|
||||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
globule@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globule/-/globule-1.1.0.tgz#c49352e4dc183d85893ee825385eb994bb6df45f"
|
||||
@ -2986,6 +3272,10 @@ ieee754@^1.1.4:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
|
||||
|
||||
ignore@^3.2.0:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.7.tgz#4810ca5f1d8eca5595213a34b94f2eb4ed926bbd"
|
||||
|
||||
immutable@^3.7.6, immutable@^3.8.1:
|
||||
version "3.8.1"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2"
|
||||
@ -3037,6 +3327,24 @@ inline-source-map@~0.6.0:
|
||||
dependencies:
|
||||
source-map "~0.5.3"
|
||||
|
||||
inquirer@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
|
||||
dependencies:
|
||||
ansi-escapes "^1.1.0"
|
||||
ansi-regex "^2.0.0"
|
||||
chalk "^1.0.0"
|
||||
cli-cursor "^1.0.1"
|
||||
cli-width "^2.0.0"
|
||||
figures "^1.3.5"
|
||||
lodash "^4.3.0"
|
||||
readline2 "^1.0.1"
|
||||
run-async "^0.1.0"
|
||||
rx-lite "^3.1.2"
|
||||
string-width "^1.0.1"
|
||||
strip-ansi "^3.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
insert-module-globals@^7.0.0:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.0.1.tgz#c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3"
|
||||
@ -3162,13 +3470,17 @@ is-fullwidth-code-point@^1.0.0:
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
|
||||
is-glob@^2.0.0, is-glob@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
|
||||
dependencies:
|
||||
is-extglob "^1.0.0"
|
||||
|
||||
is-my-json-valid@^2.12.4:
|
||||
is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4:
|
||||
version "2.15.0"
|
||||
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b"
|
||||
dependencies:
|
||||
@ -3187,6 +3499,22 @@ is-obj@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
|
||||
|
||||
is-path-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
|
||||
|
||||
is-path-in-cwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
|
||||
dependencies:
|
||||
is-path-inside "^1.0.0"
|
||||
|
||||
is-path-inside@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
|
||||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-plain-obj@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||
@ -3217,6 +3545,12 @@ is-regexp@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
|
||||
|
||||
is-resolvable@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
|
||||
dependencies:
|
||||
tryit "^1.0.1"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
@ -3298,7 +3632,7 @@ js-tokens@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
|
||||
|
||||
js-yaml@^3.4.3, js-yaml@~3.6.1:
|
||||
js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@~3.6.1:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30"
|
||||
dependencies:
|
||||
@ -3349,7 +3683,7 @@ json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
|
||||
json-stable-stringify@^1.0.1:
|
||||
json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
|
||||
dependencies:
|
||||
@ -3397,6 +3731,12 @@ jsprim@^1.2.2:
|
||||
json-schema "0.2.3"
|
||||
verror "1.3.6"
|
||||
|
||||
jsx-ast-utils@^1.3.4:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.0.tgz#5afe38868f56bc8cc7aeaef0100ba8c75bd12591"
|
||||
dependencies:
|
||||
object-assign "^4.1.0"
|
||||
|
||||
keycode@^2.1.1:
|
||||
version "2.1.7"
|
||||
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.7.tgz#7b9255919f6cff562b09a064d222dca70b020f5c"
|
||||
@ -3435,7 +3775,7 @@ lcid@^1.0.0:
|
||||
dependencies:
|
||||
invert-kv "^1.0.0"
|
||||
|
||||
levn@~0.3.0:
|
||||
levn@^0.3.0, levn@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||
dependencies:
|
||||
@ -3634,7 +3974,7 @@ lodash.tail@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
|
||||
|
||||
lodash@4.x.x, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.1:
|
||||
lodash@4.x.x, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
@ -3865,10 +4205,18 @@ ms@0.7.2:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
|
||||
|
||||
mute-stream@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
|
||||
|
||||
nan@^2.3.0, nan@^2.3.2, nan@~2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2"
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
negotiator@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
|
||||
@ -4156,6 +4504,10 @@ once@~1.3.0, once@~1.3.3:
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
onetime@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
|
||||
|
||||
optimist@~0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
|
||||
@ -4163,7 +4515,7 @@ optimist@~0.6.0:
|
||||
minimist "~0.0.1"
|
||||
wordwrap "~0.0.2"
|
||||
|
||||
optionator@^0.8.1:
|
||||
optionator@^0.8.1, optionator@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
|
||||
dependencies:
|
||||
@ -4284,6 +4636,10 @@ path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
path-is-inside@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||
|
||||
path-platform@~0.11.15:
|
||||
version "0.11.15"
|
||||
resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2"
|
||||
@ -4373,6 +4729,10 @@ pkg-dir@^1.0.0:
|
||||
dependencies:
|
||||
find-up "^1.0.0"
|
||||
|
||||
pluralize@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
|
||||
|
||||
podda@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/podda/-/podda-1.2.2.tgz#15b0edbd334ade145813343f5ecf9c10a71cf500"
|
||||
@ -4718,6 +5078,10 @@ process@^0.11.0, process@~0.11.0:
|
||||
version "0.11.9"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1"
|
||||
|
||||
progress@^1.1.8:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf"
|
||||
@ -5140,6 +5504,14 @@ readdirp@^2.0.0:
|
||||
readable-stream "^2.0.2"
|
||||
set-immediate-shim "^1.0.1"
|
||||
|
||||
readline2@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
|
||||
dependencies:
|
||||
code-point-at "^1.0.0"
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
mute-stream "0.0.5"
|
||||
|
||||
recast@^0.11.5:
|
||||
version "0.11.22"
|
||||
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.22.tgz#dedeb18fb001a2bbc6ac34475fda53dfe3d47dfa"
|
||||
@ -5341,6 +5713,13 @@ require-main-filename@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
||||
|
||||
require-uncached@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
|
||||
dependencies:
|
||||
caller-path "^0.1.0"
|
||||
resolve-from "^1.0.0"
|
||||
|
||||
requires-port@1.0.x:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
@ -5349,17 +5728,28 @@ reselect@^2.5.4:
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047"
|
||||
|
||||
resolve-from@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
|
||||
|
||||
resolve@1.1.7, resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
|
||||
restore-cursor@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
|
||||
dependencies:
|
||||
exit-hook "^1.0.0"
|
||||
onetime "^1.0.0"
|
||||
|
||||
right-align@^0.1.1:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
|
||||
dependencies:
|
||||
align-text "^0.1.1"
|
||||
|
||||
rimraf@2, rimraf@~2.5.0, rimraf@~2.5.1:
|
||||
rimraf@2, rimraf@^2.2.8, rimraf@~2.5.0, rimraf@~2.5.1:
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
|
||||
dependencies:
|
||||
@ -5373,6 +5763,16 @@ ripemd160@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e"
|
||||
|
||||
run-async@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
|
||||
rx-lite@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
|
||||
|
||||
samsam@1.1.2, samsam@~1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567"
|
||||
@ -5523,6 +5923,14 @@ shelljs@^0.7.4:
|
||||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
shelljs@^0.7.5:
|
||||
version "0.7.7"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1"
|
||||
dependencies:
|
||||
glob "^7.0.0"
|
||||
interpret "^1.0.0"
|
||||
rechoir "^0.6.2"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.1.tgz#5a4c884992b63a7acd9badb7894c3ee9cfccad81"
|
||||
@ -5548,6 +5956,10 @@ slash@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
|
||||
|
||||
slice-ansi@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||
|
||||
slide@^1.1.5:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
|
||||
@ -5692,6 +6104,13 @@ string-width@^1.0.1, string-width@^1.0.2:
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string-width@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string.prototype.padend@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
|
||||
@ -5735,6 +6154,10 @@ strip-bom@^2.0.0:
|
||||
dependencies:
|
||||
is-utf8 "^0.2.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
|
||||
strip-indent@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
|
||||
@ -5745,6 +6168,10 @@ strip-json-comments@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"
|
||||
|
||||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
|
||||
style-loader@0.13.1:
|
||||
version "0.13.1"
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.1.tgz#468280efbc0473023cd3a6cd56e33b5a1d7fc3a9"
|
||||
@ -5809,6 +6236,17 @@ syntax-error@^1.1.1:
|
||||
dependencies:
|
||||
acorn "^2.7.0"
|
||||
|
||||
table@^3.7.8:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
|
||||
dependencies:
|
||||
ajv "^4.7.0"
|
||||
ajv-keywords "^1.0.0"
|
||||
chalk "^1.1.1"
|
||||
lodash "^4.0.0"
|
||||
slice-ansi "0.0.4"
|
||||
string-width "^2.0.0"
|
||||
|
||||
tapable@^0.1.8, tapable@~0.1.8:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4"
|
||||
@ -5856,6 +6294,10 @@ tar@^2.0.0, tar@~2.2.0, tar@~2.2.1:
|
||||
fstream "^1.0.2"
|
||||
inherits "2"
|
||||
|
||||
text-table@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
|
||||
through2@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9"
|
||||
@ -5863,7 +6305,7 @@ through2@^2.0.0:
|
||||
readable-stream "~2.0.0"
|
||||
xtend "~4.0.0"
|
||||
|
||||
through@2, "through@>=2.2.7 <3":
|
||||
through@2, "through@>=2.2.7 <3", through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
@ -5909,6 +6351,10 @@ trim-right@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||
|
||||
tryit@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
|
||||
|
||||
tty-browserify@0.0.0, tty-browserify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
@ -6022,6 +6468,12 @@ user-home@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
|
||||
|
||||
user-home@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
|
||||
utf-8-validate@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-3.0.1.tgz#5d2b8656b4ddcfded47217b647a98941b63cf213"
|
||||
@ -6280,6 +6732,12 @@ write-file-atomic@^1.1.2:
|
||||
imurmurhash "^0.1.4"
|
||||
slide "^1.1.5"
|
||||
|
||||
write@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
|
||||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
ws@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-2.1.0.tgz#b24eaed9609f8632dd51e3f7698619a90fddcc92"
|
||||
|
Loading…
Reference in New Issue
Block a user