about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2020-04-06 21:44:34 +0200
committerGitHub <noreply@github.com>2020-04-06 21:44:34 +0200
commitc47be5bd864a1f5244f35122ba7fae31a149c73d (patch)
treec8e9e95a36ffb2346e3168d00364e4b614bee92a /app
parent6e426267a762f3cd1efa2c5fb120a13543567775 (diff)
parent9101254d0a70bc6f899c093f33300cffceb7c8ac (diff)
Merge pull request #1312 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/reports_controller.rb2
-rw-r--r--app/javascript/core/public.js14
-rw-r--r--app/javascript/flavours/glitch/packs/public.js22
-rw-r--r--app/javascript/mastodon/locales/eu.json18
-rw-r--r--app/javascript/mastodon/locales/fi.json40
-rw-r--r--app/javascript/mastodon/locales/fr.json4
-rw-r--r--app/javascript/mastodon/locales/gl.json10
-rw-r--r--app/javascript/mastodon/locales/hu.json2
-rw-r--r--app/javascript/mastodon/locales/pt-PT.json16
-rw-r--r--app/javascript/mastodon/locales/sk.json12
-rw-r--r--app/javascript/mastodon/locales/th.json14
-rw-r--r--app/javascript/packs/public.js22
-rw-r--r--app/lib/entity_cache.rb4
-rw-r--r--app/lib/rate_limiter.rb6
-rw-r--r--app/models/announcement.rb9
-rw-r--r--app/models/report.rb3
-rw-r--r--app/models/status.rb2
-rw-r--r--app/workers/publish_scheduled_announcement_worker.rb15
18 files changed, 135 insertions, 80 deletions
diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb
index 66c40f6f4..e10083d45 100644
--- a/app/controllers/api/v1/reports_controller.rb
+++ b/app/controllers/api/v1/reports_controller.rb
@@ -4,6 +4,8 @@ class Api::V1::ReportsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
   before_action :require_user!
 
+  override_rate_limit_headers :create, family: :reports
+
   def create
     @report = ReportService.new.call(
       current_account,
diff --git a/app/javascript/core/public.js b/app/javascript/core/public.js
index 344c05181..39f198fe7 100644
--- a/app/javascript/core/public.js
+++ b/app/javascript/core/public.js
@@ -14,20 +14,6 @@ delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
   return false;
 });
 
