Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a0f7453c6e | ||
|
46a1e16f21 | ||
|
f3f7a3840a | ||
|
7539254e96 | ||
|
456478c4e1 |
64
.babelrc
@@ -1,65 +1,7 @@
|
|||||||
{
|
{
|
||||||
"presets": [
|
"presets": ["es2015", "react"],
|
||||||
"react",
|
|
||||||
[
|
|
||||||
"env",
|
|
||||||
{
|
|
||||||
"loose": true,
|
|
||||||
"modules": false,
|
|
||||||
"targets": {
|
|
||||||
"browsers": ["last 2 versions", "IE >= 11", "iOS >= 9"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"syntax-dynamic-import",
|
|
||||||
["transform-object-rest-spread", { "useBuiltIns": true }],
|
|
||||||
"transform-decorators-legacy",
|
"transform-decorators-legacy",
|
||||||
"transform-class-properties",
|
"transform-object-rest-spread"
|
||||||
[
|
]
|
||||||
"react-intl",
|
|
||||||
{
|
|
||||||
"messagesDir": "./build/messages"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"preval"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"development": {
|
|
||||||
"plugins": [
|
|
||||||
"transform-react-jsx-source",
|
|
||||||
"transform-react-jsx-self"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"production": {
|
|
||||||
"plugins": [
|
|
||||||
"lodash",
|
|
||||||
[
|
|
||||||
"transform-react-remove-prop-types",
|
|
||||||
{
|
|
||||||
"mode": "remove",
|
|
||||||
"removeImport": true,
|
|
||||||
"additionalLibraries": [
|
|
||||||
"react-immutable-proptypes"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"transform-react-inline-elements",
|
|
||||||
[
|
|
||||||
"transform-runtime",
|
|
||||||
{
|
|
||||||
"helpers": true,
|
|
||||||
"polyfill": false,
|
|
||||||
"regenerator": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"plugins": [
|
|
||||||
"transform-es2015-modules-commonjs"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,2 @@
|
|||||||
https://github.com/heroku/heroku-buildpack-apt
|
|
||||||
https://github.com/Scalingo/nodejs-buildpack
|
https://github.com/Scalingo/nodejs-buildpack
|
||||||
https://github.com/Scalingo/ruby-buildpack
|
https://github.com/Scalingo/ruby-buildpack
|
||||||
|
@@ -1,21 +1,14 @@
|
|||||||
engines:
|
engines:
|
||||||
brakeman:
|
duplication:
|
||||||
enabled: true
|
enabled: false
|
||||||
bundler-audit:
|
rubocop:
|
||||||
enabled: true
|
enabled: true
|
||||||
duplication:
|
eslint:
|
||||||
enabled: false
|
enabled: true
|
||||||
eslint:
|
|
||||||
enabled: true
|
|
||||||
rubocop:
|
|
||||||
enabled: true
|
|
||||||
scss-lint:
|
|
||||||
enabled: true
|
|
||||||
ratings:
|
ratings:
|
||||||
paths:
|
paths:
|
||||||
- "**.rb"
|
- "**.rb"
|
||||||
- "**.js"
|
- "**.js"
|
||||||
- "**.scss"
|
|
||||||
exclude_paths:
|
exclude_paths:
|
||||||
- spec/
|
- spec/
|
||||||
- vendor/asset
|
- vendor/asset
|
||||||
|
@@ -2,12 +2,10 @@
|
|||||||
.env.*
|
.env.*
|
||||||
public/system
|
public/system
|
||||||
public/assets
|
public/assets
|
||||||
public/packs
|
|
||||||
node_modules
|
node_modules
|
||||||
|
storybook
|
||||||
neo4j
|
neo4j
|
||||||
vendor/bundle
|
vendor/bundle
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
postgres
|
|
||||||
redis
|
|
||||||
|
111
.env.nanobox
@@ -1,111 +0,0 @@
|
|||||||
# Service dependencies
|
|
||||||
# You may set REDIS_URL instead for more advanced options
|
|
||||||
REDIS_HOST=$DATA_REDIS_HOST
|
|
||||||
REDIS_PORT=6379
|
|
||||||
# REDIS_DB=0
|
|
||||||
|
|
||||||
# You may set DATABASE_URL instead for more advanced options
|
|
||||||
DB_HOST=$DATA_DB_HOST
|
|
||||||
DB_USER=$DATA_DB_USER
|
|
||||||
DB_NAME=gonano
|
|
||||||
DB_PASS=$DATA_DB_PASS
|
|
||||||
DB_PORT=5432
|
|
||||||
|
|
||||||
DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
|
|
||||||
|
|
||||||
# Federation
|
|
||||||
# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects.
|
|
||||||
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
|
||||||
LOCAL_DOMAIN=${APP_NAME}.nanoapp.io
|
|
||||||
LOCAL_HTTPS=false
|
|
||||||
|
|
||||||
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
|
||||||
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
|
||||||
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
|
|
||||||
# WEB_DOMAIN=mastodon.example.com
|
|
||||||
|
|
||||||
# Use this if you want to have several aliases handler@example1.com
|
|
||||||
# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not
|
|
||||||
# be added. Comma separated values
|
|
||||||
# ALTERNATE_DOMAINS=example1.com,example2.com
|
|
||||||
|
|
||||||
# Application secrets
|
|
||||||
# Generate each with the `rake secret` task (`nanobox run bundle exec rake secret`)
|
|
||||||
PAPERCLIP_SECRET=$PAPERCLIP_SECRET
|
|
||||||
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
|
||||||
OTP_SECRET=$OTP_SECRET
|
|
||||||
|
|
||||||
# Registrations
|
|
||||||
# Single user mode will disable registrations and redirect frontpage to the first profile
|
|
||||||
# SINGLE_USER_MODE=true
|
|
||||||
# Prevent registrations with following e-mail domains
|
|
||||||
# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc
|
|
||||||
# Only allow registrations with the following e-mail domains
|
|
||||||
# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc
|
|
||||||
|
|
||||||
# Optionally change default language
|
|
||||||
# DEFAULT_LOCALE=de
|
|
||||||
|
|
||||||
# E-mail configuration
|
|
||||||
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
|
||||||
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
|
||||||
# then set SMTP_AUTH_METHOD and SMTP_OPENSSL_VERIFY_MODE to 'none' and
|
|
||||||
# *comment* SMTP_LOGIN and SMTP_PASSWORD (leaving them blank is not enough).
|
|
||||||
SMTP_SERVER=$SMTP_SERVER
|
|
||||||
SMTP_PORT=587
|
|
||||||
SMTP_LOGIN=$SMTP_LOGIN
|
|
||||||
SMTP_PASSWORD=$SMTP_PASSWORD
|
|
||||||
SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
|
||||||
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
|
|
||||||
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
|
|
||||||
#SMTP_AUTH_METHOD=plain
|
|
||||||
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
|
||||||
#SMTP_OPENSSL_VERIFY_MODE=peer
|
|
||||||
#SMTP_ENABLE_STARTTLS_AUTO=true
|
|
||||||
|
|
||||||
|
|
||||||
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
|
||||||
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
|
||||||
# PAPERCLIP_ROOT_URL=/system
|
|
||||||
|
|
||||||
# Optional asset host for multi-server setups
|
|
||||||
# CDN_HOST=https://assets.example.com
|
|
||||||
|
|
||||||
# S3 (optional)
|
|
||||||
# S3_ENABLED=true
|
|
||||||
# S3_BUCKET=
|
|
||||||
# AWS_ACCESS_KEY_ID=
|
|
||||||
# AWS_SECRET_ACCESS_KEY=
|
|
||||||
# S3_REGION=
|
|
||||||
# S3_PROTOCOL=http
|
|
||||||
# S3_HOSTNAME=192.168.1.123:9000
|
|
||||||
|
|
||||||
# S3 (Minio Config (optional) Please check Minio instance for details)
|
|
||||||
# S3_ENABLED=true
|
|
||||||
# S3_BUCKET=
|
|
||||||
# AWS_ACCESS_KEY_ID=
|
|
||||||
# AWS_SECRET_ACCESS_KEY=
|
|
||||||
# S3_REGION=
|
|
||||||
# S3_PROTOCOL=https
|
|
||||||
# S3_HOSTNAME=
|
|
||||||
# S3_ENDPOINT=
|
|
||||||
# S3_SIGNATURE_VERSION=
|
|
||||||
|
|
||||||
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
|
||||||
# S3_CLOUDFRONT_HOST=
|
|
||||||
|
|
||||||
# Streaming API integration
|
|
||||||
# STREAMING_API_BASE_URL=
|
|
||||||
|
|
||||||
# Advanced settings
|
|
||||||
# If you need to use pgBouncer, you need to disable prepared statements:
|
|
||||||
# PREPARED_STATEMENTS=false
|
|
||||||
|
|
||||||
# Cluster number setting for streaming API server.
|
|
||||||
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
|
||||||
STREAMING_CLUSTER_NUM=1
|
|
||||||
|
|
||||||
# Docker mastodon user
|
|
||||||
# If you use Docker, you may want to assign UID/GID manually.
|
|
||||||
# UID=1000
|
|
||||||
# GID=1000
|
|
@@ -1,8 +1,7 @@
|
|||||||
# Service dependencies
|
# Service dependencies
|
||||||
# You may set REDIS_URL instead for more advanced options
|
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
# You may set DATABASE_URL instead for more advanced options
|
# REDIS_DB=0
|
||||||
DB_HOST=db
|
DB_HOST=db
|
||||||
DB_USER=postgres
|
DB_USER=postgres
|
||||||
DB_NAME=postgres
|
DB_NAME=postgres
|
||||||
@@ -10,38 +9,19 @@ DB_PASS=
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
|
||||||
# Federation
|
# Federation
|
||||||
# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects.
|
LOCAL_DOMAIN=example.com
|
||||||
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
|
||||||
LOCAL_DOMAIN=example.com
|
|
||||||
LOCAL_HTTPS=true
|
LOCAL_HTTPS=true
|
||||||
|
|
||||||
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
||||||
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
# Do not use this unless you know exactly what you are doing.
|
||||||
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
|
|
||||||
# WEB_DOMAIN=mastodon.example.com
|
# WEB_DOMAIN=mastodon.example.com
|
||||||
|
|
||||||
# Use this if you want to have several aliases handler@example1.com
|
|
||||||
# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not
|
|
||||||
# be added. Comma separated values
|
|
||||||
# ALTERNATE_DOMAINS=example1.com,example2.com
|
|
||||||
|
|
||||||
# Application secrets
|
# Application secrets
|
||||||
# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
|
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
|
||||||
PAPERCLIP_SECRET=
|
PAPERCLIP_SECRET=
|
||||||
SECRET_KEY_BASE=
|
SECRET_KEY_BASE=
|
||||||
OTP_SECRET=
|
OTP_SECRET=
|
||||||
|
|
||||||
# VAPID keys (used for push notifications
|
|
||||||
# You can generate the keys using the following command (first is the private key, second is the public one)
|
|
||||||
# You should only generate this once per instance. If you later decide to change it, all push subscription will
|
|
||||||
# be invalidated, requiring the users to access the website again to resubscribe.
|
|
||||||
#
|
|
||||||
# Generate with `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose)
|
|
||||||
#
|
|
||||||
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
|
||||||
VAPID_PRIVATE_KEY=
|
|
||||||
VAPID_PUBLIC_KEY=
|
|
||||||
|
|
||||||
# Registrations
|
# Registrations
|
||||||
# Single user mode will disable registrations and redirect frontpage to the first profile
|
# Single user mode will disable registrations and redirect frontpage to the first profile
|
||||||
# SINGLE_USER_MODE=true
|
# SINGLE_USER_MODE=true
|
||||||
@@ -56,8 +36,8 @@ VAPID_PUBLIC_KEY=
|
|||||||
# E-mail configuration
|
# E-mail configuration
|
||||||
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
||||||
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
||||||
# then set SMTP_AUTH_METHOD and SMTP_OPENSSL_VERIFY_MODE to 'none' and
|
# then set SMTP_AUTH_METHOD to 'none' and *comment* SMTP_LOGIN and SMTP_PASSWORD.
|
||||||
# *comment* SMTP_LOGIN and SMTP_PASSWORD (leaving them blank is not enough).
|
# Leaving them blank is not enough for authentication method 'none'.
|
||||||
SMTP_SERVER=smtp.mailgun.org
|
SMTP_SERVER=smtp.mailgun.org
|
||||||
SMTP_PORT=587
|
SMTP_PORT=587
|
||||||
SMTP_LOGIN=
|
SMTP_LOGIN=
|
||||||
@@ -66,17 +46,16 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||||||
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
|
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
|
||||||
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
|
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
|
||||||
#SMTP_AUTH_METHOD=plain
|
#SMTP_AUTH_METHOD=plain
|
||||||
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
|
||||||
#SMTP_OPENSSL_VERIFY_MODE=peer
|
#SMTP_OPENSSL_VERIFY_MODE=peer
|
||||||
#SMTP_ENABLE_STARTTLS_AUTO=true
|
#SMTP_ENABLE_STARTTLS_AUTO=true
|
||||||
#SMTP_TLS=true
|
|
||||||
|
|
||||||
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
||||||
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
||||||
# PAPERCLIP_ROOT_URL=/system
|
# PAPERCLIP_ROOT_URL=/system
|
||||||
|
|
||||||
# Optional asset host for multi-server setups
|
# Optional asset host for multi-server setups
|
||||||
# CDN_HOST=https://assets.example.com
|
# CDN_HOST=assets.example.com
|
||||||
|
|
||||||
# S3 (optional)
|
# S3 (optional)
|
||||||
# S3_ENABLED=true
|
# S3_ENABLED=true
|
||||||
@@ -98,23 +77,6 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||||||
# S3_ENDPOINT=
|
# S3_ENDPOINT=
|
||||||
# S3_SIGNATURE_VERSION=
|
# S3_SIGNATURE_VERSION=
|
||||||
|
|
||||||
# Swift (optional)
|
|
||||||
# SWIFT_ENABLED=true
|
|
||||||
# SWIFT_USERNAME=
|
|
||||||
# For Keystone V3, the value for SWIFT_TENANT should be the project name
|
|
||||||
# SWIFT_TENANT=
|
|
||||||
# SWIFT_PASSWORD=
|
|
||||||
# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid
|
|
||||||
# issues with token rate-limiting during high load.
|
|
||||||
# SWIFT_AUTH_URL=
|
|
||||||
# SWIFT_CONTAINER=
|
|
||||||
# SWIFT_OBJECT_URL=
|
|
||||||
# SWIFT_REGION=
|
|
||||||
# Defaults to 'default'
|
|
||||||
# SWIFT_DOMAIN_NAME=
|
|
||||||
# Defaults to 60 seconds. Set to 0 to disable
|
|
||||||
# SWIFT_CACHE_TTL=
|
|
||||||
|
|
||||||
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||||
# S3_CLOUDFRONT_HOST=
|
# S3_CLOUDFRONT_HOST=
|
||||||
|
|
||||||
@@ -128,8 +90,3 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||||||
# Cluster number setting for streaming API server.
|
# Cluster number setting for streaming API server.
|
||||||
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
||||||
STREAMING_CLUSTER_NUM=1
|
STREAMING_CLUSTER_NUM=1
|
||||||
|
|
||||||
# Docker mastodon user
|
|
||||||
# If you use Docker, you may want to assign UID/GID manually.
|
|
||||||
# UID=1000
|
|
||||||
# GID=1000
|
|
||||||
|
79
.eslintrc.json
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"node": false,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
|
||||||
|
"plugins": [
|
||||||
|
"react",
|
||||||
|
"jsx-a11y"
|
||||||
|
],
|
||||||
|
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module",
|
||||||
|
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"arrowFunctions": true,
|
||||||
|
"jsx": true,
|
||||||
|
"destructuring": true,
|
||||||
|
"modules": true,
|
||||||
|
"spread": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"rules": {
|
||||||
|
"no-cond-assign": 2,
|
||||||
|
"no-console": 1,
|
||||||
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-unreachable": 2,
|
||||||
|
"valid-typeof": 2,
|
||||||
|
"consistent-return": 2,
|
||||||
|
"dot-notation": 2,
|
||||||
|
"eqeqeq": 2,
|
||||||
|
"no-fallthrough": 2,
|
||||||
|
"no-unused-expressions": 2,
|
||||||
|
"strict": 0,
|
||||||
|
"no-catch-shadow": 2,
|
||||||
|
"indent": [1, 2],
|
||||||
|
"brace-style": 1,
|
||||||
|
"comma-spacing": [1, {"before": false, "after": true}],
|
||||||
|
"comma-style": [1, "last"],
|
||||||
|
"no-mixed-spaces-and-tabs": 1,
|
||||||
|
"no-nested-ternary": 1,
|
||||||
|
"no-trailing-spaces": 1,
|
||||||
|
|
||||||
|
"react/jsx-wrap-multilines": 2,
|
||||||
|
"react/self-closing-comp": 2,
|
||||||
|
"react/prop-types": 2,
|
||||||
|
"react/no-multi-comp": 0,
|
||||||
|
|
||||||
|
"jsx-a11y/accessible-emoji": 1,
|
||||||
|
"jsx-a11y/anchor-has-content": 1,
|
||||||
|
"jsx-a11y/aria-activedescendant-has-tabindex": 1,
|
||||||
|
"jsx-a11y/aria-props": 1,
|
||||||
|
"jsx-a11y/aria-proptypes": 1,
|
||||||
|
"jsx-a11y/aria-role": 1,
|
||||||
|
"jsx-a11y/aria-unsupported-elements": 1,
|
||||||
|
"jsx-a11y/heading-has-content": 1,
|
||||||
|
"jsx-a11y/href-no-hash": 1,
|
||||||
|
"jsx-a11y/html-has-lang": 1,
|
||||||
|
"jsx-a11y/iframe-has-title": 1,
|
||||||
|
"jsx-a11y/img-has-alt": 1,
|
||||||
|
"jsx-a11y/img-redundant-alt": 1,
|
||||||
|
"jsx-a11y/label-has-for": 1,
|
||||||
|
"jsx-a11y/mouse-events-have-key-events": 1,
|
||||||
|
"jsx-a11y/no-access-key": 1,
|
||||||
|
"jsx-a11y/no-distracting-elements": 1,
|
||||||
|
"jsx-a11y/no-onchange": 1,
|
||||||
|
"jsx-a11y/no-redundant-roles": 1,
|
||||||
|
"jsx-a11y/onclick-has-focus": 1,
|
||||||
|
"jsx-a11y/onclick-has-role": 1,
|
||||||
|
"jsx-a11y/role-has-required-aria-props": 1,
|
||||||
|
"jsx-a11y/role-supports-aria-props": 1,
|
||||||
|
"jsx-a11y/scope": 1,
|
||||||
|
"jsx-a11y/tabindex-no-positive": 1
|
||||||
|
}
|
||||||
|
}
|
127
.eslintrc.yml
@@ -1,127 +0,0 @@
|
|||||||
---
|
|
||||||
root: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
browser: true
|
|
||||||
node: true
|
|
||||||
es6: true
|
|
||||||
|
|
||||||
parser: babel-eslint
|
|
||||||
|
|
||||||
plugins:
|
|
||||||
- react
|
|
||||||
- jsx-a11y
|
|
||||||
|
|
||||||
parserOptions:
|
|
||||||
sourceType: module
|
|
||||||
ecmaFeatures:
|
|
||||||
arrowFunctions: true
|
|
||||||
jsx: true
|
|
||||||
destructuring: true
|
|
||||||
modules: true
|
|
||||||
spread: true
|
|
||||||
|
|
||||||
rules:
|
|
||||||
|
|
||||||
brace-style: warn
|
|
||||||
comma-dangle:
|
|
||||||
- error
|
|
||||||
- always-multiline
|
|
||||||
comma-spacing:
|
|
||||||
- warn
|
|
||||||
- before: false
|
|
||||||
after: true
|
|
||||||
comma-style:
|
|
||||||
- warn
|
|
||||||
- last
|
|
||||||
consistent-return: error
|
|
||||||
dot-notation: error
|
|
||||||
eqeqeq: error
|
|
||||||
indent:
|
|
||||||
- warn
|
|
||||||
- 2
|
|
||||||
jsx-quotes:
|
|
||||||
- error
|
|
||||||
- prefer-single
|
|
||||||
no-catch-shadow: error
|
|
||||||
no-cond-assign: error
|
|
||||||
no-console:
|
|
||||||
- warn
|
|
||||||
- allow:
|
|
||||||
- error
|
|
||||||
- warn
|
|
||||||
no-fallthrough: error
|
|
||||||
no-irregular-whitespace: error
|
|
||||||
no-mixed-spaces-and-tabs: warn
|
|
||||||
no-nested-ternary: warn
|
|
||||||
no-trailing-spaces: warn
|
|
||||||
no-undef: error
|
|
||||||
no-unreachable: error
|
|
||||||
no-unused-expressions: error
|
|
||||||
no-unused-vars:
|
|
||||||
- error
|
|
||||||
- vars: all
|
|
||||||
args: after-used
|
|
||||||
ignoreRestSiblings: true
|
|
||||||
object-curly-spacing:
|
|
||||||
- error
|
|
||||||
- always
|
|
||||||
padded-blocks:
|
|
||||||
- error
|
|
||||||
- classes: always
|
|
||||||
quotes:
|
|
||||||
- error
|
|
||||||
- single
|
|
||||||
semi: error
|
|
||||||
strict: off
|
|
||||||
valid-typeof: error
|
|
||||||
|
|
||||||
react/jsx-boolean-value: error
|
|
||||||
react/jsx-closing-bracket-location:
|
|
||||||
- error
|
|
||||||
- line-aligned
|
|
||||||
react/jsx-curly-spacing: error
|
|
||||||
react/jsx-equals-spacing: error
|
|
||||||
react/jsx-first-prop-new-line:
|
|
||||||
- error
|
|
||||||
- multiline-multiprop
|
|
||||||
react/jsx-indent:
|
|
||||||
- error
|
|
||||||
- 2
|
|
||||||
react/jsx-no-bind: error
|
|
||||||
react/jsx-no-duplicate-props: error
|
|
||||||
react/jsx-no-undef: error
|
|
||||||
react/jsx-tag-spacing: error
|
|
||||||
react/jsx-uses-react: error
|
|
||||||
react/jsx-uses-vars: error
|
|
||||||
react/jsx-wrap-multilines: error
|
|
||||||
react/no-multi-comp: off
|
|
||||||
react/no-string-refs: error
|
|
||||||
react/prop-types: error
|
|
||||||
react/self-closing-comp: error
|
|
||||||
|
|
||||||
jsx-a11y/accessible-emoji: warn
|
|
||||||
jsx-a11y/anchor-has-content: warn
|
|
||||||
jsx-a11y/aria-activedescendant-has-tabindex: warn
|
|
||||||
jsx-a11y/aria-props: warn
|
|
||||||
jsx-a11y/aria-proptypes: warn
|
|
||||||
jsx-a11y/aria-role: warn
|
|
||||||
jsx-a11y/aria-unsupported-elements: warn
|
|
||||||
jsx-a11y/heading-has-content: warn
|
|
||||||
jsx-a11y/href-no-hash: warn
|
|
||||||
jsx-a11y/html-has-lang: warn
|
|
||||||
jsx-a11y/iframe-has-title: warn
|
|
||||||
jsx-a11y/img-has-alt: warn
|
|
||||||
jsx-a11y/img-redundant-alt: warn
|
|
||||||
jsx-a11y/label-has-for: off
|
|
||||||
jsx-a11y/mouse-events-have-key-events: warn
|
|
||||||
jsx-a11y/no-access-key: warn
|
|
||||||
jsx-a11y/no-distracting-elements: warn
|
|
||||||
jsx-a11y/no-onchange: warn
|
|
||||||
jsx-a11y/no-redundant-roles: warn
|
|
||||||
jsx-a11y/onclick-has-focus: warn
|
|
||||||
jsx-a11y/onclick-has-role: warn
|
|
||||||
jsx-a11y/role-has-required-aria-props: warn
|
|
||||||
jsx-a11y/role-supports-aria-props: off
|
|
||||||
jsx-a11y/scope: warn
|
|
||||||
jsx-a11y/tabindex-no-positive: warn
|
|
14
.gitattributes
vendored
@@ -1,14 +0,0 @@
|
|||||||
* text=auto eol=lf
|
|
||||||
*.eot -text
|
|
||||||
*.gif -text
|
|
||||||
*.gz -text
|
|
||||||
*.ico -text
|
|
||||||
*.jpg -text
|
|
||||||
*.mp3 -text
|
|
||||||
*.ogg -text
|
|
||||||
*.png -text
|
|
||||||
*.ttf -text
|
|
||||||
*.webm -text
|
|
||||||
*.woff -text
|
|
||||||
*.woff2 -text
|
|
||||||
spec/fixtures/requests/** -text !eol
|
|
16
.gitignore
vendored
@@ -19,12 +19,10 @@
|
|||||||
coverage
|
coverage
|
||||||
public/system
|
public/system
|
||||||
public/assets
|
public/assets
|
||||||
public/packs
|
|
||||||
public/packs-test
|
|
||||||
.env
|
.env
|
||||||
.env.production
|
.env.production
|
||||||
node_modules/
|
node_modules/
|
||||||
build/
|
neo4j/
|
||||||
|
|
||||||
# Ignore Vagrant files
|
# Ignore Vagrant files
|
||||||
.vagrant/
|
.vagrant/
|
||||||
@@ -34,7 +32,6 @@ config/deploy/*
|
|||||||
|
|
||||||
# Ignore IDE files
|
# Ignore IDE files
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
|
||||||
|
|
||||||
# Ignore postgres + redis volume optionally created by docker-compose
|
# Ignore postgres + redis volume optionally created by docker-compose
|
||||||
postgres
|
postgres
|
||||||
@@ -46,14 +43,3 @@ redis
|
|||||||
# Ignore vim files
|
# Ignore vim files
|
||||||
*~
|
*~
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
# Ignore npm debug log
|
|
||||||
npm-debug.log
|
|
||||||
|
|
||||||
# Ignore yarn log files
|
|
||||||
yarn-error.log
|
|
||||||
yarn-debug.log
|
|
||||||
|
|
||||||
# Ignore Docker option files
|
|
||||||
docker-compose.override.yml
|
|
||||||
|
|
||||||
|
108
.haml-lint.yml
@@ -1,108 +0,0 @@
|
|||||||
# Whether to ignore frontmatter at the beginning of HAML documents for
|
|
||||||
# frameworks such as Jekyll/Middleman
|
|
||||||
skip_frontmatter: false
|
|
||||||
|
|
||||||
exclude:
|
|
||||||
- 'vendor/**/*'
|
|
||||||
- 'spec/**/*'
|
|
||||||
- 'lib/templates/**/*'
|
|
||||||
- 'app/views/kaminari/**/*'
|
|
||||||
|
|
||||||
linters:
|
|
||||||
AltText:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
ClassAttributeWithStaticValue:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
ClassesBeforeIds:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
ConsecutiveComments:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
ConsecutiveSilentScripts:
|
|
||||||
enabled: true
|
|
||||||
max_consecutive: 2
|
|
||||||
|
|
||||||
EmptyObjectReference:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
EmptyScript:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
FinalNewline:
|
|
||||||
enabled: true
|
|
||||||
present: true
|
|
||||||
|
|
||||||
HtmlAttributes:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
ImplicitDiv:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
LeadingCommentSpace:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
LineLength:
|
|
||||||
enabled: false
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
MultilinePipe:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
MultilineScript:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
ObjectReferenceAttributes:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
RuboCop:
|
|
||||||
enabled: true
|
|
||||||
# These cops are incredibly noisy when it comes to HAML templates, so we
|
|
||||||
# ignore them.
|
|
||||||
ignored_cops:
|
|
||||||
- Lint/BlockAlignment
|
|
||||||
- Lint/EndAlignment
|
|
||||||
- Lint/Void
|
|
||||||
- Metrics/BlockLength
|
|
||||||
- Metrics/LineLength
|
|
||||||
- Style/AlignParameters
|
|
||||||
- Style/BlockNesting
|
|
||||||
- Style/ElseAlignment
|
|
||||||
- Style/EndOfLine
|
|
||||||
- Style/FileName
|
|
||||||
- Style/FinalNewline
|
|
||||||
- Style/FrozenStringLiteralComment
|
|
||||||
- Style/IfUnlessModifier
|
|
||||||
- Style/IndentationWidth
|
|
||||||
- Style/Next
|
|
||||||
- Style/TrailingBlankLines
|
|
||||||
- Style/TrailingWhitespace
|
|
||||||
- Style/WhileUntilModifier
|
|
||||||
|
|
||||||
RubyComments:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
SpaceBeforeScript:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
SpaceInsideHashAttributes:
|
|
||||||
enabled: true
|
|
||||||
style: space
|
|
||||||
|
|
||||||
Indentation:
|
|
||||||
enabled: true
|
|
||||||
character: space # or tab
|
|
||||||
|
|
||||||
TagName:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
TrailingWhitespace:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
UnnecessaryInterpolation:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
UnnecessaryStringOutput:
|
|
||||||
enabled: true
|
|
19
.nanoignore
@@ -1,19 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
.git/
|
|
||||||
.gitignore
|
|
||||||
|
|
||||||
.bundle/
|
|
||||||
.cache/
|
|
||||||
config/deploy/*
|
|
||||||
coverage
|
|
||||||
docs/
|
|
||||||
.env
|
|
||||||
log/*.log
|
|
||||||
neo4j/
|
|
||||||
node_modules/
|
|
||||||
public/assets/
|
|
||||||
public/system/
|
|
||||||
spec/
|
|
||||||
tmp/
|
|
||||||
.vagrant/
|
|
||||||
vendor/bundle/
|
|
@@ -1,9 +0,0 @@
|
|||||||
plugins:
|
|
||||||
postcss-smart-import: {}
|
|
||||||
precss: {}
|
|
||||||
autoprefixer:
|
|
||||||
browsers:
|
|
||||||
- last 2 versions
|
|
||||||
- IE >= 11
|
|
||||||
- iOS >= 9
|
|
||||||
postcss-object-fit-images: {}
|
|
1
.profile
@@ -1 +0,0 @@
|
|||||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio
|
|
117
.rubocop.yml
@@ -1,46 +1,14 @@
|
|||||||
AllCops:
|
Rails:
|
||||||
TargetRubyVersion: 2.3
|
Enabled: true
|
||||||
Exclude:
|
|
||||||
- 'spec/**/*'
|
|
||||||
- 'db/**/*'
|
|
||||||
- 'app/views/**/*'
|
|
||||||
- 'config/**/*'
|
|
||||||
- 'bin/*'
|
|
||||||
- 'Rakefile'
|
|
||||||
- 'node_modules/**/*'
|
|
||||||
- 'Vagrantfile'
|
|
||||||
- 'vendor/**/*'
|
|
||||||
- 'lib/json_ld/*'
|
|
||||||
|
|
||||||
Bundler/OrderedGems:
|
Style/PerlBackrefs:
|
||||||
|
AutoCorrect: false
|
||||||
|
|
||||||
|
Style/ClassAndModuleChildren:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Layout/AccessModifierIndentation:
|
|
||||||
EnforcedStyle: indent
|
|
||||||
|
|
||||||
Layout/EmptyLineAfterMagicComment:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Layout/SpaceInsideHashLiteralBraces:
|
|
||||||
EnforcedStyle: space
|
|
||||||
|
|
||||||
Metrics/AbcSize:
|
|
||||||
Max: 100
|
|
||||||
|
|
||||||
Metrics/BlockLength:
|
|
||||||
Max: 35
|
|
||||||
Exclude:
|
|
||||||
- 'lib/tasks/**/*'
|
|
||||||
|
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
Max: 3
|
Max: 2
|
||||||
|
|
||||||
Metrics/ClassLength:
|
|
||||||
CountComments: false
|
|
||||||
Max: 300
|
|
||||||
|
|
||||||
Metrics/CyclomaticComplexity:
|
|
||||||
Max: 25
|
|
||||||
|
|
||||||
Metrics/LineLength:
|
Metrics/LineLength:
|
||||||
AllowURI: true
|
AllowURI: true
|
||||||
@@ -48,30 +16,37 @@ Metrics/LineLength:
|
|||||||
|
|
||||||
Metrics/MethodLength:
|
Metrics/MethodLength:
|
||||||
CountComments: false
|
CountComments: false
|
||||||
|
Max: 10
|
||||||
|
|
||||||
|
Metrics/AbcSize:
|
||||||
|
Max: 100
|
||||||
|
|
||||||
|
Metrics/BlockNesting:
|
||||||
|
Max: 3
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
CountComments: false
|
||||||
|
Max: 200
|
||||||
|
|
||||||
|
Metrics/CyclomaticComplexity:
|
||||||
|
Max: 15
|
||||||
|
|
||||||
|
Metrics/MethodLength:
|
||||||
Max: 55
|
Max: 55
|
||||||
|
|
||||||
Metrics/ModuleLength:
|
Metrics/ModuleLength:
|
||||||
CountComments: false
|
CountComments: false
|
||||||
Max: 200
|
Max: 200
|
||||||
|
|
||||||
|
Metrics/PerceivedComplexity:
|
||||||
|
Max: 10
|
||||||
|
|
||||||
Metrics/ParameterLists:
|
Metrics/ParameterLists:
|
||||||
Max: 5
|
Max: 4
|
||||||
CountKeywordArgs: true
|
CountKeywordArgs: true
|
||||||
|
|
||||||
Metrics/PerceivedComplexity:
|
Style/AccessModifierIndentation:
|
||||||
Max: 20
|
EnforcedStyle: indent
|
||||||
|
|
||||||
Rails:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
Rails/HasAndBelongsToMany:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Rails/SkipsModelValidations:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Style/ClassAndModuleChildren:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Style/CollectionMethods:
|
Style/CollectionMethods:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
@@ -87,25 +62,29 @@ Style/DoubleNegation:
|
|||||||
Style/FrozenStringLiteralComment:
|
Style/FrozenStringLiteralComment:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
Style/GuardClause:
|
Style/SpaceInsideHashLiteralBraces:
|
||||||
|
EnforcedStyle: space
|
||||||
|
|
||||||
|
Style/TrailingCommaInLiteral:
|
||||||
|
EnforcedStyleForMultiline: 'comma'
|
||||||
|
|
||||||
|
Style/RegexpLiteral:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/Lambda:
|
Style/Lambda:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/PercentLiteralDelimiters:
|
Rails/HasAndBelongsToMany:
|
||||||
PreferredDelimiters:
|
|
||||||
'%i': '()'
|
|
||||||
'%w': '()'
|
|
||||||
|
|
||||||
Style/PerlBackrefs:
|
|
||||||
AutoCorrect: false
|
|
||||||
|
|
||||||
Style/RegexpLiteral:
|
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Style/SymbolArray:
|
AllCops:
|
||||||
Enabled: false
|
TargetRubyVersion: 2.3
|
||||||
|
Exclude:
|
||||||
Style/TrailingCommaInLiteral:
|
- 'spec/**/*'
|
||||||
EnforcedStyleForMultiline: 'comma'
|
- 'db/**/*'
|
||||||
|
- 'app/views/**/*'
|
||||||
|
- 'config/**/*'
|
||||||
|
- 'bin/*'
|
||||||
|
- 'Rakefile'
|
||||||
|
- 'node_modules/**/*'
|
||||||
|
- 'Vagrantfile'
|
||||||
|
264
.scss-lint.yml
@@ -1,264 +0,0 @@
|
|||||||
# Linter Documentation:
|
|
||||||
# https://github.com/brigade/scss-lint/blob/v0.42.2/lib/scss_lint/linter/README.md
|
|
||||||
|
|
||||||
scss_files: 'app/javascript/styles/**/*.scss'
|
|
||||||
|
|
||||||
exclude:
|
|
||||||
- app/javascript/styles/reset.scss
|
|
||||||
|
|
||||||
linters:
|
|
||||||
# Reports when you use improper spacing around ! (the "bang") in !default,
|
|
||||||
# !global, !important, and !optional flags.
|
|
||||||
BangFormat:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Whether or not to prefer `border: 0` over `border: none`.
|
|
||||||
BorderZero:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Reports when you define a rule set using a selector with chained classes
|
|
||||||
# (a.k.a. adjoining classes).
|
|
||||||
ChainedClasses:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Prefer hexadecimal color codes over color keywords.
|
|
||||||
# (e.g. `color: green` is a color keyword)
|
|
||||||
ColorKeyword:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Prefer color literals (keywords or hexadecimal codes) to be used only in
|
|
||||||
# variable declarations. They should be referred to via variables everywhere
|
|
||||||
# else.
|
|
||||||
ColorVariable:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Which form of comments to prefer in CSS.
|
|
||||||
Comment:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Reports @debug statements (which you probably left behind accidentally).
|
|
||||||
DebugStatement:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Rule sets should be ordered as follows:
|
|
||||||
# - @extend declarations
|
|
||||||
# - @include declarations without inner @content
|
|
||||||
# - properties, @include declarations with inner @content
|
|
||||||
# - nested rule sets.
|
|
||||||
DeclarationOrder:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# `scss-lint:disable` control comments should be preceded by a comment
|
|
||||||
# explaining why these linters are being disabled for this file.
|
|
||||||
# See https://github.com/brigade/scss-lint#disabling-linters-via-source for
|
|
||||||
# more information.
|
|
||||||
DisableLinterReason:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Reports when you define the same property twice in a single rule set.
|
|
||||||
DuplicateProperty:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Separate rule, function, and mixin declarations with empty lines.
|
|
||||||
EmptyLineBetweenBlocks:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Reports when you have an empty rule set.
|
|
||||||
EmptyRule:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Reports when you have an @extend directive.
|
|
||||||
ExtendDirective:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Files should always have a final newline. This results in better diffs
|
|
||||||
# when adding lines to the file, since SCM systems such as git won't
|
|
||||||
# think that you touched the last line.
|
|
||||||
FinalNewline:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# HEX colors should use three-character values where possible.
|
|
||||||
HexLength:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# HEX color values should use lower-case colors to differentiate between
|
|
||||||
# letters and numbers, e.g. `#E3E3E3` vs. `#e3e3e3`.
|
|
||||||
HexNotation:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Avoid using ID selectors.
|
|
||||||
IdSelector:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# The basenames of @imported SCSS partials should not begin with an
|
|
||||||
# underscore and should not include the filename extension.
|
|
||||||
ImportPath:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Avoid using !important in properties. It is usually indicative of a
|
|
||||||
# misunderstanding of CSS specificity and can lead to brittle code.
|
|
||||||
ImportantRule:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Indentation should always be done in increments of 2 spaces.
|
|
||||||
Indentation:
|
|
||||||
enabled: true
|
|
||||||
width: 2
|
|
||||||
|
|
||||||
# Don't write leading zeros for numeric values with a decimal point.
|
|
||||||
LeadingZero:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Reports when you define the same selector twice in a single sheet.
|
|
||||||
MergeableSelector:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Functions, mixins, variables, and placeholders should be declared
|
|
||||||
# with all lowercase letters and hyphens instead of underscores.
|
|
||||||
NameFormat:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Avoid nesting selectors too deeply.
|
|
||||||
NestingDepth:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Always use placeholder selectors in @extend.
|
|
||||||
PlaceholderInExtend:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Sort properties in a strict order.
|
|
||||||
PropertySortOrder:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Reports when you use an unknown or disabled CSS property
|
|
||||||
# (ignoring vendor-prefixed properties).
|
|
||||||
PropertySpelling:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Configure which units are allowed for property values.
|
|
||||||
PropertyUnits:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Pseudo-elements, like ::before, and ::first-letter, should be declared
|
|
||||||
# with two colons. Pseudo-classes, like :hover and :first-child, should
|
|
||||||
# be declared with one colon.
|
|
||||||
PseudoElement:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Avoid qualifying elements in selectors (also known as "tag-qualifying").
|
|
||||||
QualifyingElement:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Don't write selectors with a depth of applicability greater than 3.
|
|
||||||
SelectorDepth:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Selectors should always use hyphenated-lowercase, rather than camelCase or
|
|
||||||
# snake_case.
|
|
||||||
SelectorFormat:
|
|
||||||
enabled: false
|
|
||||||
convention: hyphenated_lowercase
|
|
||||||
|
|
||||||
# Prefer the shortest shorthand form possible for properties that support it.
|
|
||||||
Shorthand:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Each property should have its own line, except in the special case of
|
|
||||||
# single line rulesets.
|
|
||||||
SingleLinePerProperty:
|
|
||||||
enabled: true
|
|
||||||
allow_single_line_rule_sets: true
|
|
||||||
|
|
||||||
# Split selectors onto separate lines after each comma, and have each
|
|
||||||
# individual selector occupy a single line.
|
|
||||||
SingleLinePerSelector:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Commas in lists should be followed by a space.
|
|
||||||
SpaceAfterComma:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Properties should be formatted with a single space separating the colon
|
|
||||||
# from the property's value.
|
|
||||||
SpaceAfterPropertyColon:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Properties should be formatted with no space between the name and the
|
|
||||||
# colon.
|
|
||||||
SpaceAfterPropertyName:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Variables should be formatted with a single space separating the colon
|
|
||||||
# from the variable's value.
|
|
||||||
SpaceAfterVariableColon:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Variables should be formatted with no space between the name and the
|
|
||||||
# colon.
|
|
||||||
SpaceAfterVariableName:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Operators should be formatted with a single space on both sides of an
|
|
||||||
# infix operator.
|
|
||||||
SpaceAroundOperator:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Opening braces should be preceded by a single space.
|
|
||||||
SpaceBeforeBrace:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Parentheses should not be padded with spaces.
|
|
||||||
SpaceBetweenParens:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Enforces that string literals should be written with a consistent form
|
|
||||||
# of quotes (single or double).
|
|
||||||
StringQuotes:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Property values, @extend, @include, and @import directives, and variable
|
|
||||||
# declarations should always end with a semicolon.
|
|
||||||
TrailingSemicolon:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Reports lines containing trailing whitespace.
|
|
||||||
TrailingWhitespace:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Don't write trailing zeros for numeric values with a decimal point.
|
|
||||||
TrailingZero:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Don't use the `all` keyword to specify transition properties.
|
|
||||||
TransitionAll:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Numeric values should not contain unnecessary fractional portions.
|
|
||||||
UnnecessaryMantissa:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Do not use parent selector references (&) when they would otherwise
|
|
||||||
# be unnecessary.
|
|
||||||
UnnecessaryParentReference:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# URLs should be valid and not contain protocols or domain names.
|
|
||||||
UrlFormat:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# URLs should always be enclosed within quotes.
|
|
||||||
UrlQuotes:
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
# Properties, like color and font, are easier to read and maintain
|
|
||||||
# when defined using variables rather than literals.
|
|
||||||
VariableForProperty:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Avoid vendor prefixes. Or rather: don't write them yourself.
|
|
||||||
VendorPrefix:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Omit length units on zero values, e.g. `0px` vs. `0`.
|
|
||||||
ZeroUnit:
|
|
||||||
enabled: true
|
|
@@ -2,3 +2,4 @@ node_modules/
|
|||||||
.cache/
|
.cache/
|
||||||
docs/
|
docs/
|
||||||
spec/
|
spec/
|
||||||
|
storybook/
|
||||||
|
29
.travis.yml
@@ -3,12 +3,9 @@ cache:
|
|||||||
bundler: true
|
bundler: true
|
||||||
yarn: true
|
yarn: true
|
||||||
directories:
|
directories:
|
||||||
- node_modules
|
- node_modules
|
||||||
- public/assets
|
|
||||||
- public/packs-test
|
|
||||||
- tmp/cache/babel-loader
|
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: false
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
@@ -18,10 +15,7 @@ env:
|
|||||||
- LOCAL_DOMAIN=cb6e6126.ngrok.io
|
- LOCAL_DOMAIN=cb6e6126.ngrok.io
|
||||||
- LOCAL_HTTPS=true
|
- LOCAL_HTTPS=true
|
||||||
- RAILS_ENV=test
|
- RAILS_ENV=test
|
||||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
- CXX=g++-4.8
|
||||||
- PARALLEL_TEST_PROCESSORS=2
|
|
||||||
- "PATH=$HOME:$PATH"
|
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
postgresql: 9.4
|
postgresql: 9.4
|
||||||
apt:
|
apt:
|
||||||
@@ -29,11 +23,8 @@ addons:
|
|||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- trusty-media
|
- trusty-media
|
||||||
packages:
|
packages:
|
||||||
|
- g++-4.8
|
||||||
- ffmpeg
|
- ffmpeg
|
||||||
- g++-6
|
|
||||||
- libprotobuf-dev
|
|
||||||
- protobuf-compiler
|
|
||||||
- libicu-dev
|
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 2.3.4
|
- 2.3.4
|
||||||
@@ -42,18 +33,18 @@ rvm:
|
|||||||
services:
|
services:
|
||||||
- redis-server
|
- redis-server
|
||||||
|
|
||||||
|
bundler_args: --without development production --retry=3 --jobs=3
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- nvm install
|
- nvm install
|
||||||
- npm install -g yarn
|
- npm install -g yarn
|
||||||
- bundle install --path=vendor/bundle --without development production --retry=3 --jobs=16
|
- bundle install
|
||||||
- yarn install
|
- yarn install
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- bundle exec rake parallel:create parallel:load_schema parallel:prepare
|
- bundle exec rails db:create db:migrate
|
||||||
- bundle exec rails assets:precompile
|
|
||||||
- ln -s /usr/bin/x86_64-linux-gnu-g++-6 "$HOME/g++"
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
|
- bundle exec rspec
|
||||||
- npm test
|
- npm test
|
||||||
- bundle exec i18n-tasks unused
|
- i18n-tasks unused
|
||||||
|
10
Aptfile
@@ -1,10 +0,0 @@
|
|||||||
ffmpeg
|
|
||||||
libicu[0-9][0-9]
|
|
||||||
libicu-dev
|
|
||||||
libidn11
|
|
||||||
libidn11-dev
|
|
||||||
libpq-dev
|
|
||||||
libprotobuf-dev
|
|
||||||
libxdamage1
|
|
||||||
libxfixes3
|
|
||||||
protobuf-compiler
|
|
15
CODEOWNERS
@@ -1,15 +0,0 @@
|
|||||||
# CODEOWNERS for tootsuite/mastodon
|
|
||||||
|
|
||||||
# Translators
|
|
||||||
# To add translator, copy these lines, replace `fr` with appropriate language code and replace `@żelipapą` with user's GitHub nickname preceded by `@` sign or e-mail address.
|
|
||||||
# /app/javascript/mastodon/locales/fr.json @żelipapą
|
|
||||||
# /app/views/user_mailer/*.fr.html.erb @żelipapą
|
|
||||||
# /app/views/user_mailer/*.fr.text.erb @żelipapą
|
|
||||||
# /config/locales/*.fr.yml @żelipapą
|
|
||||||
# /config/locales/fr.yml @żelipapą
|
|
||||||
|
|
||||||
/app/javascript/mastodon/locales/pl.json @m4sk1n
|
|
||||||
/app/views/user_mailer/*.pl.html.erb @m4sk1n
|
|
||||||
/app/views/user_mailer/*.pl.text.erb @m4sk1n
|
|
||||||
/config/locales/*.pl.yml @m4sk1n
|
|
||||||
/config/locales/pl.yml @m4sk1n
|
|
2
Capfile
@@ -1,4 +1,3 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
require 'capistrano/setup'
|
require 'capistrano/setup'
|
||||||
require 'capistrano/deploy'
|
require 'capistrano/deploy'
|
||||||
require 'capistrano/scm/git'
|
require 'capistrano/scm/git'
|
||||||
@@ -9,6 +8,7 @@ require 'capistrano/rbenv'
|
|||||||
require 'capistrano/bundler'
|
require 'capistrano/bundler'
|
||||||
require 'capistrano/yarn'
|
require 'capistrano/yarn'
|
||||||
require 'capistrano/rails/assets'
|
require 'capistrano/rails/assets'
|
||||||
|
require 'capistrano/faster_assets'
|
||||||
require 'capistrano/rails/migrations'
|
require 'capistrano/rails/migrations'
|
||||||
|
|
||||||
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
|
||||||
|
85
Dockerfile
@@ -1,69 +1,44 @@
|
|||||||
FROM ruby:2.4.1-alpine3.6
|
FROM ruby:2.4.1-alpine
|
||||||
|
|
||||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||||
description="A GNU Social-compatible microblogging server"
|
description="A GNU Social-compatible microblogging server"
|
||||||
|
|
||||||
ENV UID=991 GID=991 \
|
ENV RAILS_ENV=production \
|
||||||
RAILS_SERVE_STATIC_FILES=true \
|
NODE_ENV=production
|
||||||
RAILS_ENV=production NODE_ENV=production
|
|
||||||
|
|
||||||
ARG LIBICONV_VERSION=1.15
|
|
||||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
|
||||||
|
|
||||||
EXPOSE 3000 4000
|
EXPOSE 3000 4000
|
||||||
|
|
||||||
WORKDIR /mastodon
|
WORKDIR /mastodon
|
||||||
|
|
||||||
RUN apk -U upgrade \
|
|
||||||
&& apk add -t build-dependencies \
|
|
||||||
build-base \
|
|
||||||
icu-dev \
|
|
||||||
libidn-dev \
|
|
||||||
libtool \
|
|
||||||
postgresql-dev \
|
|
||||||
protobuf-dev \
|
|
||||||
python \
|
|
||||||
&& apk add \
|
|
||||||
ca-certificates \
|
|
||||||
ffmpeg \
|
|
||||||
file \
|
|
||||||
git \
|
|
||||||
icu-libs \
|
|
||||||
imagemagick \
|
|
||||||
libidn \
|
|
||||||
libpq \
|
|
||||||
nodejs-npm \
|
|
||||||
nodejs \
|
|
||||||
protobuf \
|
|
||||||
su-exec \
|
|
||||||
tini \
|
|
||||||
yarn \
|
|
||||||
&& update-ca-certificates \
|
|
||||||
&& wget -O libiconv.tar.gz "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
|
||||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
|
||||||
&& mkdir -p /tmp/src \
|
|
||||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
|
||||||
&& rm libiconv.tar.gz \
|
|
||||||
&& cd /tmp/src/libiconv-$LIBICONV_VERSION \
|
|
||||||
&& ./configure --prefix=/usr/local \
|
|
||||||
&& make -j$(getconf _NPROCESSORS_ONLN)\
|
|
||||||
&& make install \
|
|
||||||
&& libtool --finish /usr/local/lib \
|
|
||||||
&& cd /mastodon \
|
|
||||||
&& rm -rf /tmp/* /var/cache/apk/*
|
|
||||||
|
|
||||||
COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/
|
COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/
|
||||||
|
|
||||||
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
|
RUN echo "@edge https://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
|
||||||
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
|
&& BUILD_DEPS=" \
|
||||||
&& yarn --ignore-optional --pure-lockfile
|
postgresql-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libxslt-dev \
|
||||||
|
python \
|
||||||
|
build-base" \
|
||||||
|
&& apk -U upgrade && apk add \
|
||||||
|
$BUILD_DEPS \
|
||||||
|
nodejs@edge \
|
||||||
|
nodejs-npm@edge \
|
||||||
|
libpq \
|
||||||
|
libxml2 \
|
||||||
|
libxslt \
|
||||||
|
ffmpeg \
|
||||||
|
file \
|
||||||
|
imagemagick@edge \
|
||||||
|
ca-certificates \
|
||||||
|
&& npm install -g npm@3 && npm install -g yarn \
|
||||||
|
&& bundle install --deployment --without test development \
|
||||||
|
&& yarn --ignore-optional \
|
||||||
|
&& yarn cache clean \
|
||||||
|
&& npm -g cache clean \
|
||||||
|
&& update-ca-certificates \
|
||||||
|
&& apk del $BUILD_DEPS \
|
||||||
|
&& rm -rf /tmp/* /var/cache/apk/*
|
||||||
|
|
||||||
COPY . /mastodon
|
COPY . /mastodon
|
||||||
|
|
||||||
COPY docker_entrypoint.sh /usr/local/bin/run
|
VOLUME /mastodon/public/system /mastodon/public/assets
|
||||||
|
|
||||||
RUN chmod +x /usr/local/bin/run
|
|
||||||
|
|
||||||
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/run"]
|
|
||||||
|
172
Gemfile
@@ -3,116 +3,104 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '>= 2.3.0', '< 2.5.0'
|
ruby '>= 2.3.0', '< 2.5.0'
|
||||||
|
|
||||||
gem 'pkg-config', '~> 1.2'
|
gem 'pkg-config'
|
||||||
|
|
||||||
gem 'puma', '~> 3.10'
|
gem 'rails', '~> 5.0.2'
|
||||||
gem 'rails', '~> 5.1.4'
|
gem 'sass-rails', '~> 5.0'
|
||||||
gem 'uglifier', '~> 3.2'
|
gem 'uglifier', '>= 1.3.0'
|
||||||
|
gem 'jquery-rails'
|
||||||
|
gem 'puma'
|
||||||
|
|
||||||
gem 'hamlit-rails', '~> 0.2'
|
gem 'hamlit-rails'
|
||||||
gem 'pg', '~> 0.20'
|
gem 'pg'
|
||||||
gem 'pghero', '~> 1.7'
|
gem 'pghero'
|
||||||
gem 'dotenv-rails', '~> 2.2'
|
gem 'dotenv-rails'
|
||||||
|
gem 'font-awesome-rails'
|
||||||
|
gem 'best_in_place', '~> 3.0.1'
|
||||||
|
|
||||||
gem 'aws-sdk', '~> 2.9'
|
|
||||||
gem 'fog-openstack', '~> 0.1'
|
|
||||||
gem 'paperclip', '~> 5.1'
|
gem 'paperclip', '~> 5.1'
|
||||||
gem 'paperclip-av-transcoder', '~> 0.6'
|
gem 'paperclip-av-transcoder'
|
||||||
|
gem 'aws-sdk', '>= 2.0'
|
||||||
|
|
||||||
gem 'active_model_serializers', '~> 0.10'
|
gem 'addressable'
|
||||||
gem 'addressable', '~> 2.5'
|
gem 'devise'
|
||||||
gem 'bootsnap'
|
gem 'devise-two-factor'
|
||||||
gem 'browser'
|
gem 'doorkeeper'
|
||||||
gem 'charlock_holmes', '~> 0.7.5'
|
gem 'fast_blank'
|
||||||
gem 'iso-639'
|
gem 'goldfinger'
|
||||||
gem 'cld3', '~> 3.2.0'
|
gem 'hiredis'
|
||||||
gem 'devise', '~> 4.2'
|
gem 'htmlentities'
|
||||||
gem 'devise-two-factor', '~> 3.0'
|
gem 'http'
|
||||||
gem 'doorkeeper', '~> 4.2'
|
gem 'http_accept_language'
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'httplog'
|
||||||
gem 'goldfinger', '~> 2.0'
|
gem 'kaminari'
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'link_header'
|
||||||
gem 'redis-namespace', '~> 1.5'
|
gem 'local_time'
|
||||||
gem 'htmlentities', '~> 4.3'
|
gem 'nokogiri'
|
||||||
gem 'http', '~> 2.2'
|
gem 'oj'
|
||||||
gem 'http_accept_language', '~> 2.1'
|
|
||||||
gem 'httplog', '~> 0.99'
|
|
||||||
gem 'idn-ruby', require: 'idn'
|
|
||||||
gem 'kaminari', '~> 1.0'
|
|
||||||
gem 'link_header', '~> 0.0'
|
|
||||||
gem 'mime-types', '~> 3.1'
|
|
||||||
gem 'nokogiri', '~> 1.7'
|
|
||||||
gem 'oj', '~> 3.0'
|
|
||||||
gem 'ostatus2', '~> 2.0'
|
gem 'ostatus2', '~> 2.0'
|
||||||
gem 'ox', '~> 2.5'
|
gem 'ox'
|
||||||
gem 'pundit', '~> 1.1'
|
gem 'rabl'
|
||||||
gem 'rabl', '~> 0.13'
|
gem 'rack-attack'
|
||||||
gem 'rack-attack', '~> 5.0'
|
gem 'rack-cors', require: 'rack/cors'
|
||||||
gem 'rack-cors', '~> 0.4', require: 'rack/cors'
|
gem 'rack-timeout'
|
||||||
gem 'rack-timeout', '~> 0.4'
|
gem 'rails-i18n'
|
||||||
gem 'rails-i18n', '~> 5.0'
|
gem 'rails-settings-cached'
|
||||||
gem 'rails-settings-cached', '~> 0.6'
|
gem 'redis', '~>3.2', require: ['redis', 'redis/connection/hiredis']
|
||||||
gem 'redis', '~> 3.3', require: ['redis', 'redis/connection/hiredis']
|
gem 'rqrcode'
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'ruby-oembed', require: 'oembed'
|
||||||
gem 'rqrcode', '~> 0.10'
|
gem 'sanitize'
|
||||||
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
gem 'sidekiq'
|
||||||
gem 'sanitize', '~> 4.4'
|
gem 'sidekiq-scheduler'
|
||||||
gem 'sidekiq', '~> 5.0'
|
gem 'sidekiq-unique-jobs'
|
||||||
gem 'sidekiq-scheduler', '~> 2.1'
|
gem 'simple-navigation'
|
||||||
gem 'sidekiq-unique-jobs', '~> 5.0'
|
gem 'simple_form'
|
||||||
gem 'sidekiq-bulk', '~>0.1.1'
|
gem 'sprockets-rails', require: 'sprockets/railtie'
|
||||||
gem 'simple-navigation', '~> 4.0'
|
gem 'statsd-instrument'
|
||||||
gem 'simple_form', '~> 3.4'
|
gem 'twitter-text'
|
||||||
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
gem 'tzinfo-data'
|
||||||
gem 'statsd-instrument', '~> 2.1'
|
gem 'whatlanguage'
|
||||||
gem 'twitter-text', '~> 1.14'
|
|
||||||
gem 'tzinfo-data', '~> 1.2017'
|
|
||||||
gem 'webpacker', '~> 2.0'
|
|
||||||
gem 'webpush'
|
|
||||||
|
|
||||||
gem 'json-ld-preloaded', '~> 2.2.1'
|
gem 'react-rails'
|
||||||
gem 'rdf-normalize', '~> 0.3.1'
|
gem 'browserify-rails'
|
||||||
|
gem 'autoprefixer-rails'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'fabrication', '~> 2.16'
|
gem 'rspec-rails'
|
||||||
gem 'fuubar', '~> 2.2'
|
gem 'pry-rails'
|
||||||
gem 'i18n-tasks', '~> 0.9', require: false
|
gem 'fuubar'
|
||||||
gem 'pry-rails', '~> 0.3'
|
gem 'fabrication'
|
||||||
gem 'rspec-rails', '~> 3.6'
|
gem 'i18n-tasks', '~> 0.9.6'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara', '~> 2.14'
|
gem 'capybara'
|
||||||
gem 'climate_control', '~> 0.2'
|
gem 'faker'
|
||||||
gem 'faker', '~> 1.7'
|
gem 'microformats2'
|
||||||
gem 'microformats', '~> 4.0'
|
gem 'rails-controller-testing'
|
||||||
gem 'rails-controller-testing', '~> 1.0'
|
gem 'rspec-sidekiq'
|
||||||
gem 'rspec-sidekiq', '~> 3.0'
|
gem 'simplecov', require: false
|
||||||
gem 'simplecov', '~> 0.14', require: false
|
gem 'webmock'
|
||||||
gem 'webmock', '~> 3.0'
|
|
||||||
gem 'parallel_tests', '~> 2.14'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'active_record_query_trace', '~> 1.5'
|
|
||||||
gem 'annotate', '~> 2.7'
|
|
||||||
gem 'better_errors', '~> 2.1'
|
|
||||||
gem 'binding_of_caller', '~> 0.7'
|
|
||||||
gem 'bullet', '~> 5.5'
|
|
||||||
gem 'letter_opener', '~> 1.4'
|
|
||||||
gem 'letter_opener_web', '~> 1.3'
|
|
||||||
gem 'rubocop', require: false
|
gem 'rubocop', require: false
|
||||||
gem 'brakeman', '~> 3.6', require: false
|
gem 'better_errors'
|
||||||
gem 'bundler-audit', '~> 0.5', require: false
|
gem 'binding_of_caller'
|
||||||
gem 'scss_lint', '~> 0.53', require: false
|
gem 'letter_opener'
|
||||||
|
gem 'letter_opener_web'
|
||||||
|
gem 'bullet'
|
||||||
|
gem 'active_record_query_trace'
|
||||||
|
|
||||||
gem 'capistrano', '~> 3.8'
|
gem 'capistrano', '3.8.0'
|
||||||
gem 'capistrano-rails', '~> 1.2'
|
gem 'capistrano-rails'
|
||||||
gem 'capistrano-rbenv', '~> 2.1'
|
gem 'capistrano-rbenv'
|
||||||
gem 'capistrano-yarn', '~> 2.0'
|
gem 'capistrano-yarn'
|
||||||
|
gem 'capistrano-faster-assets', '~> 1.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem 'lograge', '~> 0.5'
|
gem 'rails_12factor'
|
||||||
gem 'redis-rails', '~> 5.0'
|
gem 'redis-rails'
|
||||||
|
gem 'lograge'
|
||||||
end
|
end
|
||||||
|
593
Gemfile.lock
@@ -1,89 +1,87 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (5.1.4)
|
actioncable (5.0.2)
|
||||||
actionpack (= 5.1.4)
|
actionpack (= 5.0.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (>= 1.2, < 3.0)
|
||||||
websocket-driver (~> 0.6.1)
|
websocket-driver (~> 0.6.1)
|
||||||
actionmailer (5.1.4)
|
actionmailer (5.0.2)
|
||||||
actionpack (= 5.1.4)
|
actionpack (= 5.0.2)
|
||||||
actionview (= 5.1.4)
|
actionview (= 5.0.2)
|
||||||
activejob (= 5.1.4)
|
activejob (= 5.0.2)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (5.1.4)
|
actionpack (5.0.2)
|
||||||
actionview (= 5.1.4)
|
actionview (= 5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
rack (~> 2.0)
|
rack (~> 2.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (~> 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (5.1.4)
|
actionview (5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
active_model_serializers (0.10.6)
|
|
||||||
actionpack (>= 4.1, < 6)
|
|
||||||
activemodel (>= 4.1, < 6)
|
|
||||||
case_transform (>= 0.2)
|
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
|
||||||
active_record_query_trace (1.5.4)
|
active_record_query_trace (1.5.4)
|
||||||
activejob (5.1.4)
|
activejob (5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (5.1.4)
|
activemodel (5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
activerecord (5.1.4)
|
activerecord (5.0.2)
|
||||||
activemodel (= 5.1.4)
|
activemodel (= 5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
arel (~> 8.0)
|
arel (~> 7.0)
|
||||||
activesupport (5.1.4)
|
activesupport (5.0.2)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.5.2)
|
addressable (2.5.1)
|
||||||
public_suffix (>= 2.0.2, < 4.0)
|
public_suffix (~> 2.0, >= 2.0.2)
|
||||||
airbrussh (1.3.0)
|
airbrussh (1.2.0)
|
||||||
sshkit (>= 1.6.1, != 1.7.0)
|
sshkit (>= 1.6.1, != 1.7.0)
|
||||||
annotate (2.7.2)
|
arel (7.1.4)
|
||||||
activerecord (>= 3.2, < 6.0)
|
|
||||||
rake (>= 10.4, < 13.0)
|
|
||||||
arel (8.0.0)
|
|
||||||
ast (2.3.0)
|
ast (2.3.0)
|
||||||
attr_encrypted (3.0.3)
|
attr_encrypted (3.0.3)
|
||||||
encryptor (~> 3.0.0)
|
encryptor (~> 3.0.0)
|
||||||
|
autoprefixer-rails (6.7.7.2)
|
||||||
|
execjs
|
||||||
av (0.9.0)
|
av (0.9.0)
|
||||||
cocaine (~> 0.5.3)
|
cocaine (~> 0.5.3)
|
||||||
aws-sdk (2.10.21)
|
aws-sdk (2.9.12)
|
||||||
aws-sdk-resources (= 2.10.21)
|
aws-sdk-resources (= 2.9.12)
|
||||||
aws-sdk-core (2.10.21)
|
aws-sdk-core (2.9.12)
|
||||||
aws-sigv4 (~> 1.0)
|
aws-sigv4 (~> 1.0)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1.0)
|
||||||
aws-sdk-resources (2.10.21)
|
aws-sdk-resources (2.9.12)
|
||||||
aws-sdk-core (= 2.10.21)
|
aws-sdk-core (= 2.9.12)
|
||||||
aws-sigv4 (1.0.1)
|
aws-sigv4 (1.0.0)
|
||||||
|
babel-source (5.8.35)
|
||||||
|
babel-transpiler (0.7.0)
|
||||||
|
babel-source (>= 4.0, < 6)
|
||||||
|
execjs (~> 2.0)
|
||||||
bcrypt (3.1.11)
|
bcrypt (3.1.11)
|
||||||
|
best_in_place (3.0.3)
|
||||||
|
actionpack (>= 3.2)
|
||||||
|
railties (>= 3.2)
|
||||||
better_errors (2.1.1)
|
better_errors (2.1.1)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubis (>= 2.6.6)
|
erubis (>= 2.6.6)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
binding_of_caller (0.7.2)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
bootsnap (1.1.2)
|
browserify-rails (4.1.0)
|
||||||
msgpack (~> 1.0)
|
addressable (>= 2.4.0)
|
||||||
brakeman (3.7.2)
|
railties (>= 4.0.0, < 5.1)
|
||||||
browser (2.4.0)
|
sprockets (>= 3.6.0)
|
||||||
builder (3.2.3)
|
builder (3.2.3)
|
||||||
bullet (5.5.1)
|
bullet (5.5.1)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.10.0)
|
uniform_notifier (~> 1.10.0)
|
||||||
bundler-audit (0.6.0)
|
capistrano (3.8.0)
|
||||||
bundler (~> 1.2)
|
|
||||||
thor (~> 0.18)
|
|
||||||
capistrano (3.8.2)
|
|
||||||
airbrussh (>= 1.0.0)
|
airbrussh (>= 1.0.0)
|
||||||
i18n
|
i18n
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
@@ -91,7 +89,9 @@ GEM
|
|||||||
capistrano-bundler (1.2.0)
|
capistrano-bundler (1.2.0)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
sshkit (~> 1.2)
|
sshkit (~> 1.2)
|
||||||
capistrano-rails (1.3.0)
|
capistrano-faster-assets (1.0.2)
|
||||||
|
capistrano (>= 3.1)
|
||||||
|
capistrano-rails (1.2.3)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
capistrano-bundler (~> 1.1)
|
capistrano-bundler (~> 1.1)
|
||||||
capistrano-rbenv (2.1.1)
|
capistrano-rbenv (2.1.1)
|
||||||
@@ -99,34 +99,36 @@ GEM
|
|||||||
sshkit (~> 1.3)
|
sshkit (~> 1.3)
|
||||||
capistrano-yarn (2.0.2)
|
capistrano-yarn (2.0.2)
|
||||||
capistrano (~> 3.0)
|
capistrano (~> 3.0)
|
||||||
capybara (2.14.4)
|
capybara (2.13.0)
|
||||||
addressable
|
addressable
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
xpath (~> 2.0)
|
xpath (~> 2.0)
|
||||||
case_transform (0.2)
|
|
||||||
activesupport
|
|
||||||
charlock_holmes (0.7.5)
|
|
||||||
chunky_png (1.3.8)
|
chunky_png (1.3.8)
|
||||||
cld3 (3.2.0)
|
climate_control (0.1.0)
|
||||||
ffi (>= 1.1.0, < 1.10.0)
|
|
||||||
climate_control (0.2.0)
|
|
||||||
cocaine (0.5.8)
|
cocaine (0.5.8)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
coderay (1.1.1)
|
coderay (1.1.1)
|
||||||
|
coffee-rails (4.2.1)
|
||||||
|
coffee-script (>= 2.2.0)
|
||||||
|
railties (>= 4.0.0, < 5.2.x)
|
||||||
|
coffee-script (2.4.1)
|
||||||
|
coffee-script-source
|
||||||
|
execjs
|
||||||
|
coffee-script-source (1.12.2)
|
||||||
colorize (0.8.1)
|
colorize (0.8.1)
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
connection_pool (2.2.1)
|
connection_pool (2.2.1)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
crass (1.0.2)
|
crass (1.0.2)
|
||||||
debug_inspector (0.0.3)
|
debug_inspector (0.0.2)
|
||||||
devise (4.3.0)
|
devise (4.2.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0, < 5.2)
|
railties (>= 4.1.0, < 5.1)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (3.0.0)
|
devise-two-factor (3.0.0)
|
||||||
@@ -139,51 +141,37 @@ GEM
|
|||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
domain_name (0.5.20170404)
|
domain_name (0.5.20170404)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
doorkeeper (4.2.6)
|
doorkeeper (4.2.5)
|
||||||
railties (>= 4.2)
|
railties (>= 4.2)
|
||||||
dotenv (2.2.1)
|
dotenv (2.2.0)
|
||||||
dotenv-rails (2.2.1)
|
dotenv-rails (2.2.0)
|
||||||
dotenv (= 2.2.1)
|
dotenv (= 2.2.0)
|
||||||
railties (>= 3.2, < 5.2)
|
railties (>= 3.2, < 5.1)
|
||||||
easy_translate (0.5.0)
|
easy_translate (0.5.0)
|
||||||
json
|
json
|
||||||
thread
|
thread
|
||||||
thread_safe
|
thread_safe
|
||||||
encryptor (3.0.0)
|
encryptor (3.0.0)
|
||||||
erubi (1.6.1)
|
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
et-orbi (1.0.5)
|
et-orbi (1.0.3)
|
||||||
tzinfo
|
tzinfo
|
||||||
excon (0.58.0)
|
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
fabrication (2.16.2)
|
fabrication (2.16.1)
|
||||||
faker (1.7.3)
|
faker (1.7.3)
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
fast_blank (1.0.0)
|
fast_blank (1.0.0)
|
||||||
ffi (1.9.18)
|
font-awesome-rails (4.7.0.1)
|
||||||
fog-core (1.45.0)
|
railties (>= 3.2, < 5.1)
|
||||||
builder
|
|
||||||
excon (~> 0.58)
|
|
||||||
formatador (~> 0.2)
|
|
||||||
fog-json (1.0.2)
|
|
||||||
fog-core (~> 1.0)
|
|
||||||
multi_json (~> 1.10)
|
|
||||||
fog-openstack (0.1.21)
|
|
||||||
fog-core (>= 1.40)
|
|
||||||
fog-json (>= 1.0)
|
|
||||||
ipaddress (>= 0.8)
|
|
||||||
formatador (0.2.5)
|
|
||||||
fuubar (2.2.0)
|
fuubar (2.2.0)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
globalid (0.4.0)
|
globalid (0.4.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
goldfinger (2.0.1)
|
goldfinger (1.2.0)
|
||||||
addressable (~> 2.5)
|
addressable (~> 2.4)
|
||||||
http (~> 2.2)
|
http (~> 2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.6)
|
||||||
oj (~> 3.0)
|
hamlit (2.8.1)
|
||||||
hamlit (2.8.4)
|
|
||||||
temple (>= 0.8.0)
|
temple (>= 0.8.0)
|
||||||
thor
|
thor
|
||||||
tilt
|
tilt
|
||||||
@@ -192,12 +180,9 @@ GEM
|
|||||||
activesupport (>= 4.0.1)
|
activesupport (>= 4.0.1)
|
||||||
hamlit (>= 1.2.0)
|
hamlit (>= 1.2.0)
|
||||||
railties (>= 4.0.1)
|
railties (>= 4.0.1)
|
||||||
hamster (3.0.0)
|
hashdiff (0.3.2)
|
||||||
concurrent-ruby (~> 1.0)
|
|
||||||
hashdiff (0.3.5)
|
|
||||||
highline (1.7.8)
|
highline (1.7.8)
|
||||||
hiredis (0.6.1)
|
hiredis (0.6.1)
|
||||||
hkdf (0.3.0)
|
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http (2.2.2)
|
http (2.2.2)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
@@ -206,14 +191,14 @@ GEM
|
|||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (1.0.3)
|
http-form_data (1.0.1)
|
||||||
http_accept_language (2.1.1)
|
http_accept_language (2.1.0)
|
||||||
http_parser.rb (0.6.0)
|
http_parser.rb (0.6.0)
|
||||||
httplog (0.99.7)
|
httplog (0.99.3)
|
||||||
colorize
|
colorize
|
||||||
rack
|
rack
|
||||||
i18n (0.8.6)
|
i18n (0.8.1)
|
||||||
i18n-tasks (0.9.16)
|
i18n-tasks (0.9.13)
|
||||||
activesupport (>= 4.0.2)
|
activesupport (>= 4.0.2)
|
||||||
ast (>= 2.1.0)
|
ast (>= 2.1.0)
|
||||||
easy_translate (>= 0.5.0)
|
easy_translate (>= 0.5.0)
|
||||||
@@ -223,20 +208,12 @@ GEM
|
|||||||
parser (>= 2.2.3.0)
|
parser (>= 2.2.3.0)
|
||||||
rainbow (~> 2.2)
|
rainbow (~> 2.2)
|
||||||
terminal-table (>= 1.5.1)
|
terminal-table (>= 1.5.1)
|
||||||
idn-ruby (0.1.0)
|
|
||||||
ipaddress (0.8.3)
|
|
||||||
iso-639 (0.2.8)
|
|
||||||
jmespath (1.3.1)
|
jmespath (1.3.1)
|
||||||
|
jquery-rails (4.3.1)
|
||||||
|
rails-dom-testing (>= 1, < 3)
|
||||||
|
railties (>= 4.2.0)
|
||||||
|
thor (>= 0.14, < 2.0)
|
||||||
json (2.1.0)
|
json (2.1.0)
|
||||||
json-ld (2.1.5)
|
|
||||||
multi_json (~> 1.12)
|
|
||||||
rdf (~> 2.2)
|
|
||||||
json-ld-preloaded (2.2.1)
|
|
||||||
json-ld (~> 2.1, >= 2.1.5)
|
|
||||||
multi_json (~> 1.11)
|
|
||||||
rdf (~> 2.2)
|
|
||||||
jsonapi-renderer (0.1.3)
|
|
||||||
jwt (1.5.6)
|
|
||||||
kaminari (1.0.1)
|
kaminari (1.0.1)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
kaminari-actionview (= 1.0.1)
|
kaminari-actionview (= 1.0.1)
|
||||||
@@ -258,45 +235,44 @@ GEM
|
|||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
link_header (0.0.8)
|
link_header (0.0.8)
|
||||||
lograge (0.5.1)
|
local_time (1.0.3)
|
||||||
actionpack (>= 4, < 5.2)
|
coffee-rails
|
||||||
activesupport (>= 4, < 5.2)
|
lograge (0.4.1)
|
||||||
railties (>= 4, < 5.2)
|
actionpack (>= 4, < 5.1)
|
||||||
|
activesupport (>= 4, < 5.1)
|
||||||
|
railties (>= 4, < 5.1)
|
||||||
loofah (2.0.3)
|
loofah (2.0.3)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.6)
|
mail (2.6.5)
|
||||||
mime-types (>= 1.16, < 4)
|
mime-types (>= 1.16, < 4)
|
||||||
mario-redis-lock (1.2.0)
|
|
||||||
redis (~> 3, >= 3.0.5)
|
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
microformats (4.0.7)
|
microformats2 (2.1.0)
|
||||||
|
activesupport
|
||||||
json
|
json
|
||||||
nokogiri
|
nokogiri
|
||||||
mime-types (3.1)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2016.0521)
|
mime-types-data (3.2016.0521)
|
||||||
mimemagic (0.3.2)
|
mimemagic (0.3.2)
|
||||||
mini_portile2 (2.2.0)
|
mini_portile2 (2.1.0)
|
||||||
minitest (5.10.3)
|
minitest (5.10.1)
|
||||||
msgpack (1.1.0)
|
|
||||||
multi_json (1.12.1)
|
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (4.1.0)
|
net-ssh (4.1.0)
|
||||||
nio4r (2.1.0)
|
nio4r (2.0.0)
|
||||||
nokogiri (1.8.0)
|
nokogiri (1.7.1)
|
||||||
mini_portile2 (~> 2.2.0)
|
mini_portile2 (~> 2.1.0)
|
||||||
nokogumbo (1.4.13)
|
nokogumbo (1.4.10)
|
||||||
nokogiri
|
nokogiri
|
||||||
oj (3.3.4)
|
oj (3.0.2)
|
||||||
openssl (2.0.4)
|
openssl (2.0.3)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ostatus2 (2.0.1)
|
ostatus2 (2.0.0)
|
||||||
addressable (~> 2.4)
|
addressable (~> 2.4)
|
||||||
http (~> 2.0)
|
http (~> 2.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
openssl (~> 2.0)
|
openssl (~> 2.0)
|
||||||
ox (2.5.0)
|
ox (2.4.13)
|
||||||
paperclip (5.1.0)
|
paperclip (5.1.0)
|
||||||
activemodel (>= 4.2.0)
|
activemodel (>= 4.2.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
@@ -306,15 +282,12 @@ GEM
|
|||||||
paperclip-av-transcoder (0.6.4)
|
paperclip-av-transcoder (0.6.4)
|
||||||
av (~> 0.9.0)
|
av (~> 0.9.0)
|
||||||
paperclip (>= 2.5.2)
|
paperclip (>= 2.5.2)
|
||||||
parallel (1.11.2)
|
|
||||||
parallel_tests (2.14.2)
|
|
||||||
parallel
|
|
||||||
parser (2.4.0.0)
|
parser (2.4.0.0)
|
||||||
ast (~> 2.2)
|
ast (~> 2.2)
|
||||||
pg (0.21.0)
|
pg (0.20.0)
|
||||||
pghero (1.7.0)
|
pghero (1.6.5)
|
||||||
activerecord
|
activerecord
|
||||||
pkg-config (1.2.4)
|
pkg-config (1.2.0)
|
||||||
powerpack (0.1.1)
|
powerpack (0.1.1)
|
||||||
pry (0.10.4)
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
@@ -322,71 +295,73 @@ GEM
|
|||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
pry-rails (0.3.6)
|
pry-rails (0.3.6)
|
||||||
pry (>= 0.10.4)
|
pry (>= 0.10.4)
|
||||||
public_suffix (3.0.0)
|
public_suffix (2.0.5)
|
||||||
puma (3.10.0)
|
puma (3.8.2)
|
||||||
pundit (1.1.0)
|
|
||||||
activesupport (>= 3.0.0)
|
|
||||||
rabl (0.13.1)
|
rabl (0.13.1)
|
||||||
activesupport (>= 2.3.14)
|
activesupport (>= 2.3.14)
|
||||||
rack (2.0.3)
|
rack (2.0.1)
|
||||||
rack-attack (5.0.1)
|
rack-attack (5.0.1)
|
||||||
rack
|
rack
|
||||||
rack-cors (0.4.1)
|
rack-cors (0.4.1)
|
||||||
rack-protection (2.0.0)
|
rack-protection (1.5.3)
|
||||||
rack
|
rack
|
||||||
rack-test (0.7.0)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0)
|
||||||
rack-timeout (0.4.2)
|
rack-timeout (0.4.2)
|
||||||
rails (5.1.4)
|
rails (5.0.2)
|
||||||
actioncable (= 5.1.4)
|
actioncable (= 5.0.2)
|
||||||
actionmailer (= 5.1.4)
|
actionmailer (= 5.0.2)
|
||||||
actionpack (= 5.1.4)
|
actionpack (= 5.0.2)
|
||||||
actionview (= 5.1.4)
|
actionview (= 5.0.2)
|
||||||
activejob (= 5.1.4)
|
activejob (= 5.0.2)
|
||||||
activemodel (= 5.1.4)
|
activemodel (= 5.0.2)
|
||||||
activerecord (= 5.1.4)
|
activerecord (= 5.0.2)
|
||||||
activesupport (= 5.1.4)
|
activesupport (= 5.0.2)
|
||||||
bundler (>= 1.3.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 5.1.4)
|
railties (= 5.0.2)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-controller-testing (1.0.2)
|
rails-controller-testing (1.0.1)
|
||||||
actionpack (~> 5.x, >= 5.0.1)
|
actionpack (~> 5.x)
|
||||||
actionview (~> 5.x, >= 5.0.1)
|
actionview (~> 5.x)
|
||||||
activesupport (~> 5.x)
|
activesupport (~> 5.x)
|
||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.0.2)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0, < 6.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (~> 1.6)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
rails-i18n (5.0.4)
|
rails-i18n (5.0.3)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
railties (~> 5.0)
|
railties (~> 5.0)
|
||||||
rails-settings-cached (0.6.6)
|
rails-settings-cached (0.6.5)
|
||||||
rails (>= 4.2.0)
|
rails (>= 4.2.0)
|
||||||
railties (5.1.4)
|
rails_12factor (0.0.3)
|
||||||
actionpack (= 5.1.4)
|
rails_serve_static_assets
|
||||||
activesupport (= 5.1.4)
|
rails_stdout_logging
|
||||||
|
rails_serve_static_assets (0.0.5)
|
||||||
|
rails_stdout_logging (0.0.5)
|
||||||
|
railties (5.0.2)
|
||||||
|
actionpack (= 5.0.2)
|
||||||
|
activesupport (= 5.0.2)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.2.2)
|
rainbow (2.2.2)
|
||||||
rake
|
rake
|
||||||
rake (12.0.0)
|
rake (12.0.0)
|
||||||
rdf (2.2.8)
|
react-rails (1.11.0)
|
||||||
hamster (~> 3.0)
|
babel-transpiler (>= 0.7.0)
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
connection_pool
|
||||||
rdf-normalize (0.3.2)
|
execjs
|
||||||
rdf (~> 2.0)
|
railties (>= 3.2)
|
||||||
|
tilt
|
||||||
redis (3.3.3)
|
redis (3.3.3)
|
||||||
redis-actionpack (5.0.1)
|
redis-actionpack (5.0.1)
|
||||||
actionpack (>= 4.0, < 6)
|
actionpack (>= 4.0, < 6)
|
||||||
redis-rack (>= 1, < 3)
|
redis-rack (>= 1, < 3)
|
||||||
redis-store (>= 1.1.0, < 1.4.0)
|
redis-store (>= 1.1.0, < 1.4.0)
|
||||||
redis-activesupport (5.0.3)
|
redis-activesupport (5.0.2)
|
||||||
activesupport (>= 3, < 6)
|
activesupport (>= 3, < 6)
|
||||||
redis-store (~> 1.3.0)
|
redis-store (~> 1.3.0)
|
||||||
redis-namespace (1.5.3)
|
|
||||||
redis (~> 3.0, >= 3.0.4)
|
|
||||||
redis-rack (2.0.2)
|
redis-rack (2.0.2)
|
||||||
rack (>= 1.5, < 3)
|
rack (>= 1.5, < 3)
|
||||||
redis-store (>= 1.2, < 1.4)
|
redis-store (>= 1.2, < 1.4)
|
||||||
@@ -396,34 +371,32 @@ GEM
|
|||||||
redis-store (>= 1.2, < 2)
|
redis-store (>= 1.2, < 2)
|
||||||
redis-store (1.3.0)
|
redis-store (1.3.0)
|
||||||
redis (>= 2.2)
|
redis (>= 2.2)
|
||||||
responders (2.4.0)
|
responders (2.3.0)
|
||||||
actionpack (>= 4.2.0, < 5.3)
|
railties (>= 4.2.0, < 5.1)
|
||||||
railties (>= 4.2.0, < 5.3)
|
|
||||||
rotp (2.1.2)
|
rotp (2.1.2)
|
||||||
rqrcode (0.10.1)
|
rqrcode (0.10.1)
|
||||||
chunky_png (~> 1.0)
|
chunky_png (~> 1.0)
|
||||||
rspec-core (3.6.0)
|
rspec-core (3.5.4)
|
||||||
rspec-support (~> 3.6.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-expectations (3.6.0)
|
rspec-expectations (3.5.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.6.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-mocks (3.6.0)
|
rspec-mocks (3.5.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.6.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-rails (3.6.0)
|
rspec-rails (3.5.2)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec-core (~> 3.6.0)
|
rspec-core (~> 3.5.0)
|
||||||
rspec-expectations (~> 3.6.0)
|
rspec-expectations (~> 3.5.0)
|
||||||
rspec-mocks (~> 3.6.0)
|
rspec-mocks (~> 3.5.0)
|
||||||
rspec-support (~> 3.6.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-sidekiq (3.0.3)
|
rspec-sidekiq (3.0.0)
|
||||||
rspec-core (~> 3.0, >= 3.0.0)
|
rspec-core (~> 3.0, >= 3.0.0)
|
||||||
sidekiq (>= 2.4.0)
|
sidekiq (>= 2.4.0)
|
||||||
rspec-support (3.6.0)
|
rspec-support (3.5.0)
|
||||||
rubocop (0.49.1)
|
rubocop (0.48.1)
|
||||||
parallel (~> 1.10)
|
|
||||||
parser (>= 2.3.3.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
@@ -431,63 +404,63 @@ GEM
|
|||||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
ruby-oembed (0.12.0)
|
ruby-oembed (0.12.0)
|
||||||
ruby-progressbar (1.8.1)
|
ruby-progressbar (1.8.1)
|
||||||
rufus-scheduler (3.4.2)
|
rufus-scheduler (3.4.0)
|
||||||
et-orbi (~> 1.0)
|
et-orbi (~> 1.0)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
sanitize (4.5.0)
|
sanitize (4.4.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.4.4)
|
nokogiri (>= 1.4.4)
|
||||||
nokogumbo (~> 1.4.1)
|
nokogumbo (~> 1.4.1)
|
||||||
sass (3.4.24)
|
sass (3.4.23)
|
||||||
scss_lint (0.54.0)
|
sass-rails (5.0.6)
|
||||||
rake (>= 0.9, < 13)
|
railties (>= 4.0.0, < 6)
|
||||||
sass (~> 3.4.20)
|
sass (~> 3.1)
|
||||||
sidekiq (5.0.4)
|
sprockets (>= 2.8, < 4.0)
|
||||||
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
|
tilt (>= 1.1, < 3)
|
||||||
|
sidekiq (4.2.10)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
connection_pool (~> 2.2, >= 2.2.0)
|
connection_pool (~> 2.2, >= 2.2.0)
|
||||||
rack-protection (>= 1.5.0)
|
rack-protection (>= 1.5.0)
|
||||||
redis (~> 3.3, >= 3.3.3)
|
redis (~> 3.2, >= 3.2.1)
|
||||||
sidekiq-bulk (0.1.1)
|
sidekiq-scheduler (2.1.4)
|
||||||
activesupport
|
|
||||||
sidekiq
|
|
||||||
sidekiq-scheduler (2.1.8)
|
|
||||||
redis (~> 3)
|
redis (~> 3)
|
||||||
rufus-scheduler (~> 3.2)
|
rufus-scheduler (~> 3.2)
|
||||||
sidekiq (>= 3)
|
sidekiq (>= 3)
|
||||||
tilt (>= 1.4.0)
|
tilt (>= 1.4.0)
|
||||||
sidekiq-unique-jobs (5.0.9)
|
sidekiq-unique-jobs (5.0.0)
|
||||||
sidekiq (>= 4.0, <= 6.0)
|
sidekiq (>= 4.0)
|
||||||
thor (~> 0)
|
thor
|
||||||
simple-navigation (4.0.5)
|
simple-navigation (4.0.5)
|
||||||
activesupport (>= 2.3.2)
|
activesupport (>= 2.3.2)
|
||||||
simple_form (3.5.0)
|
simple_form (3.4.0)
|
||||||
actionpack (> 4, < 5.2)
|
actionpack (> 4, < 5.1)
|
||||||
activemodel (> 4, < 5.2)
|
activemodel (> 4, < 5.1)
|
||||||
simplecov (0.14.1)
|
simplecov (0.14.1)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.1)
|
simplecov-html (0.10.0)
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
sprockets (3.7.1)
|
sprockets (3.7.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
sprockets-rails (3.2.1)
|
sprockets-rails (3.2.0)
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sshkit (1.13.1)
|
sshkit (1.13.1)
|
||||||
net-scp (>= 1.1.2)
|
net-scp (>= 1.1.2)
|
||||||
net-ssh (>= 2.8.0)
|
net-ssh (>= 2.8.0)
|
||||||
statsd-instrument (2.1.4)
|
statsd-instrument (2.1.2)
|
||||||
temple (0.8.0)
|
temple (0.8.0)
|
||||||
terminal-table (1.8.0)
|
terminal-table (1.7.3)
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
unicode-display_width (~> 1.1.1)
|
||||||
thor (0.20.0)
|
thor (0.19.4)
|
||||||
thread (0.2.2)
|
thread (0.2.2)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.8)
|
tilt (2.0.7)
|
||||||
twitter-text (1.14.7)
|
twitter-text (1.14.5)
|
||||||
unf (~> 0.1.0)
|
unf (~> 0.1.0)
|
||||||
tzinfo (1.2.3)
|
tzinfo (1.2.3)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
@@ -498,7 +471,7 @@ GEM
|
|||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.4)
|
unf_ext (0.0.7.4)
|
||||||
unicode-display_width (1.3.0)
|
unicode-display_width (1.1.3)
|
||||||
uniform_notifier (1.10.0)
|
uniform_notifier (1.10.0)
|
||||||
warden (1.2.7)
|
warden (1.2.7)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
@@ -506,121 +479,103 @@ GEM
|
|||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff
|
hashdiff
|
||||||
webpacker (2.0)
|
|
||||||
activesupport (>= 4.2)
|
|
||||||
multi_json (~> 1.2)
|
|
||||||
railties (>= 4.2)
|
|
||||||
webpush (0.3.2)
|
|
||||||
hkdf (~> 0.2)
|
|
||||||
jwt
|
|
||||||
websocket-driver (0.6.5)
|
websocket-driver (0.6.5)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.2)
|
websocket-extensions (0.1.2)
|
||||||
xpath (2.1.0)
|
whatlanguage (1.0.6)
|
||||||
|
xpath (2.0.0)
|
||||||
nokogiri (~> 1.3)
|
nokogiri (~> 1.3)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
active_model_serializers (~> 0.10)
|
active_record_query_trace
|
||||||
active_record_query_trace (~> 1.5)
|
addressable
|
||||||
addressable (~> 2.5)
|
autoprefixer-rails
|
||||||
annotate (~> 2.7)
|
aws-sdk (>= 2.0)
|
||||||
aws-sdk (~> 2.9)
|
best_in_place (~> 3.0.1)
|
||||||
better_errors (~> 2.1)
|
better_errors
|
||||||
binding_of_caller (~> 0.7)
|
binding_of_caller
|
||||||
bootsnap
|
browserify-rails
|
||||||
brakeman (~> 3.6)
|
bullet
|
||||||
browser
|
capistrano (= 3.8.0)
|
||||||
bullet (~> 5.5)
|
capistrano-faster-assets (~> 1.0)
|
||||||
bundler-audit (~> 0.5)
|
capistrano-rails
|
||||||
capistrano (~> 3.8)
|
capistrano-rbenv
|
||||||
capistrano-rails (~> 1.2)
|
capistrano-yarn
|
||||||
capistrano-rbenv (~> 2.1)
|
capybara
|
||||||
capistrano-yarn (~> 2.0)
|
devise
|
||||||
capybara (~> 2.14)
|
devise-two-factor
|
||||||
charlock_holmes (~> 0.7.5)
|
doorkeeper
|
||||||
cld3 (~> 3.2.0)
|
dotenv-rails
|
||||||
climate_control (~> 0.2)
|
fabrication
|
||||||
devise (~> 4.2)
|
faker
|
||||||
devise-two-factor (~> 3.0)
|
fast_blank
|
||||||
doorkeeper (~> 4.2)
|
font-awesome-rails
|
||||||
dotenv-rails (~> 2.2)
|
fuubar
|
||||||
fabrication (~> 2.16)
|
goldfinger
|
||||||
faker (~> 1.7)
|
hamlit-rails
|
||||||
fast_blank (~> 1.0)
|
hiredis
|
||||||
fog-openstack (~> 0.1)
|
htmlentities
|
||||||
fuubar (~> 2.2)
|
http
|
||||||
goldfinger (~> 2.0)
|
http_accept_language
|
||||||
hamlit-rails (~> 0.2)
|
httplog
|
||||||
hiredis (~> 0.6)
|
i18n-tasks (~> 0.9.6)
|
||||||
htmlentities (~> 4.3)
|
jquery-rails
|
||||||
http (~> 2.2)
|
kaminari
|
||||||
http_accept_language (~> 2.1)
|
letter_opener
|
||||||
httplog (~> 0.99)
|
letter_opener_web
|
||||||
i18n-tasks (~> 0.9)
|
link_header
|
||||||
idn-ruby
|
local_time
|
||||||
iso-639
|
lograge
|
||||||
json-ld-preloaded (~> 2.2.1)
|
microformats2
|
||||||
kaminari (~> 1.0)
|
nokogiri
|
||||||
letter_opener (~> 1.4)
|
oj
|
||||||
letter_opener_web (~> 1.3)
|
|
||||||
link_header (~> 0.0)
|
|
||||||
lograge (~> 0.5)
|
|
||||||
mario-redis-lock (~> 1.2)
|
|
||||||
microformats (~> 4.0)
|
|
||||||
mime-types (~> 3.1)
|
|
||||||
nokogiri (~> 1.7)
|
|
||||||
oj (~> 3.0)
|
|
||||||
ostatus2 (~> 2.0)
|
ostatus2 (~> 2.0)
|
||||||
ox (~> 2.5)
|
ox
|
||||||
paperclip (~> 5.1)
|
paperclip (~> 5.1)
|
||||||
paperclip-av-transcoder (~> 0.6)
|
paperclip-av-transcoder
|
||||||
parallel_tests (~> 2.14)
|
pg
|
||||||
pg (~> 0.20)
|
pghero
|
||||||
pghero (~> 1.7)
|
pkg-config
|
||||||
pkg-config (~> 1.2)
|
pry-rails
|
||||||
pry-rails (~> 0.3)
|
puma
|
||||||
puma (~> 3.10)
|
rabl
|
||||||
pundit (~> 1.1)
|
rack-attack
|
||||||
rabl (~> 0.13)
|
rack-cors
|
||||||
rack-attack (~> 5.0)
|
rack-timeout
|
||||||
rack-cors (~> 0.4)
|
rails (~> 5.0.2)
|
||||||
rack-timeout (~> 0.4)
|
rails-controller-testing
|
||||||
rails (~> 5.1.4)
|
rails-i18n
|
||||||
rails-controller-testing (~> 1.0)
|
rails-settings-cached
|
||||||
rails-i18n (~> 5.0)
|
rails_12factor
|
||||||
rails-settings-cached (~> 0.6)
|
react-rails
|
||||||
rdf-normalize (~> 0.3.1)
|
redis (~> 3.2)
|
||||||
redis (~> 3.3)
|
redis-rails
|
||||||
redis-namespace (~> 1.5)
|
rqrcode
|
||||||
redis-rails (~> 5.0)
|
rspec-rails
|
||||||
rqrcode (~> 0.10)
|
rspec-sidekiq
|
||||||
rspec-rails (~> 3.6)
|
|
||||||
rspec-sidekiq (~> 3.0)
|
|
||||||
rubocop
|
rubocop
|
||||||
ruby-oembed (~> 0.12)
|
ruby-oembed
|
||||||
sanitize (~> 4.4)
|
sanitize
|
||||||
scss_lint (~> 0.53)
|
sass-rails (~> 5.0)
|
||||||
sidekiq (~> 5.0)
|
sidekiq
|
||||||
sidekiq-bulk (~> 0.1.1)
|
sidekiq-scheduler
|
||||||
sidekiq-scheduler (~> 2.1)
|
sidekiq-unique-jobs
|
||||||
sidekiq-unique-jobs (~> 5.0)
|
simple-navigation
|
||||||
simple-navigation (~> 4.0)
|
simple_form
|
||||||
simple_form (~> 3.4)
|
simplecov
|
||||||
simplecov (~> 0.14)
|
sprockets-rails
|
||||||
sprockets-rails (~> 3.2)
|
statsd-instrument
|
||||||
statsd-instrument (~> 2.1)
|
twitter-text
|
||||||
twitter-text (~> 1.14)
|
tzinfo-data
|
||||||
tzinfo-data (~> 1.2017)
|
uglifier (>= 1.3.0)
|
||||||
uglifier (~> 3.2)
|
webmock
|
||||||
webmock (~> 3.0)
|
whatlanguage
|
||||||
webpacker (~> 2.0)
|
|
||||||
webpush
|
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 2.4.1p111
|
ruby 2.4.1p111
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.15.4
|
1.14.6
|
||||||
|
@@ -1,4 +0,0 @@
|
|||||||
web: PORT=3000 bundle exec puma -C config/puma.rb
|
|
||||||
sidekiq: PORT=3000 bundle exec sidekiq
|
|
||||||
stream: PORT=4000 yarn run start
|
|
||||||
webpack: ./bin/webpack-dev-server --host 0.0.0.0
|
|
12
README.md
@@ -1,4 +1,4 @@
|
|||||||

|
Mastodon
|
||||||
========
|
========
|
||||||
|
|
||||||
[][travis]
|
[][travis]
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
Mastodon is a free, open-source social network server. A decentralized solution to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly.
|
Mastodon is a free, open-source social network server. A decentralized solution to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly.
|
||||||
|
|
||||||
An alternative implementation of the GNU social project. Based on [ActivityStreams](https://en.wikipedia.org/wiki/Activity_Streams_(format)), [Webfinger](https://en.wikipedia.org/wiki/WebFinger), [WebSub](https://en.wikipedia.org/wiki/WebSub) and [Salmon](https://en.wikipedia.org/wiki/Salmon_(protocol)).
|
An alternative implementation of the GNU social project. Based on [ActivityStreams](https://en.wikipedia.org/wiki/Activity_Streams_(format)), [Webfinger](https://en.wikipedia.org/wiki/WebFinger), [PubsubHubbub](https://en.wikipedia.org/wiki/PubSubHubbub) and [Salmon](https://en.wikipedia.org/wiki/Salmon_(protocol)).
|
||||||
|
|
||||||
Click on the screenshot to watch a demo of the UI:
|
Click on the screenshot to watch a demo of the UI:
|
||||||
|
|
||||||
[][youtube_demo]
|
[][youtube_demo]
|
||||||
|
|
||||||
[youtube_demo]: https://www.youtube.com/watch?v=YO1jQ8_rAMU
|
[youtube_demo]: https://www.youtube.com/watch?v=YO1jQ8_rAMU
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ If you would like, you can [support the development of this project on Patreon][
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Fully interoperable with GNU social and any OStatus platform**
|
- **Fully interoperable with GNU social and any OStatus platform**
|
||||||
Whatever implements Atom feeds, ActivityStreams, Salmon, WebSub and Webfinger is part of the network
|
Whatever implements Atom feeds, ActivityStreams, Salmon, PubSubHubbub and Webfinger is part of the network
|
||||||
- **Real-time timeline updates**
|
- **Real-time timeline updates**
|
||||||
See the updates of people you're following appear in real-time in the UI via WebSockets
|
See the updates of people you're following appear in real-time in the UI via WebSockets
|
||||||
- **Federated thread resolving**
|
- **Federated thread resolving**
|
||||||
@@ -47,10 +47,6 @@ If you would like, you can [support the development of this project on Patreon][
|
|||||||
Mastodon tries to be as fast and responsive as possible, so all long-running tasks that can be delegated to background processing, are
|
Mastodon tries to be as fast and responsive as possible, so all long-running tasks that can be delegated to background processing, are
|
||||||
- **Deployable via Docker**
|
- **Deployable via Docker**
|
||||||
You don't need to mess with dependencies and configuration if you want to try Mastodon, if you have Docker and Docker Compose the deployment is extremely easy
|
You don't need to mess with dependencies and configuration if you want to try Mastodon, if you have Docker and Docker Compose the deployment is extremely easy
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
Please follow the [development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md) from the documentation repository.
|
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
|
37
Vagrantfile
vendored
@@ -1,8 +1,6 @@
|
|||||||
# -*- mode: ruby -*-
|
# -*- mode: ruby -*-
|
||||||
# vi: set ft=ruby :
|
# vi: set ft=ruby :
|
||||||
|
|
||||||
ENV["PORT"] ||= "3000"
|
|
||||||
|
|
||||||
$provision = <<SCRIPT
|
$provision = <<SCRIPT
|
||||||
|
|
||||||
cd /vagrant # This is where the host folder/repo is mounted
|
cd /vagrant # This is where the host folder/repo is mounted
|
||||||
@@ -12,10 +10,10 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
|||||||
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
||||||
|
|
||||||
# Add repo for NodeJS
|
# Add repo for NodeJS
|
||||||
curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
|
curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
|
||||||
|
|
||||||
# Add firewall rule to redirect 80 to PORT and save
|
# Add firewall rule to redirect 80 to 3000 and save
|
||||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000
|
||||||
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
|
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
|
||||||
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
|
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
|
||||||
sudo apt-get install iptables-persistent -y
|
sudo apt-get install iptables-persistent -y
|
||||||
@@ -33,45 +31,38 @@ sudo apt-get install \
|
|||||||
redis-tools \
|
redis-tools \
|
||||||
postgresql \
|
postgresql \
|
||||||
postgresql-contrib \
|
postgresql-contrib \
|
||||||
protobuf-compiler \
|
|
||||||
yarn \
|
yarn \
|
||||||
libicu-dev \
|
|
||||||
libidn11-dev \
|
|
||||||
libprotobuf-dev \
|
|
||||||
libreadline-dev \
|
libreadline-dev \
|
||||||
-y
|
-y
|
||||||
|
|
||||||
# Install rvm
|
# Install rvm
|
||||||
|
cd /vagrant
|
||||||
read RUBY_VERSION < .ruby-version
|
read RUBY_VERSION < .ruby-version
|
||||||
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
||||||
curl -sSL https://raw.githubusercontent.com/rvm/rvm/stable/binscripts/rvm-installer | bash -s stable --ruby=$RUBY_VERSION
|
curl -sSL https://get.rvm.io | bash -s stable --ruby=$RUBY_VERSION
|
||||||
source /home/vagrant/.rvm/scripts/rvm
|
source /home/vagrant/.rvm/scripts/rvm
|
||||||
|
|
||||||
# Install Ruby
|
|
||||||
rvm install ruby-$RUBY_VERSION
|
|
||||||
|
|
||||||
# Configure database
|
# Configure database
|
||||||
sudo -u postgres createuser -U postgres vagrant -s
|
sudo -u postgres createuser -U postgres vagrant -s
|
||||||
sudo -u postgres createdb -U postgres mastodon_development
|
sudo -u postgres createdb -U postgres mastodon_development
|
||||||
|
|
||||||
# Install gems and node modules
|
# Install gems and node modules
|
||||||
gem install bundler foreman
|
gem install bundler
|
||||||
bundle install
|
bundle install
|
||||||
yarn install
|
yarn install
|
||||||
|
|
||||||
# Build Mastodon
|
# Build Mastodon
|
||||||
export $(cat ".env.vagrant" | xargs)
|
export $(cat ".env.vagrant" | xargs)
|
||||||
bundle exec rails db:setup
|
bundle exec rails db:setup
|
||||||
|
bundle exec rails assets:precompile
|
||||||
# Configure automatic loading of environment variable
|
|
||||||
echo 'export $(cat "/vagrant/.env.vagrant" | xargs)' >> ~/.bash_profile
|
|
||||||
|
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
||||||
$start = <<SCRIPT
|
$start = <<SCRIPT
|
||||||
|
|
||||||
echo 'To start server'
|
cd /vagrant
|
||||||
echo ' $ vagrant ssh -c "cd /vagrant && foreman start"'
|
export $(cat ".env.vagrant" | xargs)
|
||||||
|
rails s -d -b 0.0.0.0
|
||||||
|
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
||||||
@@ -83,7 +74,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||||||
|
|
||||||
config.vm.provider :virtualbox do |vb|
|
config.vm.provider :virtualbox do |vb|
|
||||||
vb.name = "mastodon"
|
vb.name = "mastodon"
|
||||||
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
vb.customize ["modifyvm", :id, "--memory", "1024"]
|
||||||
|
|
||||||
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
||||||
# https://github.com/mitchellh/vagrant/issues/1172
|
# https://github.com/mitchellh/vagrant/issues/1172
|
||||||
@@ -113,10 +104,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||||||
config.vm.synced_folder ".", "/vagrant"
|
config.vm.synced_folder ".", "/vagrant"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080
|
# Otherwise, you can access the site at http://localhost:3000
|
||||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
config.vm.network :forwarded_port, guest: 80, host: 3000
|
||||||
config.vm.network :forwarded_port, guest: 4000, host: 4000
|
|
||||||
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
|
||||||
|
|
||||||
# Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision'
|
# Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision'
|
||||||
config.vm.provision :shell, inline: $provision, privileged: false
|
config.vm.provision :shell, inline: $provision, privileged: false
|
||||||
|
5
app.json
@@ -2,7 +2,7 @@
|
|||||||
"name": "Mastodon",
|
"name": "Mastodon",
|
||||||
"description": "A GNU Social-compatible microblogging server",
|
"description": "A GNU Social-compatible microblogging server",
|
||||||
"repository": "https://github.com/tootsuite/mastodon",
|
"repository": "https://github.com/tootsuite/mastodon",
|
||||||
"logo": "https://github.com/tootsuite.png",
|
"logo": "https://github.com/tootsuite/mastodon/raw/master/app/assets/images/logo.png",
|
||||||
"env": {
|
"env": {
|
||||||
"HEROKU": {
|
"HEROKU": {
|
||||||
"description": "Leave this as true",
|
"description": "Leave this as true",
|
||||||
@@ -94,9 +94,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buildpacks": [
|
"buildpacks": [
|
||||||
{
|
|
||||||
"url": "https://github.com/heroku/heroku-buildpack-apt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "heroku/nodejs"
|
"url": "heroku/nodejs"
|
||||||
},
|
},
|
||||||
|
BIN
app/assets/fonts/montserrat/Montserrat-Regular.eot
Normal file
BIN
app/assets/fonts/roboto-mono/robotomono-regular-webfont.eot
Normal file
Before Width: | Height: | Size: 339 KiB After Width: | Height: | Size: 339 KiB |
BIN
app/assets/fonts/roboto/roboto-bold-webfont.eot
Normal file
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
app/assets/fonts/roboto/roboto-italic-webfont.eot
Normal file
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
app/assets/fonts/roboto/roboto-medium-webfont.eot
Normal file
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
BIN
app/assets/fonts/roboto/roboto-regular-webfont.eot
Normal file
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
BIN
app/assets/images/background-photo.jpg
Normal file
After Width: | Height: | Size: 258 KiB |
BIN
app/assets/images/boost_sprite.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
BIN
app/assets/images/fluffy-elephant-friend.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
app/assets/images/logo.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
1
app/assets/images/logo.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" height="1000" width="1000"><path d="M500 0a500 500 0 0 0-353.553 146.447 500 500 0 1 0 707.106 707.106A500 500 0 0 0 500 0zm-.059 280.05h107.12c-19.071 13.424-26.187 51.016-27.12 73.843V562.05c0 44.32-35.68 80-80 80s-80-35.68-80-80v-202c0-44.32 35.68-80 80-80zm-.441 52c-15.464 0-28 12.537-28 28 0 15.465 12.536 28 28 28s28-12.535 28-28c0-15.463-12.536-28-28-28zm-279.059 7.9c44.32 0 80 35.68 80 80v206.157c.933 22.827 8.049 60.42 27.12 73.842H220.44c-44.32 0-80-35.68-80-80v-200c0-44.32 35.68-80 80-80zm559.12 0c44.32 0 80 35.68 80 80v200c0 44.32-35.68 80-80 80H672.44c19.071-13.424 26.187-51.016 27.12-73.843V419.95c0-44.32 35.68-80 80-80zM220 392c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28zm560 0c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28zm-280.5 40.05c-15.464 0-28 12.537-28 28 0 15.465 12.536 28 28 28s28-12.535 28-28c0-15.463-12.536-28-28-28zM220 491.95c-15.464 0-28 12.535-28 28 0 15.463 12.536 28 28 28s28-12.537 28-28c0-15.465-12.536-28-28-28zm560 0c-15.464 0-28 12.535-28 28 0 15.463 12.536 28 28 28s28-12.537 28-28c0-15.465-12.536-28-28-28zM499.5 532c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28zM220 591.95c-15.464 0-28 12.535-28 28 0 15.463 12.536 28 28 28s28-12.537 28-28c0-15.465-12.536-28-28-28zm560 0c-15.464 0-28 12.535-28 28 0 15.463 12.536 28 28 28s28-12.537 28-28c0-15.465-12.536-28-28-28z" fill="#189efc"/></svg>
|
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
BIN
app/assets/images/mastodon.jpg
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
app/assets/images/mastodon_small.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
app/assets/images/screenshot.png
Normal file
After Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
15
app/assets/javascripts/application.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||||
|
// listed below.
|
||||||
|
//
|
||||||
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||||
|
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
||||||
|
//
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// compiled file.
|
||||||
|
//
|
||||||
|
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
||||||
|
// about supported directives.
|
||||||
|
//
|
||||||
|
//= require jquery2
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require components
|
9
app/assets/javascripts/application_public.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//= require jquery2
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require extras
|
||||||
|
//= require best_in_place
|
||||||
|
//= require local_time
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$(".best_in_place").best_in_place();
|
||||||
|
});
|
15
app/assets/javascripts/components.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//= require_self
|
||||||
|
//= require react_ujs
|
||||||
|
|
||||||
|
window.React = require('react');
|
||||||
|
window.ReactDOM = require('react-dom');
|
||||||
|
window.Perf = require('react-addons-perf');
|
||||||
|
|
||||||
|
if (!window.Intl) {
|
||||||
|
require('intl');
|
||||||
|
require('intl/locale-data/jsonp/en.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
//= require_tree ./components
|
||||||
|
|
||||||
|
window.Mastodon = require('./components/containers/mastodon');
|
0
app/assets/javascripts/components/.gitkeep
Normal file
@@ -1,4 +1,5 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
|
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
|
||||||
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
|
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
|
||||||
@@ -28,6 +29,14 @@ export const ACCOUNT_UNMUTE_REQUEST = 'ACCOUNT_UNMUTE_REQUEST';
|
|||||||
export const ACCOUNT_UNMUTE_SUCCESS = 'ACCOUNT_UNMUTE_SUCCESS';
|
export const ACCOUNT_UNMUTE_SUCCESS = 'ACCOUNT_UNMUTE_SUCCESS';
|
||||||
export const ACCOUNT_UNMUTE_FAIL = 'ACCOUNT_UNMUTE_FAIL';
|
export const ACCOUNT_UNMUTE_FAIL = 'ACCOUNT_UNMUTE_FAIL';
|
||||||
|
|
||||||
|
export const ACCOUNT_TIMELINE_FETCH_REQUEST = 'ACCOUNT_TIMELINE_FETCH_REQUEST';
|
||||||
|
export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS';
|
||||||
|
export const ACCOUNT_TIMELINE_FETCH_FAIL = 'ACCOUNT_TIMELINE_FETCH_FAIL';
|
||||||
|
|
||||||
|
export const ACCOUNT_TIMELINE_EXPAND_REQUEST = 'ACCOUNT_TIMELINE_EXPAND_REQUEST';
|
||||||
|
export const ACCOUNT_TIMELINE_EXPAND_SUCCESS = 'ACCOUNT_TIMELINE_EXPAND_SUCCESS';
|
||||||
|
export const ACCOUNT_TIMELINE_EXPAND_FAIL = 'ACCOUNT_TIMELINE_EXPAND_FAIL';
|
||||||
|
|
||||||
export const FOLLOWERS_FETCH_REQUEST = 'FOLLOWERS_FETCH_REQUEST';
|
export const FOLLOWERS_FETCH_REQUEST = 'FOLLOWERS_FETCH_REQUEST';
|
||||||
export const FOLLOWERS_FETCH_SUCCESS = 'FOLLOWERS_FETCH_SUCCESS';
|
export const FOLLOWERS_FETCH_SUCCESS = 'FOLLOWERS_FETCH_SUCCESS';
|
||||||
export const FOLLOWERS_FETCH_FAIL = 'FOLLOWERS_FETCH_FAIL';
|
export const FOLLOWERS_FETCH_FAIL = 'FOLLOWERS_FETCH_FAIL';
|
||||||
@@ -82,17 +91,60 @@ export function fetchAccount(id) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function fetchAccountTimeline(id, replace = false) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const ids = getState().getIn(['timelines', 'accounts_timelines', id, 'items'], Immutable.List());
|
||||||
|
const newestId = ids.size > 0 ? ids.first() : null;
|
||||||
|
|
||||||
|
let params = '';
|
||||||
|
let skipLoading = false;
|
||||||
|
|
||||||
|
if (newestId !== null && !replace) {
|
||||||
|
params = `?since_id=${newestId}`;
|
||||||
|
skipLoading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(fetchAccountTimelineRequest(id, skipLoading));
|
||||||
|
|
||||||
|
api(getState).get(`/api/v1/accounts/${id}/statuses${params}`).then(response => {
|
||||||
|
dispatch(fetchAccountTimelineSuccess(id, response.data, replace, skipLoading));
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch(fetchAccountTimelineFail(id, error, skipLoading));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function expandAccountTimeline(id) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const lastId = getState().getIn(['timelines', 'accounts_timelines', id, 'items'], Immutable.List()).last();
|
||||||
|
|
||||||
|
dispatch(expandAccountTimelineRequest(id));
|
||||||
|
|
||||||
|
api(getState).get(`/api/v1/accounts/${id}/statuses`, {
|
||||||
|
params: {
|
||||||
|
limit: 10,
|
||||||
|
max_id: lastId
|
||||||
|
}
|
||||||
|
}).then(response => {
|
||||||
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
dispatch(expandAccountTimelineSuccess(id, response.data, next));
|
||||||
|
}).catch(error => {
|
||||||
|
dispatch(expandAccountTimelineFail(id, error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export function fetchAccountRequest(id) {
|
export function fetchAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FETCH_REQUEST,
|
type: ACCOUNT_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchAccountSuccess(account) {
|
export function fetchAccountSuccess(account) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FETCH_SUCCESS,
|
type: ACCOUNT_FETCH_SUCCESS,
|
||||||
account,
|
account
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,7 +153,7 @@ export function fetchAccountFail(id, error) {
|
|||||||
type: ACCOUNT_FETCH_FAIL,
|
type: ACCOUNT_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipAlert: true,
|
skipAlert: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,48 +178,100 @@ export function unfollowAccount(id) {
|
|||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(unfollowAccountFail(error));
|
dispatch(unfollowAccountFail(error));
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function followAccountRequest(id) {
|
export function followAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FOLLOW_REQUEST,
|
type: ACCOUNT_FOLLOW_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function followAccountSuccess(relationship) {
|
export function followAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FOLLOW_SUCCESS,
|
type: ACCOUNT_FOLLOW_SUCCESS,
|
||||||
relationship,
|
relationship
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function followAccountFail(error) {
|
export function followAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_FOLLOW_FAIL,
|
type: ACCOUNT_FOLLOW_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unfollowAccountRequest(id) {
|
export function unfollowAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNFOLLOW_REQUEST,
|
type: ACCOUNT_UNFOLLOW_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unfollowAccountSuccess(relationship) {
|
export function unfollowAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNFOLLOW_SUCCESS,
|
type: ACCOUNT_UNFOLLOW_SUCCESS,
|
||||||
relationship,
|
relationship
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unfollowAccountFail(error) {
|
export function unfollowAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNFOLLOW_FAIL,
|
type: ACCOUNT_UNFOLLOW_FAIL,
|
||||||
|
error
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchAccountTimelineRequest(id, skipLoading) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_FETCH_REQUEST,
|
||||||
|
id,
|
||||||
|
skipLoading
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchAccountTimelineSuccess(id, statuses, replace, skipLoading) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_FETCH_SUCCESS,
|
||||||
|
id,
|
||||||
|
statuses,
|
||||||
|
replace,
|
||||||
|
skipLoading
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function fetchAccountTimelineFail(id, error, skipLoading) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_FETCH_FAIL,
|
||||||
|
id,
|
||||||
error,
|
error,
|
||||||
|
skipLoading,
|
||||||
|
skipAlert: error.response.status === 404
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function expandAccountTimelineRequest(id) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_EXPAND_REQUEST,
|
||||||
|
id
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function expandAccountTimelineSuccess(id, statuses, next) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_EXPAND_SUCCESS,
|
||||||
|
id,
|
||||||
|
statuses,
|
||||||
|
next
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function expandAccountTimelineFail(id, error) {
|
||||||
|
return {
|
||||||
|
type: ACCOUNT_TIMELINE_EXPAND_FAIL,
|
||||||
|
id,
|
||||||
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,7 +303,7 @@ export function unblockAccount(id) {
|
|||||||
export function blockAccountRequest(id) {
|
export function blockAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_BLOCK_REQUEST,
|
type: ACCOUNT_BLOCK_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -207,35 +311,35 @@ export function blockAccountSuccess(relationship, statuses) {
|
|||||||
return {
|
return {
|
||||||
type: ACCOUNT_BLOCK_SUCCESS,
|
type: ACCOUNT_BLOCK_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
statuses,
|
statuses
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function blockAccountFail(error) {
|
export function blockAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_BLOCK_FAIL,
|
type: ACCOUNT_BLOCK_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unblockAccountRequest(id) {
|
export function unblockAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_REQUEST,
|
type: ACCOUNT_UNBLOCK_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unblockAccountSuccess(relationship) {
|
export function unblockAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_SUCCESS,
|
type: ACCOUNT_UNBLOCK_SUCCESS,
|
||||||
relationship,
|
relationship
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unblockAccountFail(error) {
|
export function unblockAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNBLOCK_FAIL,
|
type: ACCOUNT_UNBLOCK_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -268,7 +372,7 @@ export function unmuteAccount(id) {
|
|||||||
export function muteAccountRequest(id) {
|
export function muteAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_MUTE_REQUEST,
|
type: ACCOUNT_MUTE_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -276,35 +380,35 @@ export function muteAccountSuccess(relationship, statuses) {
|
|||||||
return {
|
return {
|
||||||
type: ACCOUNT_MUTE_SUCCESS,
|
type: ACCOUNT_MUTE_SUCCESS,
|
||||||
relationship,
|
relationship,
|
||||||
statuses,
|
statuses
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function muteAccountFail(error) {
|
export function muteAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_MUTE_FAIL,
|
type: ACCOUNT_MUTE_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unmuteAccountRequest(id) {
|
export function unmuteAccountRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_REQUEST,
|
type: ACCOUNT_UNMUTE_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unmuteAccountSuccess(relationship) {
|
export function unmuteAccountSuccess(relationship) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_SUCCESS,
|
type: ACCOUNT_UNMUTE_SUCCESS,
|
||||||
relationship,
|
relationship
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unmuteAccountFail(error) {
|
export function unmuteAccountFail(error) {
|
||||||
return {
|
return {
|
||||||
type: ACCOUNT_UNMUTE_FAIL,
|
type: ACCOUNT_UNMUTE_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -327,7 +431,7 @@ export function fetchFollowers(id) {
|
|||||||
export function fetchFollowersRequest(id) {
|
export function fetchFollowersRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWERS_FETCH_REQUEST,
|
type: FOLLOWERS_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -336,7 +440,7 @@ export function fetchFollowersSuccess(id, accounts, next) {
|
|||||||
type: FOLLOWERS_FETCH_SUCCESS,
|
type: FOLLOWERS_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -344,7 +448,7 @@ export function fetchFollowersFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOWERS_FETCH_FAIL,
|
type: FOLLOWERS_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -372,7 +476,7 @@ export function expandFollowers(id) {
|
|||||||
export function expandFollowersRequest(id) {
|
export function expandFollowersRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWERS_EXPAND_REQUEST,
|
type: FOLLOWERS_EXPAND_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -381,7 +485,7 @@ export function expandFollowersSuccess(id, accounts, next) {
|
|||||||
type: FOLLOWERS_EXPAND_SUCCESS,
|
type: FOLLOWERS_EXPAND_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -389,7 +493,7 @@ export function expandFollowersFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOWERS_EXPAND_FAIL,
|
type: FOLLOWERS_EXPAND_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -411,7 +515,7 @@ export function fetchFollowing(id) {
|
|||||||
export function fetchFollowingRequest(id) {
|
export function fetchFollowingRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWING_FETCH_REQUEST,
|
type: FOLLOWING_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -420,7 +524,7 @@ export function fetchFollowingSuccess(id, accounts, next) {
|
|||||||
type: FOLLOWING_FETCH_SUCCESS,
|
type: FOLLOWING_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -428,7 +532,7 @@ export function fetchFollowingFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOWING_FETCH_FAIL,
|
type: FOLLOWING_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -456,7 +560,7 @@ export function expandFollowing(id) {
|
|||||||
export function expandFollowingRequest(id) {
|
export function expandFollowingRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWING_EXPAND_REQUEST,
|
type: FOLLOWING_EXPAND_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -465,7 +569,7 @@ export function expandFollowingSuccess(id, accounts, next) {
|
|||||||
type: FOLLOWING_EXPAND_SUCCESS,
|
type: FOLLOWING_EXPAND_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -473,7 +577,7 @@ export function expandFollowingFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOWING_EXPAND_FAIL,
|
type: FOLLOWING_EXPAND_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -500,7 +604,7 @@ export function fetchRelationshipsRequest(ids) {
|
|||||||
return {
|
return {
|
||||||
type: RELATIONSHIPS_FETCH_REQUEST,
|
type: RELATIONSHIPS_FETCH_REQUEST,
|
||||||
ids,
|
ids,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -508,7 +612,7 @@ export function fetchRelationshipsSuccess(relationships) {
|
|||||||
return {
|
return {
|
||||||
type: RELATIONSHIPS_FETCH_SUCCESS,
|
type: RELATIONSHIPS_FETCH_SUCCESS,
|
||||||
relationships,
|
relationships,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -516,7 +620,7 @@ export function fetchRelationshipsFail(error) {
|
|||||||
return {
|
return {
|
||||||
type: RELATIONSHIPS_FETCH_FAIL,
|
type: RELATIONSHIPS_FETCH_FAIL,
|
||||||
error,
|
error,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -526,14 +630,14 @@ export function fetchFollowRequests() {
|
|||||||
|
|
||||||
api(getState).get('/api/v1/follow_requests').then(response => {
|
api(getState).get('/api/v1/follow_requests').then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
|
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null))
|
||||||
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
|
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchFollowRequestsRequest() {
|
export function fetchFollowRequestsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_FETCH_REQUEST,
|
type: FOLLOW_REQUESTS_FETCH_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -541,14 +645,14 @@ export function fetchFollowRequestsSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_FETCH_SUCCESS,
|
type: FOLLOW_REQUESTS_FETCH_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchFollowRequestsFail(error) {
|
export function fetchFollowRequestsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_FETCH_FAIL,
|
type: FOLLOW_REQUESTS_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -564,14 +668,14 @@ export function expandFollowRequests() {
|
|||||||
|
|
||||||
api(getState).get(url).then(response => {
|
api(getState).get(url).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
|
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null))
|
||||||
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandFollowRequestsRequest() {
|
export function expandFollowRequestsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_EXPAND_REQUEST,
|
type: FOLLOW_REQUESTS_EXPAND_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -579,14 +683,14 @@ export function expandFollowRequestsSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
type: FOLLOW_REQUESTS_EXPAND_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandFollowRequestsFail(error) {
|
export function expandFollowRequestsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUESTS_EXPAND_FAIL,
|
type: FOLLOW_REQUESTS_EXPAND_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -596,7 +700,7 @@ export function authorizeFollowRequest(id) {
|
|||||||
|
|
||||||
api(getState)
|
api(getState)
|
||||||
.post(`/api/v1/follow_requests/${id}/authorize`)
|
.post(`/api/v1/follow_requests/${id}/authorize`)
|
||||||
.then(() => dispatch(authorizeFollowRequestSuccess(id)))
|
.then(response => dispatch(authorizeFollowRequestSuccess(id)))
|
||||||
.catch(error => dispatch(authorizeFollowRequestFail(id, error)));
|
.catch(error => dispatch(authorizeFollowRequestFail(id, error)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -604,14 +708,14 @@ export function authorizeFollowRequest(id) {
|
|||||||
export function authorizeFollowRequestRequest(id) {
|
export function authorizeFollowRequestRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function authorizeFollowRequestSuccess(id) {
|
export function authorizeFollowRequestSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -619,7 +723,7 @@ export function authorizeFollowRequestFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_AUTHORIZE_FAIL,
|
type: FOLLOW_REQUEST_AUTHORIZE_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -630,7 +734,7 @@ export function rejectFollowRequest(id) {
|
|||||||
|
|
||||||
api(getState)
|
api(getState)
|
||||||
.post(`/api/v1/follow_requests/${id}/reject`)
|
.post(`/api/v1/follow_requests/${id}/reject`)
|
||||||
.then(() => dispatch(rejectFollowRequestSuccess(id)))
|
.then(response => dispatch(rejectFollowRequestSuccess(id)))
|
||||||
.catch(error => dispatch(rejectFollowRequestFail(id, error)));
|
.catch(error => dispatch(rejectFollowRequestFail(id, error)));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -638,14 +742,14 @@ export function rejectFollowRequest(id) {
|
|||||||
export function rejectFollowRequestRequest(id) {
|
export function rejectFollowRequestRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_REJECT_REQUEST,
|
type: FOLLOW_REQUEST_REJECT_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function rejectFollowRequestSuccess(id) {
|
export function rejectFollowRequestSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_REJECT_SUCCESS,
|
type: FOLLOW_REQUEST_REJECT_SUCCESS,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -653,6 +757,6 @@ export function rejectFollowRequestFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: FOLLOW_REQUEST_REJECT_FAIL,
|
type: FOLLOW_REQUEST_REJECT_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -5,13 +5,13 @@ export const ALERT_CLEAR = 'ALERT_CLEAR';
|
|||||||
export function dismissAlert(alert) {
|
export function dismissAlert(alert) {
|
||||||
return {
|
return {
|
||||||
type: ALERT_DISMISS,
|
type: ALERT_DISMISS,
|
||||||
alert,
|
alert
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function clearAlert() {
|
export function clearAlert() {
|
||||||
return {
|
return {
|
||||||
type: ALERT_CLEAR,
|
type: ALERT_CLEAR
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,6 +19,6 @@ export function showAlert(title, message) {
|
|||||||
return {
|
return {
|
||||||
type: ALERT_SHOW,
|
type: ALERT_SHOW,
|
||||||
title,
|
title,
|
||||||
message,
|
message
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
import { fetchRelationships } from './accounts';
|
import { fetchRelationships } from './accounts';
|
||||||
|
|
||||||
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
|
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
|
||||||
@@ -23,7 +23,7 @@ export function fetchBlocks() {
|
|||||||
|
|
||||||
export function fetchBlocksRequest() {
|
export function fetchBlocksRequest() {
|
||||||
return {
|
return {
|
||||||
type: BLOCKS_FETCH_REQUEST,
|
type: BLOCKS_FETCH_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -31,14 +31,14 @@ export function fetchBlocksSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: BLOCKS_FETCH_SUCCESS,
|
type: BLOCKS_FETCH_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchBlocksFail(error) {
|
export function fetchBlocksFail(error) {
|
||||||
return {
|
return {
|
||||||
type: BLOCKS_FETCH_FAIL,
|
type: BLOCKS_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export function expandBlocks() {
|
|||||||
|
|
||||||
export function expandBlocksRequest() {
|
export function expandBlocksRequest() {
|
||||||
return {
|
return {
|
||||||
type: BLOCKS_EXPAND_REQUEST,
|
type: BLOCKS_EXPAND_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,13 +70,13 @@ export function expandBlocksSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: BLOCKS_EXPAND_SUCCESS,
|
type: BLOCKS_EXPAND_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandBlocksFail(error) {
|
export function expandBlocksFail(error) {
|
||||||
return {
|
return {
|
||||||
type: BLOCKS_EXPAND_FAIL,
|
type: BLOCKS_EXPAND_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -28,7 +28,7 @@ export function fetchStatusCardRequest(id) {
|
|||||||
return {
|
return {
|
||||||
type: STATUS_CARD_FETCH_REQUEST,
|
type: STATUS_CARD_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ export function fetchStatusCardSuccess(id, card) {
|
|||||||
type: STATUS_CARD_FETCH_SUCCESS,
|
type: STATUS_CARD_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
card,
|
card,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,6 +47,6 @@ export function fetchStatusCardFail(id, error) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
skipAlert: true,
|
skipAlert: true
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,11 +1,8 @@
|
|||||||
import api from '../api';
|
import api from '../api';
|
||||||
|
|
||||||
import {
|
import { updateTimeline } from './timelines';
|
||||||
updateTimeline,
|
|
||||||
refreshHomeTimeline,
|
import * as emojione from 'emojione';
|
||||||
refreshCommunityTimeline,
|
|
||||||
refreshPublicTimeline,
|
|
||||||
} from './timelines';
|
|
||||||
|
|
||||||
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
|
||||||
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
|
||||||
@@ -32,14 +29,13 @@ export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
|
|||||||
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
|
||||||
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
|
||||||
export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
|
export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
|
||||||
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
|
|
||||||
|
|
||||||
export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
|
export const COMPOSE_EMOJI_INSERT = 'COMPOSE_EMOJI_INSERT';
|
||||||
|
|
||||||
export function changeCompose(text) {
|
export function changeCompose(text) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_CHANGE,
|
type: COMPOSE_CHANGE,
|
||||||
text: text,
|
text: text
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,7 +43,7 @@ export function replyCompose(status, router) {
|
|||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: COMPOSE_REPLY,
|
type: COMPOSE_REPLY,
|
||||||
status: status,
|
status: status
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!getState().getIn(['compose', 'mounted'])) {
|
if (!getState().getIn(['compose', 'mounted'])) {
|
||||||
@@ -58,7 +54,7 @@ export function replyCompose(status, router) {
|
|||||||
|
|
||||||
export function cancelReplyCompose() {
|
export function cancelReplyCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_REPLY_CANCEL,
|
type: COMPOSE_REPLY_CANCEL
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,7 +62,7 @@ export function mentionCompose(account, router) {
|
|||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: COMPOSE_MENTION,
|
type: COMPOSE_MENTION,
|
||||||
account: account,
|
account: account
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!getState().getIn(['compose', 'mounted'])) {
|
if (!getState().getIn(['compose', 'mounted'])) {
|
||||||
@@ -77,43 +73,36 @@ export function mentionCompose(account, router) {
|
|||||||
|
|
||||||
export function submitCompose() {
|
export function submitCompose() {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const status = getState().getIn(['compose', 'text'], '');
|
const status = emojione.shortnameToUnicode(getState().getIn(['compose', 'text'], ''));
|
||||||
|
|
||||||
if (!status || !status.length) {
|
if (!status || !status.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(submitComposeRequest());
|
dispatch(submitComposeRequest());
|
||||||
|
|
||||||
api(getState).post('/api/v1/statuses', {
|
api(getState).post('/api/v1/statuses', {
|
||||||
status,
|
status,
|
||||||
in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
|
in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
|
||||||
media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')),
|
media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')),
|
||||||
sensitive: getState().getIn(['compose', 'sensitive']),
|
sensitive: getState().getIn(['compose', 'sensitive']),
|
||||||
spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
|
spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''),
|
||||||
visibility: getState().getIn(['compose', 'privacy']),
|
visibility: getState().getIn(['compose', 'privacy'])
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']),
|
'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey'])
|
||||||
},
|
}
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
dispatch(submitComposeSuccess({ ...response.data }));
|
dispatch(submitComposeSuccess({ ...response.data }));
|
||||||
|
|
||||||
// To make the app more responsive, immediately get the status into the columns
|
// To make the app more responsive, immediately get the status into the columns
|
||||||
|
dispatch(updateTimeline('home', { ...response.data }));
|
||||||
const insertOrRefresh = (timelineId, refreshAction) => {
|
|
||||||
if (getState().getIn(['timelines', timelineId, 'online'])) {
|
|
||||||
dispatch(updateTimeline(timelineId, { ...response.data }));
|
|
||||||
} else if (getState().getIn(['timelines', timelineId, 'loaded'])) {
|
|
||||||
dispatch(refreshAction());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
insertOrRefresh('home', refreshHomeTimeline);
|
|
||||||
|
|
||||||
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
|
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
|
||||||
insertOrRefresh('community', refreshCommunityTimeline);
|
if (getState().getIn(['timelines', 'community', 'loaded'])) {
|
||||||
insertOrRefresh('public', refreshPublicTimeline);
|
dispatch(updateTimeline('community', { ...response.data }));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getState().getIn(['timelines', 'public', 'loaded'])) {
|
||||||
|
dispatch(updateTimeline('public', { ...response.data }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
dispatch(submitComposeFail(error));
|
dispatch(submitComposeFail(error));
|
||||||
@@ -123,21 +112,21 @@ export function submitCompose() {
|
|||||||
|
|
||||||
export function submitComposeRequest() {
|
export function submitComposeRequest() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_REQUEST,
|
type: COMPOSE_SUBMIT_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitComposeSuccess(status) {
|
export function submitComposeSuccess(status) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_SUCCESS,
|
type: COMPOSE_SUBMIT_SUCCESS,
|
||||||
status: status,
|
status: status
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitComposeFail(error) {
|
export function submitComposeFail(error) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUBMIT_FAIL,
|
type: COMPOSE_SUBMIT_FAIL,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,7 +144,7 @@ export function uploadCompose(files) {
|
|||||||
api(getState).post('/api/v1/media', data, {
|
api(getState).post('/api/v1/media', data, {
|
||||||
onUploadProgress: function (e) {
|
onUploadProgress: function (e) {
|
||||||
dispatch(uploadComposeProgress(e.loaded, e.total));
|
dispatch(uploadComposeProgress(e.loaded, e.total));
|
||||||
},
|
}
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
dispatch(uploadComposeSuccess(response.data));
|
dispatch(uploadComposeSuccess(response.data));
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
@@ -167,7 +156,7 @@ export function uploadCompose(files) {
|
|||||||
export function uploadComposeRequest() {
|
export function uploadComposeRequest() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_REQUEST,
|
type: COMPOSE_UPLOAD_REQUEST,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,7 +164,7 @@ export function uploadComposeProgress(loaded, total) {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_PROGRESS,
|
type: COMPOSE_UPLOAD_PROGRESS,
|
||||||
loaded: loaded,
|
loaded: loaded,
|
||||||
total: total,
|
total: total
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -183,7 +172,7 @@ export function uploadComposeSuccess(media) {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_SUCCESS,
|
type: COMPOSE_UPLOAD_SUCCESS,
|
||||||
media: media,
|
media: media,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,20 +180,20 @@ export function uploadComposeFail(error) {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_FAIL,
|
type: COMPOSE_UPLOAD_FAIL,
|
||||||
error: error,
|
error: error,
|
||||||
skipLoading: true,
|
skipLoading: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function undoUploadCompose(media_id) {
|
export function undoUploadCompose(media_id) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UPLOAD_UNDO,
|
type: COMPOSE_UPLOAD_UNDO,
|
||||||
media_id: media_id,
|
media_id: media_id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function clearComposeSuggestions() {
|
export function clearComposeSuggestions() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SUGGESTIONS_CLEAR,
|
type: COMPOSE_SUGGESTIONS_CLEAR
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -214,8 +203,8 @@ export function fetchComposeSuggestions(token) {
|
|||||||
params: {
|
params: {
|
||||||
q: token,
|
q: token,
|
||||||
resolve: false,
|
resolve: false,
|
||||||
limit: 4,
|
limit: 4
|
||||||
},
|
}
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
dispatch(readyComposeSuggestions(token, response.data));
|
dispatch(readyComposeSuggestions(token, response.data));
|
||||||
});
|
});
|
||||||
@@ -226,7 +215,7 @@ export function readyComposeSuggestions(token, accounts) {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_SUGGESTIONS_READY,
|
type: COMPOSE_SUGGESTIONS_READY,
|
||||||
token,
|
token,
|
||||||
accounts,
|
accounts
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -238,20 +227,20 @@ export function selectComposeSuggestion(position, token, accountId) {
|
|||||||
type: COMPOSE_SUGGESTION_SELECT,
|
type: COMPOSE_SUGGESTION_SELECT,
|
||||||
position,
|
position,
|
||||||
token,
|
token,
|
||||||
completion,
|
completion
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function mountCompose() {
|
export function mountCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_MOUNT,
|
type: COMPOSE_MOUNT
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unmountCompose() {
|
export function unmountCompose() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_UNMOUNT,
|
type: COMPOSE_UNMOUNT
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -263,21 +252,21 @@ export function changeComposeSensitivity() {
|
|||||||
|
|
||||||
export function changeComposeSpoilerness() {
|
export function changeComposeSpoilerness() {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SPOILERNESS_CHANGE,
|
type: COMPOSE_SPOILERNESS_CHANGE
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function changeComposeSpoilerText(text) {
|
export function changeComposeSpoilerText(text) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_SPOILER_TEXT_CHANGE,
|
type: COMPOSE_SPOILER_TEXT_CHANGE,
|
||||||
text,
|
text
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function changeComposeVisibility(value) {
|
export function changeComposeVisibility(value) {
|
||||||
return {
|
return {
|
||||||
type: COMPOSE_VISIBILITY_CHANGE,
|
type: COMPOSE_VISIBILITY_CHANGE,
|
||||||
value,
|
value
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -285,13 +274,6 @@ export function insertEmojiCompose(position, emoji) {
|
|||||||
return {
|
return {
|
||||||
type: COMPOSE_EMOJI_INSERT,
|
type: COMPOSE_EMOJI_INSERT,
|
||||||
position,
|
position,
|
||||||
emoji,
|
emoji
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function changeComposing(value) {
|
|
||||||
return {
|
|
||||||
type: COMPOSE_COMPOSING_CHANGE,
|
|
||||||
value,
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,4 +1,4 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
|
|
||||||
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
|
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
|
||||||
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
|
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
|
||||||
@@ -23,7 +23,7 @@ export function fetchFavouritedStatuses() {
|
|||||||
|
|
||||||
export function fetchFavouritedStatusesRequest() {
|
export function fetchFavouritedStatusesRequest() {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_FETCH_REQUEST,
|
type: FAVOURITED_STATUSES_FETCH_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -31,14 +31,14 @@ export function fetchFavouritedStatusesSuccess(statuses, next) {
|
|||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_FETCH_SUCCESS,
|
type: FAVOURITED_STATUSES_FETCH_SUCCESS,
|
||||||
statuses,
|
statuses,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchFavouritedStatusesFail(error) {
|
export function fetchFavouritedStatusesFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_FETCH_FAIL,
|
type: FAVOURITED_STATUSES_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export function expandFavouritedStatuses() {
|
|||||||
|
|
||||||
export function expandFavouritedStatusesRequest() {
|
export function expandFavouritedStatusesRequest() {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_EXPAND_REQUEST,
|
type: FAVOURITED_STATUSES_EXPAND_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,13 +71,13 @@ export function expandFavouritedStatusesSuccess(statuses, next) {
|
|||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_EXPAND_SUCCESS,
|
type: FAVOURITED_STATUSES_EXPAND_SUCCESS,
|
||||||
statuses,
|
statuses,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandFavouritedStatusesFail(error) {
|
export function expandFavouritedStatusesFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITED_STATUSES_EXPAND_FAIL,
|
type: FAVOURITED_STATUSES_EXPAND_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
import api from '../api';
|
import api from '../api'
|
||||||
|
|
||||||
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
|
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
|
||||||
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
|
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
|
||||||
@@ -24,14 +24,6 @@ export const FAVOURITES_FETCH_REQUEST = 'FAVOURITES_FETCH_REQUEST';
|
|||||||
export const FAVOURITES_FETCH_SUCCESS = 'FAVOURITES_FETCH_SUCCESS';
|
export const FAVOURITES_FETCH_SUCCESS = 'FAVOURITES_FETCH_SUCCESS';
|
||||||
export const FAVOURITES_FETCH_FAIL = 'FAVOURITES_FETCH_FAIL';
|
export const FAVOURITES_FETCH_FAIL = 'FAVOURITES_FETCH_FAIL';
|
||||||
|
|
||||||
export const PIN_REQUEST = 'PIN_REQUEST';
|
|
||||||
export const PIN_SUCCESS = 'PIN_SUCCESS';
|
|
||||||
export const PIN_FAIL = 'PIN_FAIL';
|
|
||||||
|
|
||||||
export const UNPIN_REQUEST = 'UNPIN_REQUEST';
|
|
||||||
export const UNPIN_SUCCESS = 'UNPIN_SUCCESS';
|
|
||||||
export const UNPIN_FAIL = 'UNPIN_FAIL';
|
|
||||||
|
|
||||||
export function reblog(status) {
|
export function reblog(status) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
dispatch(reblogRequest(status));
|
dispatch(reblogRequest(status));
|
||||||
@@ -61,7 +53,7 @@ export function unreblog(status) {
|
|||||||
export function reblogRequest(status) {
|
export function reblogRequest(status) {
|
||||||
return {
|
return {
|
||||||
type: REBLOG_REQUEST,
|
type: REBLOG_REQUEST,
|
||||||
status: status,
|
status: status
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +61,7 @@ export function reblogSuccess(status, response) {
|
|||||||
return {
|
return {
|
||||||
type: REBLOG_SUCCESS,
|
type: REBLOG_SUCCESS,
|
||||||
status: status,
|
status: status,
|
||||||
response: response,
|
response: response
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,14 +69,14 @@ export function reblogFail(status, error) {
|
|||||||
return {
|
return {
|
||||||
type: REBLOG_FAIL,
|
type: REBLOG_FAIL,
|
||||||
status: status,
|
status: status,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unreblogRequest(status) {
|
export function unreblogRequest(status) {
|
||||||
return {
|
return {
|
||||||
type: UNREBLOG_REQUEST,
|
type: UNREBLOG_REQUEST,
|
||||||
status: status,
|
status: status
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,7 +84,7 @@ export function unreblogSuccess(status, response) {
|
|||||||
return {
|
return {
|
||||||
type: UNREBLOG_SUCCESS,
|
type: UNREBLOG_SUCCESS,
|
||||||
status: status,
|
status: status,
|
||||||
response: response,
|
response: response
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,7 +92,7 @@ export function unreblogFail(status, error) {
|
|||||||
return {
|
return {
|
||||||
type: UNREBLOG_FAIL,
|
type: UNREBLOG_FAIL,
|
||||||
status: status,
|
status: status,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,7 +123,7 @@ export function unfavourite(status) {
|
|||||||
export function favouriteRequest(status) {
|
export function favouriteRequest(status) {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITE_REQUEST,
|
type: FAVOURITE_REQUEST,
|
||||||
status: status,
|
status: status
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -139,7 +131,7 @@ export function favouriteSuccess(status, response) {
|
|||||||
return {
|
return {
|
||||||
type: FAVOURITE_SUCCESS,
|
type: FAVOURITE_SUCCESS,
|
||||||
status: status,
|
status: status,
|
||||||
response: response,
|
response: response
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -147,14 +139,14 @@ export function favouriteFail(status, error) {
|
|||||||
return {
|
return {
|
||||||
type: FAVOURITE_FAIL,
|
type: FAVOURITE_FAIL,
|
||||||
status: status,
|
status: status,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function unfavouriteRequest(status) {
|
export function unfavouriteRequest(status) {
|
||||||
return {
|
return {
|
||||||
type: UNFAVOURITE_REQUEST,
|
type: UNFAVOURITE_REQUEST,
|
||||||
status: status,
|
status: status
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -162,7 +154,7 @@ export function unfavouriteSuccess(status, response) {
|
|||||||
return {
|
return {
|
||||||
type: UNFAVOURITE_SUCCESS,
|
type: UNFAVOURITE_SUCCESS,
|
||||||
status: status,
|
status: status,
|
||||||
response: response,
|
response: response
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,7 +162,7 @@ export function unfavouriteFail(status, error) {
|
|||||||
return {
|
return {
|
||||||
type: UNFAVOURITE_FAIL,
|
type: UNFAVOURITE_FAIL,
|
||||||
status: status,
|
status: status,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -189,7 +181,7 @@ export function fetchReblogs(id) {
|
|||||||
export function fetchReblogsRequest(id) {
|
export function fetchReblogsRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: REBLOGS_FETCH_REQUEST,
|
type: REBLOGS_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,14 +189,14 @@ export function fetchReblogsSuccess(id, accounts) {
|
|||||||
return {
|
return {
|
||||||
type: REBLOGS_FETCH_SUCCESS,
|
type: REBLOGS_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchReblogsFail(id, error) {
|
export function fetchReblogsFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: REBLOGS_FETCH_FAIL,
|
type: REBLOGS_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -223,7 +215,7 @@ export function fetchFavourites(id) {
|
|||||||
export function fetchFavouritesRequest(id) {
|
export function fetchFavouritesRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITES_FETCH_REQUEST,
|
type: FAVOURITES_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,83 +223,13 @@ export function fetchFavouritesSuccess(id, accounts) {
|
|||||||
return {
|
return {
|
||||||
type: FAVOURITES_FETCH_SUCCESS,
|
type: FAVOURITES_FETCH_SUCCESS,
|
||||||
id,
|
id,
|
||||||
accounts,
|
accounts
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchFavouritesFail(id, error) {
|
export function fetchFavouritesFail(id, error) {
|
||||||
return {
|
return {
|
||||||
type: FAVOURITES_FETCH_FAIL,
|
type: FAVOURITES_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function pin(status) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
dispatch(pinRequest(status));
|
|
||||||
|
|
||||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => {
|
|
||||||
dispatch(pinSuccess(status, response.data));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(pinFail(status, error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function pinRequest(status) {
|
|
||||||
return {
|
|
||||||
type: PIN_REQUEST,
|
|
||||||
status,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function pinSuccess(status, response) {
|
|
||||||
return {
|
|
||||||
type: PIN_SUCCESS,
|
|
||||||
status,
|
|
||||||
response,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function pinFail(status, error) {
|
|
||||||
return {
|
|
||||||
type: PIN_FAIL,
|
|
||||||
status,
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unpin (status) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
dispatch(unpinRequest(status));
|
|
||||||
|
|
||||||
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => {
|
|
||||||
dispatch(unpinSuccess(status, response.data));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(unpinFail(status, error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unpinRequest(status) {
|
|
||||||
return {
|
|
||||||
type: UNPIN_REQUEST,
|
|
||||||
status,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unpinSuccess(status, response) {
|
|
||||||
return {
|
|
||||||
type: UNPIN_SUCCESS,
|
|
||||||
status,
|
|
||||||
response,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unpinFail(status, error) {
|
|
||||||
return {
|
|
||||||
type: UNPIN_FAIL,
|
|
||||||
status,
|
|
||||||
error,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -5,12 +5,12 @@ export function openModal(type, props) {
|
|||||||
return {
|
return {
|
||||||
type: MODAL_OPEN,
|
type: MODAL_OPEN,
|
||||||
modalType: type,
|
modalType: type,
|
||||||
modalProps: props,
|
modalProps: props
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function closeModal() {
|
export function closeModal() {
|
||||||
return {
|
return {
|
||||||
type: MODAL_CLOSE,
|
type: MODAL_CLOSE
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
import { fetchRelationships } from './accounts';
|
import { fetchRelationships } from './accounts';
|
||||||
|
|
||||||
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
|
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
|
||||||
@@ -23,7 +23,7 @@ export function fetchMutes() {
|
|||||||
|
|
||||||
export function fetchMutesRequest() {
|
export function fetchMutesRequest() {
|
||||||
return {
|
return {
|
||||||
type: MUTES_FETCH_REQUEST,
|
type: MUTES_FETCH_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -31,14 +31,14 @@ export function fetchMutesSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: MUTES_FETCH_SUCCESS,
|
type: MUTES_FETCH_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchMutesFail(error) {
|
export function fetchMutesFail(error) {
|
||||||
return {
|
return {
|
||||||
type: MUTES_FETCH_FAIL,
|
type: MUTES_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export function expandMutes() {
|
|||||||
|
|
||||||
export function expandMutesRequest() {
|
export function expandMutesRequest() {
|
||||||
return {
|
return {
|
||||||
type: MUTES_EXPAND_REQUEST,
|
type: MUTES_EXPAND_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,13 +70,13 @@ export function expandMutesSuccess(accounts, next) {
|
|||||||
return {
|
return {
|
||||||
type: MUTES_EXPAND_SUCCESS,
|
type: MUTES_EXPAND_SUCCESS,
|
||||||
accounts,
|
accounts,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandMutesFail(error) {
|
export function expandMutesFail(error) {
|
||||||
return {
|
return {
|
||||||
type: MUTES_EXPAND_FAIL,
|
type: MUTES_EXPAND_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,8 +1,8 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
import { List as ImmutableList } from 'immutable';
|
import Immutable from 'immutable';
|
||||||
import IntlMessageFormat from 'intl-messageformat';
|
import IntlMessageFormat from 'intl-messageformat';
|
||||||
|
|
||||||
import { fetchRelationships } from './accounts';
|
import { fetchRelationships } from './accounts';
|
||||||
import { defineMessages } from 'react-intl';
|
|
||||||
|
|
||||||
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
|
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
|
||||||
|
|
||||||
@@ -17,10 +17,6 @@ export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL';
|
|||||||
export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
|
export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
|
||||||
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
|
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
|
||||||
|
|
||||||
defineMessages({
|
|
||||||
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const fetchRelatedRelationships = (dispatch, notifications) => {
|
const fetchRelatedRelationships = (dispatch, notifications) => {
|
||||||
const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id);
|
const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id);
|
||||||
|
|
||||||
@@ -29,12 +25,6 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const unescapeHTML = (html) => {
|
|
||||||
const wrapper = document.createElement('div');
|
|
||||||
wrapper.innerHTML = html;
|
|
||||||
return wrapper.textContent;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function updateNotifications(notification, intlMessages, intlLocale) {
|
export function updateNotifications(notification, intlMessages, intlLocale) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
|
const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
|
||||||
@@ -45,7 +35,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||||||
notification,
|
notification,
|
||||||
account: notification.account,
|
account: notification.account,
|
||||||
status: notification.status,
|
status: notification.status,
|
||||||
meta: playSound ? { sound: 'boop' } : undefined,
|
meta: playSound ? { sound: 'boop' } : undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchRelatedRelationships(dispatch, [notification]);
|
fetchRelatedRelationships(dispatch, [notification]);
|
||||||
@@ -53,13 +43,9 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||||||
// Desktop notifications
|
// Desktop notifications
|
||||||
if (typeof window.Notification !== 'undefined' && showAlert) {
|
if (typeof window.Notification !== 'undefined' && showAlert) {
|
||||||
const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
|
const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
|
||||||
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
|
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : $('<p>').html(notification.status ? notification.status.content : '').text();
|
||||||
|
|
||||||
const notify = new Notification(title, { body, icon: notification.account.avatar, tag: notification.id });
|
new Notification(title, { body, icon: notification.account.avatar, tag: notification.id });
|
||||||
notify.addEventListener('click', () => {
|
|
||||||
window.focus();
|
|
||||||
notify.close();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -68,78 +54,68 @@ const excludeTypesFromSettings = state => state.getIn(['settings', 'notification
|
|||||||
|
|
||||||
export function refreshNotifications() {
|
export function refreshNotifications() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
|
dispatch(refreshNotificationsRequest());
|
||||||
|
|
||||||
const params = {};
|
const params = {};
|
||||||
const ids = getState().getIn(['notifications', 'items']);
|
const ids = getState().getIn(['notifications', 'items']);
|
||||||
|
|
||||||
let skipLoading = false;
|
|
||||||
|
|
||||||
if (ids.size > 0) {
|
if (ids.size > 0) {
|
||||||
params.since_id = ids.first().get('id');
|
params.since_id = ids.first().get('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getState().getIn(['notifications', 'loaded'])) {
|
|
||||||
skipLoading = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
params.exclude_types = excludeTypesFromSettings(getState());
|
params.exclude_types = excludeTypesFromSettings(getState());
|
||||||
|
|
||||||
dispatch(refreshNotificationsRequest(skipLoading));
|
|
||||||
|
|
||||||
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
|
||||||
dispatch(refreshNotificationsSuccess(response.data, skipLoading, next ? next.uri : null));
|
dispatch(refreshNotificationsSuccess(response.data, next ? next.uri : null));
|
||||||
fetchRelatedRelationships(dispatch, response.data);
|
fetchRelatedRelationships(dispatch, response.data);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(refreshNotificationsFail(error, skipLoading));
|
dispatch(refreshNotificationsFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function refreshNotificationsRequest(skipLoading) {
|
export function refreshNotificationsRequest() {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_REFRESH_REQUEST,
|
type: NOTIFICATIONS_REFRESH_REQUEST
|
||||||
skipLoading,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function refreshNotificationsSuccess(notifications, skipLoading, next) {
|
export function refreshNotificationsSuccess(notifications, next) {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_REFRESH_SUCCESS,
|
type: NOTIFICATIONS_REFRESH_SUCCESS,
|
||||||
notifications,
|
notifications,
|
||||||
accounts: notifications.map(item => item.account),
|
accounts: notifications.map(item => item.account),
|
||||||
statuses: notifications.map(item => item.status).filter(status => !!status),
|
statuses: notifications.map(item => item.status).filter(status => !!status),
|
||||||
skipLoading,
|
next
|
||||||
next,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function refreshNotificationsFail(error, skipLoading) {
|
export function refreshNotificationsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_REFRESH_FAIL,
|
type: NOTIFICATIONS_REFRESH_FAIL,
|
||||||
error,
|
error
|
||||||
skipLoading,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandNotifications() {
|
export function expandNotifications() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const items = getState().getIn(['notifications', 'items'], ImmutableList());
|
const url = getState().getIn(['notifications', 'next'], null);
|
||||||
|
|
||||||
if (getState().getIn(['notifications', 'isLoading']) || items.size === 0) {
|
if (url === null || getState().getIn(['notifications', 'isLoading'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = {
|
|
||||||
max_id: items.last().get('id'),
|
|
||||||
limit: 20,
|
|
||||||
exclude_types: excludeTypesFromSettings(getState()),
|
|
||||||
};
|
|
||||||
|
|
||||||
dispatch(expandNotificationsRequest());
|
dispatch(expandNotificationsRequest());
|
||||||
|
|
||||||
api(getState).get('/api/v1/notifications', { params }).then(response => {
|
const params = {};
|
||||||
|
|
||||||
|
params.exclude_types = excludeTypesFromSettings(getState());
|
||||||
|
|
||||||
|
api(getState).get(url, params).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
|
||||||
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
|
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
|
||||||
fetchRelatedRelationships(dispatch, response.data);
|
fetchRelatedRelationships(dispatch, response.data);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@@ -150,7 +126,7 @@ export function expandNotifications() {
|
|||||||
|
|
||||||
export function expandNotificationsRequest() {
|
export function expandNotificationsRequest() {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_EXPAND_REQUEST,
|
type: NOTIFICATIONS_EXPAND_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,21 +136,21 @@ export function expandNotificationsSuccess(notifications, next) {
|
|||||||
notifications,
|
notifications,
|
||||||
accounts: notifications.map(item => item.account),
|
accounts: notifications.map(item => item.account),
|
||||||
statuses: notifications.map(item => item.status).filter(status => !!status),
|
statuses: notifications.map(item => item.status).filter(status => !!status),
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandNotificationsFail(error) {
|
export function expandNotificationsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_EXPAND_FAIL,
|
type: NOTIFICATIONS_EXPAND_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function clearNotifications() {
|
export function clearNotifications() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: NOTIFICATIONS_CLEAR,
|
type: NOTIFICATIONS_CLEAR
|
||||||
});
|
});
|
||||||
|
|
||||||
api(getState).post('/api/v1/notifications/clear');
|
api(getState).post('/api/v1/notifications/clear');
|
||||||
@@ -184,6 +160,6 @@ export function clearNotifications() {
|
|||||||
export function scrollTopNotifications(top) {
|
export function scrollTopNotifications(top) {
|
||||||
return {
|
return {
|
||||||
type: NOTIFICATIONS_SCROLL_TOP,
|
type: NOTIFICATIONS_SCROLL_TOP,
|
||||||
top,
|
top
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,5 +1,4 @@
|
|||||||
import api from '../api';
|
import api from '../api';
|
||||||
import { openModal, closeModal } from './modal';
|
|
||||||
|
|
||||||
export const REPORT_INIT = 'REPORT_INIT';
|
export const REPORT_INIT = 'REPORT_INIT';
|
||||||
export const REPORT_CANCEL = 'REPORT_CANCEL';
|
export const REPORT_CANCEL = 'REPORT_CANCEL';
|
||||||
@@ -12,20 +11,16 @@ export const REPORT_STATUS_TOGGLE = 'REPORT_STATUS_TOGGLE';
|
|||||||
export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE';
|
export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE';
|
||||||
|
|
||||||
export function initReport(account, status) {
|
export function initReport(account, status) {
|
||||||
return dispatch => {
|
return {
|
||||||
dispatch({
|
type: REPORT_INIT,
|
||||||
type: REPORT_INIT,
|
account,
|
||||||
account,
|
status
|
||||||
status,
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(openModal('REPORT'));
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function cancelReport() {
|
export function cancelReport() {
|
||||||
return {
|
return {
|
||||||
type: REPORT_CANCEL,
|
type: REPORT_CANCEL
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,37 +39,34 @@ export function submitReport() {
|
|||||||
api(getState).post('/api/v1/reports', {
|
api(getState).post('/api/v1/reports', {
|
||||||
account_id: getState().getIn(['reports', 'new', 'account_id']),
|
account_id: getState().getIn(['reports', 'new', 'account_id']),
|
||||||
status_ids: getState().getIn(['reports', 'new', 'status_ids']),
|
status_ids: getState().getIn(['reports', 'new', 'status_ids']),
|
||||||
comment: getState().getIn(['reports', 'new', 'comment']),
|
comment: getState().getIn(['reports', 'new', 'comment'])
|
||||||
}).then(response => {
|
}).then(response => dispatch(submitReportSuccess(response.data))).catch(error => dispatch(submitReportFail(error)));
|
||||||
dispatch(closeModal());
|
|
||||||
dispatch(submitReportSuccess(response.data));
|
|
||||||
}).catch(error => dispatch(submitReportFail(error)));
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitReportRequest() {
|
export function submitReportRequest() {
|
||||||
return {
|
return {
|
||||||
type: REPORT_SUBMIT_REQUEST,
|
type: REPORT_SUBMIT_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitReportSuccess(report) {
|
export function submitReportSuccess(report) {
|
||||||
return {
|
return {
|
||||||
type: REPORT_SUBMIT_SUCCESS,
|
type: REPORT_SUBMIT_SUCCESS,
|
||||||
report,
|
report
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function submitReportFail(error) {
|
export function submitReportFail(error) {
|
||||||
return {
|
return {
|
||||||
type: REPORT_SUBMIT_FAIL,
|
type: REPORT_SUBMIT_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function changeReportComment(comment) {
|
export function changeReportComment(comment) {
|
||||||
return {
|
return {
|
||||||
type: REPORT_COMMENT_CHANGE,
|
type: REPORT_COMMENT_CHANGE,
|
||||||
comment,
|
comment
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
import api from '../api';
|
import api from '../api'
|
||||||
|
|
||||||
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
|
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
|
||||||
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
|
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
|
||||||
@@ -11,13 +11,13 @@ export const SEARCH_FETCH_FAIL = 'SEARCH_FETCH_FAIL';
|
|||||||
export function changeSearch(value) {
|
export function changeSearch(value) {
|
||||||
return {
|
return {
|
||||||
type: SEARCH_CHANGE,
|
type: SEARCH_CHANGE,
|
||||||
value,
|
value
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function clearSearch() {
|
export function clearSearch() {
|
||||||
return {
|
return {
|
||||||
type: SEARCH_CLEAR,
|
type: SEARCH_CLEAR
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ export function submitSearch() {
|
|||||||
api(getState).get('/api/v1/search', {
|
api(getState).get('/api/v1/search', {
|
||||||
params: {
|
params: {
|
||||||
q: value,
|
q: value,
|
||||||
resolve: true,
|
resolve: true
|
||||||
},
|
}
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
dispatch(fetchSearchSuccess(response.data));
|
dispatch(fetchSearchSuccess(response.data));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@@ -46,7 +46,7 @@ export function submitSearch() {
|
|||||||
|
|
||||||
export function fetchSearchRequest() {
|
export function fetchSearchRequest() {
|
||||||
return {
|
return {
|
||||||
type: SEARCH_FETCH_REQUEST,
|
type: SEARCH_FETCH_REQUEST
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,19 +55,19 @@ export function fetchSearchSuccess(results) {
|
|||||||
type: SEARCH_FETCH_SUCCESS,
|
type: SEARCH_FETCH_SUCCESS,
|
||||||
results,
|
results,
|
||||||
accounts: results.accounts,
|
accounts: results.accounts,
|
||||||
statuses: results.statuses,
|
statuses: results.statuses
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function fetchSearchFail(error) {
|
export function fetchSearchFail(error) {
|
||||||
return {
|
return {
|
||||||
type: SEARCH_FETCH_FAIL,
|
type: SEARCH_FETCH_FAIL,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function showSearch() {
|
export function showSearch() {
|
||||||
return {
|
return {
|
||||||
type: SEARCH_SHOW,
|
type: SEARCH_SHOW
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -3,21 +3,17 @@ import axios from 'axios';
|
|||||||
export const SETTING_CHANGE = 'SETTING_CHANGE';
|
export const SETTING_CHANGE = 'SETTING_CHANGE';
|
||||||
|
|
||||||
export function changeSetting(key, value) {
|
export function changeSetting(key, value) {
|
||||||
return dispatch => {
|
return {
|
||||||
dispatch({
|
type: SETTING_CHANGE,
|
||||||
type: SETTING_CHANGE,
|
key,
|
||||||
key,
|
value
|
||||||
value,
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(saveSettings());
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function saveSettings() {
|
export function saveSettings() {
|
||||||
return (_, getState) => {
|
return (_, getState) => {
|
||||||
axios.put('/api/web/settings', {
|
axios.put('/api/web/settings', {
|
||||||
data: getState().get('settings').toJS(),
|
data: getState().get('settings').toJS()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -15,19 +15,11 @@ export const CONTEXT_FETCH_REQUEST = 'CONTEXT_FETCH_REQUEST';
|
|||||||
export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
|
export const CONTEXT_FETCH_SUCCESS = 'CONTEXT_FETCH_SUCCESS';
|
||||||
export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
|
export const CONTEXT_FETCH_FAIL = 'CONTEXT_FETCH_FAIL';
|
||||||
|
|
||||||
export const STATUS_MUTE_REQUEST = 'STATUS_MUTE_REQUEST';
|
|
||||||
export const STATUS_MUTE_SUCCESS = 'STATUS_MUTE_SUCCESS';
|
|
||||||
export const STATUS_MUTE_FAIL = 'STATUS_MUTE_FAIL';
|
|
||||||
|
|
||||||
export const STATUS_UNMUTE_REQUEST = 'STATUS_UNMUTE_REQUEST';
|
|
||||||
export const STATUS_UNMUTE_SUCCESS = 'STATUS_UNMUTE_SUCCESS';
|
|
||||||
export const STATUS_UNMUTE_FAIL = 'STATUS_UNMUTE_FAIL';
|
|
||||||
|
|
||||||
export function fetchStatusRequest(id, skipLoading) {
|
export function fetchStatusRequest(id, skipLoading) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_FETCH_REQUEST,
|
type: STATUS_FETCH_REQUEST,
|
||||||
id,
|
id,
|
||||||
skipLoading,
|
skipLoading
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,7 +48,7 @@ export function fetchStatusSuccess(status, skipLoading) {
|
|||||||
return {
|
return {
|
||||||
type: STATUS_FETCH_SUCCESS,
|
type: STATUS_FETCH_SUCCESS,
|
||||||
status,
|
status,
|
||||||
skipLoading,
|
skipLoading
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -66,7 +58,7 @@ export function fetchStatusFail(id, error, skipLoading) {
|
|||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
skipAlert: true,
|
skipAlert: true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,7 +66,7 @@ export function deleteStatus(id) {
|
|||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(deleteStatusRequest(id));
|
dispatch(deleteStatusRequest(id));
|
||||||
|
|
||||||
api(getState).delete(`/api/v1/statuses/${id}`).then(() => {
|
api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
|
||||||
dispatch(deleteStatusSuccess(id));
|
dispatch(deleteStatusSuccess(id));
|
||||||
dispatch(deleteFromTimelines(id));
|
dispatch(deleteFromTimelines(id));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@@ -86,14 +78,14 @@ export function deleteStatus(id) {
|
|||||||
export function deleteStatusRequest(id) {
|
export function deleteStatusRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_REQUEST,
|
type: STATUS_DELETE_REQUEST,
|
||||||
id: id,
|
id: id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function deleteStatusSuccess(id) {
|
export function deleteStatusSuccess(id) {
|
||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_SUCCESS,
|
type: STATUS_DELETE_SUCCESS,
|
||||||
id: id,
|
id: id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,7 +93,7 @@ export function deleteStatusFail(id, error) {
|
|||||||
return {
|
return {
|
||||||
type: STATUS_DELETE_FAIL,
|
type: STATUS_DELETE_FAIL,
|
||||||
id: id,
|
id: id,
|
||||||
error: error,
|
error: error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -113,7 +105,7 @@ export function fetchContext(id) {
|
|||||||
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
|
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
|
||||||
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error.response && error.response.status === 404) {
|
if (error.response.status === 404) {
|
||||||
dispatch(deleteFromTimelines(id));
|
dispatch(deleteFromTimelines(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +117,7 @@ export function fetchContext(id) {
|
|||||||
export function fetchContextRequest(id) {
|
export function fetchContextRequest(id) {
|
||||||
return {
|
return {
|
||||||
type: CONTEXT_FETCH_REQUEST,
|
type: CONTEXT_FETCH_REQUEST,
|
||||||
id,
|
id
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,7 +127,7 @@ export function fetchContextSuccess(id, ancestors, descendants) {
|
|||||||
id,
|
id,
|
||||||
ancestors,
|
ancestors,
|
||||||
descendants,
|
descendants,
|
||||||
statuses: ancestors.concat(descendants),
|
statuses: ancestors.concat(descendants)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -144,74 +136,6 @@ export function fetchContextFail(id, error) {
|
|||||||
type: CONTEXT_FETCH_FAIL,
|
type: CONTEXT_FETCH_FAIL,
|
||||||
id,
|
id,
|
||||||
error,
|
error,
|
||||||
skipAlert: true,
|
skipAlert: true
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function muteStatus(id) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
dispatch(muteStatusRequest(id));
|
|
||||||
|
|
||||||
api(getState).post(`/api/v1/statuses/${id}/mute`).then(() => {
|
|
||||||
dispatch(muteStatusSuccess(id));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(muteStatusFail(id, error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function muteStatusRequest(id) {
|
|
||||||
return {
|
|
||||||
type: STATUS_MUTE_REQUEST,
|
|
||||||
id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function muteStatusSuccess(id) {
|
|
||||||
return {
|
|
||||||
type: STATUS_MUTE_SUCCESS,
|
|
||||||
id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function muteStatusFail(id, error) {
|
|
||||||
return {
|
|
||||||
type: STATUS_MUTE_FAIL,
|
|
||||||
id,
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unmuteStatus(id) {
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
dispatch(unmuteStatusRequest(id));
|
|
||||||
|
|
||||||
api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => {
|
|
||||||
dispatch(unmuteStatusSuccess(id));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(unmuteStatusFail(id, error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unmuteStatusRequest(id) {
|
|
||||||
return {
|
|
||||||
type: STATUS_UNMUTE_REQUEST,
|
|
||||||
id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unmuteStatusSuccess(id) {
|
|
||||||
return {
|
|
||||||
type: STATUS_UNMUTE_SUCCESS,
|
|
||||||
id,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function unmuteStatusFail(id, error) {
|
|
||||||
return {
|
|
||||||
type: STATUS_UNMUTE_FAIL,
|
|
||||||
id,
|
|
||||||
error,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,11 +1,10 @@
|
|||||||
import { Iterable, fromJS } from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
export const STORE_HYDRATE = 'STORE_HYDRATE';
|
export const STORE_HYDRATE = 'STORE_HYDRATE';
|
||||||
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY';
|
|
||||||
|
|
||||||
const convertState = rawState =>
|
const convertState = rawState =>
|
||||||
fromJS(rawState, (k, v) =>
|
Immutable.fromJS(rawState, (k, v) =>
|
||||||
Iterable.isIndexed(v) ? v.toList() : v.toMap().mapKeys(x =>
|
Immutable.Iterable.isIndexed(v) ? v.toList() : v.toMap().mapKeys(x =>
|
||||||
Number.isNaN(x * 1) ? x : x * 1));
|
Number.isNaN(x * 1) ? x : x * 1));
|
||||||
|
|
||||||
export function hydrateStore(rawState) {
|
export function hydrateStore(rawState) {
|
||||||
@@ -13,6 +12,6 @@ export function hydrateStore(rawState) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
type: STORE_HYDRATE,
|
type: STORE_HYDRATE,
|
||||||
state,
|
state
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
import api, { getLinks } from '../api';
|
import api, { getLinks } from '../api'
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import Immutable from 'immutable';
|
||||||
|
|
||||||
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
||||||
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
|
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
|
||||||
@@ -23,7 +23,7 @@ export function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
|
|||||||
timeline,
|
timeline,
|
||||||
statuses,
|
statuses,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ export function updateTimeline(timeline, status) {
|
|||||||
type: TIMELINE_UPDATE,
|
type: TIMELINE_UPDATE,
|
||||||
timeline,
|
timeline,
|
||||||
status,
|
status,
|
||||||
references,
|
references
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -51,98 +51,98 @@ export function deleteFromTimelines(id) {
|
|||||||
id,
|
id,
|
||||||
accountId,
|
accountId,
|
||||||
references,
|
references,
|
||||||
reblogOf,
|
reblogOf
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function refreshTimelineRequest(timeline, skipLoading) {
|
export function refreshTimelineRequest(timeline, id, skipLoading) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_REFRESH_REQUEST,
|
type: TIMELINE_REFRESH_REQUEST,
|
||||||
timeline,
|
timeline,
|
||||||
skipLoading,
|
id,
|
||||||
|
skipLoading
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function refreshTimeline(timelineId, path, params = {}) {
|
export function refreshTimeline(timeline, id = null) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
if (getState().getIn(['timelines', timeline, 'isLoading'])) {
|
||||||
|
|
||||||
if (timeline.get('isLoading') || timeline.get('online')) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ids = timeline.get('items', ImmutableList());
|
const ids = getState().getIn(['timelines', timeline, 'items'], Immutable.List());
|
||||||
const newestId = ids.size > 0 ? ids.first() : null;
|
const newestId = ids.size > 0 ? ids.first() : null;
|
||||||
|
let params = getState().getIn(['timelines', timeline, 'params'], {});
|
||||||
|
const path = getState().getIn(['timelines', timeline, 'path'])(id);
|
||||||
|
|
||||||
let skipLoading = timeline.get('loaded');
|
let skipLoading = false;
|
||||||
|
|
||||||
if (newestId !== null) {
|
if (newestId !== null && getState().getIn(['timelines', timeline, 'loaded']) && (id === null || getState().getIn(['timelines', timeline, 'id']) === id)) {
|
||||||
params.since_id = newestId;
|
if (id === null && getState().getIn(['timelines', timeline, 'online'])) {
|
||||||
|
// Skip refreshing when timeline is live anyway
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = { ...params, since_id: newestId };
|
||||||
|
skipLoading = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(refreshTimelineRequest(timelineId, skipLoading));
|
dispatch(refreshTimelineRequest(timeline, id, skipLoading));
|
||||||
|
|
||||||
api(getState).get(path, { params }).then(response => {
|
api(getState).get(path, { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null));
|
dispatch(refreshTimelineSuccess(timeline, response.data, skipLoading, next ? next.uri : null));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
|
dispatch(refreshTimelineFail(timeline, error, skipLoading));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const refreshHomeTimeline = () => refreshTimeline('home', '/api/v1/timelines/home');
|
|
||||||
export const refreshPublicTimeline = () => refreshTimeline('public', '/api/v1/timelines/public');
|
|
||||||
export const refreshCommunityTimeline = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true });
|
|
||||||
export const refreshAccountTimeline = accountId => refreshTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
|
|
||||||
export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
|
|
||||||
export const refreshHashtagTimeline = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
|
|
||||||
|
|
||||||
export function refreshTimelineFail(timeline, error, skipLoading) {
|
export function refreshTimelineFail(timeline, error, skipLoading) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_REFRESH_FAIL,
|
type: TIMELINE_REFRESH_FAIL,
|
||||||
timeline,
|
timeline,
|
||||||
error,
|
error,
|
||||||
skipLoading,
|
skipLoading
|
||||||
skipAlert: error.response && error.response.status === 404,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function expandTimeline(timelineId, path, params = {}) {
|
export function expandTimeline(timeline) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
if (getState().getIn(['timelines', timeline, 'isLoading'])) {
|
||||||
const ids = timeline.get('items', ImmutableList());
|
|
||||||
|
|
||||||
if (timeline.get('isLoading') || ids.size === 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.max_id = ids.last();
|
if (getState().getIn(['timelines', timeline, 'items']).size === 0) {
|
||||||
params.limit = 10;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(expandTimelineRequest(timelineId));
|
const path = getState().getIn(['timelines', timeline, 'path'])(getState().getIn(['timelines', timeline, 'id']));
|
||||||
|
const params = getState().getIn(['timelines', timeline, 'params'], {});
|
||||||
|
const lastId = getState().getIn(['timelines', timeline, 'items']).last();
|
||||||
|
|
||||||
api(getState).get(path, { params }).then(response => {
|
dispatch(expandTimelineRequest(timeline));
|
||||||
|
|
||||||
|
api(getState).get(path, {
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
max_id: lastId,
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
}).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null));
|
dispatch(expandTimelineSuccess(timeline, response.data, next ? next.uri : null));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(expandTimelineFail(timelineId, error));
|
dispatch(expandTimelineFail(timeline, error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const expandHomeTimeline = () => expandTimeline('home', '/api/v1/timelines/home');
|
|
||||||
export const expandPublicTimeline = () => expandTimeline('public', '/api/v1/timelines/public');
|
|
||||||
export const expandCommunityTimeline = () => expandTimeline('community', '/api/v1/timelines/public', { local: true });
|
|
||||||
export const expandAccountTimeline = accountId => expandTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
|
|
||||||
export const expandAccountMediaTimeline = accountId => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
|
|
||||||
export const expandHashtagTimeline = hashtag => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
|
|
||||||
|
|
||||||
export function expandTimelineRequest(timeline) {
|
export function expandTimelineRequest(timeline) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_EXPAND_REQUEST,
|
type: TIMELINE_EXPAND_REQUEST,
|
||||||
timeline,
|
timeline
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ export function expandTimelineSuccess(timeline, statuses, next) {
|
|||||||
type: TIMELINE_EXPAND_SUCCESS,
|
type: TIMELINE_EXPAND_SUCCESS,
|
||||||
timeline,
|
timeline,
|
||||||
statuses,
|
statuses,
|
||||||
next,
|
next
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ export function expandTimelineFail(timeline, error) {
|
|||||||
return {
|
return {
|
||||||
type: TIMELINE_EXPAND_FAIL,
|
type: TIMELINE_EXPAND_FAIL,
|
||||||
timeline,
|
timeline,
|
||||||
error,
|
error
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,20 +167,20 @@ export function scrollTopTimeline(timeline, top) {
|
|||||||
return {
|
return {
|
||||||
type: TIMELINE_SCROLL_TOP,
|
type: TIMELINE_SCROLL_TOP,
|
||||||
timeline,
|
timeline,
|
||||||
top,
|
top
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function connectTimeline(timeline) {
|
export function connectTimeline(timeline) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_CONNECT,
|
type: TIMELINE_CONNECT,
|
||||||
timeline,
|
timeline
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export function disconnectTimeline(timeline) {
|
export function disconnectTimeline(timeline) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_DISCONNECT,
|
type: TIMELINE_DISCONNECT,
|
||||||
timeline,
|
timeline
|
||||||
};
|
};
|
||||||
};
|
};
|
@@ -13,7 +13,7 @@ export const getLinks = response => {
|
|||||||
|
|
||||||
export default getState => axios.create({
|
export default getState => axios.create({
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${getState().getIn(['meta', 'access_token'], '')}`,
|
'Authorization': `Bearer ${getState().getIn(['meta', 'access_token'], '')}`
|
||||||
},
|
},
|
||||||
|
|
||||||
transformResponse: [function (data) {
|
transformResponse: [function (data) {
|
||||||
@@ -22,5 +22,5 @@ export default getState => axios.create({
|
|||||||
} catch(Exception) {
|
} catch(Exception) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}],
|
}]
|
||||||
});
|
});
|
@@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Avatar from './avatar';
|
import Avatar from './avatar';
|
||||||
@@ -6,57 +5,43 @@ import DisplayName from './display_name';
|
|||||||
import Permalink from './permalink';
|
import Permalink from './permalink';
|
||||||
import IconButton from './icon_button';
|
import IconButton from './icon_button';
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
||||||
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' },
|
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' },
|
||||||
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }
|
||||||
});
|
});
|
||||||
|
|
||||||
@injectIntl
|
class Account extends React.PureComponent {
|
||||||
export default class Account extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
constructor (props, context) {
|
||||||
account: ImmutablePropTypes.map.isRequired,
|
super(props, context);
|
||||||
me: PropTypes.number.isRequired,
|
this.handleFollow = this.handleFollow.bind(this);
|
||||||
onFollow: PropTypes.func.isRequired,
|
this.handleBlock = this.handleBlock.bind(this);
|
||||||
onBlock: PropTypes.func.isRequired,
|
this.handleMute = this.handleMute.bind(this);
|
||||||
onMute: PropTypes.func.isRequired,
|
}
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
hidden: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleFollow = () => {
|
handleFollow () {
|
||||||
this.props.onFollow(this.props.account);
|
this.props.onFollow(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBlock = () => {
|
handleBlock () {
|
||||||
this.props.onBlock(this.props.account);
|
this.props.onBlock(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMute = () => {
|
handleMute () {
|
||||||
this.props.onMute(this.props.account);
|
this.props.onMute(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, me, intl, hidden } = this.props;
|
const { account, me, intl } = this.props;
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hidden) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{account.get('display_name')}
|
|
||||||
{account.get('username')}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buttons;
|
let buttons;
|
||||||
|
|
||||||
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
||||||
@@ -66,11 +51,11 @@ export default class Account extends ImmutablePureComponent {
|
|||||||
const muting = account.getIn(['relationship', 'muting']);
|
const muting = account.getIn(['relationship', 'muting']);
|
||||||
|
|
||||||
if (requested) {
|
if (requested) {
|
||||||
buttons = <IconButton disabled icon='hourglass' title={intl.formatMessage(messages.requested)} />;
|
buttons = <IconButton disabled={true} icon='hourglass' title={intl.formatMessage(messages.requested)} />
|
||||||
} else if (blocking) {
|
} else if (blocking) {
|
||||||
buttons = <IconButton active icon='unlock-alt' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />;
|
buttons = <IconButton active={true} icon='unlock-alt' title={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.handleBlock} />;
|
||||||
} else if (muting) {
|
} else if (muting) {
|
||||||
buttons = <IconButton active icon='volume-up' title={intl.formatMessage(messages.unmute, { name: account.get('username') })} onClick={this.handleMute} />;
|
buttons = <IconButton active={true} icon='volume-up' title={intl.formatMessage(messages.unmute, { name: account.get('username') })} onClick={this.handleMute} />;
|
||||||
} else {
|
} else {
|
||||||
buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />;
|
buttons = <IconButton icon={following ? 'user-times' : 'user-plus'} title={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} active={following} />;
|
||||||
}
|
}
|
||||||
@@ -80,7 +65,7 @@ export default class Account extends ImmutablePureComponent {
|
|||||||
<div className='account'>
|
<div className='account'>
|
||||||
<div className='account__wrapper'>
|
<div className='account__wrapper'>
|
||||||
<Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
<Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
|
||||||
<div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
|
<div className='account__avatar-wrapper'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={36} /></div>
|
||||||
<DisplayName account={account} />
|
<DisplayName account={account} />
|
||||||
</Permalink>
|
</Permalink>
|
||||||
|
|
||||||
@@ -93,3 +78,14 @@ export default class Account extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Account.propTypes = {
|
||||||
|
account: ImmutablePropTypes.map.isRequired,
|
||||||
|
me: PropTypes.number.isRequired,
|
||||||
|
onFollow: PropTypes.func.isRequired,
|
||||||
|
onBlock: PropTypes.func.isRequired,
|
||||||
|
onMute: PropTypes.func.isRequired,
|
||||||
|
intl: PropTypes.object.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
export default injectIntl(Account);
|
@@ -1,14 +1,8 @@
|
|||||||
import React from 'react';
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
|
const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
|
||||||
|
|
||||||
export default class AttachmentList extends ImmutablePureComponent {
|
class AttachmentList extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
media: ImmutablePropTypes.list.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { media } = this.props;
|
const { media } = this.props;
|
||||||
@@ -29,5 +23,10 @@ export default class AttachmentList extends ImmutablePureComponent {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttachmentList.propTypes = {
|
||||||
|
media: ImmutablePropTypes.list.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AttachmentList;
|
@@ -1,10 +1,7 @@
|
|||||||
import React from 'react';
|
|
||||||
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
|
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isRtl } from '../rtl';
|
import { isRtl } from '../rtl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import Textarea from 'react-textarea-autosize';
|
|
||||||
|
|
||||||
const textAtCursorMatchesToken = (str, caretPosition) => {
|
const textAtCursorMatchesToken = (str, caretPosition) => {
|
||||||
let word;
|
let word;
|
||||||
@@ -31,35 +28,25 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class AutosuggestTextarea extends ImmutablePureComponent {
|
class AutosuggestTextarea extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
constructor (props, context) {
|
||||||
value: PropTypes.string,
|
super(props, context);
|
||||||
suggestions: ImmutablePropTypes.list,
|
this.state = {
|
||||||
disabled: PropTypes.bool,
|
suggestionsHidden: false,
|
||||||
placeholder: PropTypes.string,
|
selectedSuggestion: 0,
|
||||||
onSuggestionSelected: PropTypes.func.isRequired,
|
lastToken: null,
|
||||||
onSuggestionsClearRequested: PropTypes.func.isRequired,
|
tokenStart: 0
|
||||||
onSuggestionsFetchRequested: PropTypes.func.isRequired,
|
};
|
||||||
onChange: PropTypes.func.isRequired,
|
this.onChange = this.onChange.bind(this);
|
||||||
onKeyUp: PropTypes.func,
|
this.onKeyDown = this.onKeyDown.bind(this);
|
||||||
onKeyDown: PropTypes.func,
|
this.onBlur = this.onBlur.bind(this);
|
||||||
onPaste: PropTypes.func.isRequired,
|
this.onSuggestionClick = this.onSuggestionClick.bind(this);
|
||||||
autoFocus: PropTypes.bool,
|
this.setTextarea = this.setTextarea.bind(this);
|
||||||
};
|
this.onPaste = this.onPaste.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
onChange (e) {
|
||||||
autoFocus: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
state = {
|
|
||||||
suggestionsHidden: false,
|
|
||||||
selectedSuggestion: 0,
|
|
||||||
lastToken: null,
|
|
||||||
tokenStart: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
onChange = (e) => {
|
|
||||||
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
|
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart);
|
||||||
|
|
||||||
if (token !== null && this.state.lastToken !== token) {
|
if (token !== null && this.state.lastToken !== token) {
|
||||||
@@ -70,10 +57,14 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
this.props.onSuggestionsClearRequested();
|
this.props.onSuggestionsClearRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auto-resize textarea
|
||||||
|
e.target.style.height = 'auto';
|
||||||
|
e.target.style.height = `${e.target.scrollHeight}px`;
|
||||||
|
|
||||||
this.props.onChange(e);
|
this.props.onChange(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown = (e) => {
|
onKeyDown (e) {
|
||||||
const { suggestions, disabled } = this.props;
|
const { suggestions, disabled } = this.props;
|
||||||
const { selectedSuggestion, suggestionsHidden } = this.state;
|
const { selectedSuggestion, suggestionsHidden } = this.state;
|
||||||
|
|
||||||
@@ -123,12 +114,17 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
this.props.onKeyDown(e);
|
this.props.onKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur () {
|
||||||
this.setState({ suggestionsHidden: true });
|
// If we hide the suggestions immediately, then this will prevent the
|
||||||
|
// onClick for the suggestions themselves from firing.
|
||||||
|
// Setting a short window for that to take place before hiding the
|
||||||
|
// suggestions ensures that can't happen.
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({ suggestionsHidden: true });
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSuggestionClick = (e) => {
|
onSuggestionClick (suggestion, e) {
|
||||||
const suggestion = Number(e.currentTarget.getAttribute('data-index'));
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
||||||
this.textarea.focus();
|
this.textarea.focus();
|
||||||
@@ -140,19 +136,19 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTextarea = (c) => {
|
setTextarea (c) {
|
||||||
this.textarea = c;
|
this.textarea = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPaste = (e) => {
|
onPaste (e) {
|
||||||
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
||||||
this.props.onPaste(e.clipboardData.files);
|
this.props.onPaste(e.clipboardData.files)
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp } = this.props;
|
||||||
const { suggestionsHidden, selectedSuggestion } = this.state;
|
const { suggestionsHidden, selectedSuggestion } = this.state;
|
||||||
const style = { direction: 'ltr' };
|
const style = { direction: 'ltr' };
|
||||||
|
|
||||||
@@ -162,34 +158,29 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='autosuggest-textarea'>
|
<div className='autosuggest-textarea'>
|
||||||
<label>
|
<textarea
|
||||||
<span style={{ display: 'none' }}>{placeholder}</span>
|
ref={this.setTextarea}
|
||||||
<Textarea
|
className='autosuggest-textarea__textarea'
|
||||||
inputRef={this.setTextarea}
|
disabled={disabled}
|
||||||
className='autosuggest-textarea__textarea'
|
placeholder={placeholder}
|
||||||
disabled={disabled}
|
autoFocus={true}
|
||||||
placeholder={placeholder}
|
value={value}
|
||||||
autoFocus={autoFocus}
|
onChange={this.onChange}
|
||||||
value={value}
|
onKeyDown={this.onKeyDown}
|
||||||
onChange={this.onChange}
|
onKeyUp={onKeyUp}
|
||||||
onKeyDown={this.onKeyDown}
|
onBlur={this.onBlur}
|
||||||
onKeyUp={onKeyUp}
|
onPaste={this.onPaste}
|
||||||
onBlur={this.onBlur}
|
style={style}
|
||||||
onPaste={this.onPaste}
|
/>
|
||||||
style={style}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
|
<div style={{ display: (suggestions.size > 0 && !suggestionsHidden) ? 'block' : 'none' }} className='autosuggest-textarea__suggestions'>
|
||||||
{suggestions.map((suggestion, i) => (
|
{suggestions.map((suggestion, i) => (
|
||||||
<div
|
<div
|
||||||
role='button'
|
role='button'
|
||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
key={suggestion}
|
key={suggestion}
|
||||||
data-index={suggestion}
|
|
||||||
className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`}
|
className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`}
|
||||||
onMouseDown={this.onSuggestionClick}
|
onClick={this.onSuggestionClick.bind(this, suggestion)}>
|
||||||
>
|
|
||||||
<AutosuggestAccountContainer id={suggestion} />
|
<AutosuggestAccountContainer id={suggestion} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -198,4 +189,20 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
|
AutosuggestTextarea.propTypes = {
|
||||||
|
value: PropTypes.string,
|
||||||
|
suggestions: ImmutablePropTypes.list,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
placeholder: PropTypes.string,
|
||||||
|
onSuggestionSelected: PropTypes.func.isRequired,
|
||||||
|
onSuggestionsClearRequested: PropTypes.func.isRequired,
|
||||||
|
onSuggestionsFetchRequested: PropTypes.func.isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
onKeyUp: PropTypes.func,
|
||||||
|
onKeyDown: PropTypes.func,
|
||||||
|
onPaste: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AutosuggestTextarea;
|
63
app/assets/javascripts/components/components/avatar.jsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
class Avatar extends React.PureComponent {
|
||||||
|
|
||||||
|
constructor (props, context) {
|
||||||
|
super(props, context);
|
||||||
|
this.state = {
|
||||||
|
hovering: false
|
||||||
|
};
|
||||||
|
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||||
|
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseEnter () {
|
||||||
|
this.setState({ hovering: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseLeave () {
|
||||||
|
this.setState({ hovering: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { src, size, staticSrc, animate } = this.props;
|
||||||
|
const { hovering } = this.state;
|
||||||
|
|
||||||
|
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
|
||||||
|
className='account__avatar'
|
||||||
|
onMouseEnter={this.handleMouseEnter}
|
||||||
|
onMouseLeave={this.handleMouseLeave}
|
||||||
|
style={style}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Avatar.propTypes = {
|
||||||
|
src: PropTypes.string.isRequired,
|
||||||
|
staticSrc: PropTypes.string,
|
||||||
|
size: PropTypes.number.isRequired,
|
||||||
|
style: PropTypes.object,
|
||||||
|
animate: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
Avatar.defaultProps = {
|
||||||
|
animate: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Avatar;
|
49
app/assets/javascripts/components/components/button.jsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
class Button extends React.PureComponent {
|
||||||
|
|
||||||
|
constructor (props, context) {
|
||||||
|
super(props, context);
|
||||||
|
this.handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick (e) {
|
||||||
|
if (!this.props.disabled) {
|
||||||
|
this.props.onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const style = {
|
||||||
|
display: this.props.block ? 'block' : 'inline-block',
|
||||||
|
width: this.props.block ? '100%' : 'auto',
|
||||||
|
padding: `0 ${this.props.size / 2.25}px`,
|
||||||
|
height: `${this.props.size}px`,
|
||||||
|
lineHeight: `${this.props.size}px`
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button className={`button ${this.props.secondary ? 'button-secondary' : ''}`} disabled={this.props.disabled} onClick={this.handleClick} style={{ ...style, ...this.props.style }}>
|
||||||
|
{this.props.text || this.props.children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Button.propTypes = {
|
||||||
|
text: PropTypes.node,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
block: PropTypes.bool,
|
||||||
|
secondary: PropTypes.bool,
|
||||||
|
size: PropTypes.number,
|
||||||
|
style: PropTypes.object,
|
||||||
|
children: PropTypes.node
|
||||||
|
};
|
||||||
|
|
||||||
|
Button.defaultProps = {
|
||||||
|
size: 36
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Button;
|
@@ -1,6 +1,4 @@
|
|||||||
import React from 'react';
|
import { Motion, spring } from 'react-motion';
|
||||||
import Motion from 'react-motion/lib/Motion';
|
|
||||||
import spring from 'react-motion/lib/spring';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const Collapsable = ({ fullHeight, isVisible, children }) => (
|
const Collapsable = ({ fullHeight, isVisible, children }) => (
|
||||||
@@ -16,7 +14,7 @@ const Collapsable = ({ fullHeight, isVisible, children }) => (
|
|||||||
Collapsable.propTypes = {
|
Collapsable.propTypes = {
|
||||||
fullHeight: PropTypes.number.isRequired,
|
fullHeight: PropTypes.number.isRequired,
|
||||||
isVisible: PropTypes.bool.isRequired,
|
isVisible: PropTypes.bool.isRequired,
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Collapsable;
|
export default Collapsable;
|
@@ -0,0 +1,31 @@
|
|||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
class ColumnBackButton extends React.PureComponent {
|
||||||
|
|
||||||
|
constructor (props, context) {
|
||||||
|
super(props, context);
|
||||||
|
this.handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick () {
|
||||||
|
if (window.history && window.history.length === 1) this.context.router.push("/");
|
||||||
|
else this.context.router.goBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div role='button' tabIndex='0' onClick={this.handleClick} className='column-back-button'>
|
||||||
|
<i className='fa fa-fw fa-chevron-left column-back-button__icon'/>
|
||||||
|
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ColumnBackButton.contextTypes = {
|
||||||
|
router: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ColumnBackButton;
|