Compare commits

..

372 Commits

Author SHA1 Message Date
Yamagishi Kazutoshi
6aa5ea1b5d Weblate translations (2018-05-20) (#7552)
* Translated using Weblate (French)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fr/

* Translated using Weblate (Italian)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/it/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ca/

* Translated using Weblate (French)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (628 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Galician)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (625 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Italian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Italian)

Currently translated at 83.7% (525 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/ja/

* Translated using Weblate (Galician)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (628 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Galician)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (French)

Currently translated at 99.5% (624 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/

* Translated using Weblate (French)

Currently translated at 99.6% (625 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ca/

* Translated using Weblate (Galician)

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Japanese)

Currently translated at 93.9% (62 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (627 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (626 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (French)

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (628 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (French)

Currently translated at 99.6% (626 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Swedish)

Currently translated at 99.5% (625 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sv/

* Translated using Weblate (Slovak)

Currently translated at 98.4% (65 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Swedish)

Currently translated at 95.4% (63 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sv/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (627 of 628 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Persian)

Currently translated at 100.0% (66 of 66 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fa/

* i18n-tasks normalize && i18n-tasks remove-unused && yarn manage:translations
2018-05-19 21:42:21 +02:00
Eugen Rochko
8378b72eba Ensure push subscription is immediately removed when application is revoked (#7548)
* Ensure push subscription is immediately removed when application is revoked

* When token is revoked from app, unsubscribe too
2018-05-19 21:05:08 +02:00
Peter
5910eb9b61 Add :few keys for sk lang plurals (#7551)
* Add :few keys for sk lang plurals

* i18n-tasks normalize
2018-05-20 03:46:18 +09:00
Ash Furrow
50db106252 Disables autocorrect/autocapitalize on remote username field. (#7549) 2018-05-19 19:36:23 +02:00
Akihiko Odaki
4e1400cecb Cache media only when storage can be freed (#7547) 2018-05-19 19:22:11 +02:00
Eugen Rochko
bcbb6aa46f Bump version to 2.4.0rc4 2018-05-19 18:38:10 +02:00
Eugen Rochko
1bbe12254d Improve direct message warning again (#7546) 2018-05-19 18:37:33 +02:00
Eugen Rochko
93c66f0c03 In footer, replace text "Mastodon" with logo (#7545) 2018-05-19 16:10:55 +02:00
takayamaki
587da93152 checking http status code with range (#7544) 2018-05-19 14:47:44 +02:00
Eugen Rochko
4b94e9c65e Improve payload format of Web Push API now that it's open (#7521)
> Good lord what is happening in there

Previously the contents of the Web Push API payloads closely resembled the structure of JavaScript's [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification). But now that the API is open to non-browser apps, and given that there is no required coupling between contents of the payload and a Notification object, here is how I changed the payload:

```json
{ 
  "access_token": "...",
  "preferred_locale": "en",
  "notification_id": "12345",
  "notification_type": "follow",
  "title": "So and so followed you",
  "body": "This is my bio",
  "icon": "https://example.com/avatar.png"
}
```

The title, body and icon attributes are included as a fallback so you can construct a minimal notification if you cannot perform a network request to the API to get more data.
2018-05-19 14:46:47 +02:00
Akihiko Odaki
1951ff41b3 Do not override the default push notification settings (#6037) 2018-05-19 14:45:58 +02:00
bsky
138512d204 Remove outline (#7543) 2018-05-19 12:16:52 +02:00
Eugen Rochko
7871d29aff Skip pagination logic for pinned account timelines in reducer (#7540)
Fix #7516
2018-05-19 02:51:29 +02:00
MIYAGI Hikaru
0b1f88cfd5 Upgrade posix-spawn to master (#7542) 2018-05-19 02:20:43 +02:00
Eugen Rochko
97f02f2c08 Do not raise delivery failure on 4xx errors, increase stoplight threshold (#7541)
* Do not raise delivery failure on 4xx errors, increase stoplight threshold

Stoplight failure threshold from 3 to 10
Status code 429 will raise a failure/get retried

* Oops
2018-05-19 00:23:19 +02:00
Eugen Rochko
9422b3e0d8 Fix double-encoding of display name in title and e-mails (#7534) 2018-05-18 15:56:57 +02:00
Akihiko Odaki
2beeea1e7d Change Japanese translation for privacy.private.short (#7535)
The old translation means "hidden," but it is vague in terms that it does
not specify the scope status is hidden. The new translation is a literal
translation of "Followers-only," without such ambiguity.
2018-05-18 22:30:45 +09:00
Eugen Rochko
57b503d4ef Resolve unknown status from Add activity, skip Remove if unknown (#7526)
Fix #7518
2018-05-18 11:33:56 +02:00
Eugen Rochko
dafd7afc5e Use randomized setTimeout when fallback-polling and re-add since_id (#7522) 2018-05-18 02:32:35 +02:00
Eugen Rochko
1e02dc8715 Add preference to hide following/followers lists (#7532)
* Add preference to hide following/followers lists

- Public pages
- ActivityPub collections (does not return pages but does give total)
- REST API (unless it's your own) (does not federate)

Fix #6901

* Add preference

* Add delegation

* Fix issue

* Fix issue
2018-05-18 02:26:51 +02:00
MIYAGI Hikaru
919eef3098 User agent for WebFinger (#7531)
* User agent for WebFinger

* local_domain → web_domain

* 'http' is away accidentally...
2018-05-18 01:47:22 +02:00
Eugen Rochko
7293b9fc61 Ensure unfilled fields are shown when errors are shown (#7523)
Fix #7486
2018-05-17 13:00:56 +02:00
Shuhei Kitagawa
b48a166c82 Add tests for account_moderation_notes_controller (#7524) 2018-05-17 04:26:51 +02:00
Eugen Rochko
dfb6907e08 HTTP signatures spec no longer requires algorithms field (#7525)
Fix #7520
2018-05-17 04:03:28 +02:00
MIYAGI Hikaru
6bed372ad2 Fix posix-spawn to version 0.3.12 (#7517)
Because 0.3.13 causes build error in x86 or other ILP32 environments.
closes #7453
2018-05-16 16:52:19 +02:00
Evgeny Petrov
5e87c79d25 Russian language for 2.4.0 (#7512)
* Russian language for 2.4.0

* Russian language for 2.4.0

* bundle exec i18n-tasks normalize

* RU: Updated some strings after new commits appeared
2018-05-16 16:25:11 +02:00
Eugen Rochko
2b97451168 Fix images resized in browser getting cropped (#7514)
Fix #7487
2018-05-16 16:24:16 +02:00
Technowix
4ea376121a French translation tweaks (#7513)
- Use more neutral terminology for readability.
- Maintains the use of "Personne" instead of "Utilisateur⋅ice" to emphasis on the "You're not the product".
- Some fixes for accounts.
2018-05-16 23:21:48 +09:00
Quentí
f60c1d3989 [l10n] Occitan update (#7505)
* Update oc.json

* Update doorkeeper.oc.yml

* Update oc.yml

* Update simple_form.oc.yml

* Update oc.json

Accept is the opp. of reject, I think it's better like this.

* bundle exec i18n-tasks normalize
2018-05-16 23:18:32 +09:00
nightpool
dbf65e1b76 Update bot preference text (#7507)
* Update simple_form.en.yml

* fix #2
2018-05-16 14:47:29 +02:00
Sylvhem
53c2164e9c Reword the direct message warning (#7420)
* Change direct message warning

Reword the direct message warning to set proper privacy expectations.

* Update the French translation

Update the French translation to reflect the changes made to the direct message warning.

* Wording update

Update the message's wording according to the feedback.
2018-05-16 14:47:11 +02:00
Akihiko Odaki
77cd6b5096 Do not use permitted_for scope when querying pinned statuses (#7510)
permitted_for scope is slow when combined with pinned status scope.
Fortunately permitted_for scope can safely be removed because a pinned
status is always public.
2018-05-16 12:30:14 +02:00
Akihiko Odaki
55fd55714a Raise Mastodon::RaceConditionError if Redis lock failed (#7511)
An explicit error allows user agents to know the error and Sidekiq to
retry.
2018-05-16 12:29:45 +02:00
Akihiko Odaki
65d6b253fb Let navigator follow redirect instead that handling redirect in fetch (#7500)
* Let navigator follow redirect instead that handling redirect in fetch

* Do not use cache when fetched resource is to redirect
2018-05-16 04:59:44 +02:00
Akihiko Odaki
17c1a62ec8 Consider only-if-cached in FetchEvent valid on non-Mozilla-Firefox browser (#7506) 2018-05-15 21:42:31 +02:00
Akihiko Odaki
4511a10e66 Test if navigator.storage.estimate exists before using it (#7504) 2018-05-15 20:15:08 +02:00
Akihiko Odaki
918cfd3be6 Ignore only-if-cached cache mode on Mozilla Firefox prior to version 60 (#7503) 2018-05-15 20:14:30 +02:00
Marcin Mikołajczak
ff84c18e3d 🌍: 🇵🇱⬆️ (#7494)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-05-16 01:20:40 +09:00
unarist
d47091eb97 Fix custom emoji handling in UpdateRemoteProfileService (OStatus) (#7501)
This patch fixes NoMethodError and others in RemoteProfileUpdateWorker.
2018-05-15 16:03:34 +02:00
Renato "Lond" Cerqueira
1f74c1dbcb Weblate translations 20180515 (#7496)
* Translated using Weblate (Catalan)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/ca/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Italian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Korean)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (French)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (Slovak)

Currently translated at 95.3% (597 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Korean)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ko/

* Translated using Weblate (Korean)

Currently translated at 99.8% (625 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Added translation using Weblate (Slovenian)

* Added translation using Weblate (Slovenian)

* Added translation using Weblate (Slovenian)

* Added translation using Weblate (Slovenian)

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 99.3% (623 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 98.4% (63 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/zh_Hant_HK/

* Translated using Weblate (Arabic)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/

* Translated using Weblate (Arabic)

Currently translated at 99.6% (294 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (Italian)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Galician)

Currently translated at 100.0% (76 of 76 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (Slovenian)

Currently translated at 7.8% (5 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sl/

* Translated using Weblate (Slovenian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (Slovenian)

Currently translated at 12.5% (8 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sl/

* Translated using Weblate (Italian)

Currently translated at 100.0% (295 of 295 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Slovenian)

Currently translated at 11.9% (75 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sl/

* Translated using Weblate (Slovenian)

Currently translated at 14.1% (89 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sl/

* Translated using Weblate (Japanese)

Currently translated at 99.5% (624 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.6% (625 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Normalize translations
ran yarn build:development && i18n-tasks normalize && yarn
manage:translations && i18n-tasks remove-unused

* Remove translations causing issues in arabic

Related to #6673
2018-05-15 14:25:07 +02:00
Akihiko Odaki
3705cd8322 Clone response before using when caching web page (#7498) 2018-05-15 14:24:50 +02:00
Wiktor
7fe2993b87 Fix account URI when updating ActivityPub account (#7488)
Updates account `uri` field on each call to `update_account` instead of
only once during `create_account` to mirror the same behavior in OStatus
`ResolveAccountService` class [0].

ActivityPub accounts are identified using `@username` and `@domain` pair
instead of URI since #6842.

This fixes #7479: a bug when the account identified by `@username` and
`@domain` changes its URI.

[0]:
03b69ebc45/app/services/resolve_account_service.rb (L121)
2018-05-14 22:56:45 +02:00
Akihiko Odaki
03b69ebc45 Disallow async function in service worker (#7482)
offline-plugin depends on webpack.optimize.UglifyJsPlugin, which is an
alias of uglifyjs-webpack-plugin v0.4.6. uglifyjs-webpack-plugin v0.4.6
uses uglify-js 2.8.29, which is not compatible with async function.
2018-05-14 19:58:11 +02:00
Akihiko Odaki
ed4bae182b Revert index change on statuses for api/v1/accounts account_id statuses (#7484) 2018-05-14 19:56:17 +02:00
Eugen Rochko
8756fd1e82 Bump version to 2.4.0rc3 2018-05-14 17:46:44 +02:00
Akihiko Odaki
d8b3f5fb9a Limit environment variables to expose to webpack (#7480) 2018-05-14 17:45:37 +02:00
Eugen Rochko
d75b63e4fb Bump version to 2.4.0rc2 2018-05-14 14:49:38 +02:00
Yamagishi Kazutoshi
2226d987f9 Add Slovene language (#7475) 2018-05-14 12:52:25 +02:00
abcang
3793e598d0 Call media.present? because media may be nil (#7474) 2018-05-14 12:51:53 +02:00
Akihiko Odaki
42a1231245 Improve index on statuses for api/v1/accounts account_id statuses (#7476)
Queries with the combination of account_id, id, and visibility can be
categorized in three types:
1. Querying for public and unlisted to enumerate statuses visible to
anyone.
2. Querying for public, unlisted, and private to enumerate statuses
visible to follower.
3. Querying for direct to enumerate own direct statuses.

1 and 2 is covered by the index with condition 'visibility IN (0, 1, 2)'.
It would bring better performance in case that there are many direct
statuses.

The index with condition 'visibility = 3' is just for 3. It would be much
faster to query direct statuses thanks to this query.

The total size of those two indexes are expected to be smaller than the
deleted one because they are partial and does not have to cover all the
table.
2018-05-14 12:50:45 +02:00
Eugen Rochko
416f644505 Fix 404 for GET /api/v1/push/subscription (#7472)
My bad...
2018-05-13 21:45:18 +02:00
Eugen Rochko
97e43ec5f0 Add GET /api/v1/push/subscription REST API (#7471)
* Add Api::V1::Push::SubscriptionsController#show

* Add to routes
2018-05-13 21:07:31 +02:00
Eugen Rochko
f31e58af9e Fix nil error in StatusFilter (#7470)
Fix #7462
2018-05-13 20:26:30 +02:00
Akihiko Odaki
f1ed855f96 Test if navigator.storage is present before using it (#7460) 2018-05-13 13:48:32 +02:00
Yamagishi Kazutoshi
d9b2f84c92 Open video modal on public UI (#7469) 2018-05-13 13:48:14 +02:00
Yamagishi Kazutoshi
f77b11cd10 Update http_parser.rb to head version (#7467) 2018-05-13 11:32:46 +02:00
ThibG
0f2fbf7d05 Improvements to toots display in admin view (#7452)
* Distinguish boosts from original statuses in the admin panel (fixes #7449)

* Show the “show more” button in admin view to make CWs clearer (fixes #7451)

* Make content warnings swag
2018-05-12 17:44:15 +02:00
ThibG
7467361d70 Fetch boosted statuses on behalf of a follower (fixes #7426) (#7459)
When an ActivityPub Announce is processed and the boosted toot is not known,
fetch it on behalf of one of the booster's followers. This is to allow
fetching self-boosts of previously-unknown private toots.

If fetching on behalf of a user fails, try fetching it anonymously: the
selected follower of a boosting user may be banned by the boosted toot's
author.
2018-05-12 16:48:32 +02:00
Yamagishi Kazutoshi
f9afd06221 Combine similar components into one on public UI (#7458) 2018-05-12 15:30:06 +02:00
Yamagishi Kazutoshi
4d706f9976 Downgrade doorkeeper to version 4.2.6 (#7456)
ref https://github.com/doorkeeper-gem/doorkeeper/pull/1060
2018-05-12 12:08:12 +02:00
ThibG
352bae8c3e Update session activation time (fixes #5605) (#7408) 2018-05-11 13:20:58 +02:00
ThibG
b241cb2704 Change wording of the “undo” media upload button (fixes #6857) (#7417) 2018-05-11 13:20:31 +02:00
ThibG
be7eeb7856 Catch Paperclip processing failures (fixes #6378) (#7439) 2018-05-11 13:14:50 +02:00
Shuhei Kitagawa
50491e0d92 Add tests for invites controller (#7441)
* Add tests for invites controller

* Small refactoring and fix for invites controller
2018-05-11 13:14:33 +02:00
Yamagishi Kazutoshi
1337ca837b Add CONTINUOUS_INTEGRATION: true to .circleci/config.yml (#7447) 2018-05-11 11:51:07 +02:00
Eugen Rochko
b4fb766b23 Add REST API for Web Push Notifications subscriptions (#7445)
- POST /api/v1/push/subscription
- PUT /api/v1/push/subscription
- DELETE /api/v1/push/subscription
- New OAuth scope: "push" (required for the above methods)
2018-05-11 11:49:12 +02:00
Yamagishi Kazutoshi
9a794067f7 Weblate translations (2018-05-10) (#7438)
* Translated using Weblate (Arabic)

Currently translated at 83.6% (523 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Japanese)

Currently translated at 99.5% (622 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (French)

Currently translated at 99.6% (623 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Korean)

Currently translated at 99.8% (624 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/

* Translated using Weblate (Korean)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Persian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fa/

* Translated using Weblate (Finnish)

Currently translated at 95.1% (59 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Finnish)

Currently translated at 95.1% (59 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Finnish)

Currently translated at 99.6% (293 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Finnish)

Currently translated at 96.7% (60 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Finnish)

Currently translated at 97.9% (612 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Arabic)

Currently translated at 90.8% (568 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

in overeestemming met andere vertalingen

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (2 of 2 strings)

Translation: Mastodon/Activerecord
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/activerecord/nl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (620 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Japanese)

Currently translated at 99.6% (623 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Galician)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Galician)

Currently translated at 98.3% (61 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (German)

Currently translated at 99.2% (620 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Translated using Weblate (German)

Currently translated at 99.2% (620 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/

* Translated using Weblate (Esperanto)

Currently translated at 99.8% (624 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Russian)

Currently translated at 93.5% (58 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/

* Translated using Weblate (Russian)

Currently translated at 95.1% (59 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/

I’m not sure this is the best translation for custom fields, something like «Характеристика» might work better; hopefully someone will review this for second opinions

* Translated using Weblate (Persian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fa/

* Translated using Weblate (Persian)

Currently translated at 99.6% (623 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fa/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Persian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Russian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (German)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (625 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.3% (621 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (621 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ca/

* Translated using Weblate (Japanese)

Currently translated at 92.1% (59 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Corsican)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/co/

* Translated using Weblate (Corsican)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/co/

* Translated using Weblate (Corsican)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/co/

* Translated using Weblate (Corsican)

Currently translated at 99.8% (624 of 625 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/co/

* Translated using Weblate (Corsican)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/co/

* Translated using Weblate (Corsican)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/co/

* Translated using Weblate (French)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/

* Translated using Weblate (French)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/

* Translated using Weblate (Arabic)

Currently translated at 90.8% (569 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Slovak)

Currently translated at 95.2% (596 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Esperanto)

Currently translated at 99.8% (625 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Japanese)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/

* Translated using Weblate (Finnish)

Currently translated at 99.6% (293 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Persian)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/

* Translated using Weblate (Japanese)

Currently translated at 93.7% (60 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (German)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Translated using Weblate (German)

Currently translated at 100.0% (64 of 64 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/

* Translated using Weblate (German)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Added translation using Weblate (Slovenian)

* Translated using Weblate (Slovenian)

Currently translated at 5.7% (36 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sl/

* Added translation using Weblate (Slovenian)

* Translated using Weblate (Slovenian)

Currently translated at 1.3% (4 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/

* Translated using Weblate (French)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Greek)

Currently translated at 29.3% (184 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.3% (184 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.5% (185 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.5% (185 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.8% (187 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.8% (187 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.0% (188 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.0% (188 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.1% (189 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.3% (190 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.5% (191 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.5% (191 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 30.6% (192 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 33.7% (211 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* yarn manage:translations && i18n-tasks normalize && i18n-tasks remove-unused
2018-05-10 14:48:26 +02:00
Yamagishi Kazutoshi
bd5f57cbc3 Strip tags from og:description on public tag page (#7437) 2018-05-10 14:38:40 +02:00
Yamagishi Kazutoshi
0a7e8320b2 Add alternate for RSS (#7436) 2018-05-10 14:38:19 +02:00
Yamagishi Kazutoshi
6588f6a0a9 Disable inflate gzip on head method (#7432) 2018-05-10 14:36:12 +02:00
Yamagishi Kazutoshi
ac788ad47e Disable simplecov on CircleCI (#7416)
* Disable simplecov on CircleCI

* Remove --format progress
2018-05-09 16:59:58 +02:00
Yamagishi Kazutoshi
edf882320a Support gzip encoding on Request (#7425) 2018-05-09 16:59:39 +02:00
Yamagishi Kazutoshi
16fee0335f Show card modal on public pages (#7428) 2018-05-09 16:22:52 +02:00
Marcin Mikołajczak
dc010cc77a 🌍: 🇵🇱⬆️ (#7427)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-05-09 19:20:49 +09:00
Shuhei Kitagawa
ce35d81db7 Add tests for admin/roles_controller (#7421) 2018-05-09 08:41:46 +02:00
Shuhei Kitagawa
35eff337d5 Add tests for admin/invites_controller (#7412) 2018-05-09 08:41:26 +02:00
Yamagishi Kazutoshi
6832110af4 Correct rotate of image using EXIF (#7422) 2018-05-09 08:41:07 +02:00
Yamagishi Kazutoshi
d2ee48977c Rescue Mastodon::LengthValidationError in FetchLinkCardService (#7424) 2018-05-09 08:39:08 +02:00
Yamagishi Kazutoshi
40097f438b Multiple Issue templates (#7402)
* Multiple Issue templates

* Update bug_report.md
2018-05-08 13:35:33 +02:00
Yamagishi Kazutoshi
e0b1e17bd0 Show media modal on public timeline (#7413) 2018-05-08 13:33:09 +02:00
Surinna Curtis
01dfd6dbc8 Take the first recognized actor_type. (#7410) 2018-05-08 13:30:04 +02:00
ThibG
b1938d7853 Do not crash in getStatusIds when there is a gap in the timeline (fixes #7400) (#7415)
Fixes a crash occurring when the “gap” disconnection indicator is to be
displayed in a filtered timeline.
2018-05-08 13:28:55 +02:00
ThibG
993e68a7dd Fix hashtags not being federated on mentions (fixes #6900) (#7406) 2018-05-08 03:36:59 +02:00
Eugen Rochko
6208ea5a53 If an OStatus message contains nsfw hashtag, mark it as sensitive (#7398)
* If an OStatus message contains nsfw hashtag, mark it as sensitive

Undo parts of #7048

* Put nsfw hashtag on OStatus messages if they have any media

* Fix code style issues
2018-05-07 14:49:13 +02:00
Eugen Rochko
42cd363542 Bot nameplates (#7391)
* Store actor type in database

* Add bot nameplate to web UI, add setting to preferences, API, AP
Fix #7365

* Fix code style issues
2018-05-07 09:31:07 +02:00
Eugen Rochko
0f0cc3f2eb Support explicitly supplying language code for status via REST API (#7389) 2018-05-07 09:30:53 +02:00
Eugen Rochko
d185f3ddaf Use plaintext value for field value tooltips in web UI (#7388)
Fix #7383
2018-05-07 09:30:38 +02:00
abcang
db012b57c2 Fix distribute_add_activity and distribute_remove_activity (#7393) 2018-05-07 09:30:18 +02:00
Hugo Gameiro
ea4e243303 Improve OpenStack v3 compatibility (#7392)
* Update paperclip.rb

* Update .env.production.sample

* Update paperclip.rb
2018-05-07 02:28:28 +02:00
Eugen Rochko
95595ccd21 Add Corsican localization (#7390)
* Added Corsican localization

* Declaring Corsican localization

* Fixed activerecord locale

* Added a missing translation and switched to French-style apostrophes

* Fixed a (predictable) mistake made while bulk-replacing apostrophes

* More fixing

* i18n-tasks normalize
2018-05-07 01:34:19 +02:00
ThibG
e06fbc4fcf Fixes/rollback scroll changes (#7387)
* Revert "Do not re-position scroll when loading more (inserting items from below) (#7344)"

This reverts commit 8c601b54cc.

* Revert "Prevent timeline from moving when cursor is hovering over it (fixes #7278) (#7327)"

This reverts commit 58852695c8.
2018-05-06 22:26:39 +02:00
ThibG
5c7bed6bbc Various improvements to the report UI (#7342)
* Also display replies in report modal

* Allow report modal to be up to 80% of viewport height

* Use narrow no-break space where needed in the French translation
2018-05-06 20:38:17 +02:00
Yamagishi Kazutoshi
e571de29bf Weblate translations (2018-05-06) (#7381)
* Translated using Weblate (Dutch)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Greek)

Currently translated at 28.2% (177 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Occitan)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/oc/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 98.2% (615 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/

* Translated using Weblate (Occitan)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/oc/

* Translated using Weblate (Occitan)

Currently translated at 97.9% (613 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/oc/

* Translated using Weblate (Galician)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (627 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Greek)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 28.5% (179 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 28.5% (179 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.0% (182 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.0% (182 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.2% (183 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.3% (184 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.5% (185 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.7% (186 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 29.7% (186 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Slovak)

Currently translated at 95.3% (597 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 95.2% (597 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 97.6% (612 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 99.3% (623 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/

* Translated using Weblate (Polish)

Currently translated at 99.8% (626 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Arabic)

Currently translated at 83.7% (525 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Spanish)

Currently translated at 99.8% (626 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Italian)

Currently translated at 54.7% (343 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Italian)

Currently translated at 78.9% (495 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (626 of 627 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* i18n-tasks normalize && i18n-tasks remove-unused && yarn manage:translations
2018-05-06 20:19:56 +09:00
Eugen Rochko
50ed1e83ac Bump version to 2.4.0rc1 (#7283) 2018-05-06 11:50:00 +02:00
Eugen Rochko
61a9018607 Enable custom emojis in profiles (notes, field values, display names) (#7374)
Follow-up to #6124
2018-05-06 11:48:51 +02:00
Shuhei Kitagawa
bd10a7e480 Add resend confirmation for admin (#7378)
* Add confirmations_controller#resend

* Add tests for confirmations_controller#resend

* Add translations
2018-05-06 10:59:03 +02:00
Yamagishi Kazutoshi
8c35d163a5 Port travis_retry for CI (#7379)
* Port travis_retry for CI

* Add license
2018-05-06 10:55:50 +02:00
Eugen Rochko
39efc6d533 Add hint about 7 day cooldown for archive takeout (#7375) 2018-05-06 10:53:10 +02:00
Eugen Rochko
b611dbac79 Add contact e-mail hint to 2FA login form (#7376) 2018-05-06 10:52:36 +02:00
Eugen Rochko
2f63d52b92 Fallback to old on-the-fly URI for follows/blocks if no stored URI (#7371)
Fix #7367
2018-05-05 23:07:51 +02:00
Eugen Rochko
c7d1a2e400 Improve admin UI for accounts (#7360)
* Improve design of account statuses admin UI (consistent with reports)

* Make account moderation notes look consistent with report notes

* i18n-tasks remove-unused

* Fix code style issues

* Fix tests
2018-05-05 23:06:29 +02:00
Eugen Rochko
660db468c0 Do not count search route as compose being mounted in web UI (#7372)
Fix #7144
2018-05-05 23:05:43 +02:00
Eugen Rochko
8da4bf0f90 4 profile fields max, store only 255 characters per name/value (#7348)
Fix #7303
2018-05-05 21:11:19 +02:00
Reto Kromer
80b23a6a85 uniform email rather than e-mail (#7373) 2018-05-05 21:03:21 +02:00
Eugen Rochko
c947e2e4c5 Fix handling of malformed ActivityPub payloads when URIs are nil (#7370)
* Fix handling of malformed ActivityPub payloads when URIs are nil

* Gracefully handle JSON-LD canonicalization failures
2018-05-05 18:22:34 +02:00
Shuhei Kitagawa
661f7e6d9d Add tests for admin/custom_emojis_controller (#7350) 2018-05-05 15:53:59 +02:00
Eugen Rochko
2ef9d65052 Improve rendering of bio fields (#7353)
Fix #7335
2018-05-05 00:55:09 +02:00
Akihiko Odaki
66359ec522 Fix gap insertion for timeline disconnection (#7363) 2018-05-05 00:54:56 +02:00
Eugen Rochko
c73ce7b695 Store home feeds for 7 days instead of 14 (#7354)
* Store home feeds for 7 days instead of 14

Reduces workload for status fan-out to active followers

* Fix test for user model
2018-05-05 00:54:24 +02:00
ThibG
ef7d64c801 Dropdowns accessibility (#7318)
* Mark currently selected privacy setting in privacy dropdown

* Prevent Enter keypresses from triggering dropdown display toggle twice

* Give focus to first/selected item of dropdown menus

* Implement keyboard navigation in privacy dropdown

* Implement keyboard navigation in generic dropdown menus
2018-05-04 22:13:26 +02:00
Eugen Rochko
6793bec4c6 Store URIs of follows, follow requests and blocks for ActivityPub (#7160)
Same URI passed between follow request and follow, since they are
the same thing in ActivityPub. Local URIs are generated during
creation using UUIDs and are passed to serializers.
2018-05-04 21:14:34 +02:00
ThibG
d1aef17f9a Do not render first page of following and followers collections unless explicitly asked to (#7357) 2018-05-04 20:17:01 +02:00
Eugen Rochko
2c1f7b2ece Better pagination for ActivityPub outbox (#7356) 2018-05-04 19:19:11 +02:00
Marcin Mikołajczak
d181aad033 Improve “how to translate” (#7358) 2018-05-04 18:37:37 +02:00
Yamagishi Kazutoshi
00ff8dc00a Add translate guide to CONTRIBUTING.md (#7355) 2018-05-04 18:01:12 +02:00
Eugen Rochko
251bbf9728 Show remote reports in admin UI as coming from domain rather than user (#7347)
Fix #6994
2018-05-04 13:26:25 +02:00
Eugen Rochko
a78b27c7cc Marginally improve convert/ffmpeg calls performance with posix-spawn (#7346) 2018-05-04 13:22:23 +02:00
Shuhei Kitagawa
c61ddd8249 Fix 2fa description in Japanese (#7349) 2018-05-04 13:58:08 +09:00
ThibG
a24605961a Fixes/do not override timestamps (#7336)
* Revert "Fixes/do not override timestamps (#7331)"

This reverts commit 581a5c9d29.

* Document Snowflake ID corner-case a bit more

Snowflake IDs are used for two purposes: making object identifiers harder to
guess and ensuring they are in chronological order. For this reason, they
are based on the `created_at` attribute of the object.

Unfortunately, inserting items with older snowflakes IDs will break the
assumption of consumers of the paging APIs that new items will always have
a greater identifier than the last seen one.

* Add `override_timestamps` virtual attribute to not correlate snowflake ID with created_at
2018-05-03 23:02:46 +02:00
ThibG
8c601b54cc Do not re-position scroll when loading more (inserting items from below) (#7344) 2018-05-03 22:32:05 +02:00
Akihiko Odaki
a7e71bbd08 Add a missing question mark in rack_attack.rb (#7338) 2018-05-03 18:51:00 +02:00
Akihiko Odaki
b1d4471e36 Throttle media post (#7337)
The previous rate limit allowed to post media so fast that it is possible
to fill up the disk space even before an administrator notices. The new
rate limit is configured so that it takes 24 hours to eat 10 gigabytes:
10 * 1024 / 8 / (24 * 60 / 30) = 27 (which rounded to 30)

The period is set long so that it does not prevent from attaching several
media to one post, which would happen in a short period. For example,
if the period is 5 minutes, the rate limit would be:
10 * 1024 / 8 / (24 * 60 / 5) = 4

This long period allows to lift the limit up.
2018-05-03 17:32:00 +02:00
Yamagishi Kazutoshi
7495a3470e Add el and te (#7332)
* Add el and te

* Add missing locale files
2018-05-03 15:54:10 +02:00
Yamagishi Kazutoshi
e9c5c16ba0 Delete dump.rdb (#7334) 2018-05-03 14:30:18 +02:00
ThibG
581a5c9d29 Fixes/do not override timestamps (#7331)
* Do not override timestamps for incoming toots

* Remove every reference to override_timestamps

Statuses are now created with the announced publishing date
and are only pushed to timelines if that date is at most
6 hours earlier than the time at which it is processed.
2018-05-03 13:33:08 +02:00
Eugen Rochko
d5fa4fbcd2 Revert "Do not override timestamps for incoming toots" (#7330)
* Revert "Weblate translations 20180503 (#7325)"

This reverts commit dfa6bccb64.

* Revert "Prevent timeline from moving when cursor is hovering over it (fixes #7278) (#7327)"

This reverts commit 58852695c8.

* Revert "Add pry-byebug (#7307)"

This reverts commit ab773e4d5f.

* Revert "Do not override timestamps for incoming toots (#7326)"

This reverts commit bd36791832.
2018-05-03 12:32:33 +02:00
Renato "Lond" Cerqueira
dfa6bccb64 Weblate translations 20180503 (#7325)
* Translated using Weblate (German)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/de/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (578 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Added translation using Weblate (Greek)

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 93.5% (58 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/zh_Hant_HK/

* Translated using Weblate (Chinese (Hong Kong))

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/

* Added translation using Weblate (Greek)

* Added translation using Weblate (Malay)

* Translated using Weblate (Greek)

Currently translated at 0.6% (2 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 1.3% (4 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 2.0% (6 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 2.3% (7 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 2.7% (8 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 3.0% (9 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 4.3% (27 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 4.7% (30 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 4.7% (30 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 5.1% (32 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Greek)

Currently translated at 5.2% (33 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/

* Translated using Weblate (Swedish)

Currently translated at 95.1% (59 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sv/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.3% (622 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Greek)

Currently translated at 23.8% (70 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 94.0% (589 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Added translation using Weblate (Telugu)

* Translated using Weblate (German)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/de/

* Translated using Weblate (German)

Currently translated at 98.3% (61 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/

* Translated using Weblate (Telugu)

Currently translated at 0.3% (2 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/te/

* Translated using Weblate (German)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/de/

* Translated using Weblate (German)

Currently translated at 98.3% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/

* Translated using Weblate (German)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/

* Translated using Weblate (German)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/de/

* Translated using Weblate (German)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/de/

* Translated using Weblate (German)

Currently translated at 99.5% (623 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Translated using Weblate (Spanish)

Currently translated at 93.2% (584 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 93.2% (584 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 93.2% (584 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 93.2% (584 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 99.8% (625 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Slovak)

Currently translated at 95.0% (595 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Greek)

Currently translated at 24.1% (71 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (Greek)

Currently translated at 24.1% (71 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/

* Translated using Weblate (French)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Italian)

Currently translated at 54.6% (342 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Slovak)

Currently translated at 95.3% (597 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (625 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (German)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/de/

* Translated using Weblate (German)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Galician)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* Translated using Weblate (Galician)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sv/

* Translated using Weblate (Swedish)

Currently translated at 99.5% (623 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sv/

* Normalize translations
ran yarn build:development && i18n-tasks normalize && yarn
manage:translations && i18n-tasks remove-unused

* Add back file removed by weblate
2018-05-03 19:12:09 +09:00
ThibG
58852695c8 Prevent timeline from moving when cursor is hovering over it (fixes #7278) (#7327) 2018-05-03 12:09:11 +02:00
Shuhei Kitagawa
ab773e4d5f Add pry-byebug (#7307) 2018-05-03 12:08:54 +02:00
ThibG
bd36791832 Do not override timestamps for incoming toots (#7326) 2018-05-03 11:42:52 +02:00
Shuhei Kitagawa
28b366d065 Add missing tests for report.rb (#7324) 2018-05-03 10:42:36 +02:00
ThibG
ad5d3134e4 Place emoji picker top if it is closer to the bottom of the viewport (fixes #7277) (#7314) 2018-05-03 10:42:18 +02:00
Eugen Rochko
a5293fdf61 Fix n+1 queries in StatusThreadingConcern (#7321) 2018-05-03 10:41:58 +02:00
Eugen Rochko
a3d84e705a Fix cache_associated no longer working (#7320) 2018-05-03 10:41:41 +02:00
Eugen Rochko
28bd4b9800 Serialize webfinger XML with Ox instead of Nokogiri (#7319)
25ms -> 0.5ms
2018-05-02 22:28:46 +02:00
Eugen Rochko
658cbc9425 Improve PostStatusService performance (#7317)
Offload creation of local notifications to a worker. Remove two
redundant SQL queries from ProcessMentionsService, remove n+1
XML/JSON serialization via memoization
2018-05-02 22:10:57 +02:00
Eugen Rochko
cb5b5cb5f7 Slightly reduce RAM usage (#7301)
* No need to re-require sidekiq plugins, they are required via Gemfile

* Add derailed_benchmarks tool, no need to require TTY gems in Gemfile

* Replace ruby-oembed with FetchOEmbedService

Reduce startup by 45382 allocated objects

* Remove preloaded JSON-LD in favour of caching HTTP responses

Reduce boot RAM by about 6 MiB

* Fix tests

* Fix test suite by stubbing out JSON-LD contexts
2018-05-02 18:58:48 +02:00
abcang
71a7cea73f Keep notification when muting_notifications is true (#7311)
* Keep notification when muting_notifications is true

* Retrun mute object

* Fix test
2018-05-02 16:14:51 +02:00
ThibG
d0cdd5cf94 Accept actor object updates from all supported actor types (#7312) 2018-05-02 16:08:16 +02:00
Eugen Rochko
cae933510c Allow updating bio fields via PUT /api/v1/accounts/update_credentials (#7288)
Add raw bio fields to the source attribute on GET /api/v1/accounts/verify_credentials
2018-05-02 15:57:37 +02:00
Eugen Rochko
f62539ce5c Remove most behaviour disparities between blocks and mutes (#7231)
* Remove most behaviour disparities between blocks and mutes

The only differences between block and mute should be:

- Mutes can optionally NOT affect notifications
- Mutes should not be visible to the muted

Fix #7230
Fix #5713

* Do not allow boosting someone you blocked

Fix #7248

* Do not allow favouriting someone you blocked

* Fix nil error in StatusPolicy
2018-05-02 15:50:20 +02:00
Eugen Rochko
c5dcd7d836 Speed up test suite by not generating RSA keys in test environment (#7296)
One RSA keypair for all fabricated test accounts is enough
2018-05-02 15:45:24 +02:00
Eugen Rochko
965345316f Guard against nil URLs in Request class (#7284)
Fix #7265
2018-05-02 15:44:22 +02:00
Shuhei Kitagawa
6c40e567aa Add missing tests for user.rb (#7306) 2018-05-02 14:13:52 +02:00
Surinna Curtis
dc786c0cf4 Support Actors/Statuses with multiple types (#7305)
* Add equals_or_includes_any? helper in JsonLdHelper

* Support arrays in JSON-LD type fields for actors/tags/objects.

* Spec for resolving accounts with extension types

* Style tweaks for codeclimate
2018-05-02 12:40:24 +02:00
Lynx Kotoura
86efccce2a Fix low-contrasted cancel button of reply indicator (#7300) 2018-05-01 14:02:04 +02:00
Eugen Rochko
705f1d7bf1 Fix missing updated_at attribute on emoji EntityCache (#7297)
Just don't try to save space by only selecting few attributes. If
anyone is wondering, this is needed because the emoji entity cache
is not really only used for entities, it's accessed again to
generate Emoji tags in ActivityPub/OStatus, so a lot more properties
are used than what is needed in HTML alone...
2018-04-30 22:49:33 +02:00
Yamagishi Kazutoshi
16468bdf1b [i18n] Occitan update (#7294)
* Translated new strings

+ few changes

* First update

* Almost complet

Missing the changes in the privacy policy

* Update simple_form.oc.yml

* bundle exec i18n-tasks normalize

* bundle exec i18n-tasks remove-unused
2018-04-30 13:14:50 +02:00
Eugen Rochko
f62ee1ddb0 Disable API access when login is disabled (#7289) 2018-04-30 09:13:14 +02:00
Eugen Rochko
295e3ef02b Fix missing domain attribute in EntityCache for emoji (#7290) 2018-04-30 09:12:55 +02:00
Eugen Rochko
54f34d3f2a Return HTTP 410 for suspended accounts in GET /api/v1/accounts/:id (#7287)
Fix #7243
2018-04-30 09:12:36 +02:00
Eugen Rochko
da61352fab Fix "Show more" URL on paginated threads for remote statuses (#7285)
* Fix URL of "Show more" link in paginated threads (ancestors side)

Increase item limits in threads

Fix #7268

* Fix "Show more" link in paginated threads (descendants side)
2018-04-30 01:59:42 +02:00
Yamagishi Kazutoshi
1c3ace23cb Remove unnecessary hyphen from restore_cache key (#7276) 2018-04-28 11:20:30 +02:00
Marcin Mikołajczak
fc01ae31c6 🌍: 🇵🇱⬆️ (#7275)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-27 15:12:14 +02:00
Eugen Rochko
a872392cd9 Add entity cache (#7271)
* Add entity cache

Use a caching layer for mentions and custom emojis that are
dynamically extracted from text.

Reduce duplicate text extractions

* Fix code style issue
2018-04-27 01:38:10 +02:00
Eugen Rochko
63553c6b5c Add support for separate Redis for cache (#7272)
* Add support for separate Redis for cache

CACHE_REDIS_URL to allow using a different Redis server for cache
purposes, with cache-specific configuration such as key eviction

* Fix code style issues
2018-04-27 01:37:59 +02:00
Yamagishi Kazutoshi
36b6631c12 Add Basque language support (#7267) 2018-04-26 13:56:45 +02:00
Renato "Lond" Cerqueira
3afdd6a17b Weblate translations 20180426 (#7266)
* Translated using Weblate (Swedish)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sv/

* Translated using Weblate (Slovak)

Currently translated at 92.0% (576 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sv/

* Translated using Weblate (Swedish)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sv/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.3% (622 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/

* Translated using Weblate (Galician)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (621 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Basque)

Currently translated at 32.2% (20 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eu/

* Translated using Weblate (Arabic)

Currently translated at 99.6% (293 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Arabic)

Currently translated at 82.4% (516 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Slovak)

Currently translated at 92.1% (577 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Basque)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eu/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (578 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Basque)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eu/

https://sustatu.eus/1380226549995

* Translated using Weblate (Catalan)

Currently translated at 100.0% (294 of 294 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Normalize translations
ran yarn build:development && i18n-tasks normalize && yarn
manage:translations && i18n-tasks remove-unused
2018-04-26 18:58:22 +09:00
Stefan Midjich
fa5b28df8a Better phrasing in swedish translation (#7263)
* more sane phrasing in 🇸🇪 translation

* another small issue in 🇸🇪 translation

* better phrasing in 🇸🇪 translation
2018-04-26 07:36:52 +09:00
MIYAGI Hikaru
eb593a5a0c Append '.test' to hostname in stub data (#7260) 2018-04-25 14:12:28 +02:00
MIYAGI Hikaru
f58dcbc981 HTTP proxy support for outgoing request, manage access to hidden service (#7134)
* Add support for HTTP client proxy

* Add access control for darknet

Supress error when access to darknet via transparent proxy

* Fix the codes pointed out

* Lint

* Fix an omission + lint

* any? -> include?

* Change detection method to regexp to avoid test fail
2018-04-25 02:14:49 +02:00
Eugen Rochko
9d4710ed00 Add RSS feeds for end-users (#7259)
* Add RSS feed for accounts

* Add RSS feeds for hashtags

* Fix code style issues

* Fix code style issues
2018-04-25 02:10:02 +02:00
Stefan Midjich
bfc41711dd more sane phrasing in 🇸🇪 translation (#7256)
* more sane phrasing in 🇸🇪 translation

* another small issue in 🇸🇪 translation
2018-04-25 01:54:24 +02:00
Renato "Lond" Cerqueira
7681ad8044 Weblate translations (2018-04-24) (#7252)
* Translated using Weblate (Dutch)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (French)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (626 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Japanese)

Currently translated at 99.6% (287 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.5% (623 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Galician)

Currently translated at 99.8% (625 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (French)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (French)

Currently translated at 99.6% (624 of 626 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (French)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.5% (631 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Korean)

Currently translated at 99.8% (633 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/

* Translated using Weblate (Korean)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ko/

* Translated using Weblate (French)

Currently translated at 99.6% (632 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Japanese)

Currently translated at 99.6% (632 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (634 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (634 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/

* Translated using Weblate (Japanese)

Currently translated at 93.5% (58 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Added translation using Weblate (Basque)

* Added translation using Weblate (Basque)

* Translated using Weblate (Galician)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/

* Added translation using Weblate (Basque)

* Added translation using Weblate (Basque)

* Added translation using Weblate (Basque)

* Added translation using Weblate (Basque)

* Translated using Weblate (Galician)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* Translated using Weblate (Galician)

Currently translated at 99.8% (633 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Basque)

Currently translated at 0.3% (1 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eu/

* Translated using Weblate (Basque)

Currently translated at 50.0% (1 of 2 strings)

Translation: Mastodon/Activerecord
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/activerecord/eu/

* Translated using Weblate (Basque)

Currently translated at 1.6% (1 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/eu/

* Translated using Weblate (Basque)

Currently translated at 1.3% (1 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/eu/

* Translated using Weblate (Basque)

Currently translated at 1.6% (1 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eu/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (634 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (634 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Japanese)

Currently translated at 93.5% (58 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Japanese)

Currently translated at 93.5% (58 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/

* Translated using Weblate (Slovak)

Currently translated at 99.6% (287 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 88.4% (561 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 90.3% (573 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Korean)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/

* Translated using Weblate (Italian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/it/

* Translated using Weblate (Italian)

Currently translated at 3.2% (2 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (288 of 288 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/it/

* Translated using Weblate (Italian)

Currently translated at 32.4% (206 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/it/

* Translated using Weblate (Arabic)

Currently translated at 81.3% (516 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Italian)

Currently translated at 51.2% (325 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Translated using Weblate (Slovak)

Currently translated at 91.6% (581 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Italian)

Currently translated at 51.8% (329 of 634 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/

* Normalize translations
Ran yarn build:development && i18n-tasks normalize && yarn manage:translations

* Remove unused translations
Ran i18n-tasks remove-unused
2018-04-24 11:48:11 +02:00
Akihiko Odaki
306267dbd2 Fix ID duplication in timelines (#7251) 2018-04-24 11:47:27 +02:00
Emelia Smith
60b871d56c Implement the ability for instances to define a list of disallowed hashtags (#7176)
The goal here isn't to prevent these hashtags from existing, but just to strongly curtail their usage; The hashtags may still exist in the database via federated status, or from being created prior to this feature.
2018-04-23 23:52:58 +02:00
Emelia Smith
495303d9b8 Prevent suspended accounts from appearing in AccountSearchService (#7246) 2018-04-23 21:27:18 +02:00
ThibG
53b1d88873 Fix fullscreen video player (fixes #7244) (#7245) 2018-04-23 20:12:16 +02:00
Akihiko Odaki
1258efa882 Paginate descendant statuses in public page (#7148) 2018-04-23 19:27:35 +02:00
Alejandro Martinez Ruiz
06817b3c1f tasks/mastodon: fix prompt for Redis password (#7241) 2018-04-23 16:03:58 +02:00
Marcin Mikołajczak
3ccca6cece 🌍: Make 🇵🇱 translation more consistent (#7239)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-23 18:49:03 +09:00
Yamagishi Kazutoshi
9613a53cb3 Update dependencies for Ruby (2018-04-23) (#7237)
* Update annotate to version 2.7.3

* Update aws-sdk-s3 to version 1.9.2

* Update browser to version 2.5.3

* Update capistrano to version 3.10.2

* Update domain_name to version 0.5.20180417

* Update http to version 3.2.0

* Update lograge to version 0.10.0

* Update oj to version 3.5.1

* Update parallel_tests to version 2.21.3

* Update puma to version 3.11.4

* Update rubocop to version 0.55.0

* Update scss_lint to version 0.57.0

* Update simplecov to version 0.16.1

* Update tty-command to version 0.8.0

* Update tty-prompt to version 0.16.0

* Update pkg-config to version 1.3.0

* Update fog-local to version 0.5.0

* Update fog-openstack to version 0.1.25

* Update devise-two-factor to version 3.0.3

* bundle update
2018-04-23 11:29:17 +02:00
Eugen Rochko
7db7d68136 Detect and prevent image bombs, max. processable dimension 4096^2 (#7229) 2018-04-23 09:16:38 +02:00
Yamagishi Kazutoshi
3bf6da1ffc Move precompile step to build stage (#7235) 2018-04-23 09:16:26 +02:00
Yamagishi Kazutoshi
0758b00bfd Refactor resizeImage method (#7236)
- Use URL.createObjectURL (replace from FileReader)
- Use HTMLCanvasElement.prototype.toBlob
  (replace from HTMLCanvasElement.prototype.toDataURL)
- Use Promise (replace callback interface)
2018-04-23 09:15:51 +02:00
Eugen Rochko
660cb058e1 Improve relative timestamps in web UI (#7233)
Use short instead of numeric month, display year when different year

E.g.: "Apr 4" instead of "4/4", "Apr 4, 2017" if different year
2018-04-23 00:43:53 +02:00
Eugen Rochko
05fb6f096d Resize images before upload in web UI to reduce bandwidth (#7223)
* Resize images before upload in web UI to reduce bandwidth

Fix #7218

* Fix issues

* Do not resize GIFs in JS
2018-04-23 00:43:36 +02:00
Eugen Rochko
75c4ab9d12 Remove "nsfw" category for sensitive statuses in OStatus serializer (#7048)
Fix #7011
2018-04-22 22:09:03 +02:00
Eugen Rochko
4ca2f73b12 Rescue Mastodon::LengthValidationError in Remoteable (#7228)
Fix #7198 by allowing records with optional attachments to save
2018-04-22 15:42:00 +02:00
jumoru
b305a23933 Fix: Use "exportierten" instead of "exportieren" in translation (#7186)
Spotted when looking at https://metalhead.club/@thomas/99881521526619858
2018-04-22 14:46:19 +02:00
Lynx Kotoura
3c5006ec7f Fix text colors (#7227) 2018-04-22 14:29:40 +02:00
ThibG
597948fb13 Do not set emoji as inline-block (fixes #5743) (#7207) 2018-04-22 12:10:37 +02:00
David Baucum
ca9192d9ba Ability to specify Redis passwd on mastodon:setup (#7222)
Closes #7221
2018-04-22 11:49:16 +02:00
Yamagishi Kazutoshi
648d645c2f Fix randomly fail (similar #7219) (#7225) 2018-04-22 11:41:39 +02:00
Matthias Beyer
3fa3161472 Fix: Use "welches" instead of "dass" in translation (#7185) 2018-04-22 12:28:12 +09:00
Yamagishi Kazutoshi
3f6893c641 Reset locale on registration tests (#7219) 2018-04-21 23:37:07 +02:00
Yamagishi Kazutoshi
9b8bb2a5df Replace badge to CircleCI (#7216) 2018-04-21 21:56:40 +02:00
Yamagishi Kazutoshi
b8f0cfd6e3 Add parallel test processors (#7215) 2018-04-21 21:36:22 +02:00
Lynx Kotoura
a4a36d994b Separate high contrast theme (#7213) 2018-04-21 21:35:55 +02:00
Yamagishi Kazutoshi
d10447c3a8 Use raw status code on have_http_status (#7214) 2018-04-21 21:35:07 +02:00
Eugen Rochko
bfe26ef67b Force convert to JPG for preview card thumbnails to avoid animations (#7109)
* Force convert to JPG for preview card thumbnails to avoid animations

Fix #7093

* Conditionally convert to JPG only if original is GIF
Coalesce and strip on all formats to ensure no animated APNGs
2018-04-21 21:34:36 +02:00
goofy-bz
1a27f9f46f one grammar fix (#7212) 2018-04-22 03:07:25 +09:00
Yamagishi Kazutoshi
b438224751 Introduce rspec-retry (#7206) 2018-04-20 19:31:30 +02:00
unarist
84214b864c Ignore keyevents during text composition (#7205)
KeyboardEvent.key may be physical key name (Escape, Tab, etc.)
even in text composition and it causes hotkeys or suggestion selection.
So we need to check e.which or e.isComposing.

Checking e.which also allows us to avoid Esc key on compositionend in Safari.
2018-04-20 18:36:52 +02:00
Yamagishi Kazutoshi
87e3f0a41d Fix spec for sr-Latn (#7203) 2018-04-20 18:14:31 +02:00
TakesxiSximada
23106844a1 Fix the hot key (j, k) does not function correctly when there is a pinned toot in account timeline. (#7202)
* Fix the hot key (j, k) does not function correctly when there is a pinned toot in account timeline.

* Fix typo

* Add custom attribute prefix
2018-04-20 18:14:21 +02:00
mayaeh
ee2e0f694a Fix #6157: boosting own private toots (#7200)
* Fix boosting own private toots.

* Run yarn manage:translations and update Japanese translations.
2018-04-20 14:58:33 +02:00
unarist
4e35ce8269 Fix Esc hotkey behavior (#7199)
This fixes following cases which causes hotkey action accidentally:

* hitting Esc key to cancel text composition (mostly in CJK)

  Although events on cancelling composition are still heavily
  browser / input method dependent, but this implementation would
  covers current UI Events spec and some exceptions.

* hitting Esc key to close autocomplete suggestions

This PR changes to use keydown event instead of keyup event as well as other hotkeys.
2018-04-20 14:04:16 +02:00
Yamagishi Kazutoshi
6f63cbb53c Replace Travis to CircleCI (#7196) 2018-04-20 13:46:08 +02:00
Yamagishi Kazutoshi
084cf0babf Add extract_foreign_key_action to Mastodon::MigrationHelpers (#7195) 2018-04-20 12:21:28 +02:00
Eugen Rochko
a9c440637c Improve report layout (#7188)
* Use table for statuses in report

* Display reported account and reporter in the same table

* Split accounts and general report info into two tables again

* Redesign report statuses table, notes, merge notes and action log

* Remove unused translations

* Fix code style issue

* Fix code style issue

* Fix code style issue
2018-04-20 02:28:48 +02:00
Yamagishi Kazutoshi
1663368724 Replace preload link tag to Rails helper (#7192) 2018-04-20 02:06:53 +02:00
beatrix
ca2cbe8f0f Fix webkit scrollbars (#7191)
* Revert "Make scroll bars wider (#7060)"

This reverts commit 11715454d0.

* for real make webkit scrollbar wider
2018-04-19 23:35:47 +02:00
Emelia Smith
b9c35785e2 Reports: Merge contents and comment columns (#7189) 2018-04-19 15:39:54 +02:00
Eugen Rochko
ba917e15f6 Fix text color in "show more" link inside boost confirmation modal (#7183) 2018-04-19 02:36:31 +02:00
Eugen Rochko
ff87d1bc3e Rescue SSL errors when processing mentions, remove useless line (#7184) 2018-04-19 00:53:31 +02:00
Marcin Mikołajczak
1957209efd i18n: Update Polish translation (#7181)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-19 00:14:21 +09:00
Lynx Kotoura
74dae9458d Add color variables of texts for better accesibility (#7125)
* Add variables for text colors

* Change variables in sass files

* Apply text color variables for recently added colors

* Fix text colors of emoji mart anchors

* Fix text colors of search__input

* Fix text colors of text area of compose-form

* Fix icon colors of privacy dropdown and modal

* Inverted icon colors by classname

* Change variables in boost.scss

* Change action-button-color

* Fix text colors of pre-header
2018-04-18 16:52:15 +02:00
abcang
0ba49eca8b Fix comparing id (#7180) 2018-04-18 16:50:19 +02:00
Marcin Mikołajczak
7162a28c34 Add revealing/hiding statuses button to keyboard shortcuts legend column (#7178)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-18 13:15:57 +02:00
Kaito Sinclaire
156b916caf Direct messages column (#4514)
* Added a timeline for Direct statuses
* Lists all Direct statuses you've sent and received
* Displayed in Getting Started
* Streaming server support for direct TL

* Changes to match other timelines in 2.0
2018-04-18 13:09:06 +02:00
luzi82
aedfea3554 zh-HK translation (#7177)
* zh-HK translation

* zh-HK fix

* zh-HK translation

* add missing zh-HK translate

* fix translate

* i18n-tasks normalize
2018-04-18 14:28:26 +09:00
Neil Moore
fad7b9f5f2 Adds keyboard hotkey for revealing/hiding statuses (#7173)
Resolves #5550
2018-04-18 03:33:59 +02:00
ThibG
e5dd385431 Allow boosting own private toots (#6157)
* Adjust policy to allow boosting own private toots

* Add ability to reblog private toots from dropdown menu
2018-04-17 23:35:45 +02:00
Sam Schlinkert
11715454d0 Make scroll bars wider (#7060)
* Set scrollbars to 12 px wide rather than 8px

Should overwrite the setting in reset.scss. This is untested at this point.

* removes scrollbar height and width specifications from reset.scss and basics.scss
2018-04-17 23:25:54 +02:00
abcang
897199910f Improve web api protect (#6343) 2018-04-17 15:23:46 +02:00
Emelia Smith
204d72fbe4 Feature: add count of account notes to reports (#7130)
* Reports: Colocate account details with reports

* Reports: Add count of account moderation notes

Sometimes an account will be left with a note instead of the report, this adds a way to quickly see from a given report if this is the case.
2018-04-17 14:58:11 +02:00
Jennifer Kruse
ef12a2b74c Able to deactivate invites if they aren't expired (#7163) 2018-04-17 13:52:08 +02:00
Eugen Rochko
07a7d5959c Fix missing "Administered by" when timeline preview disabled (#7161) 2018-04-17 13:51:14 +02:00
Eugen Rochko
aab5581c43 Set Referrer-Policy to origin in web UI and public pages of private toots (#7162)
Fix #7115
2018-04-17 13:51:01 +02:00
Eugen Rochko
bb58fc003b Fix warning about using SQL in order for Account#partitioned (#7159) 2018-04-17 13:50:48 +02:00
abcang
727917e91e Fix caret position after inserting emoji (#7167) 2018-04-17 13:50:33 +02:00
abcang
609bf93029 Perform processing that does not use the database before connecting to the database (#7168) 2018-04-17 13:49:09 +02:00
Remi Rampin
3c722fe687 Update French javascript locale file (#7165)
Match config/locales/fr.yml: "private" was changed to "followers-only"
by 501514960a.
2018-04-17 11:37:51 +09:00
ThibG
7e0aed398f Fix scrolling behavior (#7151)
* Update React.JS

* Use React's new lifecycles for scrollable lists

* Clean up dead code

* Make CodeClimate happy
2018-04-16 21:04:24 +02:00
ThibG
1c379b7ef4 Remove extra spaces from search API queries and public account headers (fixes #7129) (#7152) 2018-04-16 17:19:04 +02:00
Akihiko Odaki
1a37d7e252 Fix status filtering in contexts reducer (#7149) 2018-04-16 11:34:34 +02:00
Akihiko Odaki
a1049e9380 Redirect to account status page for page of status stream entry (#7104)
Commit 519119f657 missed a change for
stream entry page. Instead of duplicating the change, redirect to account
status page. It would also help crawlers (of search engines, for example)
to understand a stream entry URL and its corresponding status URL points
to the same page.
2018-04-16 10:04:31 +02:00
Yamagishi Kazutoshi
7c43ed04fe Weblate translations (2018-04-15) (#7141)
* Translated using Weblate (Galician)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Arabic)

Currently translated at 76.4% (449 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Polish)

Currently translated at 98.9% (581 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/

* Translated using Weblate (French)

Currently translated at 99.6% (585 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Persian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/

* Translated using Weblate (French)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/zh_Hant/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant/

* Translated using Weblate (Arabic)

Currently translated at 76.6% (450 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Slovak)

Currently translated at 92.6% (544 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/

* Translated using Weblate (Arabic)

Currently translated at 82.9% (487 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 98.6% (74 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/ar/

* Translated using Weblate (Slovak)

Currently translated at 93.6% (550 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 95.4% (560 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/id/

* Translated using Weblate (Korean)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ko/

* Translated using Weblate (Korean)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/

* Translated using Weblate (Korean)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Arabic)

Currently translated at 82.9% (487 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 99.2% (278 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Arabic)

Currently translated at 87.3% (513 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 99.6% (279 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Arabic)

Currently translated at 88.0% (517 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fi/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Slovak)

Currently translated at 95.4% (560 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/sk/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fi/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fi/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fi/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Finnish)

Currently translated at 25.8% (152 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/

* Translated using Weblate (Finnish)

Currently translated at 25.8% (152 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Finnish)

Currently translated at 33.0% (194 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Finnish)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/

* Translated using Weblate (Slovak)

Currently translated at 95.5% (561 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Galician)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/gl/

* yarn manage:translations
2018-04-15 16:56:03 +02:00
YMHuang
9f5ae7c2e8 Add and revise Traditional Chinese (zh-TW) translation for serveral strings (#7002)
* Translation: add and revise Traditional Chinese translation for serveral strings

* Translation: polish zh-TW locale

* Translation: polish zh-TW locale
2018-04-15 14:00:32 +02:00
Marcin Mikołajczak
fa04945365 Change icon for domain blocks (#7139)
* Change icon for domain blocks

Both domain blocks and user blocks uses the same icon…

* Update index.js
2018-04-15 13:58:47 +02:00
Valentin Lorentz
1e87ed44d5 docker-compose: Only bind ports 3000 and 4000 on localhost. (#7138) 2018-04-15 13:57:58 +02:00
Marcin Mikołajczak
fed0b5ed04 i18n: Update Polish translation (#7131)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-15 14:12:41 +09:00
Eugen Rochko
78ed4ab75f Add bio fields (#6645)
* Add bio fields

- Fix #3211
- Fix #232
- Fix #121

* Display bio fields in web UI

* Fix output of links and missing fields

* Federate bio fields over ActivityPub as PropertyValue

* Improve how the fields are stored, add to Edit profile form

* Add rel=me to links in fields

Fix #121
2018-04-14 12:41:08 +02:00
mayaeh
85ab30abf7 i18n: Add Japanese translations for privacy policy and more (#7049)
* Update Japanese translations.

* Update Japanese translations.

* Update Japanese translations.

* Update Japanese translations.

* Add Japanese translations for #6984, #7040, #7072.
Update Japanese translations for privacy policy.

* Add Japanese translations for #7032, #7074, #7089.

* Proofreading Japanese translations for privacy policy.
2018-04-13 20:11:26 +09:00
Eugen Rochko
778562c223 Ensure SynchronizeFeaturedCollectionWorker is unique and clean up (#7043)
* Ensure SynchronizeFeaturedCollectionWorker is unique and clean up

Fix #7041

* Fix code style issue
2018-04-13 01:27:22 +02:00
Eugen Rochko
9e45b051cf When notification type filtered, ignore live updates for it (#7101)
Fix #5625
2018-04-13 01:20:04 +02:00
Renato "Lond" Cerqueira
14d86eb0d0 Allow more than the max pins if account is not local (#7105)
Sidekiq sometimes throws errors for users that have more pinned items
than the allowed by the local instance. It should only validate the
number of pins for local accounts.
2018-04-12 20:36:02 +02:00
Yamagishi Kazutoshi
50529cbceb Upgrade Rails to version 5.2.0 (#5898) 2018-04-12 14:45:17 +02:00
Alexander
8e88a18316 update gem, test pam authentication (#7028)
* update gem, test pam authentication

* add description for test parameters

* fix inclusion of optional group
2018-04-11 21:40:38 +02:00
ThibG
12f5f13fab Place privacy dropdown menu top if it is closer to the bottom of the viewport (#7106) 2018-04-11 20:42:50 +02:00
Akihiko Odaki
519119f657 Paginate ancestor statuses in public page (#7102)
This also limits the statuses returned by API, but pagination is not
implemented in Web API yet. I still expect it brings user experience
better than making a user wait to fetch all ancestor statuses and flooding
the column with them.
2018-04-11 12:35:09 +02:00
Emelia Smith
d9b62e34da Feature: Improve reports ui (#7032)
* Further improvements to Reports UI

- Clean up notes display
- Clean up add new note form
- Simplify controller
- Allow reopening a report with a note
- Show created at date for reports
- Fix report details table formatting

* Show history of report using Admin::ActionLog beneath the report

* Fix incorrect log message when reopening a report

* Implement fetching of all ActionLog items that could be related to the report

* Ensure adding a report_note updates the report's updated_at

* Limit Report History to actions that happened between the report being created and the report being resolved

* Fix linting issues

* Improve report history builder

Thanks @gargron for the improvements
2018-04-10 20:27:59 +02:00
Eugen Rochko
45c9f16f71 Improve load gap styling in web UI (#7100) 2018-04-10 17:12:10 +02:00
Eugen Rochko
49bbef1202 Use RAILS_LOG_LEVEL to set log level of Sidekiq, too (#7079)
Fix #3565 (oops)
2018-04-10 16:08:28 +02:00
Paul Woolcock
8f800ad691 Change custom emoji search to ILIKE instead of = (#7099) 2018-04-10 15:46:27 +02:00
Emelia Smith
219a4423d8 Feature: Allow staff to change user emails (#7074)
* Admin: Show unconfirmed email address on account page

* Admin: Allow staff to change user email addresses

* ActionLog: On change_email, log current email address and new unconfirmed email address
2018-04-10 09:16:06 +02:00
MIYAGI Hikaru
e6e93ecd8a Fix GIFV encoding params (#7098)
- Explicitly specify video codec.
  When ffmpeg isn't compiled with libx264 but openh264, mpeg4 is selected as video codec.
- Swap avarage bitrate and max bitrate.
2018-04-10 09:11:55 +02:00
Eugen Rochko
80a944c882 Log rate limit hits (#7096)
Fix #7095
2018-04-10 01:20:18 +02:00
Renato "Lond" Cerqueira
0c52654b52 When creating status, if no sensitive status is given, use default (#7057)
Clients using the API that do not provide the sensitive flag are always
posting with false sensitive option.
2018-04-09 23:02:42 +02:00
Emelia Smith
904a2479dd Feature: Direct message from Statuses (#7089)
* Fix: Switching between composing direct message and mention from menus

Previously clicking "direct message" followed by "mention" resulted in the composed status staying as "direct", along with weird spacing of items in the text area. This attempts to fix that.

* Fix: Add missing proptype check for onMention in Status component

* Add the ability to send a direct message to a user from the menu on Statuses

* Add space between "Embed" and "Mention" on expanded statuses menu
2018-04-09 17:09:11 +02:00
Una
e057c0e525 Optimize public/headers/missing.png (#7084) 2018-04-09 11:34:48 +02:00
Marcin Mikołajczak
07d90b0414 i18n: Update Polish translation (#7085)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-09 17:28:53 +09:00
Akihiko Odaki
498327b2e3 Exclude status itself from context query (#7083)
ancestor_statuses and descendant_statuses used to include the root status
itself, but the behavior is confusing because the root status is not
an ancestor nor descendant.
2018-04-09 09:58:53 +02:00
Emelia Smith
0893b16695 Hide search from Compose on mobile devices (#7077)
* Hide search from Compose on mobile devices

We're presently seeing large numbers of users accidentally tooting what they're trying to search for. This PR hides the search form from the Compose view, now that we have a dedicated "search" tab on mobile.

* Don't "showSearch" on mobile if we're not currently searching (isSearchPage)
2018-04-08 18:25:08 +02:00
Emelia Smith
c9cbb8de70 Add search item to tab bar for mobile devices (#7072)
* Add search item to tab bar for mobile devices

* Fix missing prop validation
2018-04-08 14:26:58 +02:00
Levi Bard
cd0eaa349c Enable updating additional account information from user preferences via rest api (#6789)
* Enable updating additional account information from user preferences via rest api
Resolves #6553

* Pacify rubocop

* Decoerce incoming settings in UserSettingsDecorator

* Create user preferences hash directly from incoming credentials instead of going through ActionController::Parameters

* Clean up user preferences update

* Use ActiveModel::Type::Boolean instead of manually checking stringified number equivalence
2018-04-08 13:43:10 +02:00
ThibG
1364e9e4ae Fix follow/unfollow buttons on public profile (fixes #7036) (#7040)
* Fix follow/unfollow buttons on public profile

- Present non-logged users with web+mastodon:// URLs for remote accounts
- Present logged-in users with appropriate links (authorize_follows and
  remote_unfollows) for remote accounts

* Do not cache rendered cards if user is logged in
2018-04-08 13:40:22 +02:00
Akihiko Odaki
1ed1014546 Free stroage if it is exceeding disk quota (#7061) 2018-04-08 13:32:39 +02:00
THE BOSS ♨
b83ce18b30 Ignore elasticsearch directory (#7070) 2018-04-08 16:57:16 +09:00
Eugen Rochko
d4de2239b0 Add a circuit breaker for ActivityPub deliveries (#7053) 2018-04-07 21:36:58 +02:00
Hisham Muhammad
4a9becfca2 i18n: improve "Welcome" translation in Portuguese (#7068)
* i18n: update gender-neutral language for pt and pt-BR

Instead of using "bem-vindo(a)" (a masculine form of "Welcome"
with a "(a)" in the end to mean "bem-vinda" for the feminine form),
use "boas-vindas", which is a gender-neutral form of "Welcome").

There is already precedent for using "boas-vindas" in the
Brazilian Portuguese localization, in `config/locales/pt-BR.yml`.
European Portuguese dictionary Priberam also registers it as a valid form:
https://www.priberam.pt/dlpo/boas-vindas

* i18n: pt-BR minor orthography fix

The form "a bordo" does not take an accent.
http://oredator.com.br/curso-de-redacao/uncategorized/a-bordo-ou-a-bordo
2018-04-07 21:36:03 +02:00
Alda Marteau-Hardi
b65eb00c53 Prevent admins and moderators eavesdropping in private and direct toots (#7067)
Fix #6986
2018-04-07 21:33:01 +02:00
Eugen Rochko
b5726def55 Forward deletes on the same path as reply forwarding (#7058)
* Forward deletes on the same path as reply forwarding

* Remove trailing whitespace
2018-04-07 18:54:46 +02:00
Harmon
98146281e1 Remove duplicate frequently used emojis (#7064) 2018-04-07 14:53:11 +02:00
Isatis
b08ab329f4 retrieve custom emoji list via API instead of before page load (#7047) 2018-04-04 22:25:34 +02:00
Eugen Rochko
f1867a7388 Adjust privacy policy (#6666)
* Adjust privacy policy to be more specific to Mastodon

Fix #6613

* Change data retention of IP addresses from 5 years to 1 year

* Add even more information

* Remove all (now invalid) translations of the privacy policy

* Add information about archive takeout, remove pointless consent section

* Emphasis on DM privacy

* Improve wording

* Add line about data use for moderation purposes
2018-04-04 21:47:39 +02:00
Marcin Mikołajczak
1c1042556d i18n: Update Polish translation (#7037)
* i18n: Update Polish translation

Signed-off-by: Marcin Mikołajczak <me@m4sk.in>

* i18n: Update Polish translation

Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-04 20:13:43 +02:00
Emelia Smith
7a81082704 Revert "Add double-tap zoom functionary to ZoomableImage (#6944)" (#7035)
Unfortunately the new hammer.js functionality wasn't correctly tested and didn't work across devices and browsers, as such, it's best to revert PR #6944 until we can revisit this functionality and make it work across all devices and browsers that are supported by Mastodon.

This reverts commit 5021c4e9ca.
2018-04-04 11:58:15 +02:00
Eugen Rochko
07176fed37 Add contact account to landing page ("Administered by") (#6984) 2018-04-04 01:11:26 +02:00
ThibG
d8d4217959 Fix french wording of reblogged toots in public views, matching the wording of reblogged_by (#7029) 2018-04-03 21:09:14 +02:00
Nolan Lawson
6ff3b3e4db Fix nil account issue in ProcessAccountService (#7019) 2018-04-03 13:08:11 +02:00
Emelia Smith
2e59751823 Improve require_admin! and require_staff! filters (#7018)
Previously these returns 302 redirects instead of 403s, which meant posting links to admin pages in slack caused them to unfurl, rather than stay as a link. Additionally, require_admin! doesn't appear to be actively used, on require_staff!
2018-04-03 13:07:32 +02:00
mayaeh
1c293086a1 i18n: Add Japanese translations for #7000 (#7022)
* run yarn manage:translations.

* run i18n-tasks add-missing ja.

* Update Japanese translations.
2018-04-03 18:21:33 +09:00
Emelia Smith
e85cffb236 Feature: Report improvements (#6967) (#7000)
* Implement Assignment of Reports (#6967)

* Change translation of admin.report.comment.label to "Report Comment" for clarity

As we'll soon add the ability for reports to have comments on them, this clarification makes sense.

* Implement notes for Reports

This enables moderators to leave comments about a report whilst they work on it

* Fix display of report moderation notes

* Allow reports to be reopened / marked as unresolved

* Redirect to reports listing upon resolution of report

* Implement "resolve with note" functionality

* Add inverse relationship for report notes

* Remove additional database querying when loading report notes

* Fix tests for reports

* Fix localisations for report notes / reports
2018-04-02 22:04:14 +02:00
Eugen Rochko
36eac8ba90 Do not default SMTP verify mode to "peer", default to "none" (#6996) 2018-04-02 19:19:51 +02:00
unarist
2c51bc0ca5 Add missing rejection handling for Promises (#7008)
* Add eslint-plugin-promise to detect uncaught rejections

* Move alert generation for errors to actions/alert

* Add missing rejection handling for Promises

* Use catch() instead of onReject on then()

Then it will catches rejection from onFulfilled. This detection can be
disabled by `allowThen` option, though.
2018-04-02 14:51:02 +02:00
Emelia Smith
e7a1716701 Implement the ability for an Administrator or Moderator to remove an account avatar (#6998) 2018-04-02 13:45:07 +02:00
Emelia Smith
4fd71accd4 Fix issues with sending direct messages from user profile (#6999)
* Clear compose textarea when starting a new direct message

Previous behaviour resulted in potentially misdirected direct messages.

* Hide search when starting to compose a direct message
2018-04-02 13:44:19 +02:00
Yamagishi Kazutoshi
3f51c6efaa Weblate translations (2018-04-02) (#7007)
* Translated using Weblate (Galician)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Arabic)

Currently translated at 76.4% (449 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Polish)

Currently translated at 98.9% (581 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/

* Translated using Weblate (French)

Currently translated at 99.6% (585 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* Translated using Weblate (Persian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/

* Translated using Weblate (French)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/zh_Hant/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/zh_Hant/

* Translated using Weblate (Arabic)

Currently translated at 76.6% (450 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Slovak)

Currently translated at 92.6% (544 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/

* Translated using Weblate (Arabic)

Currently translated at 82.9% (487 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 98.6% (74 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/ar/

* Translated using Weblate (Slovak)

Currently translated at 93.6% (550 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 95.4% (560 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (75 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/id/

* Translated using Weblate (Korean)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ko/

* Translated using Weblate (Korean)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/

* Translated using Weblate (Korean)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/

* Translated using Weblate (Arabic)

Currently translated at 82.9% (487 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 99.2% (278 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Translated using Weblate (Arabic)

Currently translated at 87.3% (513 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 99.6% (279 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* bundle exec i18n-tasks normalize && yarn manage:translations

* revert
2018-04-02 13:43:30 +02:00
Evgeny Petrov
b04f73ce66 Russian language updated (#7005)
* Russian language updated

* Small fixes for RU language

* bundle exec i18n-tasks normalize
2018-04-02 19:49:06 +09:00
luzi82
24611d8deb i18n: update zh-HK translation (#7004)
* i18n: update zh-HK translation

* i18n: update zh-HK translation

* i18n-tasks normalize
2018-04-02 19:11:37 +09:00
Eugen Rochko
f890d2a766 Support all ActivityPub actor types (#6997)
Fix #6973
2018-04-02 02:10:53 +02:00
Eugen Rochko
33513753b9 Fix unpermitted parameters warning when generating pagination URLs (#6995) 2018-04-02 02:09:50 +02:00
David Underwood
123a343d11 [WIP] Enable custom emoji on account pages and in the sidebar (#6124)
Federate custom emojis with accounts
2018-04-01 23:55:42 +02:00
Yamagishi Kazutoshi
f464f98fd3 Update Ruby to version 2.4.4 (#6964)
https://www.ruby-lang.org/en/news/2018/03/28/ruby-2-4-4-released/

> This release includes some bug fixes and some security fixes.
>
> - CVE-2017-17742: HTTP response splitting in WEBrick
> - CVE-2018-6914: Unintentional file and directory creation with directory traversal in tempfile and tmpdir
> - CVE-2018-8777: DoS by large request in WEBrick
> - CVE-2018-8778: Buffer under-read in String#unpack
> - CVE-2018-8779: Unintentional socket creation by poisoned NUL byte in UNIXServer and UNIXSocket
> - CVE-2018-8780: Unintentional directory traversal by poisoned NUL byte in Dir
> - Multiple vulnerabilities in RubyGems
2018-04-01 23:43:08 +02:00
Emelia Smith
6a895e1ab3 Fix: Prevent submission using same logic as submit button disabling. (#6993)
This prevents submission through ctrl/cmd+enter when the submit button is disabled.
2018-04-01 22:19:43 +02:00
luzi82
993ce0e5a7 improve zh-HK localization by referring zh-TW and zh-CN (#6988) 2018-04-01 21:57:26 +09:00
Marcin Mikołajczak
929f58f180 i18n: Update Polish translation (#6985)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-04-01 10:31:38 +02:00
mayaeh
b7d633c1bb i18n: Add Japanese translations for domain blocks (#6979)
* run yarn manage:translations

* Update Japanese translations for domain blocks.
2018-03-31 21:09:39 +09:00
Daniel Hunsaker
3886bfb5eb [Nanobox] Enable ElasticSearch support by default (#6977)
Admins can still disable the feature by adding `ES_ENABLED=false` to their environment, if they prefer not to use it. Be sure to set the variable before you deploy!
2018-03-31 13:17:25 +02:00
unarist
fb3dc00dda Ignore AbortError when cancelled sharing (#6978)
`navigator.share()` rejects Promise if user cancelled sharing, and it may
print it as an error on JavaScript console.

This patch ignores it and prints other errors on the console.
2018-03-31 13:16:38 +02:00
ThibG
e573bb0990 Fix compatibility with PeerTube (#6968)
* Support fetching objects of convertible types by URL (fixes #6924)

* Ignore invalid hashtags
2018-03-30 15:44:54 +02:00
ThibG
a6c129ddbd Add some UI for user-defined domain blocks (#6628)
* Keep list of blocked domains

Might be overkill, but I'm trying to follow the same logic as for blocked users

* Add basic domain block UI

* Add the domain blocks UI to Getting Started

* Fix undefined URL in `fetchDomainBlocks`

* Update all known users' domain_blocking relationship instead of just one's
2018-03-30 12:38:00 +02:00
Pierre-Morgan Gate
47cee7cc8e Upgrade charlock_holmes to version 0.7.6 (#6966)
This version fixes compilation errors when trying to build its native extension with ICU 61.
2018-03-30 09:52:44 +02:00
takayamaki
947eedcab2 update ja locale (#6965)
related https://github.com/tootsuite/mastodon/pull/6956
2018-03-30 10:04:04 +09:00
Emelia Smith
d1f34151ae Feature: Direct message from menu (#6956)
* Implement ability to send direct messages from the user menu

* Implement message warning users that direct messages are visible to all mentioned users

* Update locales
2018-03-29 19:08:34 +02:00
unarist
f1f846045f Fix ReferenceError when Cache API is missing (#6953)
Cache API is not supported on Safari 11.0 / iOS 11.

Since those caching is optional, this patch simply ignores it.
2018-03-29 14:57:02 +02:00
unarist
41452e8302 Fix TypeError on follow notification (#6950)
`notification.status` may not be present, e.g. follow notification.
2018-03-29 12:59:12 +02:00
ThibG
9ed5eebd7c Do not ignore unknown media attachments, only skip them (#6948)
That way, they are displayed in a list below the corresponding toot.
2018-03-29 00:52:24 +02:00
Yuto Tokunaga
5021c4e9ca Add double-tap zoom functionary to ZoomableImage (#6944)
add <div.zoomable-image__margin/> to keep margin of the image on zooming
move setting `scrollLeft` and `scrollTop` of container from callback of
`setState` to `componentDidUpdate`
add 'hammerjs' package for touch gesture detection
rewrite `ZoomableImage` using 'hammerjs'
2018-03-28 20:40:51 +02:00
Akihiko Odaki
4f9136d2d5 Document CORS requirement for asset host (#6941) 2018-03-28 20:40:18 +02:00
unarist
3523aa440b Fix LoadMore on account media gallery (#6933)
max_id in the fetch request should be a status id, but media attachment id was used.
2018-03-27 16:53:52 +02:00
unarist
f5ed5f3860 Clone response before put it to the cache (#6932)
`Response.prototype.clone()` must be called before the response used.

This fixes an error from ServiceWorker and failing to load image when the
image is not cached.
2018-03-27 15:18:35 +02:00
unarist
2f3ac14a43 Add missing null handling in notification reducer (#6930)
This patch adds null item (i.e. gap) handling on below functions to avoid TypeError.

* `filterNotifications` called on user mute/block
* `deleteByStatus` called on status deletion
2018-03-27 13:05:59 +02:00
Akihiko Odaki
ca42f9b0eb Cache media (#6902) 2018-03-27 12:32:30 +02:00
Yuto Tokunaga
31e7b73084 fix #6846 (#6914) 2018-03-27 12:30:28 +02:00
unarist
a1d0915585 Add a spec for UniqueUsernameValidator (#6927)
Note that this spec has a pending test about dots in the username,
because allowing it has been reverted for now.
2018-03-27 05:22:58 +02:00
Eugen Rochko
2a90da1837 Fix UniqueUsernameValidator comparison (#6926)
Comparison was downcasing only one side, therefore if previously
existing account had a non-lowercase spelling, it would be ignored
when checking for duplicates.

New rake task `mastodon:maintenance:find_duplicate_usernames` will
help find constraint violations that might have occured from the
presence of this bug.

Bump version to 2.3.3
2018-03-27 04:33:57 +02:00
Akihiko Odaki
40e5d2303b Validate HTTP response length while receiving (#6891)
to_s method of HTTP::Response keeps blocking while it receives the whole
content, no matter how it is big. This means it may waste time to receive
unacceptably large files. It may also consume memory and disk in the
process. This solves the inefficency by checking response length while
receiving.
2018-03-26 14:02:10 +02:00
Stephen Burgess
18965cb0e6 feat(ShowMore): Add classname to show more/show less button (#6904) 2018-03-26 13:59:44 +02:00
Yuto Tokunaga
f691afaae9 Refactor scss (#6913)
* Refactoring scss

introduce scss variables for the media modal
fix css block structure corresponding to react components
fix flex layouts
remove background image of the loaded image on the media modal

* Fix typo
2018-03-26 13:59:21 +02:00
unarist
605a92b460 Fix moved account handling in IndexedDB feature (#6915)
* Fix stack overflow on importFetchedAccounts

  When the account has moved property, it should process destination
  account instead of source account itself.

* Set account id instead of account object for moved property

  This restores "foo has moved to" indication on account view, and
  fixes `reblog` index on `accounts` object store.
2018-03-26 12:48:01 +02:00
Yann Klis
3b2c7a33a9 Missing OTP_SECRET in scalingo.json (#6917) 2018-03-26 12:47:34 +02:00
Marcin Mikołajczak
85a395fab6 i18n: Update Polish translation (#6903)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-03-25 23:33:07 +09:00
Akihiko Odaki
cbf97c03bb Allow clients to fetch notifications made while they were offline (#6886) 2018-03-24 22:07:23 +01:00
Akihiko Odaki
9a1a55ce52 Allow clients to fetch statuses made while they were offline (#6876) 2018-03-24 15:25:15 +01:00
Akihiko Odaki
59657e24b9 Rename variables to have semantic meanings in notifications reducer (#6890) 2018-03-24 13:36:44 +01:00
Akihiko Odaki
fe398a098e Store objects to IndexedDB (#6826) 2018-03-24 13:06:27 +01:00
Yamagishi Kazutoshi
28384c1771 Revert "Revert "Upgrade Paperclip to version 6.0.0" (#6807)" (#6808)
This reverts commit 40871caa4b.
2018-03-24 12:52:45 +01:00
Akihiko Odaki
ff7941e652 Show media modal on public pages (#6801) 2018-03-24 12:52:26 +01:00
Marcin Mikołajczak
1c15329cce Change “Toots with replies” to “Toots and replies” (#6875)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-03-24 12:51:51 +01:00
Akihiko Odaki
b2a4ffd3a9 Change columns in notifications nonnullable (#6764) 2018-03-24 12:51:28 +01:00
Akihiko Odaki
fa310695fa Note if the user is already following the target when authorizing follow (#6325) 2018-03-24 12:50:41 +01:00
Jeroen
580835ab69 Invites: Add '1 week' as expire option (#6872)
* Invites: Add '1 week' as expire option

IMO a max. of 1 day is too short. Not everyone has the time and motivation to use an invite in a 24 hour period. 1 week as a max. is I think a good compromise between convenience and security.

* Invites: Add '1 week' as expire option

IMO a max. of 1 day is too short. Not everyone has the time and motivation to use an invite in a 24 hour period. 1 week as a max. is I think a good compromise between convenience and security.

* Update en.yml
2018-03-24 12:50:14 +01:00
Akihiko Odaki
54b273bf99 Close http connection in perform method of Request class (#6889)
HTTP connections must be explicitly closed in many cases, and letting
perform method close connections makes its callers less redundant and
prevent them from forgetting to close connections.
2018-03-24 12:49:54 +01:00
Akihiko Odaki
4e71b104e6 Internationalize unexpected error message (#6887) 2018-03-24 10:54:19 +01:00
Yamagishi Kazutoshi
65c10c0bc8 Weblate translations (2018-03-23) (#6874)
* Translated using Weblate (Galician)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (587 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/

* Translated using Weblate (Arabic)

Currently translated at 76.4% (449 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Japanese)

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 92.3% (542 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/

* Translated using Weblate (Polish)

Currently translated at 98.9% (581 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/

* Translated using Weblate (French)

Currently translated at 99.6% (585 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (586 of 587 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/

* bundle exec i18n-tasks normalize && yarn manage:translations
2018-03-24 01:04:02 +01:00
Quentí
ecdc5957a3 [i18n] Occitan update (#6869)
* Update oc.yml

* Update simple_form.oc.yml

* Update oc.json

* Update oc.yml

* bundle exec i18n-tasks normalize
2018-03-23 18:52:25 +09:00
Eugen Rochko
6cc432bbc4 Bump version to 2.3.2 2018-03-22 14:13:46 +01:00
Eugen Rochko
dafae9818d Bump version to 2.3.2rc5 2018-03-22 11:31:52 +01:00
Eugen Rochko
9fe1619db9 Do not re-query mentions from serializers (#6858)
Fix performance regression from #6836
2018-03-22 11:31:17 +01:00
Eugen Rochko
da70aca28e Restore username validation to disallow dots, for now (#6863)
Usernames with dots in them do not work with routes, because the dot usually separates the desired page format (e.g. json). I don't want to mess with changing route constraints for this patch release.
2018-03-22 11:30:22 +01:00
ThibG
6f531d140b Fix MENTION_RE to not match nil usernames (#6862) 2018-03-22 10:45:48 +01:00
Eugen Rochko
f66a786029 Hide floating action button on thread views (#6859) 2018-03-22 09:33:14 +01:00
Patrick Figel
d97903a358 Update sanitize and loofah (#6855)
Fixes CVE-2018-8048 and CVE-2018-3740, two medium-severity XSS
vulnerabilities present in these gems when built against
libxml2 >= 2.9.2.
2018-03-21 17:43:28 +01:00
Eugen Rochko
93897134ca Permit dots in usernames with conditions (#6844)
* Permit dots in usernames with conditions

- Dot cannot be the start or end of username
- a.lice and al.ice are considered the same during sign-up

* Fix regex mixin flags
2018-03-21 10:26:53 +01:00
Akihiko Odaki
a6b59cd1a3 Remove debug option from Babel preset env (#6852) 2018-03-21 10:26:15 +01:00
Eugen Rochko
f64af6473f Bump version to 2.3.2rc4 2018-03-20 23:49:24 +01:00
Eugen Rochko
ac49c7932d Add LDAP_TLS_NO_VERIFY option, don't require LDAP_ENABLED outside .env (#6845)
Fix #6816, fix #6790
2018-03-20 19:41:51 +01:00
Akihiko Odaki
61dcb686a8 Fix i18n fallback configuration conflicts with environment configurations (#6843) 2018-03-20 16:36:20 +01:00
Eugen Rochko
9381a7d9d5 Use username/domain to match existing accounts in ActivityPub (#6842)
See also: #6837, #6667
2018-03-20 14:57:46 +01:00
ThibG
a5c6c748e0 Cancel outdated pending compose suggestions (#6838) 2018-03-20 12:40:12 +01:00
Rey Tucker
36b5703796 request: in the event of failure, try other IPs (#6761) (#6813)
* request: in the event of failure, try other IPs (#6761)

In the case where a name has multiple A/AAAA records, we should
try subsequent records instead of immediately failing when we have a
failure on the first IP address.

This significantly improves delivery success when there are network
connectivity problems affecting only IPv4 or IPv6.

* fix method call style

* request_spec: adjust test case to use Addrinfo

* request: Request/open: move private addr check to within begin/rescue

* request_spec: add case to test failover, fix exception check

* Double Addrinfo.foreach so that it correctly yields instances
2018-03-20 09:06:08 +01:00
ThibG
ff6b8a6443 Serialize mentions in the order they are added (#6836)
Up until now, the order seemed to be in the *opposite* order,
which caused the WebUI to populate mentions in reversed order
when replying to toots local to one's instance.
2018-03-19 20:19:35 +01:00
ThibG
6b76a6212d Display content warning in mail notification emails (#6832) 2018-03-19 20:12:20 +01:00
Alexander
33ee347c99 rename pam email environment variable to something more understandable and default to LOCAL_DOMAIN (better fallback) (#6833) 2018-03-19 20:09:26 +01:00
Alexander
0306e3e9be bugfixes and gem update (#6831)
* update to new version of devise_pam_authenticatable2

* fix behaviour if suffix is nil, fix environment loading, fix user email creation

* code cleanup/fix linter warning
2018-03-19 20:08:56 +01:00
ThibG
357f9298bd Fix e-mail changed notification (fixes #6778) (#6835)
In Devise::Mailer#email_changed, the new email might be in the email attr.
See: https://github.com/plataformatec/devise/blob/master/app/views/devise/mailer/email_changed.html.erb
2018-03-19 20:07:47 +01:00
Renato "Lond" Cerqueira
f7c46fc113 Weblate translations 20180319 (#6827)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Spanish)

Currently translated at 99.6% (579 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/es/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (French)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/es/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/es/

* Translated using Weblate (Indonesian)

Currently translated at 94.6% (71 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/id/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/ar/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Arabic)

Currently translated at 75.5% (439 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 76.2% (443 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Russian)

Currently translated at 95.8% (557 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ru/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Slovak)

Currently translated at 91.7% (533 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Spanish)

Currently translated at 99.8% (580 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Finnish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/

* Translated using Weblate (Slovak)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/es/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sv/

* Translated using Weblate (Finnish)

Currently translated at 93.1% (54 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/

* Translated using Weblate (Arabic)

Currently translated at 76.7% (446 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Slovak)

Currently translated at 93.2% (542 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/

* Normalize translations
Ran i18n-tasks normalize && yarn manage:translations
2018-03-19 15:12:06 +01:00
Eugen Rochko
74c39fada0 Bump version to 2.3.2rc3 2018-03-19 12:20:57 +01:00
Eugen Rochko
f02411da40 Ignore media validation when attaching to status during processing (#6822)
Fix #6821
2018-03-19 01:51:19 +01:00
Eugen Rochko
a568e3ca8e Revert #6479, hide sensitive text/images from OpenGraph previews (#6818)
Display summary of attachments in description, and mark up content
warning if present, e.g.:

    Attached: 3 images · Content warning: Dota 2

When text is not supposed to be hidden, it looks more like:

    Attached: 3 images

    Here is the text of the toot

With #6817, multilinguagility should be assured...
2018-03-18 20:33:07 +01:00
Eugen Rochko
3b440bd5af Fix elephant graphic being draggable and selectable (#6819) 2018-03-18 20:32:44 +01:00
Eugen Rochko
39f27b6cf3 If DEFAULT_LOCALE is set, enforce it instead of HTTP request locale (#6817)
Fix #6784
2018-03-18 16:57:04 +01:00
Akihiko Odaki
721234230c Synchronize HTML page cache with sessions (#6815) 2018-03-18 15:14:38 +01:00
nightpool
566ace2d64 Add entropy to download filenames (#6811)
pretty quick fix, and with the 1 week expiration i don't think we need to be too worried about the existing files

closes #6798
2018-03-17 17:39:28 +01:00
Eugen Rochko
092f1df9d0 Bump version to 2.3.2rc2 2018-03-17 15:28:52 +01:00
Eugen Rochko
844616e950 Re-add git and nodejs-npm to Dockerfile (#6810)
Fix #6809

I don't know why, either
2018-03-17 15:28:09 +01:00
Eugen Rochko
40871caa4b Revert "Upgrade Paperclip to version 6.0.0" (#6807)
* Revert "Bump version to 2.3.2rc1"

This reverts commit cdf8b92fea.

* Revert "Downgrade Dockerfile to Ruby 2.4.3 on Alpine 3.6 (#6806)"

This reverts commit 0074cad44f.

* Revert "Handle Mastodon::HostValidationError when pulling remoteable assets (#6782)"

This reverts commit 4a0a19fe54.

* Revert "Correct the reference to user's password in mastodon:add_user task (#6800)"

This reverts commit 338bff8b93.

* Revert "Upgrade Paperclip to version 6.0.0 (#6754)"

This reverts commit b88fcd53f7.
2018-03-17 14:20:35 +01:00
Eugen Rochko
cdf8b92fea Bump version to 2.3.2rc1 2018-03-17 14:07:00 +01:00
Eugen Rochko
0074cad44f Downgrade Dockerfile to Ruby 2.4.3 on Alpine 3.6 (#6806)
Fix 6734
2018-03-17 14:06:25 +01:00
Daniel Hunsaker
4a0a19fe54 Handle Mastodon::HostValidationError when pulling remoteable assets (#6782)
This will prevent, for example, `rake mastodon:redownload_avatars` from crashing when an instance is no longer responding to connection attempts, instead silently continuing as expected.
2018-03-17 13:27:50 +01:00
Akihiko Odaki
338bff8b93 Correct the reference to user's password in mastodon:add_user task (#6800) 2018-03-17 13:27:19 +01:00
Yamagishi Kazutoshi
b88fcd53f7 Upgrade Paperclip to version 6.0.0 (#6754) 2018-03-17 12:37:58 +01:00
trwnh
ca7e6a6d2e Properly center .nothing-here (#6787) (#6788)
Apply "margin: 0 auto;" at line 443 to fix issue #6787
2018-03-17 12:35:35 +01:00
Akihiko Odaki
f0cd957c7a Cache HTML page with Service Worker (#6802)
This is the first step to make Mastodon work offline. It is also required
by Chromium to trigger Web Manifest automated install prompt.
2018-03-17 12:35:13 +01:00
Daniel Hunsaker
64fc8d2b07 [Nanobox] Stream backups to the warehouse (#6799)
The `curl` docs are terrible. Use `-X POST -T` instead of `--data-binary`, to avoid loading entire backups into memory _before_ transferring to the warehouse, and just stream the data across as it comes in.
2018-03-17 08:39:14 +01:00
Marcin Mikołajczak
fd385e256d i18n: Update Polish translation (#6780)
Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
2018-03-14 02:17:48 +09:00
Renato "Lond" Cerqueira
03119c857b Weblate translations (2018-03-13) (#6777)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/

* Translated using Weblate (Spanish)

Currently translated at 99.6% (579 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/es/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/

* Translated using Weblate (French)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (58 of 58 strings)

Translation: Mastodon/Preferences
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/es/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/es/

* Translated using Weblate (Indonesian)

Currently translated at 94.6% (71 of 75 strings)

Translation: Mastodon/Doorkeeper
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/id/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Arabic)

Currently translated at 100.0% (62 of 62 strings)

Translation: Mastodon/Devise
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/ar/

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/id/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (280 of 280 strings)

Translation: Mastodon/React
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/

* Translated using Weblate (Arabic)

Currently translated at 75.5% (439 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Arabic)

Currently translated at 76.2% (443 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/

* Translated using Weblate (Russian)

Currently translated at 95.8% (557 of 581 strings)

Translation: Mastodon/Backend
Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ru/

* Normalize translations
Ran i18n-tasks normalize && yarn manage:translations
2018-03-13 16:16:51 +01:00
Eugen Rochko
2ef1ce1182 Bump version to 2.3.1 2018-03-13 15:50:15 +01:00
Eugen Rochko
eb2425b53b Hide loading bar on status interactions (#6774) 2018-03-13 14:30:01 +01:00
795 changed files with 18989 additions and 7293 deletions

View File

@@ -4,6 +4,7 @@
[
"env",
{
"exclude": ["transform-async-to-generator", "transform-regenerator"],
"loose": true,
"modules": false,
"targets": {

193
.circleci/config.yml Normal file
View File

@@ -0,0 +1,193 @@
version: 2
aliases:
- &defaults
docker:
- image: circleci/ruby:2.5.1-stretch-node
environment: &ruby_environment
BUNDLE_APP_CONFIG: ./.bundle/
DB_HOST: localhost
DB_USER: root
RAILS_ENV: test
PARALLEL_TEST_PROCESSORS: 4
ALLOW_NOPAM: true
CONTINUOUS_INTEGRATION: true
DISABLE_SIMPLECOV: true
working_directory: ~/projects/mastodon/
- &attach_workspace
attach_workspace:
at: ~/projects/
- &persist_to_workspace
persist_to_workspace:
root: ~/projects/
paths:
- ./mastodon/
- &restore_ruby_dependencies
restore_cache:
keys:
- v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
- v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-
- v2-ruby-dependencies-
- &install_steps
steps:
- checkout
- *attach_workspace
- restore_cache:
keys:
- v1-node-dependencies-{{ checksum "yarn.lock" }}
- v1-node-dependencies-
- run: yarn install --frozen-lockfile
- save_cache:
key: v1-node-dependencies-{{ checksum "yarn.lock" }}
paths:
- ./node_modules/
- *persist_to_workspace
- &install_system_dependencies
run:
name: Install system dependencies
command: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev libprotobuf-dev protobuf-compiler
- &install_ruby_dependencies
steps:
- *attach_workspace
- *install_system_dependencies
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production
- save_cache:
key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
paths:
- ./.bundle/
- ./vendor/bundle/
- &test_steps
steps:
- *attach_workspace
- *install_system_dependencies
- run: sudo apt-get install -y ffmpeg
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- restore_cache:
keys:
- precompiled-assets-{{ .Branch }}-{{ .Revision }}
- precompiled-assets-{{ .Branch }}-
- precompiled-assets-
- run:
name: Prepare Tests
command: ./bin/rails parallel:create parallel:load_schema parallel:prepare
- run:
name: Run Tests
command: ./bin/retry bundle exec parallel_test ./spec/ --group-by filesize --type rspec
jobs:
install:
<<: *defaults
<<: *install_steps
install-ruby2.5:
<<: *defaults
<<: *install_ruby_dependencies
install-ruby2.4:
<<: *defaults
docker:
- image: circleci/ruby:2.4.4-stretch-node
environment: *ruby_environment
<<: *install_ruby_dependencies
build:
<<: *defaults
steps:
- *attach_workspace
- *install_system_dependencies
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: ./bin/rails assets:precompile
- save_cache:
key: precompiled-assets-{{ .Branch }}-{{ .Revision }}
paths:
- ./public/assets
- ./public/packs-test/
test-ruby2.5:
<<: *defaults
docker:
- image: circleci/ruby:2.5.1-stretch-node
environment: *ruby_environment
- image: circleci/postgres:10.3-alpine
environment:
POSTGRES_USER: root
- image: circleci/redis:4.0.9-alpine
<<: *test_steps
test-ruby2.4:
<<: *defaults
docker:
- image: circleci/ruby:2.4.4-stretch-node
environment: *ruby_environment
- image: circleci/postgres:10.3-alpine
environment:
POSTGRES_USER: root
- image: circleci/redis:4.0.9-alpine
<<: *test_steps
test-webui:
<<: *defaults
docker:
- image: circleci/node:8.11.1-stretch
steps:
- *attach_workspace
- run: ./bin/retry yarn test:jest
check-i18n:
<<: *defaults
steps:
- *attach_workspace
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
- *restore_ruby_dependencies
- run: bundle exec i18n-tasks check-normalized
- run: bundle exec i18n-tasks unused
workflows:
version: 2
build-and-test:
jobs:
- install
- install-ruby2.5:
requires:
- install
- install-ruby2.4:
requires:
- install
- build:
requires:
- install-ruby2.5
- test-ruby2.5:
requires:
- install-ruby2.5
- build
- test-ruby2.4:
requires:
- install-ruby2.4
- build
- test-webui:
requires:
- install
- check-i18n:
requires:
- install-ruby2.5

View File

@@ -11,3 +11,4 @@ vendor/bundle
*~
postgres
redis
elasticsearch

View File

@@ -14,9 +14,9 @@ DB_PORT=5432
DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
# Optional ElasticSearch configuration
# ES_ENABLED=true
# ES_HOST=localhost
# ES_PORT=9200
ES_ENABLED=true
ES_HOST=$DATA_ELASTIC_HOST
ES_PORT=9200
# Optimizations
LD_PRELOAD=/data/lib/libjemalloc.so

View File

@@ -81,6 +81,10 @@ SMTP_FROM_ADDRESS=notifications@example.com
# PAPERCLIP_ROOT_URL=/system
# Optional asset host for multi-server setups
# The asset host must allow cross origin request from WEB_DOMAIN or LOCAL_DOMAIN
# if WEB_DOMAIN is not set. For example, the server may have the
# following header field:
# Access-Control-Allow-Origin: https://example.com/
# CDN_HOST=https://assets.example.com
# S3 (optional)
@@ -109,6 +113,8 @@ SMTP_FROM_ADDRESS=notifications@example.com
# For Keystone V3, the value for SWIFT_TENANT should be the project name
# SWIFT_TENANT=
# SWIFT_PASSWORD=
# Some OpenStack V3 providers require PROJECT_ID (optional)
# SWIFT_PROJECT_ID=
# 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=
@@ -155,8 +161,8 @@ STREAMING_CLUSTER_NUM=1
# The pam environment variable "email" is provided by:
# https://github.com/devkral/pam_email_extractor
# PAM_ENABLED=true
# Fallback Suffix for email address generation (nil by default)
# PAM_DEFAULT_SUFFIX=pam
# Fallback email domain for email address generation (LOCAL_DOMAIN by default)
# PAM_EMAIL_DOMAIN=example.com
# Name of the pam service (pam "auth" section is evaluated)
# PAM_DEFAULT_SERVICE=rpam
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
@@ -210,3 +216,10 @@ STREAMING_CLUSTER_NUM=1
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
# Use HTTP proxy for outgoing request (optional)
# http_proxy=http://gateway.local:8118
# Access control for hidden service.
# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# If you use transparent proxy to access to hidden service, uncomment following for skipping private address check.
# HIDDEN_SERVICE_VIA_TRANSPARENT_PROXY=true

View File

@@ -1,3 +1,9 @@
# Node.js
NODE_ENV=test
# Federation
LOCAL_DOMAIN=cb6e6126.ngrok.io
LOCAL_HTTPS=true
# test pam authentication
PAM_ENABLED=true
PAM_DEFAULT_SERVICE=pam_test
PAM_CONTROLLED_SERVICE=pam_test_controlled

View File

@@ -13,6 +13,7 @@ plugins:
- react
- jsx-a11y
- import
- promise
parserOptions:
sourceType: module
@@ -152,3 +153,5 @@ rules:
- "app/javascript/**/__tests__/**"
import/no-unresolved: error
import/no-webpack-loader-syntax: error
promise/catch-or-return: error

View File

@@ -1,3 +1,9 @@
---
name: Bug Report
about: Create a report to help us improve
---
[Issue text goes here].
* * * *

View File

@@ -0,0 +1,11 @@
---
name: Feature Request
about: Suggest an idea for this project
---
[Issue text goes here].
* * * *
- [ ] I searched or browsed the repos other issues to ensure this is not a duplicate.

3
.gitignore vendored
View File

@@ -36,9 +36,10 @@ config/deploy/*
.vscode/
.idea/
# Ignore postgres + redis volume optionally created by docker-compose
# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
postgres
redis
elasticsearch
# Ignore Apple files
.DS_Store

View File

@@ -1 +1 @@
2.5.0
2.5.1

View File

@@ -1,59 +0,0 @@
language: ruby
cache:
bundler: true
yarn: true
directories:
- node_modules
- public/assets
- public/packs-test
- tmp/cache/babel-loader
dist: trusty
sudo: false
branches:
only:
- master
notifications:
email: false
env:
global:
- LOCAL_DOMAIN=cb6e6126.ngrok.io
- LOCAL_HTTPS=true
- RAILS_ENV=test
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
- PARALLEL_TEST_PROCESSORS=2
addons:
postgresql: 9.4
apt:
sources:
- trusty-media
- sourceline: deb https://dl.yarnpkg.com/debian/ stable main
key_url: https://dl.yarnpkg.com/debian/pubkey.gpg
packages:
- ffmpeg
- libicu-dev
- libprotobuf-dev
- protobuf-compiler
- yarn
rvm:
- 2.4.2
- 2.5.0
services:
- redis-server
install:
- nvm install
- bundle install --path=vendor/bundle --without development production --retry=3 --jobs=16
- yarn install
before_script:
- ./bin/rails parallel:create parallel:load_schema parallel:prepare assets:precompile
script:
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
- yarn run test:jest
- bundle exec i18n-tasks check-normalized && bundle exec i18n-tasks unused

View File

@@ -49,3 +49,8 @@ It is expected that you have a working development environment set up (see back-
* If you are introducing new strings, they must be using localization methods
If the JavaScript or CSS assets won't compile due to a syntax error, it's a good sign that the pull request isn't ready for submission yet.
## Translate
You can contribute to translating Mastodon via Weblate at [weblate.joinmastodon.org](https://weblate.joinmastodon.org/).
[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)

View File

@@ -1,4 +1,4 @@
FROM ruby:2.5.0-alpine3.7
FROM ruby:2.4.4-alpine3.6
LABEL maintainer="https://github.com/tootsuite/mastodon" \
description="Your self-hosted, globally interconnected microblogging community"
@@ -9,6 +9,8 @@ ARG GID=991
ENV RAILS_SERVE_STATIC_FILES=true \
RAILS_ENV=production NODE_ENV=production
ARG YARN_VERSION=1.3.2
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
ARG LIBICONV_VERSION=1.15
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
@@ -30,17 +32,24 @@ RUN apk -U upgrade \
ca-certificates \
ffmpeg \
file \
git \
icu-libs \
imagemagick \
libidn \
libpq \
nodejs \
nodejs-npm \
protobuf \
tini \
tzdata \
yarn \
&& update-ca-certificates \
&& mkdir -p /tmp/src \
&& mkdir -p /tmp/src /opt \
&& wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
&& echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
&& tar -xzf yarn.tar.gz -C /tmp/src \
&& rm yarn.tar.gz \
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
&& tar -xzf libiconv.tar.gz -C /tmp/src \

99
Gemfile
View File

@@ -3,95 +3,101 @@
source 'https://rubygems.org'
ruby '>= 2.3.0', '< 2.6.0'
gem 'pkg-config', '~> 1.2'
gem 'pkg-config', '~> 1.3'
gem 'puma', '~> 3.10'
gem 'rails', '~> 5.1.4'
gem 'puma', '~> 3.11'
gem 'rails', '~> 5.2.0'
gem 'hamlit-rails', '~> 0.2'
gem 'pg', '~> 0.20'
gem 'pghero', '~> 1.7'
gem 'dotenv-rails', '~> 2.2'
gem 'pg', '~> 1.0'
gem 'pghero', '~> 2.1'
gem 'dotenv-rails', '~> 2.2', '< 2.3'
gem 'aws-sdk', '~> 2.10', require: false
gem 'aws-sdk-s3', '~> 1.9', require: false
gem 'fog-core', '~> 1.45'
gem 'fog-local', '~> 0.4', require: false
gem 'fog-local', '~> 0.5', require: false
gem 'fog-openstack', '~> 0.1', require: false
gem 'paperclip', '~> 5.1'
gem 'paperclip', '~> 6.0'
gem 'paperclip-av-transcoder', '~> 0.6'
gem 'streamio-ffmpeg', '~> 3.0'
gem 'active_model_serializers', '~> 0.10'
gem 'addressable', '~> 2.5'
gem 'bootsnap'
gem 'bootsnap', '~> 1.3'
gem 'browser'
gem 'charlock_holmes', '~> 0.7.5'
gem 'charlock_holmes', '~> 0.7.6'
gem 'iso-639'
gem 'chewy', '~> 5.0'
gem 'cld3', '~> 3.2.0'
gem 'devise', '~> 4.4'
gem 'devise-two-factor', '~> 3.0'
gem 'devise_pam_authenticatable2', '~> 8.0', install_if: -> { ENV['PAM_ENABLED'] == 'true' }
group :pam_authentication, optional: true do
gem 'devise_pam_authenticatable2', '~> 9.1'
end
gem 'net-ldap', '~> 0.10'
gem 'omniauth-cas', '~> 1.1'
gem 'omniauth-saml', '~> 1.10'
gem 'omniauth', '~> 1.2'
gem 'doorkeeper', '~> 4.2'
gem 'doorkeeper', '~> 4.2', '< 4.3'
gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'goldfinger', '~> 2.1'
gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.5'
gem 'htmlentities', '~> 4.3'
gem 'http', '~> 3.0'
gem 'http', '~> 3.2'
gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 0.99'
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
gem 'httplog', '~> 1.0'
gem 'idn-ruby', require: 'idn'
gem 'kaminari', '~> 1.1'
gem 'link_header', '~> 0.0'
gem 'mime-types', '~> 3.1'
gem 'mime-types', '~> 3.1', require: 'mime/types/columnar'
gem 'nokogiri', '~> 1.8'
gem 'nsa', '~> 0.2'
gem 'oj', '~> 3.3'
gem 'oj', '~> 3.5'
gem 'ostatus2', '~> 2.0'
gem 'ox', '~> 2.8'
gem 'ox', '~> 2.9'
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
gem 'pundit', '~> 1.1'
gem 'premailer-rails'
gem 'rack-attack', '~> 5.0'
gem 'rack-cors', '~> 0.4', require: 'rack/cors'
gem 'rack-attack', '~> 5.2'
gem 'rack-cors', '~> 1.0', require: 'rack/cors'
gem 'rack-timeout', '~> 0.4'
gem 'rails-i18n', '~> 5.0'
gem 'rails-i18n', '~> 5.1'
gem 'rails-settings-cached', '~> 0.6'
gem 'redis', '~> 3.3', require: ['redis', 'redis/connection/hiredis']
gem 'redis', '~> 4.0', require: ['redis', 'redis/connection/hiredis']
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
gem 'rqrcode', '~> 0.10'
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
gem 'ruby-progressbar', '~> 1.4'
gem 'sanitize', '~> 4.4'
gem 'sidekiq', '~> 5.0'
gem 'sidekiq-scheduler', '~> 2.1'
gem 'sanitize', '~> 4.6'
gem 'sidekiq', '~> 5.1'
gem 'sidekiq-scheduler', '~> 2.2'
gem 'sidekiq-unique-jobs', '~> 5.0'
gem 'sidekiq-bulk', '~>0.1.1'
gem 'simple-navigation', '~> 4.0'
gem 'simple_form', '~> 3.4'
gem 'simple_form', '~> 4.0'
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
gem 'strong_migrations'
gem 'tty-command'
gem 'tty-prompt'
gem 'stoplight', '~> 2.1.3'
gem 'strong_migrations', '~> 0.2'
gem 'tty-command', '~> 0.8', require: false
gem 'tty-prompt', '~> 0.16', require: false
gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2017'
gem 'webpacker', '~> 3.0'
gem 'tzinfo-data', '~> 1.2018'
gem 'webpacker', '~> 3.4'
gem 'webpush'
gem 'json-ld-preloaded', '~> 2.2.1'
gem 'rdf-normalize', '~> 0.3.1'
gem 'json-ld', '~> 2.2'
gem 'rdf-normalize', '~> 0.3'
group :development, :test do
gem 'fabrication', '~> 2.18'
gem 'fabrication', '~> 2.20'
gem 'fuubar', '~> 2.2'
gem 'i18n-tasks', '~> 0.9', require: false
gem 'pry-byebug', '~> 3.6'
gem 'pry-rails', '~> 0.3'
gem 'rspec-rails', '~> 3.7'
end
@@ -101,15 +107,15 @@ group :production, :test do
end
group :test do
gem 'capybara', '~> 2.15'
gem 'capybara', '~> 2.18'
gem 'climate_control', '~> 0.2'
gem 'faker', '~> 1.7'
gem 'faker', '~> 1.8'
gem 'microformats', '~> 4.0'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.0'
gem 'simplecov', '~> 0.14', require: false
gem 'webmock', '~> 3.0'
gem 'parallel_tests', '~> 2.17'
gem 'simplecov', '~> 0.16', require: false
gem 'webmock', '~> 3.3'
gem 'parallel_tests', '~> 2.21'
end
group :development do
@@ -117,22 +123,25 @@ group :development do
gem 'annotate', '~> 2.7'
gem 'better_errors', '~> 2.4'
gem 'binding_of_caller', '~> 0.7'
gem 'bullet', '~> 5.5'
gem 'bullet', '~> 5.7'
gem 'letter_opener', '~> 1.4'
gem 'letter_opener_web', '~> 1.3'
gem 'memory_profiler'
gem 'rubocop', require: false
gem 'brakeman', '~> 4.0', require: false
gem 'rubocop', '~> 0.55', require: false
gem 'brakeman', '~> 4.2', require: false
gem 'bundler-audit', '~> 0.6', require: false
gem 'scss_lint', '~> 0.55', require: false
gem 'scss_lint', '~> 0.57', require: false
gem 'capistrano', '~> 3.10'
gem 'capistrano-rails', '~> 1.3'
gem 'capistrano-rbenv', '~> 2.1'
gem 'capistrano-yarn', '~> 2.0'
gem 'derailed_benchmarks'
gem 'stackprof'
end
group :production do
gem 'lograge', '~> 0.7'
gem 'lograge', '~> 0.10'
gem 'redis-rails', '~> 5.0'
end

View File

@@ -1,25 +1,39 @@
GIT
remote: https://github.com/rtomayko/posix-spawn
revision: 58465d2e213991f8afb13b984854a49fcdcc980c
ref: 58465d2e213991f8afb13b984854a49fcdcc980c
specs:
posix-spawn (0.3.13)
GIT
remote: https://github.com/tmm1/http_parser.rb
revision: 54b17ba8c7d8d20a16dfc65d1775241833219cf2
ref: 54b17ba8c7d8d20a16dfc65d1775241833219cf2
specs:
http_parser.rb (0.6.1)
GEM
remote: https://rubygems.org/
specs:
actioncable (5.1.4)
actionpack (= 5.1.4)
actioncable (5.2.0)
actionpack (= 5.2.0)
nio4r (~> 2.0)
websocket-driver (~> 0.6.1)
actionmailer (5.1.4)
actionpack (= 5.1.4)
actionview (= 5.1.4)
activejob (= 5.1.4)
websocket-driver (>= 0.6.1)
actionmailer (5.2.0)
actionpack (= 5.2.0)
actionview (= 5.2.0)
activejob (= 5.2.0)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.1.4)
actionview (= 5.1.4)
activesupport (= 5.1.4)
actionpack (5.2.0)
actionview (= 5.2.0)
activesupport (= 5.2.0)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.1.4)
activesupport (= 5.1.4)
actionview (5.2.0)
activesupport (= 5.2.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@@ -30,60 +44,71 @@ GEM
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_record_query_trace (1.5.4)
activejob (5.1.4)
activesupport (= 5.1.4)
activejob (5.2.0)
activesupport (= 5.2.0)
globalid (>= 0.3.6)
activemodel (5.1.4)
activesupport (= 5.1.4)
activerecord (5.1.4)
activemodel (= 5.1.4)
activesupport (= 5.1.4)
arel (~> 8.0)
activesupport (5.1.4)
activemodel (5.2.0)
activesupport (= 5.2.0)
activerecord (5.2.0)
activemodel (= 5.2.0)
activesupport (= 5.2.0)
arel (>= 9.0)
activestorage (5.2.0)
actionpack (= 5.2.0)
activerecord (= 5.2.0)
marcel (~> 0.3.1)
activesupport (5.2.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
airbrussh (1.3.0)
sshkit (>= 1.6.1, != 1.7.0)
annotate (2.7.2)
annotate (2.7.3)
activerecord (>= 3.2, < 6.0)
rake (>= 10.4, < 13.0)
arel (8.0.0)
ast (2.3.0)
attr_encrypted (3.0.3)
arel (9.0.0)
ast (2.4.0)
attr_encrypted (3.1.0)
encryptor (~> 3.0.0)
av (0.9.0)
cocaine (~> 0.5.3)
aws-sdk (2.10.100)
aws-sdk-resources (= 2.10.100)
aws-sdk-core (2.10.100)
aws-partitions (1.80.0)
aws-sdk-core (3.19.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
aws-sdk-resources (2.10.100)
aws-sdk-core (= 2.10.100)
aws-sdk-kms (1.5.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-s3 (1.9.1)
aws-sdk-core (~> 3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0)
aws-sigv4 (1.0.2)
bcrypt (3.1.11)
benchmark-ips (2.7.2)
better_errors (2.4.0)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bootsnap (1.1.5)
bootsnap (1.3.0)
msgpack (~> 1.0)
brakeman (4.0.1)
browser (2.5.2)
brakeman (4.2.1)
browser (2.5.3)
builder (3.2.3)
bullet (5.6.1)
bullet (5.7.5)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.10.0)
uniform_notifier (~> 1.11.0)
bundler-audit (0.6.0)
bundler (~> 1.2)
thor (~> 0.18)
capistrano (3.10.0)
byebug (10.0.2)
capistrano (3.10.2)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
@@ -99,21 +124,21 @@ GEM
sshkit (~> 1.3)
capistrano-yarn (2.0.2)
capistrano (~> 3.0)
capybara (2.16.1)
capybara (2.18.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
xpath (>= 2.0, < 4.0)
case_transform (0.2)
activesupport
charlock_holmes (0.7.5)
charlock_holmes (0.7.6)
chewy (5.0.0)
activesupport (>= 4.0)
elasticsearch (>= 2.0.0)
elasticsearch-dsl
chunky_png (1.3.8)
chunky_png (1.3.10)
cld3 (3.2.2)
ffi (>= 1.1.0, < 1.10.0)
climate_control (0.2.0)
@@ -125,62 +150,69 @@ GEM
connection_pool (2.2.1)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.3)
crass (1.0.4)
css_parser (1.6.0)
addressable
debug_inspector (0.0.3)
devise (4.4.0)
derailed_benchmarks (1.3.4)
benchmark-ips (~> 2)
get_process_mem (~> 0)
heapy (~> 0)
memory_profiler (~> 0)
rack (>= 1)
rake (> 10, < 13)
thor (~> 0.19)
devise (4.4.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.2)
railties (>= 4.1.0, < 6.0)
responders
warden (~> 1.2.3)
devise-two-factor (3.0.2)
activesupport (< 5.2)
devise-two-factor (3.0.3)
activesupport (< 5.3)
attr_encrypted (>= 1.3, < 4, != 2)
devise (~> 4.0)
railties (< 5.2)
railties (< 5.3)
rotp (~> 2.0)
devise_pam_authenticatable2 (8.0.1)
devise_pam_authenticatable2 (9.1.0)
devise (>= 4.0.0)
rpam2 (~> 3.0)
rpam2 (~> 4.0)
diff-lcs (1.3)
docile (1.1.5)
domain_name (0.5.20170404)
docile (1.3.0)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (4.2.6)
railties (>= 4.2)
dotenv (2.2.1)
dotenv-rails (2.2.1)
dotenv (= 2.2.1)
railties (>= 3.2, < 5.2)
easy_translate (0.5.0)
json
dotenv (2.2.2)
dotenv-rails (2.2.2)
dotenv (= 2.2.2)
railties (>= 3.2, < 6.0)
easy_translate (0.5.1)
thread
thread_safe
elasticsearch (6.0.1)
elasticsearch-api (= 6.0.1)
elasticsearch-transport (= 6.0.1)
elasticsearch-api (6.0.1)
elasticsearch (6.0.2)
elasticsearch-api (= 6.0.2)
elasticsearch-transport (= 6.0.2)
elasticsearch-api (6.0.2)
multi_json
elasticsearch-dsl (0.1.5)
elasticsearch-transport (6.0.1)
elasticsearch-transport (6.0.2)
faraday
multi_json
encryptor (3.0.0)
equatable (0.5.0)
erubi (1.7.0)
et-orbi (1.0.8)
erubi (1.7.1)
et-orbi (1.1.0)
tzinfo
excon (0.59.0)
fabrication (2.18.0)
faker (1.8.4)
i18n (~> 0.5)
faraday (0.14.0)
excon (0.62.0)
fabrication (2.20.1)
faker (1.8.7)
i18n (>= 0.7)
faraday (0.15.0)
multipart-post (>= 1.2, < 3)
fast_blank (1.0.0)
fastimage (2.1.1)
ffi (1.9.18)
ffi (1.9.23)
fog-core (1.45.0)
builder
excon (~> 0.58)
@@ -188,16 +220,17 @@ GEM
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
fog-local (0.4.0)
fog-core (~> 1.27)
fog-openstack (0.1.22)
fog-core (>= 1.40)
fog-local (0.5.0)
fog-core (>= 1.27, < 3.0)
fog-openstack (0.1.25)
fog-core (~> 1.40)
fog-json (>= 1.0)
ipaddress (>= 0.8)
formatador (0.2.5)
fuubar (2.2.0)
fuubar (2.3.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
get_process_mem (0.2.1)
globalid (0.4.1)
activesupport (>= 4.2.0)
goldfinger (2.1.0)
@@ -205,7 +238,7 @@ GEM
http (~> 3.0)
nokogiri (~> 1.8)
oj (~> 3.0)
hamlit (2.8.5)
hamlit (2.8.8)
temple (>= 0.8.0)
thor
tilt
@@ -218,48 +251,44 @@ GEM
concurrent-ruby (~> 1.0)
hashdiff (0.3.7)
hashie (3.5.7)
heapy (0.1.3)
highline (1.7.10)
hiredis (0.6.1)
hitimes (1.2.6)
hkdf (0.3.0)
htmlentities (4.3.4)
http (3.0.0)
http (3.2.0)
addressable (~> 2.3)
http-cookie (~> 1.0)
http-form_data (>= 2.0.0.pre.pre2, < 3)
http-form_data (~> 2.0)
http_parser.rb (~> 0.6.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
http-form_data (2.0.0)
http-form_data (2.1.0)
http_accept_language (2.1.1)
http_parser.rb (0.6.0)
httplog (0.99.7)
colorize
rack
i18n (0.9.3)
httplog (1.0.2)
colorize (~> 0.8)
rack (>= 1.0)
i18n (1.0.1)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.19)
i18n-tasks (0.9.21)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
easy_translate (>= 0.5.0)
easy_translate (>= 0.5.1)
erubi
highline (>= 1.7.3)
i18n
parser (>= 2.2.3.0)
rainbow (~> 2.2)
rainbow (>= 2.2.2, < 4.0)
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.4.0)
json (2.1.0)
json-ld (2.1.7)
json-ld (2.2.1)
multi_json (~> 1.12)
rdf (~> 2.2, >= 2.2.8)
json-ld-preloaded (2.2.2)
json-ld (~> 2.1, >= 2.1.5)
multi_json (~> 1.11)
rdf (~> 2.2)
rdf (>= 2.2.8, < 4.0)
jsonapi-renderer (0.2.0)
jwt (2.1.0)
kaminari (1.1.1)
@@ -276,25 +305,27 @@ GEM
kaminari-core (1.1.1)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.4.1)
letter_opener (1.6.0)
launchy (~> 2.2)
letter_opener_web (1.3.1)
letter_opener_web (1.3.4)
actionmailer (>= 3.2)
letter_opener (~> 1.0)
railties (>= 3.2)
link_header (0.0.8)
lograge (0.7.1)
actionpack (>= 4, < 5.2)
activesupport (>= 4, < 5.2)
railties (>= 4, < 5.2)
lograge (0.10.0)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.1.1)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.0)
mini_mime (>= 0.1.1)
mario-redis-lock (1.2.0)
redis (~> 3, >= 3.0.5)
marcel (0.3.2)
mimemagic (~> 0.3.2)
mario-redis-lock (1.2.1)
redis (>= 3.0.5)
memory_profiler (0.9.10)
method_source (0.9.0)
microformats (4.0.7)
@@ -307,25 +338,25 @@ GEM
mini_mime (1.0.0)
mini_portile2 (2.3.0)
minitest (5.11.3)
msgpack (1.1.0)
multi_json (1.12.2)
msgpack (1.2.4)
multi_json (1.13.1)
multipart-post (2.0.0)
necromancer (0.4.0)
net-ldap (0.16.1)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (4.2.0)
nio4r (2.1.0)
nokogiri (1.8.1)
nio4r (2.3.0)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
nokogumbo (1.4.13)
nokogumbo (1.5.0)
nokogiri
nsa (0.2.4)
activesupport (>= 4.2, < 6)
concurrent-ruby (~> 1.0.0)
sidekiq (>= 3.5.0)
statsd-ruby (~> 1.2.0)
oj (3.3.10)
oj (3.5.1)
omniauth (1.8.1)
hashie (>= 3.4.6, < 3.6.0)
rack (>= 1.6.2, < 3)
@@ -341,68 +372,72 @@ GEM
addressable (~> 2.5)
http (~> 3.0)
nokogiri (~> 1.8)
ox (2.8.2)
paperclip (5.2.1)
ox (2.9.2)
paperclip (6.0.0)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
cocaine (~> 0.5.5)
mime-types
mimemagic (~> 0.3.0)
terrapin (~> 0.6.0)
paperclip-av-transcoder (0.6.4)
av (~> 0.9.0)
paperclip (>= 2.5.2)
parallel (1.12.0)
parallel_tests (2.19.0)
parallel (1.12.1)
parallel_tests (2.21.3)
parallel
parser (2.4.0.2)
ast (~> 2.3)
parser (2.5.1.0)
ast (~> 2.4.0)
pastel (0.7.2)
equatable (~> 0.5.0)
tty-color (~> 0.4.0)
pg (0.21.0)
pghero (1.7.0)
pg (1.0.0)
pghero (2.1.0)
activerecord
pkg-config (1.2.8)
pkg-config (1.3.0)
powerpack (0.1.1)
premailer (1.11.1)
addressable
css_parser (>= 1.6.0)
htmlentities (>= 4.0.0)
premailer-rails (1.10.1)
premailer-rails (1.10.2)
actionmailer (>= 3, < 6)
premailer (~> 1.7, >= 1.7.9)
private_address_check (0.4.1)
pry (0.11.3)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-byebug (3.6.0)
byebug (~> 10.0)
pry (~> 0.10)
pry-rails (0.3.6)
pry (>= 0.10.4)
public_suffix (3.0.1)
puma (3.11.0)
public_suffix (3.0.2)
puma (3.11.4)
pundit (1.1.0)
activesupport (>= 3.0.0)
rack (2.0.3)
rack-attack (5.0.1)
rack (2.0.4)
rack-attack (5.2.0)
rack
rack-cors (0.4.1)
rack-protection (2.0.0)
rack-cors (1.0.2)
rack-protection (2.0.1)
rack
rack-proxy (0.6.2)
rack-proxy (0.6.4)
rack
rack-test (0.8.2)
rack-test (1.0.0)
rack (>= 1.0, < 3)
rack-timeout (0.4.2)
rails (5.1.4)
actioncable (= 5.1.4)
actionmailer (= 5.1.4)
actionpack (= 5.1.4)
actionview (= 5.1.4)
activejob (= 5.1.4)
activemodel (= 5.1.4)
activerecord (= 5.1.4)
activesupport (= 5.1.4)
rails (5.2.0)
actioncable (= 5.2.0)
actionmailer (= 5.2.0)
actionpack (= 5.2.0)
actionview (= 5.2.0)
activejob (= 5.2.0)
activemodel (= 5.2.0)
activerecord (= 5.2.0)
activestorage (= 5.2.0)
activesupport (= 5.2.0)
bundler (>= 1.3.0)
railties (= 5.1.4)
railties (= 5.2.0)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.2)
actionpack (~> 5.x, >= 5.0.1)
@@ -411,31 +446,30 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
rails-i18n (5.0.4)
i18n (~> 0.7)
railties (~> 5.0)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails-i18n (5.1.1)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
rails-settings-cached (0.6.6)
rails (>= 4.2.0)
railties (5.1.4)
actionpack (= 5.1.4)
activesupport (= 5.1.4)
railties (5.2.0)
actionpack (= 5.2.0)
activesupport (= 5.2.0)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
rake (12.3.0)
rb-fsevent (0.10.2)
rainbow (3.0.0)
rake (12.3.1)
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rdf (2.2.12)
rdf (3.0.2)
hamster (~> 3.0)
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.3.2)
rdf (~> 2.0)
redis (3.3.5)
rdf-normalize (0.3.3)
rdf (>= 2.2, < 4.0)
redis (4.0.1)
redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6)
redis-rack (>= 1, < 3)
@@ -445,24 +479,25 @@ GEM
redis-store (>= 1.3, < 2)
redis-namespace (1.6.0)
redis (>= 3.0.4)
redis-rack (2.0.3)
redis-rack (2.0.4)
rack (>= 1.5, < 3)
redis-store (>= 1.2, < 2)
redis-rails (5.0.2)
redis-actionpack (>= 5.0, < 6)
redis-activesupport (>= 5.0, < 6)
redis-store (>= 1.2, < 2)
redis-store (1.4.1)
redis-store (1.5.0)
redis (>= 2.2, < 5)
request_store (1.3.2)
request_store (1.4.1)
rack (>= 1.4)
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rotp (2.1.2)
rpam2 (3.1.0)
rpam2 (4.0.2)
rqrcode (0.10.1)
chunky_png (~> 1.0)
rspec-core (3.7.0)
rspec-core (3.7.1)
rspec-support (~> 3.7.0)
rspec-expectations (3.7.0)
diff-lcs (>= 1.2.0, < 2.0)
@@ -481,42 +516,41 @@ GEM
rspec-sidekiq (3.0.3)
rspec-core (~> 3.0, >= 3.0.0)
sidekiq (>= 2.4.0)
rspec-support (3.7.0)
rubocop (0.51.0)
rspec-support (3.7.1)
rubocop (0.55.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
parser (>= 2.5)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 3.0)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-oembed (0.12.0)
ruby-progressbar (1.9.0)
ruby-saml (1.7.2)
nokogiri (>= 1.5.10)
rufus-scheduler (3.4.2)
et-orbi (~> 1.0)
safe_yaml (1.0.4)
sanitize (4.5.0)
sanitize (4.6.4)
crass (~> 1.0.2)
nokogiri (>= 1.4.4)
nokogumbo (~> 1.4.1)
sass (3.5.3)
nokogumbo (~> 1.4)
sass (3.5.6)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
scss_lint (0.56.0)
scss_lint (0.57.0)
rake (>= 0.9, < 13)
sass (~> 3.5.3)
sidekiq (5.0.5)
sass (~> 3.5.5)
sidekiq (5.1.3)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.4, < 5)
redis (>= 3.3.5, < 5)
sidekiq-bulk (0.1.1)
activesupport
sidekiq
sidekiq-scheduler (2.1.10)
sidekiq-scheduler (2.2.1)
redis (>= 3, < 5)
rufus-scheduler (~> 3.2)
sidekiq (>= 3)
@@ -526,11 +560,11 @@ GEM
thor (~> 0)
simple-navigation (4.0.5)
activesupport (>= 2.3.2)
simple_form (3.5.0)
actionpack (> 4, < 5.2)
activemodel (> 4, < 5.2)
simplecov (0.15.1)
docile (~> 1.1.0)
simple_form (4.0.0)
actionpack (> 4)
activemodel (> 4)
simplecov (0.16.1)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
@@ -541,17 +575,21 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sshkit (1.15.1)
sshkit (1.16.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
stackprof (0.2.11)
statsd-ruby (1.2.1)
stoplight (2.1.3)
streamio-ffmpeg (3.0.2)
multi_json (~> 1.8)
strong_migrations (0.1.9)
strong_migrations (0.2.2)
activerecord (>= 3.2.0)
temple (0.8.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
thor (0.20.0)
thread (0.2.2)
thread_safe (0.3.6)
@@ -559,10 +597,10 @@ GEM
timers (4.1.2)
hitimes
tty-color (0.4.2)
tty-command (0.7.0)
tty-command (0.8.0)
pastel (~> 0.7.0)
tty-cursor (0.5.0)
tty-prompt (0.15.0)
tty-prompt (0.16.0)
necromancer (~> 0.4.0)
pastel (~> 0.7.0)
timers (~> 4.0)
@@ -575,34 +613,34 @@ GEM
tty-screen (0.6.4)
twitter-text (1.14.7)
unf (~> 0.1.0)
tzinfo (1.2.4)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2017.3)
tzinfo-data (1.2018.4)
tzinfo (>= 1.0.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.4)
unicode-display_width (1.3.0)
uniform_notifier (1.10.0)
unf_ext (0.0.7.5)
unicode-display_width (1.3.2)
uniform_notifier (1.11.0)
warden (1.2.7)
rack (>= 1.0)
webmock (3.1.1)
webmock (3.3.0)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
webpacker (3.0.2)
webpacker (3.4.3)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
webpush (0.3.3)
hkdf (~> 0.2)
jwt (~> 2.0)
websocket-driver (0.6.5)
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
wisper (2.0.0)
xpath (2.1.0)
nokogiri (~> 1.3)
xpath (3.0.0)
nokogiri (~> 1.8)
PLATFORMS
ruby
@@ -612,52 +650,54 @@ DEPENDENCIES
active_record_query_trace (~> 1.5)
addressable (~> 2.5)
annotate (~> 2.7)
aws-sdk (~> 2.10)
aws-sdk-s3 (~> 1.9)
better_errors (~> 2.4)
binding_of_caller (~> 0.7)
bootsnap
brakeman (~> 4.0)
bootsnap (~> 1.3)
brakeman (~> 4.2)
browser
bullet (~> 5.5)
bullet (~> 5.7)
bundler-audit (~> 0.6)
capistrano (~> 3.10)
capistrano-rails (~> 1.3)
capistrano-rbenv (~> 2.1)
capistrano-yarn (~> 2.0)
capybara (~> 2.15)
charlock_holmes (~> 0.7.5)
capybara (~> 2.18)
charlock_holmes (~> 0.7.6)
chewy (~> 5.0)
cld3 (~> 3.2.0)
climate_control (~> 0.2)
derailed_benchmarks
devise (~> 4.4)
devise-two-factor (~> 3.0)
devise_pam_authenticatable2 (~> 8.0)
doorkeeper (~> 4.2)
dotenv-rails (~> 2.2)
fabrication (~> 2.18)
faker (~> 1.7)
devise_pam_authenticatable2 (~> 9.1)
doorkeeper (~> 4.2, < 4.3)
dotenv-rails (~> 2.2, < 2.3)
fabrication (~> 2.20)
faker (~> 1.8)
fast_blank (~> 1.0)
fastimage
fog-core (~> 1.45)
fog-local (~> 0.4)
fog-local (~> 0.5)
fog-openstack (~> 0.1)
fuubar (~> 2.2)
goldfinger (~> 2.1)
hamlit-rails (~> 0.2)
hiredis (~> 0.6)
htmlentities (~> 4.3)
http (~> 3.0)
http (~> 3.2)
http_accept_language (~> 2.1)
httplog (~> 0.99)
http_parser.rb (~> 0.6)!
httplog (~> 1.0)
i18n-tasks (~> 0.9)
idn-ruby
iso-639
json-ld-preloaded (~> 2.2.1)
json-ld (~> 2.2)
kaminari (~> 1.1)
letter_opener (~> 1.4)
letter_opener_web (~> 1.3)
link_header (~> 0.0)
lograge (~> 0.7)
lograge (~> 0.10)
mario-redis-lock (~> 1.2)
memory_profiler
microformats (~> 4.0)
@@ -665,58 +705,61 @@ DEPENDENCIES
net-ldap (~> 0.10)
nokogiri (~> 1.8)
nsa (~> 0.2)
oj (~> 3.3)
oj (~> 3.5)
omniauth (~> 1.2)
omniauth-cas (~> 1.1)
omniauth-saml (~> 1.10)
ostatus2 (~> 2.0)
ox (~> 2.8)
paperclip (~> 5.1)
ox (~> 2.9)
paperclip (~> 6.0)
paperclip-av-transcoder (~> 0.6)
parallel_tests (~> 2.17)
pg (~> 0.20)
pghero (~> 1.7)
pkg-config (~> 1.2)
parallel_tests (~> 2.21)
pg (~> 1.0)
pghero (~> 2.1)
pkg-config (~> 1.3)
posix-spawn!
premailer-rails
private_address_check (~> 0.4.1)
pry-byebug (~> 3.6)
pry-rails (~> 0.3)
puma (~> 3.10)
puma (~> 3.11)
pundit (~> 1.1)
rack-attack (~> 5.0)
rack-cors (~> 0.4)
rack-attack (~> 5.2)
rack-cors (~> 1.0)
rack-timeout (~> 0.4)
rails (~> 5.1.4)
rails (~> 5.2.0)
rails-controller-testing (~> 1.0)
rails-i18n (~> 5.0)
rails-i18n (~> 5.1)
rails-settings-cached (~> 0.6)
rdf-normalize (~> 0.3.1)
redis (~> 3.3)
rdf-normalize (~> 0.3)
redis (~> 4.0)
redis-namespace (~> 1.5)
redis-rails (~> 5.0)
rqrcode (~> 0.10)
rspec-rails (~> 3.7)
rspec-sidekiq (~> 3.0)
rubocop
ruby-oembed (~> 0.12)
rubocop (~> 0.55)
ruby-progressbar (~> 1.4)
sanitize (~> 4.4)
scss_lint (~> 0.55)
sidekiq (~> 5.0)
sanitize (~> 4.6)
scss_lint (~> 0.57)
sidekiq (~> 5.1)
sidekiq-bulk (~> 0.1.1)
sidekiq-scheduler (~> 2.1)
sidekiq-scheduler (~> 2.2)
sidekiq-unique-jobs (~> 5.0)
simple-navigation (~> 4.0)
simple_form (~> 3.4)
simplecov (~> 0.14)
simple_form (~> 4.0)
simplecov (~> 0.16)
sprockets-rails (~> 3.2)
stackprof
stoplight (~> 2.1.3)
streamio-ffmpeg (~> 3.0)
strong_migrations
tty-command
tty-prompt
strong_migrations (~> 0.2)
tty-command (~> 0.8)
tty-prompt (~> 0.16)
twitter-text (~> 1.14)
tzinfo-data (~> 1.2017)
webmock (~> 3.0)
webpacker (~> 3.0)
tzinfo-data (~> 1.2018)
webmock (~> 3.3)
webpacker (~> 3.4)
webpush
RUBY VERSION

View File

@@ -1,10 +1,10 @@
![Mastodon](https://i.imgur.com/NhZc40l.png)
========
[![Build Status](https://img.shields.io/travis/tootsuite/mastodon.svg)][travis]
[![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci]
[![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate]
[travis]: https://travis-ci.org/tootsuite/mastodon
[circleci]: https://circleci.com/gh/tootsuite/mastodon
[code_climate]: https://codeclimate.com/github/tootsuite/mastodon
Mastodon is a **free, open-source social network server** based on **open web protocols** like ActivityPub and OStatus. The social focus of the project is a viable decentralized alternative to commercial social media silos that returns the control of the content distribution channels to the people. The technical focus of the project is a good user interface, a clean REST API for 3rd party apps and robust anti-abuse tools.

View File

@@ -20,9 +20,10 @@ class AccountsController < ApplicationController
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
@statuses = filtered_status_page(params)
@statuses = cache_collection(@statuses, Status)
unless @statuses.empty?
@older_url = older_url if @statuses.last.id > filtered_statuses.last.id
@newer_url = newer_url if @statuses.first.id < filtered_statuses.first.id
@older_url = older_url if @statuses.last.id > filtered_statuses.last.id
@newer_url = newer_url if @statuses.first.id < filtered_statuses.first.id
end
end
@@ -31,6 +32,11 @@ class AccountsController < ApplicationController
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.reject { |entry| entry.status.nil? }))
end
format.rss do
@statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status)
render xml: RSS::AccountSerializer.render(@account, @statuses)
end
format.json do
skip_session!

View File

@@ -22,7 +22,7 @@ class ActivityPub::CollectionsController < Api::BaseController
end
def set_statuses
@statuses = scope_for_collection.paginate_by_max_id(20, params[:max_id], params[:since_id])
@statuses = scope_for_collection
@statuses = cache_collection(@statuses, Status)
end

View File

@@ -1,14 +1,14 @@
# frozen_string_literal: true
class ActivityPub::OutboxesController < Api::BaseController
LIMIT = 20
include SignatureVerification
before_action :set_account
before_action :set_statuses
def show
@statuses = @account.statuses.permitted_for(@account, signed_request_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
@statuses = cache_collection(@statuses, Status)
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
@@ -19,11 +19,47 @@ class ActivityPub::OutboxesController < Api::BaseController
end
def outbox_presenter
ActivityPub::CollectionPresenter.new(
id: account_outbox_url(@account),
type: :ordered,
size: @account.statuses_count,
items: @statuses
)
if page_requested?
ActivityPub::CollectionPresenter.new(
id: account_outbox_url(@account, page_params),
type: :ordered,
part_of: account_outbox_url(@account),
prev: prev_page,
next: next_page,
items: @statuses
)
else
ActivityPub::CollectionPresenter.new(
id: account_outbox_url(@account),
type: :ordered,
size: @account.statuses_count,
first: account_outbox_url(@account, page: true),
last: account_outbox_url(@account, page: true, min_id: 0)
)
end
end
def next_page
account_outbox_url(@account, page: true, max_id: @statuses.last.id) if @statuses.size == LIMIT
end
def prev_page
account_outbox_url(@account, page: true, min_id: @statuses.first.id) unless @statuses.empty?
end
def set_statuses
return unless page_requested?
@statuses = @account.statuses.permitted_for(@account, signed_request_account)
@statuses = params[:min_id].present? ? @statuses.paginate_by_min_id(LIMIT, params[:min_id]).reverse : @statuses.paginate_by_max_id(LIMIT, params[:max_id])
@statuses = cache_collection(@statuses, Status)
end
def page_requested?
params[:page] == 'true'
end
def page_params
{ page: true, max_id: params[:max_id], min_id: params[:min_id] }.compact
end
end

View File

@@ -2,7 +2,7 @@
module Admin
class AccountsController < BaseController
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :enable, :disable, :memorialize]
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :enable, :disable, :memorialize]
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
before_action :require_local_account!, only: [:enable, :disable, :memorialize]
@@ -60,6 +60,17 @@ module Admin
redirect_to admin_account_path(@account.id)
end
def remove_avatar
authorize @account, :remove_avatar?
@account.avatar = nil
@account.save!
log_action :remove_avatar, @account.user
redirect_to admin_account_path(@account.id)
end
private
def set_account

View File

@@ -0,0 +1,49 @@
# frozen_string_literal: true
module Admin
class ChangeEmailsController < BaseController
before_action :set_account
before_action :require_local_account!
def show
authorize @user, :change_email?
end
def update
authorize @user, :change_email?
new_email = resource_params.fetch(:unconfirmed_email)
if new_email != @user.email
@user.update!(
unconfirmed_email: new_email,
# Regenerate the confirmation token:
confirmation_token: nil
)
log_action :change_email, @user
@user.send_confirmation_instructions
end
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.change_email.changed_msg')
end
private
def set_account
@account = Account.find(params[:account_id])
@user = @account.user
end
def require_local_account!
redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present?
end
def resource_params
params.require(:user).permit(
:unconfirmed_email
)
end
end
end

View File

@@ -3,6 +3,7 @@
module Admin
class ConfirmationsController < BaseController
before_action :set_user
before_action :check_confirmation, only: [:resend]
def create
authorize @user, :confirm?
@@ -11,10 +12,28 @@ module Admin
redirect_to admin_accounts_path
end
def resend
authorize @user, :confirm?
@user.resend_confirmation_instructions
log_action :confirm, @user
flash[:notice] = I18n.t('admin.accounts.resend_confirmation.success')
redirect_to admin_accounts_path
end
private
def set_user
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
end
def check_confirmation
if @user.confirmed?
flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
redirect_to admin_accounts_path
end
end
end
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
module Admin
class ReportNotesController < BaseController
before_action :set_report_note, only: [:destroy]
def create
authorize ReportNote, :create?
@report_note = current_account.report_notes.new(resource_params)
@report = @report_note.report
if @report_note.save
if params[:create_and_resolve]
@report.resolve!(current_account)
log_action :resolve, @report
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
return
end
if params[:create_and_unresolve]
@report.unresolve!
log_action :reopen, @report
end
redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg')
else
@report_notes = @report.notes.latest
@report_history = @report.history
@form = Form::StatusBatch.new
render template: 'admin/reports/show'
end
end
def destroy
authorize @report_note, :destroy?
@report_note.destroy!
redirect_to admin_report_path(@report_note.report_id), notice: I18n.t('admin.report_notes.destroyed_msg')
end
private
def resource_params
params.require(:report_note).permit(
:content,
:report_id
)
end
def set_report_note
@report_note = ReportNote.find(params[:id])
end
end
end

View File

@@ -3,31 +3,16 @@
module Admin
class ReportedStatusesController < BaseController
before_action :set_report
before_action :set_status, only: [:update, :destroy]
def create
authorize :status, :update?
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
redirect_to admin_report_path(@report)
end
def update
authorize @status, :update?
@status.update!(status_params)
log_action :update, @status
redirect_to admin_report_path(@report)
end
def destroy
authorize @status, :destroy?
RemovalWorker.perform_async(@status.id)
log_action :destroy, @status
render json: @status
end
private
def status_params
@@ -35,15 +20,21 @@ module Admin
end
def form_status_batch_params
params.require(:form_status_batch).permit(:action, status_ids: [])
params.require(:form_status_batch).permit(status_ids: [])
end
def action_from_button
if params[:nsfw_on]
'nsfw_on'
elsif params[:nsfw_off]
'nsfw_off'
elsif params[:delete]
'delete'
end
end
def set_report
@report = Report.find(params[:report_id])
end
def set_status
@status = @report.statuses.find(params[:id])
end
end
end

View File

@@ -11,45 +11,61 @@ module Admin
def show
authorize @report, :show?
@form = Form::StatusBatch.new
@report_note = @report.notes.new
@report_notes = (@report.notes.latest + @report.history).sort_by(&:created_at)
@form = Form::StatusBatch.new
end
def update
authorize @report, :update?
process_report
redirect_to admin_report_path(@report)
if @report.action_taken?
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
else
redirect_to admin_report_path(@report)
end
end
private
def process_report
case params[:outcome].to_s
when 'assign_to_self'
@report.update!(assigned_account_id: current_account.id)
log_action :assigned_to_self, @report
when 'unassign'
@report.update!(assigned_account_id: nil)
log_action :unassigned, @report
when 'reopen'
@report.unresolve!
log_action :reopen, @report
when 'resolve'
@report.update!(action_taken_by_current_attributes)
@report.resolve!(current_account)
log_action :resolve, @report
when 'suspend'
Admin::SuspensionWorker.perform_async(@report.target_account.id)
log_action :resolve, @report
log_action :suspend, @report.target_account
resolve_all_target_account_reports
when 'silence'
@report.target_account.update!(silenced: true)
log_action :resolve, @report
log_action :silence, @report.target_account
resolve_all_target_account_reports
else
raise ActiveRecord::RecordNotFound
end
end
def action_taken_by_current_attributes
{ action_taken: true, action_taken_by_account_id: current_account.id }
@report.reload
end
def resolve_all_target_account_reports
unresolved_reports_for_target_account.update_all(
action_taken_by_current_attributes
)
unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
end
def unresolved_reports_for_target_account

View File

@@ -5,14 +5,13 @@ module Admin
helper_method :current_params
before_action :set_account
before_action :set_status, only: [:update, :destroy]
PER_PAGE = 20
def index
authorize :status, :index?
@statuses = @account.statuses
@statuses = @account.statuses.where(visibility: [:public, :unlisted])
if params[:media]
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct
@@ -26,40 +25,18 @@ module Admin
def create
authorize :status, :update?
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
redirect_to admin_account_statuses_path(@account.id, current_params)
end
def update
authorize @status, :update?
@status.update!(status_params)
log_action :update, @status
redirect_to admin_account_statuses_path(@account.id, current_params)
end
def destroy
authorize @status, :destroy?
RemovalWorker.perform_async(@status.id)
log_action :destroy, @status
render json: @status
end
private
def status_params
params.require(:status).permit(:sensitive)
end
def form_status_batch_params
params.require(:form_status_batch).permit(:action, status_ids: [])
end
def set_status
@status = @account.statuses.find(params[:id])
end
def set_account
@account = Account.find(params[:account_id])
end
@@ -72,5 +49,15 @@ module Admin
page: page > 1 && page,
}.select { |_, value| value.present? }
end
def action_from_button
if params[:nsfw_on]
'nsfw_on'
elsif params[:nsfw_off]
'nsfw_off'
elsif params[:delete]
'delete'
end
end
end
end

View File

@@ -66,8 +66,10 @@ class Api::BaseController < ApplicationController
end
def require_user!
if current_user
if current_user && !current_user.disabled?
set_user_activity
elsif current_user
render json: { error: 'Your login is currently disabled' }, status: 403
else
render json: { error: 'This method requires an authenticated user' }, status: 422
end

View File

@@ -13,6 +13,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
def update
@account = current_account
UpdateAccountService.new.call(@account, account_params, raise_error: true)
UserSettingsDecorator.new(current_user).update(user_settings_params) if user_settings_params
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
render json: @account, serializer: REST::CredentialAccountSerializer
end
@@ -20,6 +21,17 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
private
def account_params
params.permit(:display_name, :note, :avatar, :header, :locked)
params.permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
end
def user_settings_params
return nil unless params.key?(:source)
source_params = params.require(:source)
{
'setting_default_privacy' => source_params.fetch(:privacy, @account.user.setting_default_privacy),
'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive),
}
end
end

View File

@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def load_accounts
return [] if @account.user_hides_network? && current_account.id != @account.id
default_accounts.merge(paginated_follows).to_a
end
@@ -63,6 +65,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -19,6 +19,8 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def load_accounts
return [] if @account.user_hides_network? && current_account.id != @account.id
default_accounts.merge(paginated_follows).to_a
end
@@ -63,6 +65,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -27,19 +27,17 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def account_statuses
default_statuses.tap do |statuses|
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
statuses.merge!(pinned_scope) if truthy_param?(:pinned)
statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies)
end
end
def default_statuses
permitted_account_statuses.paginate_by_max_id(
statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
statuses = statuses.paginate_by_max_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params[:max_id],
params[:since_id]
)
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies)
statuses
end
def permitted_account_statuses
@@ -69,7 +67,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
end
def insert_pagination_headers

View File

@@ -5,6 +5,7 @@ class Api::V1::AccountsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow }, only: [:follow, :unfollow, :block, :unblock, :mute, :unmute]
before_action :require_user!, except: [:show]
before_action :set_account
before_action :check_account_suspension, only: [:show]
respond_to :json
@@ -54,4 +55,8 @@ class Api::V1::AccountsController < Api::BaseController
def relationships(**options)
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
end
def check_account_suspension
gone if @account.suspended?
end
end

View File

@@ -57,6 +57,6 @@ class Api::V1::BlocksController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -67,7 +67,7 @@ class Api::V1::DomainBlocksController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def domain_block_params

View File

@@ -66,6 +66,6 @@ class Api::V1::FavouritesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -71,6 +71,6 @@ class Api::V1::FollowRequestsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -88,7 +88,7 @@ class Api::V1::Lists::AccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def unlimited?

View File

@@ -59,6 +59,6 @@ class Api::V1::MutesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -82,6 +82,6 @@ class Api::V1::NotificationsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit, exclude_types: []).merge(core_params)
params.slice(:limit, :exclude_types).permit(:limit, exclude_types: []).merge(core_params)
end
end

View File

@@ -0,0 +1,56 @@
# frozen_string_literal: true
class Api::V1::Push::SubscriptionsController < Api::BaseController
before_action -> { doorkeeper_authorize! :push }
before_action :require_user!
before_action :set_web_push_subscription
def create
@web_subscription&.destroy!
@web_subscription = ::Web::PushSubscription.create!(
endpoint: subscription_params[:endpoint],
key_p256dh: subscription_params[:keys][:p256dh],
key_auth: subscription_params[:keys][:auth],
data: data_params,
user_id: current_user.id,
access_token_id: doorkeeper_token.id
)
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def show
raise ActiveRecord::RecordNotFound if @web_subscription.nil?
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def update
raise ActiveRecord::RecordNotFound if @web_subscription.nil?
@web_subscription.update!(data: data_params)
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def destroy
@web_subscription&.destroy!
render_empty
end
private
def set_web_push_subscription
@web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
end
def subscription_params
params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
end
def data_params
return {} if params[:data].blank?
params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention])
end
end

View File

@@ -77,6 +77,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -39,7 +39,7 @@ class Api::V1::Statuses::PinsController < Api::BaseController
adapter: ActivityPub::Adapter
).as_json
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account)
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account.id)
end
def distribute_remove_activity!
@@ -49,6 +49,6 @@ class Api::V1::Statuses::PinsController < Api::BaseController
adapter: ActivityPub::Adapter
).as_json
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account)
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account.id)
end
end

View File

@@ -74,6 +74,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
end

View File

@@ -17,8 +17,8 @@ class Api::V1::StatusesController < Api::BaseController
end
def context
ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(current_account)
descendants_results = @status.descendants(current_account)
ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(DEFAULT_STATUSES_LIMIT, current_account)
descendants_results = @status.descendants(DEFAULT_STATUSES_LIMIT, current_account)
loaded_ancestors = cache_collection(ancestors_results, Status)
loaded_descendants = cache_collection(descendants_results, Status)
@@ -76,7 +76,7 @@ class Api::V1::StatusesController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def authorize_if_got_token

View File

@@ -0,0 +1,60 @@
# frozen_string_literal: true
class Api::V1::Timelines::DirectController < Api::BaseController
before_action -> { doorkeeper_authorize! :read }, only: [:show]
before_action :require_user!, only: [:show]
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
respond_to :json
def show
@statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
end
private
def load_statuses
cached_direct_statuses
end
def cached_direct_statuses
cache_collection direct_statuses, Status
end
def direct_statuses
direct_timeline_statuses.paginate_by_max_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params[:max_id],
params[:since_id]
)
end
def direct_timeline_statuses
Status.as_direct_timeline(current_account)
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def pagination_params(core_params)
params.permit(:local, :limit).merge(core_params)
end
def next_path
api_v1_timelines_direct_url pagination_params(max_id: pagination_max_id)
end
def prev_path
api_v1_timelines_direct_url pagination_params(since_id: pagination_since_id)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
end
end

View File

@@ -43,7 +43,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit).merge(core_params)
params.slice(:local, :limit).permit(:local, :limit).merge(core_params)
end
def next_path

View File

@@ -45,7 +45,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:limit).merge(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def next_path

View File

@@ -45,7 +45,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit, :only_media).merge(core_params)
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
end
def next_path

View File

@@ -54,7 +54,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
end
def pagination_params(core_params)
params.permit(:local, :limit, :only_media).merge(core_params)
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
end
def next_path

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
class Api::Web::BaseController < Api::BaseController
protect_from_forgery with: :exception
rescue_from ActionController::InvalidAuthenticityToken do
render json: { error: "Can't verify CSRF token authenticity." }, status: 422
end
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class Api::Web::EmbedsController < Api::BaseController
class Api::Web::EmbedsController < Api::Web::BaseController
respond_to :json
before_action :require_user!
@@ -9,9 +9,12 @@ class Api::Web::EmbedsController < Api::BaseController
status = StatusFinder.new(params[:url]).status
render json: status, serializer: OEmbedSerializer, width: 400
rescue ActiveRecord::RecordNotFound
oembed = OEmbed::Providers.get(params[:url])
render json: Oj.dump(oembed.fields)
rescue OEmbed::NotFound
render json: {}, status: :not_found
oembed = FetchOEmbedService.new.call(params[:url])
if oembed
render json: oembed
else
render json: {}, status: :not_found
end
end
end

View File

@@ -1,15 +1,11 @@
# frozen_string_literal: true
class Api::Web::PushSubscriptionsController < Api::BaseController
class Api::Web::PushSubscriptionsController < Api::Web::BaseController
respond_to :json
before_action :require_user!
protect_from_forgery with: :exception
def create
params.require(:subscription).require(:endpoint)
params.require(:subscription).require(:keys).require([:auth, :p256dh])
active_session = current_session
unless active_session.web_push_subscription.nil?
@@ -29,27 +25,38 @@ class Api::Web::PushSubscriptionsController < Api::BaseController
},
}
data.deep_merge!(params[:data]) if params[:data]
data.deep_merge!(data_params) if params[:data]
web_subscription = ::Web::PushSubscription.create!(
endpoint: params[:subscription][:endpoint],
key_p256dh: params[:subscription][:keys][:p256dh],
key_auth: params[:subscription][:keys][:auth],
data: data
endpoint: subscription_params[:endpoint],
key_p256dh: subscription_params[:keys][:p256dh],
key_auth: subscription_params[:keys][:auth],
data: data,
user_id: active_session.user_id,
access_token_id: active_session.access_token_id
)
active_session.update!(web_push_subscription: web_subscription)
render json: web_subscription.as_payload
render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def update
params.require([:id, :data])
params.require([:id])
web_subscription = ::Web::PushSubscription.find(params[:id])
web_subscription.update!(data: data_params)
web_subscription.update!(data: params[:data])
render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer
end
render json: web_subscription.as_payload
private
def subscription_params
@subscription_params ||= params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
end
def data_params
@data_params ||= params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention])
end
end

View File

@@ -1,6 +1,6 @@
# frozen_string_literal: true
class Api::Web::SettingsController < Api::BaseController
class Api::Web::SettingsController < Api::Web::BaseController
respond_to :json
before_action :require_user!

View File

@@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base
include Localized
include UserTrackingConcern
include SessionTrackingConcern
helper_method :current_account
helper_method :current_session
@@ -39,11 +40,11 @@ class ApplicationController < ActionController::Base
end
def require_admin!
redirect_to root_path unless current_user&.admin?
forbidden unless current_user&.admin?
end
def require_staff!
redirect_to root_path unless current_user&.staff?
forbidden unless current_user&.staff?
end
def check_suspension

View File

@@ -17,7 +17,11 @@ module Localized
end
def default_locale
request_locale || I18n.default_locale
if ENV['DEFAULT_LOCALE'].present?
I18n.default_locale
else
request_locale || I18n.default_locale
end
end
def request_locale
@@ -25,10 +29,14 @@ module Localized
end
def preferred_locale
http_accept_language.preferred_language_from(I18n.available_locales)
http_accept_language.preferred_language_from(available_locales)
end
def compatible_locale
http_accept_language.compatible_language_from(I18n.available_locales)
http_accept_language.compatible_language_from(available_locales)
end
def available_locales
I18n.available_locales.reverse
end
end

View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
module RemoteAccountControllerConcern
extend ActiveSupport::Concern
included do
layout 'public'
before_action :set_account
before_action :check_account_suspension
end
private
def set_account
@account = Account.find_remote!(params[:acct])
end
def check_account_suspension
gone if @account.suspended?
end
end

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
module SessionTrackingConcern
extend ActiveSupport::Concern
UPDATE_SIGN_IN_HOURS = 24
included do
before_action :set_session_activity
end
private
def set_session_activity
return unless session_needs_update?
current_session.touch
end
def session_needs_update?
!current_session.nil? && current_session.updated_at < UPDATE_SIGN_IN_HOURS.hours.ago
end
end

View File

@@ -107,9 +107,7 @@ module SignatureVerification
def incompatible_signature?(signature_params)
signature_params['keyId'].blank? ||
signature_params['signature'].blank? ||
signature_params['algorithm'].blank? ||
signature_params['algorithm'] != 'rsa-sha256'
signature_params['signature'].blank?
end
def account_from_key_id(key_id)

View File

@@ -4,14 +4,17 @@ class FollowerAccountsController < ApplicationController
include AccountControllerConcern
def index
@follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account)
respond_to do |format|
format.html do
@relationships = AccountRelationshipsPresenter.new(@follows.map(&:account_id), current_user.account_id) if user_signed_in?
next if @account.user_hides_network?
follows
@relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in?
end
format.json do
raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
render json: collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
@@ -22,28 +25,31 @@ class FollowerAccountsController < ApplicationController
private
def follows
@follows ||= Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account)
end
def page_url(page)
account_followers_url(@account, page: page) unless page.nil?
end
def collection_presenter
page = ActivityPub::CollectionPresenter.new(
id: account_followers_url(@account, page: params.fetch(:page, 1)),
type: :ordered,
size: @account.followers_count,
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) },
part_of: account_followers_url(@account),
next: page_url(@follows.next_page),
prev: page_url(@follows.prev_page)
)
if params[:page].present?
page
ActivityPub::CollectionPresenter.new(
id: account_followers_url(@account, page: params.fetch(:page, 1)),
type: :ordered,
size: @account.followers_count,
items: follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) },
part_of: account_followers_url(@account),
next: page_url(follows.next_page),
prev: page_url(follows.prev_page)
)
else
ActivityPub::CollectionPresenter.new(
id: account_followers_url(@account),
type: :ordered,
size: @account.followers_count,
first: page
first: page_url(1)
)
end
end

View File

@@ -4,14 +4,17 @@ class FollowingAccountsController < ApplicationController
include AccountControllerConcern
def index
@follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account)
respond_to do |format|
format.html do
@relationships = AccountRelationshipsPresenter.new(@follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
next if @account.user_hides_network?
follows
@relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in?
end
format.json do
raise Mastodon::NotPermittedError if params[:page].present? && @account.user_hides_network?
render json: collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
@@ -22,28 +25,31 @@ class FollowingAccountsController < ApplicationController
private
def follows
@follows ||= Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account)
end
def page_url(page)
account_following_index_url(@account, page: page) unless page.nil?
end
def collection_presenter
page = ActivityPub::CollectionPresenter.new(
id: account_following_index_url(@account, page: params.fetch(:page, 1)),
type: :ordered,
size: @account.following_count,
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) },
part_of: account_following_index_url(@account),
next: page_url(@follows.next_page),
prev: page_url(@follows.prev_page)
)
if params[:page].present?
page
ActivityPub::CollectionPresenter.new(
id: account_following_index_url(@account, page: params.fetch(:page, 1)),
type: :ordered,
size: @account.following_count,
items: follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) },
part_of: account_following_index_url(@account),
next: page_url(follows.next_page),
prev: page_url(follows.prev_page)
)
else
ActivityPub::CollectionPresenter.new(
id: account_following_index_url(@account),
type: :ordered,
size: @account.following_count,
first: page
first: page_url(1)
)
end
end

View File

@@ -2,6 +2,7 @@
class HomeController < ApplicationController
before_action :authenticate_user!
before_action :set_referrer_policy_header
before_action :set_initial_state_json
def index
@@ -62,4 +63,8 @@ class HomeController < ApplicationController
about_path
end
end
def set_referrer_policy_header
response.headers['Referrer-Policy'] = 'origin'
end
end

View File

@@ -8,9 +8,9 @@ class InvitesController < ApplicationController
before_action :authenticate_user!
def index
authorize :invite, :create?
authorize :invite, :index?
@invites = Invite.where(user: current_user)
@invites = invites
@invite = Invite.new(expires_in: 1.day.to_i)
end
@@ -23,13 +23,13 @@ class InvitesController < ApplicationController
if @invite.save
redirect_to invites_path
else
@invites = Invite.where(user: current_user)
@invites = invites
render :index
end
end
def destroy
@invite = Invite.where(user: current_user).find(params[:id])
@invite = invites.find(params[:id])
authorize @invite, :destroy?
@invite.expire!
redirect_to invites_path
@@ -37,6 +37,10 @@ class InvitesController < ApplicationController
private
def invites
Invite.where(user: current_user)
end
def resource_params
params.require(:invite).permit(:max_uses, :expires_in)
end

View File

@@ -8,6 +8,8 @@ class MediaProxyController < ApplicationController
if lock.acquired?
@media_attachment = MediaAttachment.remote.find(params[:id])
redownload! if @media_attachment.needs_redownload? && !reject_media?
else
raise Mastodon::RaceConditionError
end
end

View File

@@ -8,6 +8,11 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
include Localized
def destroy
Web::PushSubscription.unsubscribe_for(params[:id], current_resource_owner)
super
end
private
def store_current_location

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: true
class Oauth::TokensController < Doorkeeper::TokensController
def revoke
unsubscribe_for_token if authorized? && token.accessible?
super
end
private
def unsubscribe_for_token
Web::PushSubscription.where(access_token_id: token.id).delete_all
end
end

View File

@@ -0,0 +1,39 @@
# frozen_string_literal: true
class RemoteUnfollowsController < ApplicationController
layout 'modal'
before_action :authenticate_user!
before_action :set_body_classes
def create
@account = unfollow_attempt.try(:target_account)
if @account.nil?
render :error
else
render :success
end
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
render :error
end
private
def unfollow_attempt
username, domain = acct_without_prefix.split('@')
UnfollowService.new.call(current_account, Account.find_remote!(username, domain))
end
def acct_without_prefix
acct_params.gsub(/\Aacct:/, '')
end
def acct_params
params.fetch(:acct, '')
end
def set_body_classes
@body_classes = 'modal-layout'
end
end

View File

@@ -1,7 +1,5 @@
# frozen_string_literal: true
require 'sidekiq-bulk'
class Settings::FollowerDomainsController < ApplicationController
layout 'admin'
@@ -9,7 +7,7 @@ class Settings::FollowerDomainsController < ApplicationController
def show
@account = current_account
@domains = current_account.followers.reorder('MIN(follows.id) DESC').group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)
@domains = current_account.followers.reorder(Arel.sql('MIN(follows.id) DESC')).group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)
end
def update

View File

@@ -44,6 +44,7 @@ class Settings::PreferencesController < ApplicationController
:setting_system_font_ui,
:setting_noindex,
:setting_theme,
:setting_hide_network,
notification_emails: %i(follow follow_request reblog favourite mention digest),
interactions: %i(must_be_follower must_be_following)
)

View File

@@ -11,13 +11,16 @@ class Settings::ProfilesController < ApplicationController
obfuscate_filename [:account, :avatar]
obfuscate_filename [:account, :header]
def show; end
def show
@account.build_fields
end
def update
if UpdateAccountService.new.call(@account, account_params)
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
redirect_to settings_profile_path, notice: I18n.t('generic.changes_saved_msg')
else
@account.build_fields
render :show
end
end
@@ -25,7 +28,7 @@ class Settings::ProfilesController < ApplicationController
private
def account_params
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked)
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value])
end
def set_account

View File

@@ -15,6 +15,7 @@ class SharesController < ApplicationController
def initial_state_params
text = [params[:title], params[:text], params[:url]].compact.join(' ')
{
settings: Web::Setting.find_by(user: current_user)&.data || {},
push_subscription: current_account.user.web_push_subscription(current_session),

View File

@@ -4,6 +4,10 @@ class StatusesController < ApplicationController
include SignatureAuthentication
include Authorization
ANCESTORS_LIMIT = 40
DESCENDANTS_LIMIT = 60
DESCENDANTS_DEPTH_LIMIT = 20
layout 'public'
before_action :set_account
@@ -11,13 +15,14 @@ class StatusesController < ApplicationController
before_action :set_link_headers
before_action :check_account_suspension
before_action :redirect_to_original, only: [:show]
before_action :set_referrer_policy_header, only: [:show]
before_action :set_cache_headers
def show
respond_to do |format|
format.html do
@ancestors = @status.reply? ? cache_collection(@status.ancestors(current_account), Status) : []
@descendants = cache_collection(@status.descendants(current_account), Status)
set_ancestors
set_descendants
render 'stream_entries/show'
end
@@ -47,10 +52,77 @@ class StatusesController < ApplicationController
private
def create_descendant_thread(depth, statuses)
if depth < DESCENDANTS_DEPTH_LIMIT
{ statuses: statuses }
else
next_status = statuses.pop
{ statuses: statuses, next_status: next_status }
end
end
def set_account
@account = Account.find_local!(params[:account_username])
end
def set_ancestors
@ancestors = @status.reply? ? cache_collection(@status.ancestors(ANCESTORS_LIMIT, current_account), Status) : []
@next_ancestor = @ancestors.size < ANCESTORS_LIMIT ? nil : @ancestors.shift
end
def set_descendants
@max_descendant_thread_id = params[:max_descendant_thread_id]&.to_i
@since_descendant_thread_id = params[:since_descendant_thread_id]&.to_i
descendants = cache_collection(
@status.descendants(
DESCENDANTS_LIMIT,
current_account,
@max_descendant_thread_id,
@since_descendant_thread_id,
DESCENDANTS_DEPTH_LIMIT
),
Status
)
@descendant_threads = []
if descendants.present?
statuses = [descendants.first]
depth = 1
descendants.drop(1).each_with_index do |descendant, index|
if descendants[index].id == descendant.in_reply_to_id
depth += 1
statuses << descendant
else
@descendant_threads << create_descendant_thread(depth, statuses)
@descendant_threads.reverse_each do |descendant_thread|
statuses = descendant_thread[:statuses]
index = statuses.find_index do |thread_status|
thread_status.id == descendant.in_reply_to_id
end
if index.present?
depth += index - statuses.size
break
end
depth -= statuses.size
end
statuses = [descendant]
end
end
@descendant_threads << create_descendant_thread(depth, statuses)
end
@max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT
end
def set_link_headers
response.headers['Link'] = LinkHeader.new(
[
@@ -78,4 +150,9 @@ class StatusesController < ApplicationController
def redirect_to_original
redirect_to ::TagManager.instance.url_for(@status.reblog) if @status.reblog?
end
def set_referrer_policy_header
return if @status.public_visibility? || @status.unlisted_visibility?
response.headers['Referrer-Policy'] = 'origin'
end
end

View File

@@ -15,8 +15,7 @@ class StreamEntriesController < ApplicationController
def show
respond_to do |format|
format.html do
@ancestors = @stream_entry.activity.reply? ? cache_collection(@stream_entry.activity.ancestors(current_account), Status) : []
@descendants = cache_collection(@stream_entry.activity.descendants(current_account), Status)
redirect_to short_account_status_url(params[:account_username], @stream_entry.activity) if @type == 'status'
end
format.atom do
@@ -24,6 +23,7 @@ class StreamEntriesController < ApplicationController
skip_session!
expires_in 3.minutes, public: true
end
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.entry(@stream_entry, true))
end
end

View File

@@ -1,6 +1,8 @@
# frozen_string_literal: true
class TagsController < ApplicationController
PAGE_SIZE = 20
before_action :set_body_classes
before_action :set_instance_presenter
@@ -13,8 +15,15 @@ class TagsController < ApplicationController
@initial_state_json = serializable_resource.to_json
end
format.rss do
@statuses = Status.as_tag_timeline(@tag).limit(PAGE_SIZE)
@statuses = cache_collection(@statuses, Status)
render xml: RSS::TagSerializer.render(@tag, @statuses)
end
format.json do
@statuses = Status.as_tag_timeline(@tag, current_account, params[:local]).paginate_by_max_id(20, params[:max_id])
@statuses = Status.as_tag_timeline(@tag, current_account, params[:local]).paginate_by_max_id(PAGE_SIZE, params[:max_id])
@statuses = cache_collection(@statuses, Status)
render json: collection_presenter,

View File

@@ -1,4 +1,26 @@
# frozen_string_literal: true
module Admin::AccountModerationNotesHelper
def admin_account_link_to(account)
link_to admin_account_path(account.id), class: name_tag_classes(account) do
safe_join([
image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
content_tag(:span, account.acct, class: 'username'),
], ' ')
end
end
def admin_account_inline_link_to(account)
link_to admin_account_path(account.id), class: name_tag_classes(account, true) do
content_tag(:span, account.acct, class: 'username')
end
end
private
def name_tag_classes(account, inline = false)
classes = [inline ? 'inline-name-tag' : 'name-tag']
classes << 'suspended' if account.suspended?
classes.join(' ')
end
end

View File

@@ -45,6 +45,8 @@ module Admin::ActionLogsHelper
log.recorded_changes.slice('domain', 'visible_in_picker')
elsif log.target_type == 'User' && [:promote, :demote].include?(log.action)
log.recorded_changes.slice('moderator', 'admin')
elsif log.target_type == 'User' && [:change_email].include?(log.action)
log.recorded_changes.slice('email', 'unconfirmed_email')
elsif log.target_type == 'DomainBlock'
log.recorded_changes.slice('severity', 'reject_media')
elsif log.target_type == 'Status' && log.action == :update
@@ -84,9 +86,9 @@ module Admin::ActionLogsHelper
'positive'
when :create
opposite_verbs?(log) ? 'negative' : 'positive'
when :update, :reset_password, :disable_2fa, :memorialize
when :update, :reset_password, :disable_2fa, :memorialize, :change_email
'neutral'
when :demote, :silence, :disable, :suspend
when :demote, :silence, :disable, :suspend, :remove_avatar, :reopen
'negative'
when :destroy
opposite_verbs?(log) ? 'positive' : 'negative'

View File

@@ -63,4 +63,8 @@ module ApplicationHelper
def opengraph(property, content)
tag(:meta, content: content, property: property)
end
def react_component(name, props = {})
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
end
end

View File

@@ -5,6 +5,10 @@ module JsonLdHelper
haystack.is_a?(Array) ? haystack.include?(needle) : haystack == needle
end
def equals_or_includes_any?(haystack, needles)
needles.any? { |needle| equals_or_includes?(haystack, needle) }
end
def first_of_value(value)
value.is_a?(Array) ? value.first : value
end
@@ -44,25 +48,29 @@ module JsonLdHelper
end
def canonicalize(json)
graph = RDF::Graph.new << JSON::LD::API.toRdf(json)
graph = RDF::Graph.new << JSON::LD::API.toRdf(json, documentLoader: method(:load_jsonld_context))
graph.dump(:normalize)
end
def fetch_resource(uri, id)
def fetch_resource(uri, id, on_behalf_of = nil)
unless id
json = fetch_resource_without_id_validation(uri)
json = fetch_resource_without_id_validation(uri, on_behalf_of)
return unless json
uri = json['id']
end
json = fetch_resource_without_id_validation(uri)
json = fetch_resource_without_id_validation(uri, on_behalf_of)
json.present? && json['id'] == uri ? json : nil
end
def fetch_resource_without_id_validation(uri)
response = build_request(uri).perform
return if response.code != 200
body_to_json(response.to_s)
def fetch_resource_without_id_validation(uri, on_behalf_of = nil)
build_request(uri, on_behalf_of).perform do |response|
return body_to_json(response.body_with_limit) if response.code == 200
end
# If request failed, retry without doing it on behalf of a user
build_request(uri).perform do |response|
response.code == 200 ? body_to_json(response.body_with_limit) : nil
end
end
def body_to_json(body)
@@ -81,9 +89,25 @@ module JsonLdHelper
private
def build_request(uri)
def build_request(uri, on_behalf_of = nil)
request = Request.new(:get, uri)
request.on_behalf_of(on_behalf_of) if on_behalf_of
request.add_headers('Accept' => 'application/activity+json, application/ld+json')
request
end
def load_jsonld_context(url, _options = {}, &_block)
json = Rails.cache.fetch("jsonld:context:#{url}", expires_in: 30.days, raw: true) do
request = Request.new(:get, url)
request.add_headers('Accept' => 'application/ld+json')
request.perform do |res|
raise JSON::LD::JsonLdError::LoadingDocumentFailed unless res.code == 200 && res.mime_type == 'application/ld+json'
res.body_with_limit
end
end
doc = JSON::LD::API::RemoteDocument.new(url, json)
block_given? ? yield(doc) : doc
end
end

View File

@@ -6,13 +6,16 @@ module SettingsHelper
ar: 'العربية',
bg: 'Български',
ca: 'Català',
co: 'Corsu',
de: 'Deutsch',
el: 'Ελληνικά',
eo: 'Esperanto',
es: 'Español',
eu: 'Euskara',
fa: 'فارسی',
gl: 'Galego',
fi: 'Suomi',
fr: 'Français',
gl: 'Galego',
he: 'עברית',
hr: 'Hrvatski',
hu: 'Magyar',
@@ -30,9 +33,11 @@ module SettingsHelper
'pt-BR': 'Português do Brasil',
ru: 'Русский',
sk: 'Slovensky',
sl: 'Slovenščina',
sr: 'Српски',
'sr-Latn': 'Srpski (latinica)',
sv: 'Svenska',
te: 'తెలుగు',
th: 'ภาษาไทย',
tr: 'Türkçe',
uk: 'Українська',

View File

@@ -4,31 +4,64 @@ module StreamEntriesHelper
EMBEDDED_CONTROLLER = 'statuses'
EMBEDDED_ACTION = 'embed'
def display_name(account)
account.display_name.presence || account.username
def display_name(account, **options)
if options[:custom_emojify]
Formatter.instance.format_display_name(account, options)
else
account.display_name.presence || account.username
end
end
def account_description(account)
prepend_str = [
[
number_to_human(account.statuses_count, strip_insignificant_zeros: true),
t('accounts.posts'),
I18n.t('accounts.posts'),
].join(' '),
[
number_to_human(account.following_count, strip_insignificant_zeros: true),
t('accounts.following'),
I18n.t('accounts.following'),
].join(' '),
[
number_to_human(account.followers_count, strip_insignificant_zeros: true),
t('accounts.followers'),
I18n.t('accounts.followers'),
].join(' '),
].join(', ')
[prepend_str, account.note].join(' · ')
end
def media_summary(status)
attachments = { image: 0, video: 0 }
status.media_attachments.each do |media|
if media.video?
attachments[:video] += 1
else
attachments[:image] += 1
end
end
text = attachments.to_a.reject { |_, value| value.zero? }.map { |key, value| I18n.t("statuses.attached.#{key}", count: value) }.join(' · ')
return if text.blank?
I18n.t('statuses.attached.description', attached: text)
end
def status_text_summary(status)
return if status.spoiler_text.blank?
I18n.t('statuses.content_warning', warning: status.spoiler_text)
end
def status_description(status)
components = [[media_summary(status), status_text_summary(status)].reject(&:blank?).join(' · ')]
components << status.text if status.spoiler_text.blank?
components.reject(&:blank?).join("\n\n")
end
def stream_link_target
embedded_view? ? '_blank' : nil
end
@@ -84,6 +117,19 @@ module StreamEntriesHelper
end
end
def fa_visibility_icon(status)
case status.visibility
when 'public'
fa_icon 'globe fw'
when 'unlisted'
fa_icon 'unlock-alt fw'
when 'private'
fa_icon 'lock fw'
when 'direct'
fa_icon 'envelope fw'
end
end
private
def simplified_text(text)

View File

@@ -1,4 +1,6 @@
import api, { getLinks } from '../api';
import openDB from '../storage/db';
import { importAccount, importFetchedAccount, importFetchedAccounts } from './importer';
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
@@ -64,6 +66,24 @@ export const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST';
export const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS';
export const FOLLOW_REQUEST_REJECT_FAIL = 'FOLLOW_REQUEST_REJECT_FAIL';
function getFromDB(dispatch, getState, index, id) {
return new Promise((resolve, reject) => {
const request = index.get(id);
request.onerror = reject;
request.onsuccess = () => {
if (!request.result) {
reject();
return;
}
dispatch(importAccount(request.result));
resolve(request.result.moved && getFromDB(dispatch, getState, index, request.result.moved));
};
});
}
export function fetchAccount(id) {
return (dispatch, getState) => {
dispatch(fetchRelationships([id]));
@@ -74,8 +94,18 @@ export function fetchAccount(id) {
dispatch(fetchAccountRequest(id));
api(getState).get(`/api/v1/accounts/${id}`).then(response => {
dispatch(fetchAccountSuccess(response.data));
openDB().then(db => getFromDB(
dispatch,
getState,
db.transaction('accounts', 'read').objectStore('accounts').index('id'),
id
).then(() => db.close(), error => {
db.close();
throw error;
})).catch(() => api(getState).get(`/api/v1/accounts/${id}`).then(response => {
dispatch(importFetchedAccount(response.data));
})).then(() => {
dispatch(fetchAccountSuccess());
}).catch(error => {
dispatch(fetchAccountFail(id, error));
});
@@ -89,10 +119,9 @@ export function fetchAccountRequest(id) {
};
};
export function fetchAccountSuccess(account) {
export function fetchAccountSuccess() {
return {
type: ACCOUNT_FETCH_SUCCESS,
account,
};
};
@@ -319,6 +348,7 @@ export function fetchFollowers(id) {
api(getState).get(`/api/v1/accounts/${id}/followers`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowersSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -364,6 +394,7 @@ export function expandFollowers(id) {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowersSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -403,6 +434,7 @@ export function fetchFollowing(id) {
api(getState).get(`/api/v1/accounts/${id}/following`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowingSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -448,6 +480,7 @@ export function expandFollowing(id) {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowingSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -529,6 +562,7 @@ export function fetchFollowRequests() {
api(getState).get('/api/v1/follow_requests').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
};
@@ -567,6 +601,7 @@ export function expandFollowRequests() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
}).catch(error => dispatch(expandFollowRequestsFail(error)));
};

View File

@@ -1,3 +1,10 @@
import { defineMessages } from 'react-intl';
const messages = defineMessages({
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
});
export const ALERT_SHOW = 'ALERT_SHOW';
export const ALERT_DISMISS = 'ALERT_DISMISS';
export const ALERT_CLEAR = 'ALERT_CLEAR';
@@ -22,3 +29,21 @@ export function showAlert(title, message) {
message,
};
};
export function showAlertForError(error) {
if (error.response) {
const { data, status, statusText } = error.response;
let message = statusText;
let title = `${status}`;
if (data.error) {
message = data.error;
}
return showAlert(title, message);
} else {
console.error(error);
return showAlert(messages.unexpectedTitle, messages.unexpectedMessage);
}
}

View File

@@ -1,5 +1,6 @@
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
export const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
@@ -15,6 +16,7 @@ export function fetchBlocks() {
api(getState).get('/api/v1/blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(fetchBlocksFail(error)));
@@ -54,6 +56,7 @@ export function expandBlocks() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandBlocksFail(error)));

View File

@@ -1,15 +1,15 @@
import api from '../api';
import { CancelToken, isCancel } from 'axios';
import { throttle } from 'lodash';
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
import { tagHistory } from '../settings';
import { useEmoji } from './emojis';
import resizeImage from '../utils/resize_image';
import { importFetchedAccounts } from './importer';
import { updateTimeline } from './timelines';
import { showAlertForError } from './alerts';
import {
updateTimeline,
refreshHomeTimeline,
refreshCommunityTimeline,
refreshPublicTimeline,
} from './timelines';
let cancelFetchComposeSuggestionsAccounts;
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
@@ -17,6 +17,7 @@ export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
export const COMPOSE_REPLY = 'COMPOSE_REPLY';
export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL';
export const COMPOSE_DIRECT = 'COMPOSE_DIRECT';
export const COMPOSE_MENTION = 'COMPOSE_MENTION';
export const COMPOSE_RESET = 'COMPOSE_RESET';
export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
@@ -93,6 +94,19 @@ export function mentionCompose(account, router) {
};
};
export function directCompose(account, router) {
return (dispatch, getState) => {
dispatch({
type: COMPOSE_DIRECT,
account: account,
});
if (!getState().getIn(['compose', 'mounted'])) {
router.push('/statuses/new');
}
};
};
export function submitCompose() {
return function (dispatch, getState) {
const status = getState().getIn(['compose', 'text'], '');
@@ -121,19 +135,19 @@ export function submitCompose() {
// To make the app more responsive, immediately get the status into the columns
const insertOrRefresh = (timelineId, refreshAction) => {
if (getState().getIn(['timelines', timelineId, 'online'])) {
const insertIfOnline = (timelineId) => {
if (getState().getIn(['timelines', timelineId, 'items', 0]) !== null) {
dispatch(updateTimeline(timelineId, { ...response.data }));
} else if (getState().getIn(['timelines', timelineId, 'loaded'])) {
dispatch(refreshAction());
}
};
insertOrRefresh('home', refreshHomeTimeline);
insertIfOnline('home');
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
insertOrRefresh('community', refreshCommunityTimeline);
insertOrRefresh('public', refreshPublicTimeline);
insertIfOnline('community');
insertIfOnline('public');
} else if (response.data.visibility === 'direct') {
insertIfOnline('direct');
}
}).catch(function (error) {
dispatch(submitComposeFail(error));
@@ -169,18 +183,14 @@ export function uploadCompose(files) {
dispatch(uploadComposeRequest());
let data = new FormData();
data.append('file', files[0]);
resizeImage(files[0]).then(file => {
const data = new FormData();
data.append('file', file);
api(getState).post('/api/v1/media', data, {
onUploadProgress: function (e) {
dispatch(uploadComposeProgress(e.loaded, e.total));
},
}).then(function (response) {
dispatch(uploadComposeSuccess(response.data));
}).catch(function (error) {
dispatch(uploadComposeFail(error));
});
return api(getState).post('/api/v1/media', data, {
onUploadProgress: ({ loaded, total }) => dispatch(uploadComposeProgress(loaded, total)),
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
}).catch(error => dispatch(uploadComposeFail(error)));
};
};
@@ -257,20 +267,34 @@ export function undoUploadCompose(media_id) {
};
export function clearComposeSuggestions() {
if (cancelFetchComposeSuggestionsAccounts) {
cancelFetchComposeSuggestionsAccounts();
}
return {
type: COMPOSE_SUGGESTIONS_CLEAR,
};
};
const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
if (cancelFetchComposeSuggestionsAccounts) {
cancelFetchComposeSuggestionsAccounts();
}
api(getState).get('/api/v1/accounts/search', {
cancelToken: new CancelToken(cancel => {
cancelFetchComposeSuggestionsAccounts = cancel;
}),
params: {
q: token.slice(1),
resolve: false,
limit: 4,
},
}).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(readyComposeSuggestionsAccounts(token, response.data));
}).catch(error => {
if (!isCancel(error)) {
dispatch(showAlertForError(error));
}
});
}, 200, { leading: true, trailing: true });
@@ -421,11 +445,12 @@ export function changeComposeVisibility(value) {
};
};
export function insertEmojiCompose(position, emoji) {
export function insertEmojiCompose(position, emoji, needsSpace) {
return {
type: COMPOSE_EMOJI_INSERT,
position,
emoji,
needsSpace,
};
};

View File

@@ -0,0 +1,37 @@
import api from '../api';
export const CUSTOM_EMOJIS_FETCH_REQUEST = 'CUSTOM_EMOJIS_FETCH_REQUEST';
export const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS';
export const CUSTOM_EMOJIS_FETCH_FAIL = 'CUSTOM_EMOJIS_FETCH_FAIL';
export function fetchCustomEmojis() {
return (dispatch, getState) => {
dispatch(fetchCustomEmojisRequest());
api(getState).get('/api/v1/custom_emojis').then(response => {
dispatch(fetchCustomEmojisSuccess(response.data));
}).catch(error => {
dispatch(fetchCustomEmojisFail(error));
});
};
};
export function fetchCustomEmojisRequest() {
return {
type: CUSTOM_EMOJIS_FETCH_REQUEST,
};
};
export function fetchCustomEmojisSuccess(custom_emojis) {
return {
type: CUSTOM_EMOJIS_FETCH_SUCCESS,
custom_emojis,
};
};
export function fetchCustomEmojisFail(error) {
return {
type: CUSTOM_EMOJIS_FETCH_FAIL,
error,
};
};

View File

@@ -12,12 +12,18 @@ export const DOMAIN_BLOCKS_FETCH_REQUEST = 'DOMAIN_BLOCKS_FETCH_REQUEST';
export const DOMAIN_BLOCKS_FETCH_SUCCESS = 'DOMAIN_BLOCKS_FETCH_SUCCESS';
export const DOMAIN_BLOCKS_FETCH_FAIL = 'DOMAIN_BLOCKS_FETCH_FAIL';
export function blockDomain(domain, accountId) {
export const DOMAIN_BLOCKS_EXPAND_REQUEST = 'DOMAIN_BLOCKS_EXPAND_REQUEST';
export const DOMAIN_BLOCKS_EXPAND_SUCCESS = 'DOMAIN_BLOCKS_EXPAND_SUCCESS';
export const DOMAIN_BLOCKS_EXPAND_FAIL = 'DOMAIN_BLOCKS_EXPAND_FAIL';
export function blockDomain(domain) {
return (dispatch, getState) => {
dispatch(blockDomainRequest(domain));
api(getState).post('/api/v1/domain_blocks', { domain }).then(() => {
dispatch(blockDomainSuccess(domain, accountId));
const at_domain = '@' + domain;
const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id'));
dispatch(blockDomainSuccess(domain, accounts));
}).catch(err => {
dispatch(blockDomainFail(domain, err));
});
@@ -31,11 +37,11 @@ export function blockDomainRequest(domain) {
};
};
export function blockDomainSuccess(domain, accountId) {
export function blockDomainSuccess(domain, accounts) {
return {
type: DOMAIN_BLOCK_SUCCESS,
domain,
accountId,
accounts,
};
};
@@ -47,12 +53,14 @@ export function blockDomainFail(domain, error) {
};
};
export function unblockDomain(domain, accountId) {
export function unblockDomain(domain) {
return (dispatch, getState) => {
dispatch(unblockDomainRequest(domain));
api(getState).delete('/api/v1/domain_blocks', { params: { domain } }).then(() => {
dispatch(unblockDomainSuccess(domain, accountId));
const at_domain = '@' + domain;
const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id'));
dispatch(unblockDomainSuccess(domain, accounts));
}).catch(err => {
dispatch(unblockDomainFail(domain, err));
});
@@ -66,11 +74,11 @@ export function unblockDomainRequest(domain) {
};
};
export function unblockDomainSuccess(domain, accountId) {
export function unblockDomainSuccess(domain, accounts) {
return {
type: DOMAIN_UNBLOCK_SUCCESS,
domain,
accountId,
accounts,
};
};
@@ -86,7 +94,7 @@ export function fetchDomainBlocks() {
return (dispatch, getState) => {
dispatch(fetchDomainBlocksRequest());
api(getState).get().then(response => {
api(getState).get('/api/v1/domain_blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(fetchDomainBlocksSuccess(response.data, next ? next.uri : null));
}).catch(err => {
@@ -115,3 +123,43 @@ export function fetchDomainBlocksFail(error) {
error,
};
};
export function expandDomainBlocks() {
return (dispatch, getState) => {
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
if (url === null) {
return;
}
dispatch(expandDomainBlocksRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(expandDomainBlocksSuccess(response.data, next ? next.uri : null));
}).catch(err => {
dispatch(expandDomainBlocksFail(err));
});
};
};
export function expandDomainBlocksRequest() {
return {
type: DOMAIN_BLOCKS_EXPAND_REQUEST,
};
};
export function expandDomainBlocksSuccess(domains, next) {
return {
type: DOMAIN_BLOCKS_EXPAND_SUCCESS,
domains,
next,
};
};
export function expandDomainBlocksFail(error) {
return {
type: DOMAIN_BLOCKS_EXPAND_FAIL,
error,
};
};

View File

@@ -1,4 +1,5 @@
import api, { getLinks } from '../api';
import { importFetchedStatuses } from './importer';
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
@@ -18,6 +19,7 @@ export function fetchFavouritedStatuses() {
api(getState).get('/api/v1/favourites').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(fetchFavouritedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchFavouritedStatusesFail(error));
@@ -58,6 +60,7 @@ export function expandFavouritedStatuses() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(expandFavouritedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandFavouritedStatusesFail(error));

View File

@@ -0,0 +1,77 @@
import { autoPlayGif } from '../../initial_state';
import { putAccounts, putStatuses } from '../../storage/modifier';
import { normalizeAccount, normalizeStatus } from './normalizer';
export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
export const STATUS_IMPORT = 'STATUS_IMPORT';
export const STATUSES_IMPORT = 'STATUSES_IMPORT';
function pushUnique(array, object) {
if (array.every(element => element.id !== object.id)) {
array.push(object);
}
}
export function importAccount(account) {
return { type: ACCOUNT_IMPORT, account };
}
export function importAccounts(accounts) {
return { type: ACCOUNTS_IMPORT, accounts };
}
export function importStatus(status) {
return { type: STATUS_IMPORT, status };
}
export function importStatuses(statuses) {
return { type: STATUSES_IMPORT, statuses };
}
export function importFetchedAccount(account) {
return importFetchedAccounts([account]);
}
export function importFetchedAccounts(accounts) {
const normalAccounts = [];
function processAccount(account) {
pushUnique(normalAccounts, normalizeAccount(account));
if (account.moved) {
processAccount(account.moved);
}
}
accounts.forEach(processAccount);
putAccounts(normalAccounts, !autoPlayGif);
return importAccounts(normalAccounts);
}
export function importFetchedStatus(status) {
return importFetchedStatuses([status]);
}
export function importFetchedStatuses(statuses) {
return (dispatch, getState) => {
const accounts = [];
const normalStatuses = [];
function processStatus(status) {
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
pushUnique(accounts, status.account);
if (status.reblog && status.reblog.id) {
processStatus(status.reblog);
}
}
statuses.forEach(processStatus);
putStatuses(normalStatuses);
dispatch(importFetchedAccounts(accounts));
dispatch(importStatuses(normalStatuses));
};
}

View File

@@ -0,0 +1,63 @@
import escapeTextContentForBrowser from 'escape-html';
import emojify from '../../features/emoji/emoji';
import { unescapeHTML } from '../../utils/html';
const domParser = new DOMParser();
const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => {
obj[`:${emoji.shortcode}:`] = emoji;
return obj;
}, {});
export function normalizeAccount(account) {
account = { ...account };
const emojiMap = makeEmojiMap(account);
const displayName = account.display_name.length === 0 ? account.username : account.display_name;
account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap);
account.note_emojified = emojify(account.note, emojiMap);
if (account.fields) {
account.fields = account.fields.map(pair => ({
...pair,
name_emojified: emojify(escapeTextContentForBrowser(pair.name)),
value_emojified: emojify(pair.value, emojiMap),
value_plain: unescapeHTML(pair.value),
}));
}
if (account.moved) {
account.moved = account.moved.id;
}
return account;
}
export function normalizeStatus(status, normalOldStatus) {
const normalStatus = { ...status };
normalStatus.account = status.account.id;
if (status.reblog && status.reblog.id) {
normalStatus.reblog = status.reblog.id;
}
// Only calculate these values when status first encountered
// Otherwise keep the ones already in the reducer
if (normalOldStatus) {
normalStatus.search_index = normalOldStatus.get('search_index');
normalStatus.contentHtml = normalOldStatus.get('contentHtml');
normalStatus.spoilerHtml = normalOldStatus.get('spoilerHtml');
normalStatus.hidden = normalOldStatus.get('hidden');
} else {
const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
const emojiMap = makeEmojiMap(normalStatus);
normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
normalStatus.contentHtml = emojify(normalStatus.content, emojiMap);
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap);
normalStatus.hidden = normalStatus.sensitive;
}
return normalStatus;
}

View File

@@ -1,4 +1,5 @@
import api from '../api';
import { importFetchedAccounts, importFetchedStatus } from './importer';
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
@@ -39,7 +40,8 @@ export function reblog(status) {
api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`).then(function (response) {
// The reblog API method returns a new status wrapped around the original. In this case we are only
// interested in how the original is modified, hence passing it skipping the wrapper
dispatch(reblogSuccess(status, response.data.reblog));
dispatch(importFetchedStatus(response.data.reblog));
dispatch(reblogSuccess(status));
}).catch(function (error) {
dispatch(reblogFail(status, error));
});
@@ -51,7 +53,8 @@ export function unreblog(status) {
dispatch(unreblogRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then(response => {
dispatch(unreblogSuccess(status, response.data));
dispatch(importFetchedStatus(response.data));
dispatch(unreblogSuccess(status));
}).catch(error => {
dispatch(unreblogFail(status, error));
});
@@ -62,14 +65,15 @@ export function reblogRequest(status) {
return {
type: REBLOG_REQUEST,
status: status,
skipLoading: true,
};
};
export function reblogSuccess(status, response) {
export function reblogSuccess(status) {
return {
type: REBLOG_SUCCESS,
status: status,
response: response,
skipLoading: true,
};
};
@@ -78,6 +82,7 @@ export function reblogFail(status, error) {
type: REBLOG_FAIL,
status: status,
error: error,
skipLoading: true,
};
};
@@ -85,14 +90,15 @@ export function unreblogRequest(status) {
return {
type: UNREBLOG_REQUEST,
status: status,
skipLoading: true,
};
};
export function unreblogSuccess(status, response) {
export function unreblogSuccess(status) {
return {
type: UNREBLOG_SUCCESS,
status: status,
response: response,
skipLoading: true,
};
};
@@ -101,6 +107,7 @@ export function unreblogFail(status, error) {
type: UNREBLOG_FAIL,
status: status,
error: error,
skipLoading: true,
};
};
@@ -109,7 +116,8 @@ export function favourite(status) {
dispatch(favouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function (response) {
dispatch(favouriteSuccess(status, response.data));
dispatch(importFetchedStatus(response.data));
dispatch(favouriteSuccess(status));
}).catch(function (error) {
dispatch(favouriteFail(status, error));
});
@@ -121,7 +129,8 @@ export function unfavourite(status) {
dispatch(unfavouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(response => {
dispatch(unfavouriteSuccess(status, response.data));
dispatch(importFetchedStatus(response.data));
dispatch(unfavouriteSuccess(status));
}).catch(error => {
dispatch(unfavouriteFail(status, error));
});
@@ -132,14 +141,15 @@ export function favouriteRequest(status) {
return {
type: FAVOURITE_REQUEST,
status: status,
skipLoading: true,
};
};
export function favouriteSuccess(status, response) {
export function favouriteSuccess(status) {
return {
type: FAVOURITE_SUCCESS,
status: status,
response: response,
skipLoading: true,
};
};
@@ -148,6 +158,7 @@ export function favouriteFail(status, error) {
type: FAVOURITE_FAIL,
status: status,
error: error,
skipLoading: true,
};
};
@@ -155,14 +166,15 @@ export function unfavouriteRequest(status) {
return {
type: UNFAVOURITE_REQUEST,
status: status,
skipLoading: true,
};
};
export function unfavouriteSuccess(status, response) {
export function unfavouriteSuccess(status) {
return {
type: UNFAVOURITE_SUCCESS,
status: status,
response: response,
skipLoading: true,
};
};
@@ -171,6 +183,7 @@ export function unfavouriteFail(status, error) {
type: UNFAVOURITE_FAIL,
status: status,
error: error,
skipLoading: true,
};
};
@@ -179,6 +192,7 @@ export function fetchReblogs(id) {
dispatch(fetchReblogsRequest(id));
api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(fetchReblogsSuccess(id, response.data));
}).catch(error => {
dispatch(fetchReblogsFail(id, error));
@@ -213,6 +227,7 @@ export function fetchFavourites(id) {
dispatch(fetchFavouritesRequest(id));
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(fetchFavouritesSuccess(id, response.data));
}).catch(error => {
dispatch(fetchFavouritesFail(id, error));
@@ -247,7 +262,8 @@ export function pin(status) {
dispatch(pinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => {
dispatch(pinSuccess(status, response.data));
dispatch(importFetchedStatus(response.data));
dispatch(pinSuccess(status));
}).catch(error => {
dispatch(pinFail(status, error));
});
@@ -258,14 +274,15 @@ export function pinRequest(status) {
return {
type: PIN_REQUEST,
status,
skipLoading: true,
};
};
export function pinSuccess(status, response) {
export function pinSuccess(status) {
return {
type: PIN_SUCCESS,
status,
response,
skipLoading: true,
};
};
@@ -274,6 +291,7 @@ export function pinFail(status, error) {
type: PIN_FAIL,
status,
error,
skipLoading: true,
};
};
@@ -282,7 +300,8 @@ export function unpin (status) {
dispatch(unpinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => {
dispatch(unpinSuccess(status, response.data));
dispatch(importFetchedStatus(response.data));
dispatch(unpinSuccess(status));
}).catch(error => {
dispatch(unpinFail(status, error));
});
@@ -293,14 +312,15 @@ export function unpinRequest(status) {
return {
type: UNPIN_REQUEST,
status,
skipLoading: true,
};
};
export function unpinSuccess(status, response) {
export function unpinSuccess(status) {
return {
type: UNPIN_SUCCESS,
status,
response,
skipLoading: true,
};
};
@@ -309,5 +329,6 @@ export function unpinFail(status, error) {
type: UNPIN_FAIL,
status,
error,
skipLoading: true,
};
};

View File

@@ -1,4 +1,6 @@
import api from '../api';
import { importFetchedAccounts } from './importer';
import { showAlertForError } from './alerts';
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS';
@@ -200,9 +202,10 @@ export const deleteListFail = (id, error) => ({
export const fetchListAccounts = listId => (dispatch, getState) => {
dispatch(fetchListAccountsRequest(listId));
api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } })
.then(({ data }) => dispatch(fetchListAccountsSuccess(listId, data)))
.catch(err => dispatch(fetchListAccountsFail(listId, err)));
api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchListAccountsSuccess(listId, data));
}).catch(err => dispatch(fetchListAccountsFail(listId, err)));
};
export const fetchListAccountsRequest = id => ({
@@ -231,8 +234,10 @@ export const fetchListSuggestions = q => (dispatch, getState) => {
following: true,
};
api(getState).get('/api/v1/accounts/search', { params })
.then(({ data }) => dispatch(fetchListSuggestionsReady(q, data)));
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchListSuggestionsReady(q, data));
}).catch(error => dispatch(showAlertForError(error)));
};
export const fetchListSuggestionsReady = (query, accounts) => ({

View File

@@ -1,5 +1,6 @@
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import { openModal } from './modal';
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
@@ -19,6 +20,7 @@ export function fetchMutes() {
api(getState).get('/api/v1/mutes').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(fetchMutesFail(error)));
@@ -58,6 +60,7 @@ export function expandMutes() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(expandMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandMutesFail(error)));

View File

@@ -1,14 +1,17 @@
import api, { getLinks } from '../api';
import { List as ImmutableList } from 'immutable';
import IntlMessageFormat from 'intl-messageformat';
import { fetchRelationships } from './accounts';
import {
importFetchedAccount,
importFetchedAccounts,
importFetchedStatus,
importFetchedStatuses,
} from './importer';
import { defineMessages } from 'react-intl';
import { unescapeHTML } from '../utils/html';
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
export const NOTIFICATIONS_REFRESH_REQUEST = 'NOTIFICATIONS_REFRESH_REQUEST';
export const NOTIFICATIONS_REFRESH_SUCCESS = 'NOTIFICATIONS_REFRESH_SUCCESS';
export const NOTIFICATIONS_REFRESH_FAIL = 'NOTIFICATIONS_REFRESH_FAIL';
export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP';
export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
@@ -19,6 +22,7 @@ export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
});
const fetchRelatedRelationships = (dispatch, notifications) => {
@@ -29,27 +33,32 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
}
};
const unescapeHTML = (html) => {
const wrapper = document.createElement('div');
html = html.replace(/<br \/>|<br>|\n/g, ' ');
wrapper.innerHTML = html;
return wrapper.textContent;
};
export function updateNotifications(notification, intlMessages, intlLocale) {
return (dispatch, getState) => {
const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
const playSound = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true);
const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
const playSound = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
dispatch({
type: NOTIFICATIONS_UPDATE,
notification,
account: notification.account,
status: notification.status,
meta: playSound ? { sound: 'boop' } : undefined,
});
if (showInColumn) {
dispatch(importFetchedAccount(notification.account));
fetchRelatedRelationships(dispatch, [notification]);
if (notification.status) {
dispatch(importFetchedStatus(notification.status));
}
dispatch({
type: NOTIFICATIONS_UPDATE,
notification,
meta: playSound ? { sound: 'boop' } : undefined,
});
fetchRelatedRelationships(dispatch, [notification]);
} else if (playSound) {
dispatch({
type: NOTIFICATIONS_UPDATE_NOOP,
meta: { sound: 'boop' },
});
}
// Desktop notifications
if (typeof window.Notification !== 'undefined' && showAlert) {
@@ -57,6 +66,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
const notify = new Notification(title, { body, icon: notification.account.avatar, tag: notification.id });
notify.addEventListener('click', () => {
window.focus();
notify.close();
@@ -67,84 +77,40 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
export function refreshNotifications() {
const noOp = () => {};
export function expandNotifications({ maxId } = {}, done = noOp) {
return (dispatch, getState) => {
const params = {};
const ids = getState().getIn(['notifications', 'items']);
const notifications = getState().get('notifications');
let skipLoading = false;
if (ids.size > 0) {
params.since_id = ids.first().get('id');
}
if (getState().getIn(['notifications', 'loaded'])) {
skipLoading = true;
}
params.exclude_types = excludeTypesFromSettings(getState());
dispatch(refreshNotificationsRequest(skipLoading));
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(refreshNotificationsSuccess(response.data, skipLoading, next ? next.uri : null));
fetchRelatedRelationships(dispatch, response.data);
}).catch(error => {
dispatch(refreshNotificationsFail(error, skipLoading));
});
};
};
export function refreshNotificationsRequest(skipLoading) {
return {
type: NOTIFICATIONS_REFRESH_REQUEST,
skipLoading,
};
};
export function refreshNotificationsSuccess(notifications, skipLoading, next) {
return {
type: NOTIFICATIONS_REFRESH_SUCCESS,
notifications,
accounts: notifications.map(item => item.account),
statuses: notifications.map(item => item.status).filter(status => !!status),
skipLoading,
next,
};
};
export function refreshNotificationsFail(error, skipLoading) {
return {
type: NOTIFICATIONS_REFRESH_FAIL,
error,
skipLoading,
};
};
export function expandNotifications() {
return (dispatch, getState) => {
const items = getState().getIn(['notifications', 'items'], ImmutableList());
if (getState().getIn(['notifications', 'isLoading']) || items.size === 0) {
if (notifications.get('isLoading')) {
done();
return;
}
const params = {
max_id: items.last().get('id'),
limit: 20,
max_id: maxId,
exclude_types: excludeTypesFromSettings(getState()),
};
if (!maxId && notifications.get('items').size > 0) {
params.since_id = notifications.getIn(['items', 0]);
}
dispatch(expandNotificationsRequest());
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
fetchRelatedRelationships(dispatch, response.data);
done();
}).catch(error => {
dispatch(expandNotificationsFail(error));
done();
});
};
};
@@ -159,8 +125,6 @@ export function expandNotificationsSuccess(notifications, next) {
return {
type: NOTIFICATIONS_EXPAND_SUCCESS,
notifications,
accounts: notifications.map(item => item.account),
statuses: notifications.map(item => item.status).filter(status => !!status),
next,
};
};

View File

@@ -1,4 +1,5 @@
import api from '../api';
import { importFetchedStatuses } from './importer';
export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST';
export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS';
@@ -11,6 +12,7 @@ export function fetchPinnedStatuses() {
dispatch(fetchPinnedStatusesRequest());
api(getState).get(`/api/v1/accounts/${me}/statuses`, { params: { pinned: true } }).then(response => {
dispatch(importFetchedStatuses(response.data));
dispatch(fetchPinnedStatusesSuccess(response.data, null));
}).catch(error => {
dispatch(fetchPinnedStatusesFail(error));

View File

@@ -1,4 +1,5 @@
import api from '../../api';
import { decode as decodeBase64 } from '../../utils/base64';
import { pushNotificationsSetting } from '../../settings';
import { setBrowserSupport, setSubscription, clearSubscription } from './setter';
import { me } from '../../initial_state';
@@ -10,13 +11,7 @@ const urlBase64ToUint8Array = (base64String) => {
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
return decodeBase64(base64);
};
const getApplicationServerKey = () => document.querySelector('[name="applicationServerKey"]').getAttribute('content');
@@ -36,7 +31,7 @@ const subscribe = (registration) =>
const unsubscribe = ({ registration, subscription }) =>
subscription ? subscription.unsubscribe().then(() => registration) : registration;
const sendSubscriptionToBackend = (getState, subscription) => {
const sendSubscriptionToBackend = (subscription) => {
const params = { subscription };
if (me) {
@@ -46,7 +41,7 @@ const sendSubscriptionToBackend = (getState, subscription) => {
}
}
return api(getState).post('/api/web/push_subscriptions', params).then(response => response.data);
return api().post('/api/web/push_subscriptions', params).then(response => response.data);
};
// Last one checks for payload support: https://web-push-book.gauntface.com/chapter-06/01-non-standards-browsers/#no-payload
@@ -56,13 +51,6 @@ export function register () {
return (dispatch, getState) => {
dispatch(setBrowserSupport(supportsPushNotifications));
if (me && !pushNotificationsSetting.get(me)) {
const alerts = getState().getIn(['push_notifications', 'alerts']);
if (alerts) {
pushNotificationsSetting.set(me, { alerts: alerts });
}
}
if (supportsPushNotifications) {
if (!getApplicationServerKey()) {
console.error('The VAPID public key is not set. You will not be able to receive Web Push Notifications.');
@@ -85,13 +73,13 @@ export function register () {
} else {
// Something went wrong, try to subscribe again
return unsubscribe({ registration, subscription }).then(subscribe).then(
subscription => sendSubscriptionToBackend(getState, subscription));
subscription => sendSubscriptionToBackend(subscription));
}
}
// No subscription, try to subscribe
return subscribe(registration).then(
subscription => sendSubscriptionToBackend(getState, subscription));
subscription => sendSubscriptionToBackend(subscription));
})
.then(subscription => {
// If we got a PushSubscription (and not a subscription object from the backend)
@@ -116,14 +104,11 @@ export function register () {
pushNotificationsSetting.remove(me);
}
try {
getRegistration()
.then(getPushSubscription)
.then(unsubscribe);
} catch (e) {
}
});
return getRegistration()
.then(getPushSubscription)
.then(unsubscribe);
})
.catch(console.warn);
} else {
console.warn('Your browser does not support Web Push Notifications.');
}
@@ -137,12 +122,12 @@ export function saveSettings() {
const alerts = state.get('alerts');
const data = { alerts };
api(getState).put(`/api/web/push_subscriptions/${subscription.get('id')}`, {
api().put(`/api/web/push_subscriptions/${subscription.get('id')}`, {
data,
}).then(() => {
if (me) {
pushNotificationsSetting.set(me, data);
}
});
}).catch(console.warn);
};
}

View File

@@ -1,5 +1,6 @@
import api from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
@@ -38,6 +39,14 @@ export function submitSearch() {
resolve: true,
},
}).then(response => {
if (response.data.accounts) {
dispatch(importFetchedAccounts(response.data.accounts));
}
if (response.data.statuses) {
dispatch(importFetchedStatuses(response.data.statuses));
}
dispatch(fetchSearchSuccess(response.data));
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
}).catch(error => {
@@ -56,8 +65,6 @@ export function fetchSearchSuccess(results) {
return {
type: SEARCH_FETCH_SUCCESS,
results,
accounts: results.accounts,
statuses: results.statuses,
};
};

View File

@@ -1,5 +1,6 @@
import api from '../api';
import { debounce } from 'lodash';
import { showAlertForError } from './alerts';
export const SETTING_CHANGE = 'SETTING_CHANGE';
export const SETTING_SAVE = 'SETTING_SAVE';
@@ -23,7 +24,9 @@ const debouncedSave = debounce((dispatch, getState) => {
const data = getState().get('settings').filter((_, path) => path !== 'saved').toJS();
api(getState).put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE }));
api().put('/api/web/settings', { data })
.then(() => dispatch({ type: SETTING_SAVE }))
.catch(error => dispatch(showAlertForError(error)));
}, 5000, { trailing: true });
export function saveSettings() {

View File

@@ -1,7 +1,10 @@
import api from '../api';
import openDB from '../storage/db';
import { evictStatus } from '../storage/modifier';
import { deleteFromTimelines } from './timelines';
import { fetchStatusCard } from './cards';
import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus } from './importer';
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
@@ -34,6 +37,48 @@ export function fetchStatusRequest(id, skipLoading) {
};
};
function getFromDB(dispatch, getState, accountIndex, index, id) {
return new Promise((resolve, reject) => {
const request = index.get(id);
request.onerror = reject;
request.onsuccess = () => {
const promises = [];
if (!request.result) {
reject();
return;
}
dispatch(importStatus(request.result));
if (getState().getIn(['accounts', request.result.account], null) === null) {
promises.push(new Promise((accountResolve, accountReject) => {
const accountRequest = accountIndex.get(request.result.account);
accountRequest.onerror = accountReject;
accountRequest.onsuccess = () => {
if (!request.result) {
accountReject();
return;
}
dispatch(importAccount(accountRequest.result));
accountResolve();
};
}));
}
if (request.result.reblog && getState().getIn(['statuses', request.result.reblog], null) === null) {
promises.push(getFromDB(dispatch, getState, accountIndex, index, request.result.reblog));
}
resolve(Promise.all(promises));
};
});
}
export function fetchStatus(id) {
return (dispatch, getState) => {
const skipLoading = getState().getIn(['statuses', id], null) !== null;
@@ -47,18 +92,31 @@ export function fetchStatus(id) {
dispatch(fetchStatusRequest(id, skipLoading));
api(getState).get(`/api/v1/statuses/${id}`).then(response => {
dispatch(fetchStatusSuccess(response.data, skipLoading));
}).catch(error => {
openDB().then(db => {
const transaction = db.transaction(['accounts', 'statuses'], 'read');
const accountIndex = transaction.objectStore('accounts').index('id');
const index = transaction.objectStore('statuses').index('id');
return getFromDB(dispatch, getState, accountIndex, index, id).then(() => {
db.close();
}, error => {
db.close();
throw error;
});
}).then(() => {
dispatch(fetchStatusSuccess(skipLoading));
}, () => api(getState).get(`/api/v1/statuses/${id}`).then(response => {
dispatch(importFetchedStatus(response.data));
dispatch(fetchStatusSuccess(skipLoading));
})).catch(error => {
dispatch(fetchStatusFail(id, error, skipLoading));
});
};
};
export function fetchStatusSuccess(status, skipLoading) {
export function fetchStatusSuccess(skipLoading) {
return {
type: STATUS_FETCH_SUCCESS,
status,
skipLoading,
};
};
@@ -78,6 +136,7 @@ export function deleteStatus(id) {
dispatch(deleteStatusRequest(id));
api(getState).delete(`/api/v1/statuses/${id}`).then(() => {
evictStatus(id);
dispatch(deleteStatusSuccess(id));
dispatch(deleteFromTimelines(id));
}).catch(error => {
@@ -113,6 +172,7 @@ export function fetchContext(id) {
dispatch(fetchContextRequest(id));
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
dispatch(importFetchedStatuses(response.data.ancestors.concat(response.data.descendants)));
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
}).catch(error => {

View File

@@ -1,5 +1,6 @@
import { Iterable, fromJS } from 'immutable';
import { hydrateCompose } from './compose';
import { importFetchedAccounts } from './importer';
export const STORE_HYDRATE = 'STORE_HYDRATE';
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY';
@@ -18,5 +19,6 @@ export function hydrateStore(rawState) {
});
dispatch(hydrateCompose());
dispatch(importFetchedAccounts(Object.values(rawState.accounts)));
};
};

View File

@@ -2,11 +2,10 @@ import { connectStream } from '../stream';
import {
updateTimeline,
deleteFromTimelines,
refreshHomeTimeline,
connectTimeline,
expandHomeTimeline,
disconnectTimeline,
} from './timelines';
import { updateNotifications, refreshNotifications } from './notifications';
import { updateNotifications, expandNotifications } from './notifications';
import { getLocale } from '../locales';
const { messages } = getLocale();
@@ -16,10 +15,6 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
return connectStream (path, pollingRefresh, (dispatch, getState) => {
const locale = getState().getIn(['meta', 'locale']);
return {
onConnect() {
dispatch(connectTimeline(timelineId));
},
onDisconnect() {
dispatch(disconnectTimeline(timelineId));
},
@@ -41,14 +36,14 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
});
}
function refreshHomeTimelineAndNotification (dispatch) {
dispatch(refreshHomeTimeline());
dispatch(refreshNotifications());
}
const refreshHomeTimelineAndNotification = (dispatch, done) => {
dispatch(expandHomeTimeline({}, () => dispatch(expandNotifications({}, done))));
};
export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
export const connectCommunityStream = () => connectTimelineStream('community', 'public:local');
export const connectMediaStream = () => connectTimelineStream('community', 'public:local');
export const connectPublicStream = () => connectTimelineStream('public', 'public');
export const connectHashtagStream = (tag) => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
export const connectListStream = (id) => connectTimelineStream(`list:${id}`, `list&list=${id}`);

Some files were not shown because too many files have changed in this diff Show More