-delegate(document, '.status__content__spoiler-link', 'click', function() {
-  const contentEl = this.parentNode.parentNode.querySelector('.e-content');
-
-  if (contentEl.style.display === 'block') {
-    contentEl.style.display = 'none';
-    this.parentNode.style.marginBottom = 0;
-  } else {
-    contentEl.style.display = 'block';
-    this.parentNode.style.marginBottom = null;
-  }
-
-  return false;
-});
-
 delegate(document, '.modal-button', 'click', e => {
   e.preventDefault();
 
diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js
index 066479fa6..e5a567205 100644
--- a/app/javascript/flavours/glitch/packs/public.js
+++ b/app/javascript/flavours/glitch/packs/public.js
@@ -97,6 +97,28 @@ function main() {
 
     delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
     delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
+
+    delegate(document, '.status__content__spoiler-link', 'click', function() {
+      const contentEl = this.parentNode.parentNode.querySelector('.e-content');
+
+      if (contentEl.style.display === 'block') {
+        contentEl.style.display = 'none';
+        this.parentNode.style.marginBottom = 0;
+        this.textContent = (new IntlMessageFormat(messages['status.show_more'] || 'Show more', locale)).format();
+      } else {
+        contentEl.style.display = 'block';
+        this.parentNode.style.marginBottom = null;
+        this.textContent = (new IntlMessageFormat(messages['status.show_less'] || 'Show less', locale)).format();
+      }
+
+      return false;
+    });
+
+    [].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => {
+      const contentEl = spoilerLink.parentNode.parentNode.querySelector('.e-content');
+      const message = (contentEl.style.display === 'block') ? (messages['status.show_less'] || 'Show less') : (messages['status.show_more'] || 'Show more');
+      spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();
+    });
   });
 
   delegate(document, '.sidebar__toggle__icon', 'click', () => {
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 5dc4e60c2..3a44dceb5 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -27,8 +27,8 @@
   "account.mute_notifications": "Mututu @{name}(r)en jakinarazpenak",
   "account.muted": "Mutututa",
   "account.never_active": "Inoiz ez",
-  "account.posts": "Tootak",
-  "account.posts_with_replies": "Toot-ak eta erantzunak",
+  "account.posts": "Toot",
+  "account.posts_with_replies": "Tootak eta erantzunak",
   "account.report": "Salatu @{name}",
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
   "account.share": "@{name}(e)ren profila elkarbanatu",
@@ -64,7 +64,7 @@
   "column.lists": "Zerrendak",
   "column.mutes": "Mutututako erabiltzaileak",
   "column.notifications": "Jakinarazpenak",
-  "column.pins": "Finkatutako toot-ak",
+  "column.pins": "Finkatutako tootak",
   "column.public": "Federatutako denbora-lerroa",
   "column_back_button.label": "Atzera",
   "column_header.hide_settings": "Ezkutatu ezarpenak",
@@ -140,7 +140,7 @@
   "emoji_button.search_results": "Bilaketaren emaitzak",
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
-  "empty_column.account_timeline": "Ez dago toot-ik hemen!",
+  "empty_column.account_timeline": "Ez dago tootik hemen!",
   "empty_column.account_unavailable": "Profila ez dago eskuragarri",
   "empty_column.blocks": "Ez duzu erabiltzailerik blokeatu oraindik.",
   "empty_column.bookmarked_statuses": "Oraindik ez dituzu toot laster-markatutarik. Bat laster-markatzerakoan, hemen agertuko da.",
@@ -228,7 +228,7 @@
   "keyboard_shortcuts.my_profile": "zure profila irekitzeko",
   "keyboard_shortcuts.notifications": "jakinarazpenen zutabea irekitzeko",
   "keyboard_shortcuts.open_media": "media zabaltzeko",
-  "keyboard_shortcuts.pinned": "finkatutako toot-en zerrenda irekitzeko",
+  "keyboard_shortcuts.pinned": "finkatutako tooten zerrenda irekitzeko",
   "keyboard_shortcuts.profile": "egilearen profila irekitzeko",
   "keyboard_shortcuts.reply": "erantzutea",
   "keyboard_shortcuts.requests": "jarraitzeko eskarien zerrenda irekitzeko",
@@ -277,7 +277,7 @@
   "navigation_bar.logout": "Amaitu saioa",
   "navigation_bar.mutes": "Mutututako erabiltzaileak",
   "navigation_bar.personal": "Pertsonala",
-  "navigation_bar.pins": "Finkatutako toot-ak",
+  "navigation_bar.pins": "Finkatutako tootak",
   "navigation_bar.preferences": "Hobespenak",
   "navigation_bar.public_timeline": "Federatutako denbora-lerroa",
   "navigation_bar.security": "Segurtasuna",
@@ -352,8 +352,8 @@
   "search_popout.tips.user": "erabiltzailea",
   "search_results.accounts": "Jendea",
   "search_results.hashtags": "Traolak",
-  "search_results.statuses": "Toot-ak",
-  "search_results.statuses_fts_disabled": "Mastodon zerbitzari honek ez du Toot-en edukiaren bilaketa gaitu.",
+  "search_results.statuses": "Tootak",
+  "search_results.statuses_fts_disabled": "Mastodon zerbitzari honek ez du tooten edukiaren bilaketa gaitu.",
   "search_results.total": "{count, number} {count, plural, one {emaitza} other {emaitza}}",
   "status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea",
   "status.admin_status": "Ireki mezu hau moderazio interfazean",
@@ -376,7 +376,7 @@
   "status.mute_conversation": "Mututu elkarrizketa",
   "status.open": "Hedatu mezu hau",
   "status.pin": "Finkatu profilean",
-  "status.pinned": "Finkatutako toot-a",
+  "status.pinned": "Finkatutako toota",
   "status.read_more": "Irakurri gehiago",
   "status.reblog": "Bultzada",
   "status.reblog_private": "Bultzada jatorrizko hartzaileei",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index b46083477..32bc8de49 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,7 +1,7 @@
 {
   "account.add_or_remove_from_list": "Lisää tai poista listoilta",
   "account.badges.bot": "Botti",
-  "account.badges.group": "Group",
+  "account.badges.group": "Ryhmä",
   "account.block": "Estä @{name}",
   "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
   "account.blocked": "Estetty",
@@ -34,7 +34,7 @@
   "account.share": "Jaa käyttäjän @{name} profiili",
   "account.show_reblogs": "Näytä buustaukset käyttäjältä @{name}",
   "account.unblock": "Salli @{name}",
-  "account.unblock_domain": "Näytä {domain}",
+  "account.unblock_domain": "Salli {domain}",
   "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lakkaa seuraamasta",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
@@ -43,7 +43,7 @@
   "alert.rate_limited.title": "Määrää rajoitettu",
   "alert.unexpected.message": "Tapahtui odottamaton virhe.",
   "alert.unexpected.title": "Hups!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "Ilmoitus",
   "autosuggest_hashtag.per_week": "{count} viikossa",
   "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}",
   "bundle_column_error.body": "Jokin meni vikaan komponenttia ladattaessa.",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "Äänestyksen kesto",
   "compose_form.poll.option_placeholder": "Valinta numero",
   "compose_form.poll.remove_option": "Poista tämä valinta",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "Muuta kysely monivalinnaksi",
+  "compose_form.poll.switch_to_single": "Muuta kysely sallimaan vain yksi valinta",
   "compose_form.publish": "Tuuttaa",
   "compose_form.publish_loud": "Julkista!",
   "compose_form.sensitive.hide": "Valitse tämä arkaluontoisena",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "Ei ole 'toots' täällä!",
   "empty_column.account_unavailable": "Profiilia ei löydy",
   "empty_column.blocks": "Et ole vielä estänyt yhtään käyttäjää.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Et ole vielä lisännyt tuuttauksia kirjanmerkkeihisi. Kun teet niin, tuuttaus näkyy tässä.",
   "empty_column.community": "Paikallinen aikajana on tyhjä. Homma lähtee käyntiin, kun kirjoitat jotain julkista!",
   "empty_column.direct": "Sinulla ei ole vielä yhtään viestiä yksittäiselle käyttäjälle. Kun lähetät tai vastaanotat sellaisen, se näkyy täällä.",
   "empty_column.domain_blocks": "Yhtään verkko-osoitetta ei ole vielä piilotettu.",
@@ -160,7 +160,7 @@
   "empty_column.public": "Täällä ei ole mitään! Saat sisältöä, kun kirjoitat jotain julkisesti tai käyt seuraamassa muiden instanssien käyttäjiä",
   "error.unexpected_crash.explanation": "Sivua ei voi näyttää oikein, johtuen bugista tai ongelmasta selaimen yhteensopivuudessa.",
   "error.unexpected_crash.next_steps": "Kokeile päivittää sivu. Jos tämä ei auta, saatat yhä pystyä käyttämään Mastodonia toisen selaimen tai sovelluksen kautta.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "errors.unexpected_crash.copy_stacktrace": "Kopioi stacktrace leikepöydälle",
   "errors.unexpected_crash.report_issue": "Ilmoita ongelmasta",
   "follow_request.authorize": "Valtuuta",
   "follow_request.reject": "Hylkää",
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "Perusasetukset",
   "home.column_settings.show_reblogs": "Näytä buustaukset",
   "home.column_settings.show_replies": "Näytä vastaukset",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "Piilota ilmoitukset",
+  "home.show_announcements": "Näytä ilmoitukset",
   "intervals.full.days": "Päivä päiviä",
   "intervals.full.hours": "Tunti tunteja",
   "intervals.full.minutes": "Minuuti minuuteja",
@@ -215,7 +215,7 @@
   "keyboard_shortcuts.direct": "avaa pikaviestisarake",
   "keyboard_shortcuts.down": "siirry listassa alaspäin",
   "keyboard_shortcuts.enter": "avaa tilapäivitys",
-  "keyboard_shortcuts.favourite": "tykkää",
+  "keyboard_shortcuts.favourite": "lisää suosikkeihin",
   "keyboard_shortcuts.favourites": "avaa lista suosikeista",
   "keyboard_shortcuts.federated": "avaa yleinen aikajana",
   "keyboard_shortcuts.heading": "Näppäinkomennot",
@@ -227,7 +227,7 @@
   "keyboard_shortcuts.muted": "avaa lista mykistetyistä käyttäjistä",
   "keyboard_shortcuts.my_profile": "avaa profiilisi",
   "keyboard_shortcuts.notifications": "avaa ilmoitukset-sarake",
-  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.open_media": "median avaus",
   "keyboard_shortcuts.pinned": "avaa lista kiinnitetyistä tuuttauksista",
   "keyboard_shortcuts.profile": "avaa kirjoittajan profiili",
   "keyboard_shortcuts.reply": "vastaa",
@@ -260,7 +260,7 @@
   "mute_modal.hide_notifications": "Piilota tältä käyttäjältä tulevat ilmoitukset?",
   "navigation_bar.apps": "Mobiilisovellukset",
   "navigation_bar.blocks": "Estetyt käyttäjät",
-  "navigation_bar.bookmarks": "Bookmarks",
+  "navigation_bar.bookmarks": "Kirjanmerkit",
   "navigation_bar.community_timeline": "Paikallinen aikajana",
   "navigation_bar.compose": "Kirjoita uusi tuuttaus",
   "navigation_bar.direct": "Viestit",
@@ -283,9 +283,9 @@
   "navigation_bar.security": "Tunnukset",
   "notification.favourite": "{name} tykkäsi tilastasi",
   "notification.follow": "{name} seurasi sinua",
-  "notification.follow_request": "{name} has requested to follow you",
+  "notification.follow_request": "{name} haluaa seurata sinua",
   "notification.mention": "{name} mainitsi sinut",
-  "notification.own_poll": "Your poll has ended",
+  "notification.own_poll": "Kyselysi on päättynyt",
   "notification.poll": "Kysely, johon osallistuit, on päättynyt",
   "notification.reblog": "{name} buustasi tilaasi",
   "notifications.clear": "Tyhjennä ilmoitukset",
@@ -296,7 +296,7 @@
   "notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki",
   "notifications.column_settings.filter_bar.show": "Näytä",
   "notifications.column_settings.follow": "Uudet seuraajat:",
-  "notifications.column_settings.follow_request": "New follow requests:",
+  "notifications.column_settings.follow_request": "Uudet seuraamispyynnöt:",
   "notifications.column_settings.mention": "Maininnat:",
   "notifications.column_settings.poll": "Kyselyn tulokset:",
   "notifications.column_settings.push": "Push-ilmoitukset",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "nyt",
   "relative_time.minutes": "{number} m",
   "relative_time.seconds": "{number} s",
-  "relative_time.today": "today",
+  "relative_time.today": "tänään",
   "reply_indicator.cancel": "Peruuta",
   "report.forward": "Välitä kohteeseen {target}",
   "report.forward_hint": "Tämä tili on toisella palvelimella. Haluatko lähettää nimettömän raportin myös sinne?",
@@ -358,7 +358,7 @@
   "status.admin_account": "Avaa moderaattorinäkymä tilistä @{name}",
   "status.admin_status": "Avaa tilapäivitys moderaattorinäkymässä",
   "status.block": "Estä @{name}",
-  "status.bookmark": "Bookmark",
+  "status.bookmark": "Tallenna kirjanmerkki",
   "status.cancel_reblog_private": "Peru buustaus",
   "status.cannot_reblog": "Tätä julkaisua ei voi buustata",
   "status.copy": "Kopioi linkki tilapäivitykseen",
@@ -383,7 +383,7 @@
   "status.reblogged_by": "{name} buustasi",
   "status.reblogs.empty": "Kukaan ei ole vielä buustannut tätä tuuttausta. Kun joku tekee niin, näkyy kyseinen henkilö tässä.",
   "status.redraft": "Poista & palauta muokattavaksi",
-  "status.remove_bookmark": "Remove bookmark",
+  "status.remove_bookmark": "Poista kirjanmerkki",
   "status.reply": "Vastaa",
   "status.replyAll": "Vastaa ketjuun",
   "status.report": "Raportoi @{name}",
@@ -416,11 +416,11 @@
   "upload_button.label": "Lisää mediaa",
   "upload_error.limit": "Tiedostolatauksien raja ylitetty.",
   "upload_error.poll": "Tiedon lataaminen ei ole sallittua kyselyissä.",
-  "upload_form.audio_description": "Describe for people with hearing loss",
+  "upload_form.audio_description": "Kuvaile kuulovammaisille",
   "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
   "upload_form.edit": "Muokkaa",
   "upload_form.undo": "Peru",
-  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_form.video_description": "Kuvaile kuulo- tai näkövammaisille",
   "upload_modal.analyzing_picture": "Analysoidaan kuvaa…",
   "upload_modal.apply": "Käytä",
   "upload_modal.description_placeholder": "Eräänä jäätävänä ja pimeänä yönä gorilla ratkaisi sudokun kahdessa minuutissa",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index c2f01b0af..cf07cd3db 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -3,11 +3,11 @@
   "account.badges.bot": "Robot",
   "account.badges.group": "Groupe",
   "account.block": "Bloquer @{name}",
-  "account.block_domain": "Tout masquer venant de {domain}",
+  "account.block_domain": "Bloquer le domaine {domain}",
   "account.blocked": "Bloqué·e",
   "account.cancel_follow_request": "Annuler la demande de suivi",
   "account.direct": "Envoyer un message direct à @{name}",
-  "account.domain_blocked": "Domaine caché",
+  "account.domain_blocked": "Domaine bloqué",
   "account.edit_profile": "Modifier le profil",
   "account.endorse": "Recommander sur le profil",
   "account.follow": "Suivre",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index c11309ea9..f26b39c21 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -128,7 +128,7 @@
   "embed.preview": "Así será mostrado:",
   "emoji_button.activity": "Actividade",
   "emoji_button.custom": "Personalizado",
-  "emoji_button.flags": "Bandeiras",
+  "emoji_button.flags": "Marcas",
   "emoji_button.food": "Comida e Bebida",
   "emoji_button.label": "Inserir emoticona",
   "emoji_button.nature": "Natureza",
@@ -270,7 +270,7 @@
   "navigation_bar.favourites": "Favoritos",
   "navigation_bar.filters": "Palabras silenciadas",
   "navigation_bar.follow_requests": "Peticións de seguimento",
-  "navigation_bar.follows_and_followers": "Seguindo e seguidores",
+  "navigation_bar.follows_and_followers": "Seguindo e seguidoras",
   "navigation_bar.info": "Sobre este servidor",
   "navigation_bar.keyboard_shortcuts": "Atallos do teclado",
   "navigation_bar.lists": "Listaxes",
@@ -321,7 +321,7 @@
   "privacy.change": "Axustar privacidade",
   "privacy.direct.long": "Só para as usuarias mencionadas",
   "privacy.direct.short": "Directo",
-  "privacy.private.long": "Só para os seguidores",
+  "privacy.private.long": "Só para os seguidoras",
   "privacy.private.short": "Só para seguidoras",
   "privacy.public.long": "Publicar nas cronoloxías públicas",
   "privacy.public.short": "Público",
@@ -365,7 +365,7 @@
   "status.delete": "Eliminar",
   "status.detailed_status": "Vista detallada da conversa",
   "status.direct": "Mensaxe directa a @{name}",
-  "status.embed": "Embeber nunha web",
+  "status.embed": "Incrustar",
   "status.favourite": "Favorito",
   "status.filtered": "Filtrado",
   "status.load_more": "Cargar máis",
@@ -411,7 +411,7 @@
   "time_remaining.seconds": "{number, plural, one {# segundo} other {# segundos}} restantes",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {persoa} other {persoas}} falando",
   "trends.trending_now": "Tendencias actuais",
-  "ui.beforeunload": "O borrador perderase se saes do Mastodon.",
+  "ui.beforeunload": "O borrador perderase se saes de Mastodon.",
   "upload_area.title": "Arrastra e solta para subir",
   "upload_button.label": "Engadir multimedia ({formats})",
   "upload_error.limit": "Límite máximo do ficheiro a subir excedido.",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index b25369326..d2d851436 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -130,7 +130,7 @@
   "emoji_button.custom": "Egyéni",
   "emoji_button.flags": "Zászlók",
   "emoji_button.food": "Étel és Ital",
-  "emoji_button.label": "Emoji beszúrása",
+  "emoji_button.label": "Emodzsi beszúrása",
   "emoji_button.nature": "Természet",
   "emoji_button.not_found": "Nincsenek emodzsik!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Tárgyak",
diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json
index 03bc363ae..b8902d65e 100644
--- a/app/javascript/mastodon/locales/pt-PT.json
+++ b/app/javascript/mastodon/locales/pt-PT.json
@@ -17,9 +17,9 @@
   "account.follows.empty": "Este utilizador ainda não segue alguém.",
   "account.follows_you": "É teu seguidor",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
-  "account.last_status": "Última actividade",
+  "account.last_status": "Última atividade",
   "account.link_verified_on": "A posse deste link foi verificada em {date}",
-  "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente que a pode seguir.",
+  "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente quem a pode seguir.",
   "account.media": "Média",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} mudou a sua conta para:",
@@ -124,7 +124,7 @@
   "directory.local": "Apenas de {domain}",
   "directory.new_arrivals": "Recém chegados",
   "directory.recently_active": "Com actividade recente",
-  "embed.instructions": "Publica esta publicação no teu site copiando o código abaixo.",
+  "embed.instructions": "Incorpora esta publicação no teu site copiando o código abaixo.",
   "embed.preview": "Podes ver aqui como irá ficar:",
   "emoji_button.activity": "Actividade",
   "emoji_button.custom": "Personalizar",
@@ -214,7 +214,7 @@
   "keyboard_shortcuts.description": "Descrição",
   "keyboard_shortcuts.direct": "para abrir a coluna das mensagens directas",
   "keyboard_shortcuts.down": "para mover para baixo na lista",
-  "keyboard_shortcuts.enter": "para expandir um estado",
+  "keyboard_shortcuts.enter": "para expandir uma publicação",
   "keyboard_shortcuts.favourite": "para adicionar aos favoritos",
   "keyboard_shortcuts.favourites": "para abrir a lista dos favoritos",
   "keyboard_shortcuts.federated": "para abrir a cronologia federada",
@@ -281,13 +281,13 @@
   "navigation_bar.preferences": "Preferências",
   "navigation_bar.public_timeline": "Cronologia federada",
   "navigation_bar.security": "Segurança",
-  "notification.favourite": "{name} adicionou o teu estado aos favoritos",
+  "notification.favourite": "{name} adicionou a tua publicação aos favoritos",
   "notification.follow": "{name} começou a seguir-te",
   "notification.follow_request": "{name} pediu para segui-lo",
   "notification.mention": "{name} mencionou-te",
   "notification.own_poll": "A sua votação terminou",
   "notification.poll": "Uma votação em participaste chegou ao fim",
-  "notification.reblog": "{name} fez boost ao teu o teu estado",
+  "notification.reblog": "{name} partilhou a tua publicação",
   "notifications.clear": "Limpar notificações",
   "notifications.clear_confirmation": "Queres mesmo limpar todas as notificações?",
   "notifications.column_settings.alert": "Notificações no computador",
@@ -318,7 +318,7 @@
   "poll.voted": "Você votou nesta resposta",
   "poll_button.add_poll": "Adicionar votação",
   "poll_button.remove_poll": "Remover votação",
-  "privacy.change": "Ajustar a privacidade da mensagem",
+  "privacy.change": "Ajustar a privacidade da publicação",
   "privacy.direct.long": "Apenas para utilizadores mencionados",
   "privacy.direct.short": "Directo",
   "privacy.private.long": "Apenas para os seguidores",
@@ -347,7 +347,7 @@
   "search_popout.search_format": "Formato avançado de pesquisa",
   "search_popout.tips.full_text": "Texto simples devolve publicações que tu escreveste, marcaste como favorita, partilhaste ou em que foste mencionado, tal como nomes de utilizador correspondentes, alcunhas e hashtags.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "estado",
+  "search_popout.tips.status": "publicação",
   "search_popout.tips.text": "O texto simples retorna a correspondência de nomes, utilizadores e hashtags",
   "search_popout.tips.user": "utilizador",
   "search_results.accounts": "Pessoas",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index ad4407e9d..819496911 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -10,12 +10,12 @@
   "account.domain_blocked": "Doména ukrytá",
   "account.edit_profile": "Uprav profil",
   "account.endorse": "Zobrazuj na profile",
-  "account.follow": "Následuj",
+  "account.follow": "Nasleduj",
   "account.followers": "Sledujúci",
-  "account.followers.empty": "Tohto užívateľa ešte nikto nenásleduje.",
-  "account.follows": "Následuje",
-  "account.follows.empty": "Tento užívateľ ešte nikoho nenásleduje.",
-  "account.follows_you": "Následuje ťa",
+  "account.followers.empty": "Tohto používateľa ešte nikto nenásleduje.",
+  "account.follows": "Nasleduje",
+  "account.follows.empty": "Tento používateľ ešte nikoho nenasleduje.",
+  "account.follows_you": "Nasleduje ťa",
   "account.hide_reblogs": "Skry vyzdvihnutia od @{name}",
   "account.last_status": "Naposledy aktívny",
   "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}",
@@ -193,7 +193,7 @@
   "introduction.federation.federated.headline": "Federovaná",
   "introduction.federation.federated.text": "Verejné príspevky z ostatných serverov vo fediverse budú zobrazené vo federovanej časovej osi.",
   "introduction.federation.home.headline": "Domovská",
-  "introduction.federation.home.text": "Príspevky od ľudí ktorých následuješ sa zobrazia na tvojej domovskej nástenke. Môžeš následovať hocikoho na ktoromkoľvek serveri!",
+  "introduction.federation.home.text": "Príspevky od ľudí ktorých nasleduješ sa zobrazia na tvojej domovskej nástenke. Môžeš nasledovať hocikoho na ktoromkoľvek serveri!",
   "introduction.federation.local.headline": "Miestna",
   "introduction.federation.local.text": "Verejné príspevky od ľudí v rámci toho istého serveru na akom si aj ty, budú zobrazované na miestnej časovej osi.",
   "introduction.interactions.action": "Ukonči návod!",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index f66be365f..479d0ab31 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -54,7 +54,7 @@
   "bundle_modal_error.retry": "ลองอีกครั้ง",
   "column.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
   "column.bookmarks": "ที่คั่นหน้า",
-  "column.community": "เส้นเวลาในเว็บ",
+  "column.community": "เส้นเวลาในเซิร์ฟเวอร์",
   "column.direct": "ข้อความโดยตรง",
   "column.directory": "เรียกดูโปรไฟล์",
   "column.domain_blocks": "โดเมนที่ปิดกั้นอยู่",
@@ -144,7 +144,7 @@
   "empty_column.account_unavailable": "ไม่มีโปรไฟล์",
   "empty_column.blocks": "คุณยังไม่ได้ปิดกั้นผู้ใช้ใด ๆ",
   "empty_column.bookmarked_statuses": "คุณยังไม่มีโพสต์ที่เพิ่มที่คั่นหน้าไว้ใด ๆ เมื่อคุณเพิ่มที่คั่นหน้าโพสต์ โพสต์จะปรากฏที่นี่",
-  "empty_column.community": "เส้นเวลาในเว็บว่างเปล่า เขียนบางอย่างเป็นสาธารณะเพื่อเริ่มต้น!",
+  "empty_column.community": "เส้นเวลาในเซิร์ฟเวอร์ว่างเปล่า เขียนบางอย่างเป็นสาธารณะเพื่อเริ่มต้น!",
   "empty_column.direct": "คุณยังไม่มีข้อความโดยตรงใด ๆ เมื่อคุณส่งหรือรับข้อความ ข้อความจะปรากฏที่นี่",
   "empty_column.domain_blocks": "ยังไม่มีโดเมนที่ปิดกั้นอยู่",
   "empty_column.favourited_statuses": "คุณยังไม่มีโพสต์ที่ชื่นชอบใด ๆ เมื่อคุณชื่นชอบโพสต์ โพสต์จะปรากฏที่นี่",
@@ -194,8 +194,8 @@
   "introduction.federation.federated.text": "โพสต์สาธารณะจากเซิร์ฟเวอร์อื่น ๆ ของเฟดิเวิร์สจะปรากฏในเส้นเวลาที่ติดต่อกับภายนอก",
   "introduction.federation.home.headline": "หน้าแรก",
   "introduction.federation.home.text": "โพสต์จากผู้คนที่คุณติดตามจะปรากฏในฟีดหน้าแรกของคุณ คุณสามารถติดตามใครก็ตามในเซิร์ฟเวอร์ใดก็ตาม!",
-  "introduction.federation.local.headline": "ในเว็บ",
-  "introduction.federation.local.text": "โพสต์สาธารณะจากผู้คนในเซิร์ฟเวอร์เดียวกันกับคุณจะปรากฏในเส้นเวลาในเว็บ",
+  "introduction.federation.local.headline": "ในเซิร์ฟเวอร์",
+  "introduction.federation.local.text": "โพสต์สาธารณะจากผู้คนในเซิร์ฟเวอร์เดียวกันกับคุณจะปรากฏในเส้นเวลาในเซิร์ฟเวอร์",
   "introduction.interactions.action": "เสร็จสิ้นบทช่วยสอน!",
   "introduction.interactions.favourite.headline": "ชื่นชอบ",
   "introduction.interactions.favourite.text": "คุณสามารถบันทึกโพสต์ไว้ในภายหลังและแจ้งให้ผู้สร้างทราบว่าคุณชอบโพสต์โดยการชื่นชอบโพสต์",
@@ -222,7 +222,7 @@
   "keyboard_shortcuts.home": "เพื่อเปิดเส้นเวลาหน้าแรก",
   "keyboard_shortcuts.hotkey": "ปุ่มลัด",
   "keyboard_shortcuts.legend": "เพื่อแสดงคำอธิบายนี้",
-  "keyboard_shortcuts.local": "เพื่อเปิดเส้นเวลาในเว็บ",
+  "keyboard_shortcuts.local": "เพื่อเปิดเส้นเวลาในเซิร์ฟเวอร์",
   "keyboard_shortcuts.mention": "เพื่อกล่าวถึงผู้สร้าง",
   "keyboard_shortcuts.muted": "เพื่อเปิดรายการผู้ใช้ที่ปิดเสียงอยู่",
   "keyboard_shortcuts.my_profile": "เพื่อเปิดโปรไฟล์ของคุณ",
@@ -261,7 +261,7 @@
   "navigation_bar.apps": "แอปมือถือ",
   "navigation_bar.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
   "navigation_bar.bookmarks": "ที่คั่นหน้า",
-  "navigation_bar.community_timeline": "เส้นเวลาในเว็บ",
+  "navigation_bar.community_timeline": "เส้นเวลาในเซิร์ฟเวอร์",
   "navigation_bar.compose": "เขียนโพสต์ใหม่",
   "navigation_bar.direct": "ข้อความโดยตรง",
   "navigation_bar.discover": "ค้นพบ",
@@ -401,7 +401,7 @@
   "suggestions.header": "คุณอาจสนใจ…",
   "tabs_bar.federated_timeline": "ที่ติดต่อกับภายนอก",
   "tabs_bar.home": "หน้าแรก",
-  "tabs_bar.local_timeline": "ในเว็บ",
+  "tabs_bar.local_timeline": "ในเซิร์ฟเวอร์",
   "tabs_bar.notifications": "การแจ้งเตือน",
   "tabs_bar.search": "ค้นหา",
   "time_remaining.days": "เหลืออีก {number, plural, other {# วัน}}",
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index dc85164d0..5b699e767 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -101,6 +101,28 @@ function main() {
 
     delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
     delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
+
+    delegate(document, '.status__content__spoiler-link', 'click', function() {
+      const contentEl = this.parentNode.parentNode.querySelector('.e-content');
+
+      if (contentEl.style.display === 'block') {
+        contentEl.style.display = 'none';
+        this.parentNode.style.marginBottom = 0;
+        this.textContent = (new IntlMessageFormat(messages['status.show_more'] || 'Show more', locale)).format();
+      } else {
+        contentEl.style.display = 'block';
+        this.parentNode.style.marginBottom = null;
+        this.textContent = (new IntlMessageFormat(messages['status.show_less'] || 'Show less', locale)).format();
+      }
+
+      return false;
+    });
+
+    [].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => {
+      const contentEl = spoilerLink.parentNode.parentNode.querySelector('.e-content');
+      const message = (contentEl.style.display === 'block') ? (messages['status.show_less'] || 'Show less') : (messages['status.show_more'] || 'Show more');
+      spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();
+    });
   });
 
   delegate(document, '.sidebar__toggle__icon', 'click', () => {
diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb
index 35a3773d2..afdbd70f2 100644
--- a/app/lib/entity_cache.rb
+++ b/app/lib/entity_cache.rb
@@ -7,6 +7,10 @@ class EntityCache
 
   MAX_EXPIRATION = 7.days.freeze
 
+  def status(url)
+    Rails.cache.fetch(to_key(:status, url), expires_in: MAX_EXPIRATION) { FetchRemoteStatusService.new.call(url) }
+  end
+
   def mention(username, domain)
     Rails.cache.fetch(to_key(:mention, username, domain), expires_in: MAX_EXPIRATION) { Account.select(:id, :username, :domain, :url).find_remote(username, domain) }
   end
diff --git a/app/lib/rate_limiter.rb b/app/lib/rate_limiter.rb
index 68dae9add..0e2c9a894 100644
--- a/app/lib/rate_limiter.rb
+++ b/app/lib/rate_limiter.rb
@@ -14,9 +14,9 @@ class RateLimiter
       period: 3.hours.freeze,
     }.freeze,
 
-    media: {
-      limit: 30,
-      period: 30.minutes.freeze,
+    reports: {
+      limit: 400,
+      period: 24.hours.freeze,
     }.freeze,
   }.freeze
 
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index f8ac4e09d..a4e427b49 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -14,6 +14,7 @@
 #  created_at   :datetime         not null
 #  updated_at   :datetime         not null
 #  published_at :datetime
+#  status_ids   :bigint           is an Array
 #
 
 class Announcement < ApplicationRecord
@@ -49,7 +50,13 @@ class Announcement < ApplicationRecord
   end
 
   def statuses
-    @statuses ||= Status.from_text(text)
+    @statuses ||= begin
+      if status_ids.nil?
+        []
+      else
+        Status.where(id: status_ids, visibility: [:public, :unlisted])
+      end
+    end
   end
 
   def tags
diff --git a/app/models/report.rb b/app/models/report.rb
index 356c23d68..f31bcfd2e 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -18,6 +18,9 @@
 
 class Report < ApplicationRecord
   include Paginable
+  include RateLimitable
+
+  rate_limit by: :account, family: :reports
 
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
diff --git a/app/models/status.rb b/app/models/status.rb
index a78717d0c..31e77770d 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -429,7 +429,7 @@ class Status < ApplicationRecord
           if TagManager.instance.local_url?(url)
             ActivityPub::TagManager.instance.uri_to_resource(url, Status)
           else
-            Status.find_by(uri: url) || Status.find_by(url: url)
+            EntityCache.instance.status(url)
           end
         end
         status&.distributable? ? status : nil
diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb
index efca39d3d..1392efed0 100644
--- a/app/workers/publish_scheduled_announcement_worker.rb
+++ b/app/workers/publish_scheduled_announcement_worker.rb
@@ -5,15 +5,24 @@ class PublishScheduledAnnouncementWorker
   include Redisable
 
   def perform(announcement_id)
-    announcement = Announcement.find(announcement_id)
+    @announcement = Announcement.find(announcement_id)
 
-    announcement.publish! unless announcement.published?
+    refresh_status_ids!
 
-    payload = InlineRenderer.render(announcement, nil, :announcement)
+    @announcement.publish! unless @announcement.published?
+
+    payload = InlineRenderer.render(@announcement, nil, :announcement)
     payload = Oj.dump(event: :announcement, payload: payload)
 
     FeedManager.instance.with_active_accounts do |account|
       redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}")
     end
   end
+
+  private
+
+  def refresh_status_ids!
+    @announcement.status_ids = Status.from_text(@announcement.text).map(&:id)
+    @announcement.save
+  end
 end