about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb16
-rw-r--r--app/controllers/media_proxy_controller.rb2
-rw-r--r--app/javascript/mastodon/features/compose/containers/warning_container.js2
-rw-r--r--app/javascript/mastodon/locales/ar.json4
-rw-r--r--app/javascript/mastodon/locales/ca.json2
-rw-r--r--app/javascript/mastodon/locales/en.json2
-rw-r--r--app/javascript/mastodon/locales/eo.json6
-rw-r--r--app/javascript/mastodon/locales/fr.json14
-rw-r--r--app/javascript/mastodon/locales/gl.json2
-rw-r--r--app/javascript/mastodon/locales/it.json242
-rw-r--r--app/javascript/mastodon/locales/ja.json2
-rw-r--r--app/javascript/mastodon/locales/ko.json2
-rw-r--r--app/javascript/mastodon/locales/nl.json2
-rw-r--r--app/javascript/mastodon/locales/oc.json14
-rw-r--r--app/javascript/mastodon/locales/pl.json2
-rw-r--r--app/javascript/mastodon/locales/ru.json40
-rw-r--r--app/javascript/mastodon/locales/sk.json2
-rw-r--r--app/javascript/mastodon/locales/sl.json330
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json16
-rw-r--r--app/javascript/mastodon/service_worker/entry.js30
-rw-r--r--app/javascript/mastodon/storage/modifier.js3
-rw-r--r--app/javascript/mastodon/utils/resize_image.js41
-rw-r--r--app/lib/activitypub/activity/create.rb2
-rw-r--r--app/lib/ostatus/activity/creation.rb2
-rw-r--r--app/services/activitypub/process_account_service.rb4
-rw-r--r--app/services/fetch_link_card_service.rb2
-rw-r--r--app/services/resolve_account_service.rb2
-rw-r--r--app/services/update_remote_profile_service.rb12
28 files changed, 401 insertions, 399 deletions
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index cbcc7ef04..c40155cb5 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -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
diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb
index 155670837..d820b257e 100644
--- a/app/controllers/media_proxy_controller.rb
+++ b/app/controllers/media_proxy_controller.rb
@@ -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
 
diff --git a/app/javascript/mastodon/features/compose/containers/warning_container.js b/app/javascript/mastodon/features/compose/containers/warning_container.js
index efaa02e9e..88f816da4 100644
--- a/app/javascript/mastodon/features/compose/containers/warning_container.js
+++ b/app/javascript/mastodon/features/compose/containers/warning_container.js
@@ -21,7 +21,7 @@ const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning
     return <Warning message={<FormattedMessage id='compose_form.hashtag_warning' defaultMessage="This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag." />} />;
   }
   if (directMessageWarning) {
-    return <Warning message={<FormattedMessage id='compose_form.direct_message_warning' defaultMessage='This toot will only be visible to all the mentioned users.' />} />;
+    return <Warning message={<FormattedMessage id='compose_form.direct_message_warning' defaultMessage='This toot will only be sent to all the mentioned users. However, the operators of your instance and any receiving instances may see this message.' />} />;
   }
 
   return null;
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index a4f27cd31..1199c9535 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -1,5 +1,5 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "روبوت",
   "account.block": "حظر @{name}",
   "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}",
   "account.blocked": "محظور",
@@ -283,7 +283,7 @@
   "upload_button.label": "إضافة وسائط",
   "upload_form.description": "وصف للمعاقين بصريا",
   "upload_form.focus": "قص",
-  "upload_form.undo": "إلغاء",
+  "upload_form.undo": "حذف",
   "upload_progress.label": "يرفع...",
   "video.close": "إغلاق الفيديو",
   "video.exit_fullscreen": "الخروج من وضع الشاشة المليئة",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 22c5453ca..68fc4a44c 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -283,7 +283,7 @@
   "upload_button.label": "Afegir multimèdia",
   "upload_form.description": "Descriure els problemes visuals",
   "upload_form.focus": "Retallar",
-  "upload_form.undo": "Desfer",
+  "upload_form.undo": "Esborra",
   "upload_progress.label": "Pujant...",
   "video.close": "Tancar el vídeo",
   "video.exit_fullscreen": "Surt de pantalla completa",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 35c5a86e9..8eeee7c3d 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -63,7 +63,7 @@
   "column_subheading.lists": "Lists",
   "column_subheading.navigation": "Navigation",
   "column_subheading.settings": "Settings",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
+  "compose_form.direct_message_warning": "This toot will only be sent to the mentioned users. However, the operators of yours and any of the receiving instances may inspect this message.",
   "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 4aa3d80a3..d5ddc23d4 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,5 +1,5 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Roboto",
   "account.block": "Bloki @{name}",
   "account.block_domain": "Kaŝi ĉion de {domain}",
   "account.blocked": "Blokita",
@@ -18,7 +18,7 @@
   "account.mute": "Silentigi @{name}",
   "account.mute_notifications": "Silentigi sciigojn el @{name}",
   "account.muted": "Silentigita",
-  "account.posts": "Tootoj",
+  "account.posts": "Mesaĝoj",
   "account.posts_with_replies": "Kun respondoj",
   "account.report": "Signali @{name}",
   "account.requested": "Atendo de aprobo. Alklaku por nuligi peton de sekvado",
@@ -283,7 +283,7 @@
   "upload_button.label": "Aldoni aŭdovidaĵon",
   "upload_form.description": "Priskribi por misvidantaj homoj",
   "upload_form.focus": "Stuci",
-  "upload_form.undo": "Malfari",
+  "upload_form.undo": "Forigi",
   "upload_progress.label": "Alŝutado…",
   "video.close": "Fermi videon",
   "video.exit_fullscreen": "Eksigi plenekrana",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index b0bda275c..c4a41583c 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -60,7 +60,7 @@
   "column_header.unpin": "Retirer",
   "column_subheading.navigation": "Navigation",
   "column_subheading.settings": "Paramètres",
-  "compose_form.direct_message_warning": "Ce pouet sera uniquement visible à tous les utilisateurs mentionnés.",
+  "compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé qu'aux personnes mentionnées. Cependant, l'administration de votre instance et des instances réceptrices pourront inspecter ce message.",
   "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non-listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.",
   "compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
   "compose_form.lock_disclaimer.lock": "verrouillé",
@@ -104,7 +104,7 @@
   "empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !",
   "empty_column.direct": "Vous n'avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s'affichera ici.",
   "empty_column.hashtag": "Il n’y a encore aucun contenu associé à ce hashtag.",
-  "empty_column.home": "Vous ne suivez encore personne. Visitez {public} ou bien utilisez la recherche pour vous connecter à d’autres personnes.",
+  "empty_column.home": "Vous ne suivez personne. Visitez {public} ou utilisez la recherche pour trouver d’autres personnes à suivre.",
   "empty_column.home.public_timeline": "le fil public",
   "empty_column.list": "Il n'y a rien dans cette liste pour l'instant. Dès que des personnes de cette liste publierons de nouveaux statuts, ils apparaîtront ici.",
   "empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.",
@@ -189,7 +189,7 @@
   "onboarding.done": "Effectué",
   "onboarding.next": "Suivant",
   "onboarding.page_five.public_timelines": "Le fil public global affiche les messages de toutes les personnes suivies par les membres de {domain}. Le fil public local est identique, mais se limite aux membres de {domain}.",
-  "onboarding.page_four.home": "L’Accueil affiche les messages des personnes que vous suivez.",
+  "onboarding.page_four.home": "L’accueil affiche les messages des personnes que vous suivez.",
   "onboarding.page_four.notifications": "La colonne de notification vous avertit lors d'une interaction avec vous.",
   "onboarding.page_one.federation": "Mastodon est un réseau de serveurs indépendants qui se joignent pour former un réseau social plus vaste. Nous appelons ces serveurs des instances.",
   "onboarding.page_one.full_handle": "Votre identifiant complet",
@@ -218,8 +218,8 @@
   "privacy.unlisted.short": "Non-listé",
   "regeneration_indicator.label": "Chargement…",
   "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !",
-  "relative_time.days": "{number} j",
-  "relative_time.hours": "{number} h",
+  "relative_time.days": "{number} j",
+  "relative_time.hours": "{number} h",
   "relative_time.just_now": "à l’instant",
   "relative_time.minutes": "{number} min",
   "relative_time.seconds": "{number} s",
@@ -237,7 +237,7 @@
   "search_popout.tips.status": "statuts",
   "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les identifiants et les hashtags correspondants",
   "search_popout.tips.user": "utilisateur⋅ice",
-  "search_results.accounts": "Personnes",
+  "search_results.accounts": "Comptes",
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Pouets",
   "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
@@ -283,7 +283,7 @@
   "upload_button.label": "Joindre un média",
   "upload_form.description": "Décrire pour les malvoyants",
   "upload_form.focus": "Recadrer",
-  "upload_form.undo": "Annuler",
+  "upload_form.undo": "Supprimer",
   "upload_progress.label": "Envoi en cours…",
   "video.close": "Fermer la vidéo",
   "video.exit_fullscreen": "Quitter plein écran",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 29885b896..1eaaebc53 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -283,7 +283,7 @@
   "upload_button.label": "Engadir medios",
   "upload_form.description": "Describa para deficientes visuais",
   "upload_form.focus": "Crop",
-  "upload_form.undo": "Desfacer",
+  "upload_form.undo": "Eliminar",
   "upload_progress.label": "Subindo...",
   "video.close": "Pechar video",
   "video.exit_fullscreen": "Saír da pantalla completa",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 9d3486152..8bd652864 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -1,108 +1,108 @@
 {
   "account.badges.bot": "Bot",
   "account.block": "Blocca @{name}",
-  "account.block_domain": "Hide everything from {domain}",
+  "account.block_domain": "Nascondi tutto da {domain}",
   "account.blocked": "Bloccato",
   "account.direct": "Direct Message @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
+  "account.disclaimer_full": "Il profilo dell'utente mostrato qui sotto potrebbe essere incompleto",
+  "account.domain_blocked": "Dominio nascosto",
   "account.edit_profile": "Modifica profilo",
   "account.follow": "Segui",
   "account.followers": "Seguaci",
   "account.follows": "Segue",
   "account.follows_you": "Ti segue",
-  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.hide_reblogs": "Nascondi condivisioni da @{name}",
   "account.media": "Media",
   "account.mention": "Menziona @{name}",
-  "account.moved_to": "{name} has moved to:",
+  "account.moved_to": "{name} si è trasferito su:",
   "account.mute": "Silenzia @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
+  "account.mute_notifications": "Silenzia notifiche da @{name}",
+  "account.muted": "Silenziato",
   "account.posts": "Toot",
   "account.posts_with_replies": "Toot con risposte",
   "account.report": "Segnala @{name}",
   "account.requested": "In attesa di approvazione",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
+  "account.share": "Condividi il profilo di @{name}",
+  "account.show_reblogs": "Mostra condivisioni da @{name}",
   "account.unblock": "Sblocca @{name}",
-  "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_domain": "Non nascondere {domain}",
   "account.unfollow": "Non seguire",
   "account.unmute": "Non silenziare @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
+  "account.unmute_notifications": "Non silenziare più le notifiche da @{name}",
+  "account.view_full_profile": "Vedi profilo completo",
+  "alert.unexpected.message": "Si è verificato un errore inatteso.",
   "alert.unexpected.title": "Oops!",
   "boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio la prossima volta",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Try again",
+  "bundle_column_error.body": "C'è stato un errore mentre questo componente veniva caricato.",
+  "bundle_column_error.retry": "Riprova",
   "bundle_column_error.title": "Network error",
-  "bundle_modal_error.close": "Close",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Try again",
+  "bundle_modal_error.close": "Chiudi",
+  "bundle_modal_error.message": "C'è stato un errore mentre questo componente veniva caricato.",
+  "bundle_modal_error.retry": "Riprova",
   "column.blocks": "Utenti bloccati",
   "column.community": "Timeline locale",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
+  "column.direct": "Messaggi diretti",
+  "column.domain_blocks": "Domini nascosti",
   "column.favourites": "Apprezzati",
   "column.follow_requests": "Richieste di amicizia",
   "column.home": "Home",
-  "column.lists": "Lists",
+  "column.lists": "Liste",
   "column.mutes": "Utenti silenziati",
   "column.notifications": "Notifiche",
   "column.pins": "Pinned toot",
   "column.public": "Timeline federata",
   "column_back_button.label": "Indietro",
-  "column_header.hide_settings": "Hide settings",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
-  "column_header.pin": "Pin",
-  "column_header.show_settings": "Show settings",
-  "column_header.unpin": "Unpin",
+  "column_header.hide_settings": "Nascondi impostazioni",
+  "column_header.moveLeft_settings": "Sposta colonna a sinistra",
+  "column_header.moveRight_settings": "Sposta colonna a destra",
+  "column_header.pin": "Fissa in cima",
+  "column_header.show_settings": "Mostra impostazioni",
+  "column_header.unpin": "Non fissare in cima",
   "column_subheading.navigation": "Navigation",
-  "column_subheading.settings": "Settings",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
-  "compose_form.lock_disclaimer.lock": "locked",
+  "column_subheading.settings": "Impostazioni",
+  "compose_form.direct_message_warning": "Questo toot sarà visibile solo a tutti gli utenti citati.",
+  "compose_form.hashtag_warning": "Questo toot non è listato, quindi non sarà trovato nelle ricerche per hashtag. Solo i toot pubblici possono essere cercati per hashtag.",
+  "compose_form.lock_disclaimer": "Il tuo account non è {bloccato}. Chiunque può decidere di seguirti per vedere i tuoi post per soli seguaci.",
+  "compose_form.lock_disclaimer.lock": "bloccato",
   "compose_form.placeholder": "A cosa stai pensando?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
+  "compose_form.sensitive.marked": "Questo media è contrassegnato come sensibile.",
+  "compose_form.sensitive.unmarked": "Questo media non è contrassegnato come sensibile.",
+  "compose_form.spoiler.marked": "Il testo è nascosto dall'avviso",
+  "compose_form.spoiler.unmarked": "Il testo non è nascosto",
   "compose_form.spoiler_placeholder": "Content warning",
-  "confirmation_modal.cancel": "Cancel",
+  "confirmation_modal.cancel": "Annulla",
   "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.block.message": "Sei sicuro di voler bloccare {name}?",
   "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete.message": "Sei sicuro di voler cancellare questo status?",
   "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
-  "confirmations.domain_block.confirm": "Hide entire domain",
-  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
+  "confirmations.delete_list.message": "Sei sicuro di voler cancellare definitivamente questa lista?",
+  "confirmations.domain_block.confirm": "Nascondi intero dominio",
+  "confirmations.domain_block.message": "Sei davvero sicuro che vuoi bloccare l'intero {domain}? Nella maggior parte dei casi, pochi blocchi o silenziamenti mirati sono sufficienti e preferibili.",
+  "confirmations.mute.confirm": "Silenzia",
+  "confirmations.mute.message": "Sei sicuro di voler silenziare {name}?",
+  "confirmations.unfollow.confirm": "Non seguire più",
+  "confirmations.unfollow.message": "Sei sicuro che non vuoi più seguire {name}?",
+  "embed.instructions": "Inserisci questo status nel tuo sito copiando il codice qui sotto.",
+  "embed.preview": "Ecco come apparirà:",
+  "emoji_button.activity": "Attività",
+  "emoji_button.custom": "Personalizzato",
+  "emoji_button.flags": "Bandiere",
+  "emoji_button.food": "Cibo e bevande",
   "emoji_button.label": "Inserisci emoji",
-  "emoji_button.nature": "Nature",
+  "emoji_button.nature": "Natura",
   "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
+  "emoji_button.objects": "Oggetti",
+  "emoji_button.people": "Persone",
+  "emoji_button.recent": "Usati di frequente",
+  "emoji_button.search": "Cerca...",
+  "emoji_button.search_results": "Risultati della ricerca",
+  "emoji_button.symbols": "Simboli",
+  "emoji_button.travel": "Viaggi e luoghi",
   "empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.direct": "Non hai ancora nessun messaggio diretto. Quando ne manderai o riceverai qualcuno, apparirà qui.",
   "empty_column.hashtag": "Non c'è ancora nessun post con questo hashtag.",
   "empty_column.home": "Non stai ancora seguendo nessuno. Visita {public} o usa la ricerca per incontrare nuove persone.",
   "empty_column.home.public_timeline": "la timeline pubblica",
@@ -111,64 +111,64 @@
   "empty_column.public": "Qui non c'è nulla! Scrivi qualcosa pubblicamente, o aggiungi utenti da altri server per riempire questo spazio.",
   "follow_request.authorize": "Autorizza",
   "follow_request.reject": "Rifiuta",
-  "getting_started.appsshort": "Apps",
+  "getting_started.appsshort": "App",
   "getting_started.faq": "FAQ",
   "getting_started.heading": "Come iniziare",
   "getting_started.open_source_notice": "Mastodon è un software open source. Puoi contribuire o segnalare errori su GitHub all'indirizzo {github}.",
-  "getting_started.userguide": "User Guide",
+  "getting_started.userguide": "Manuale utente",
   "home.column_settings.advanced": "Avanzato",
   "home.column_settings.basic": "Semplice",
   "home.column_settings.filter_regex": "Filtra con espressioni regolari",
   "home.column_settings.show_reblogs": "Mostra post condivisi",
   "home.column_settings.show_replies": "Mostra risposte",
   "home.settings": "Impostazioni colonna",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "keyboard_shortcuts.back": "per tornare indietro",
+  "keyboard_shortcuts.boost": "per condividere",
+  "keyboard_shortcuts.column": "per portare il focus su uno status in una delle colonne",
+  "keyboard_shortcuts.compose": "per portare il focus nell'area di composizione",
   "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.down": "per spostarsi in basso nella lista",
   "keyboard_shortcuts.enter": "to open status",
-  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourite": "per segnare come apprezzato",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
   "keyboard_shortcuts.hotkey": "Hotkey",
-  "keyboard_shortcuts.legend": "to display this legend",
-  "keyboard_shortcuts.mention": "to mention author",
-  "keyboard_shortcuts.reply": "to reply",
-  "keyboard_shortcuts.search": "to focus search",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
-  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "to move up in the list",
+  "keyboard_shortcuts.legend": "per mostrare questa spiegazione",
+  "keyboard_shortcuts.mention": "per menzionare l'autore",
+  "keyboard_shortcuts.reply": "per rispondere",
+  "keyboard_shortcuts.search": "per spostare il focus sulla ricerca",
+  "keyboard_shortcuts.toggle_hidden": "per mostrare/nascondere il testo dei CW",
+  "keyboard_shortcuts.toot": "per iniziare a scrivere un toot completamente nuovo",
+  "keyboard_shortcuts.unfocus": "per uscire dall'area di composizione o dalla ricerca",
+  "keyboard_shortcuts.up": "per spostarsi in alto nella lista",
   "lightbox.close": "Chiudi",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
+  "lightbox.next": "Successivo",
+  "lightbox.previous": "Precedente",
+  "lists.account.add": "Aggiungi alla lista",
+  "lists.account.remove": "Togli dalla lista",
   "lists.delete": "Delete list",
-  "lists.edit": "Edit list",
-  "lists.new.create": "Add list",
-  "lists.new.title_placeholder": "New list title",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
+  "lists.edit": "Modifica lista",
+  "lists.new.create": "Aggiungi lista",
+  "lists.new.title_placeholder": "Titolo della nuova lista",
+  "lists.search": "Cerca tra le persone che segui",
+  "lists.subheading": "Le tue liste",
   "loading_indicator.label": "Carico...",
   "media_gallery.toggle_visible": "Imposta visibilità",
   "missing_indicator.label": "Non trovato",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "missing_indicator.sublabel": "Risorsa non trovata",
+  "mute_modal.hide_notifications": "Nascondere le notifiche da quest'utente?",
   "navigation_bar.blocks": "Utenti bloccati",
   "navigation_bar.community_timeline": "Timeline locale",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.direct": "Messaggi diretti",
+  "navigation_bar.domain_blocks": "Domini nascosti",
   "navigation_bar.edit_profile": "Modifica profilo",
   "navigation_bar.favourites": "Apprezzati",
   "navigation_bar.follow_requests": "Richieste di amicizia",
   "navigation_bar.info": "Informazioni estese",
-  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
+  "navigation_bar.keyboard_shortcuts": "Tasti di scelta rapida",
+  "navigation_bar.lists": "Liste",
+  "navigation_bar.logout": "Esci",
   "navigation_bar.mutes": "Utenti silenziati",
-  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.pins": "Toot fissati in cima",
   "navigation_bar.preferences": "Impostazioni",
   "navigation_bar.public_timeline": "Timeline federata",
   "notification.favourite": "{name} ha apprezzato il tuo post",
@@ -181,32 +181,32 @@
   "notifications.column_settings.favourite": "Apprezzati:",
   "notifications.column_settings.follow": "Nuovi seguaci:",
   "notifications.column_settings.mention": "Menzioni:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.push_meta": "This device",
+  "notifications.column_settings.push": "Notifiche push",
+  "notifications.column_settings.push_meta": "Questo dispositivo",
   "notifications.column_settings.reblog": "Post condivisi:",
   "notifications.column_settings.show": "Mostra in colonna",
   "notifications.column_settings.sound": "Riproduci suono",
-  "onboarding.done": "Done",
-  "onboarding.next": "Next",
-  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
-  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
-  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
-  "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
-  "onboarding.page_one.full_handle": "Your full handle",
-  "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
-  "onboarding.page_one.welcome": "Welcome to Mastodon!",
-  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
-  "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
-  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
-  "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
-  "onboarding.page_six.guidelines": "community guidelines",
-  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
-  "onboarding.page_six.various_app": "mobile apps",
-  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
-  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
-  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
-  "onboarding.skip": "Skip",
+  "onboarding.done": "Fatto",
+  "onboarding.next": "Prossimo",
+  "onboarding.page_five.public_timelines": "La timeline locale mostra i post pubblici di tutti gli utenti di {domain}. La timeline federata mostra i post pubblici di tutti gli utenti seguiti da quelli di {domain}. Queste sono le timeline pubbliche, che vi danno grandi possibilità di scoprire nuovi utenti.",
+  "onboarding.page_four.home": "La timeline home mostra i post degli utenti che segui.",
+  "onboarding.page_four.notifications": "La colonna delle notifiche ti fa vedere quando qualcuno interagisce con te.",
+  "onboarding.page_one.federation": "Mastodon è una rete di server indipendenti che si collegano tra loro per formare un grande social network. I singoli server sono detti istanze.",
+  "onboarding.page_one.full_handle": "Il tuo nome utente completo",
+  "onboarding.page_one.handle_hint": "È ciò che diresti ai tuoi amici di cercare per trovarti.",
+  "onboarding.page_one.welcome": "Benvenuto in Mastodon!",
+  "onboarding.page_six.admin": "L'amministratore della tua istanza è {admin}.",
+  "onboarding.page_six.almost_done": "Quasi finito...",
+  "onboarding.page_six.appetoot": "Buon appetoot!",
+  "onboarding.page_six.apps_available": "Esistono {apps} per iOS, Android e altre piattaforme.",
+  "onboarding.page_six.github": "Mastodon è software libero e open-source. Puoi segnalare bug, richiedere nuove funzionalità, o contribuire al codice su {github}.",
+  "onboarding.page_six.guidelines": "linee guida per la comunità",
+  "onboarding.page_six.read_guidelines": "Ti preghiamo di leggere le {guidelines} di {domain}!",
+  "onboarding.page_six.various_app": "app per dispositivi mobili",
+  "onboarding.page_three.profile": "Puoi modificare il tuo profilo per cambiare i tuoi avatar, biografia e nome pubblico. E potrai trovarci altre preferenze.",
+  "onboarding.page_three.search": "Usa la barra di ricerca per trovare persone e hashtag, come {illustration} e {introductions}. Per trovare una persona che non è su questa istanza, usa il suo nome utente completo.",
+  "onboarding.page_two.compose": "Puoi scrivere dei post dalla colonna di composizione. Puoi caricare immagini, modificare le impostazioni di privacy, e aggiungere avvisi sul contenuto con le icone qui sotto.",
+  "onboarding.skip": "Salta",
   "privacy.change": "Modifica privacy post",
   "privacy.direct.long": "Invia solo a utenti menzionati",
   "privacy.direct.short": "Diretto",
@@ -216,11 +216,11 @@
   "privacy.public.short": "Pubblico",
   "privacy.unlisted.long": "Non mostrare sulla timeline pubblica",
   "privacy.unlisted.short": "Non elencato",
-  "regeneration_indicator.label": "Loading…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "regeneration_indicator.label": "Caricamento in corso…",
+  "regeneration_indicator.sublabel": "Stiamo preparando il tuo home feed!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.just_now": "ora",
   "relative_time.minutes": "{number}m",
   "relative_time.seconds": "{number}s",
   "reply_indicator.cancel": "Annulla",
@@ -283,7 +283,7 @@
   "upload_button.label": "Aggiungi file multimediale",
   "upload_form.description": "Describe for the visually impaired",
   "upload_form.focus": "Crop",
-  "upload_form.undo": "Annulla",
+  "upload_form.undo": "Cancella",
   "upload_progress.label": "Sto caricando...",
   "video.close": "Close video",
   "video.exit_fullscreen": "Exit full screen",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 1bdf34a81..8fbf19bec 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -287,7 +287,7 @@
   "upload_button.label": "メディアを追加",
   "upload_form.description": "視覚障害者のための説明",
   "upload_form.focus": "焦点",
-  "upload_form.undo": "やり直す",
+  "upload_form.undo": "削除",
   "upload_progress.label": "アップロード中...",
   "video.close": "動画を閉じる",
   "video.exit_fullscreen": "全画面を終了する",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index e72a7dff9..fc13a5b5b 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -283,7 +283,7 @@
   "upload_button.label": "미디어 추가",
   "upload_form.description": "시각장애인을 위한 설명",
   "upload_form.focus": "크롭",
-  "upload_form.undo": "재시도",
+  "upload_form.undo": "삭제",
   "upload_progress.label": "업로드 중...",
   "video.close": "동영상 닫기",
   "video.exit_fullscreen": "전체화면 나가기",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index a6bfe36f9..047583ce2 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -283,7 +283,7 @@
   "upload_button.label": "Media toevoegen",
   "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
   "upload_form.focus": "Bijsnijden",
-  "upload_form.undo": "Ongedaan maken",
+  "upload_form.undo": "Verwijderen",
   "upload_progress.label": "Uploaden...",
   "video.close": "Video sluiten",
   "video.exit_fullscreen": "Volledig scherm sluiten",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index ead57d63f..615af998f 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -3,7 +3,7 @@
   "account.block": "Blocar @{name}",
   "account.block_domain": "Tot amagar del domeni {domain}",
   "account.blocked": "Blocat",
-  "account.direct": "Direct Message @{name}",
+  "account.direct": "Escriure un MP a @{name}",
   "account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.",
   "account.domain_blocked": "Domeni amagat",
   "account.edit_profile": "Modificar lo perfil",
@@ -42,7 +42,7 @@
   "column.blocks": "Personas blocadas",
   "column.community": "Flux public local",
   "column.direct": "Messatges dirèctes",
-  "column.domain_blocks": "Domenis blocats",
+  "column.domain_blocks": "Domenis resconduts",
   "column.favourites": "Favorits",
   "column.follow_requests": "Demandas d’abonament",
   "column.home": "Acuèlh",
@@ -102,14 +102,14 @@
   "emoji_button.symbols": "Simbòls",
   "emoji_button.travel": "Viatges & lòcs",
   "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !",
-  "empty_column.direct": "Avètz pas encara de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.",
+  "empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.",
   "empty_column.hashtag": "I a pas encara de contengut ligat a aquesta etiqueta.",
   "empty_column.home": "Vòstre flux d’acuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a d’autras personas.",
   "empty_column.home.public_timeline": "lo flux public",
   "empty_column.list": "I a pas res dins la lista pel moment. Quand de membres d’aquesta lista publiquen de novèls estatuts los veiretz aquí.",
   "empty_column.notifications": "Avètz pas encara de notificacions. Respondètz a qualqu’un per començar una conversacion.",
   "empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autras instàncias per garnir lo flux public",
-  "follow_request.authorize": "Autorizar",
+  "follow_request.authorize": "Acceptar",
   "follow_request.reject": "Regetar",
   "getting_started.appsshort": "Aplicacions",
   "getting_started.faq": "FAQ",
@@ -159,7 +159,7 @@
   "navigation_bar.blocks": "Personas blocadas",
   "navigation_bar.community_timeline": "Flux public local",
   "navigation_bar.direct": "Messatges dirèctes",
-  "navigation_bar.domain_blocks": "Domenis amagats",
+  "navigation_bar.domain_blocks": "Domenis resconduts",
   "navigation_bar.edit_profile": "Modificar lo perfil",
   "navigation_bar.favourites": "Favorits",
   "navigation_bar.follow_requests": "Demandas d’abonament",
@@ -259,7 +259,7 @@
   "status.pin": "Penjar al perfil",
   "status.pinned": "Tut penjat",
   "status.reblog": "Partejar",
-  "status.reblog_private": "Partejar al l’audiéncia d’origina",
+  "status.reblog_private": "Partejar a l’audiéncia d’origina",
   "status.reblogged_by": "{name} a partejat",
   "status.reply": "Respondre",
   "status.replyAll": "Respondre a la conversacion",
@@ -283,7 +283,7 @@
   "upload_button.label": "Ajustar un mèdia",
   "upload_form.description": "Descripcion pels mal vesents",
   "upload_form.focus": "Retalhar",
-  "upload_form.undo": "Anullar",
+  "upload_form.undo": "Suprimir",
   "upload_progress.label": "Mandadís…",
   "video.close": "Tampar la vidèo",
   "video.exit_fullscreen": "Sortir plen ecran",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 120edcb1c..658b5887d 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -287,7 +287,7 @@
   "upload_button.label": "Dodaj zawartość multimedialną",
   "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
   "upload_form.focus": "Przytnij",
-  "upload_form.undo": "Cofnij",
+  "upload_form.undo": "Usuń",
   "upload_progress.label": "Wysyłanie",
   "video.close": "Zamknij film",
   "video.exit_fullscreen": "Opuść tryb pełnoekranowy",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 599873439..5cf983b83 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -1,5 +1,5 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Бот",
   "account.block": "Блокировать",
   "account.block_domain": "Блокировать все с {domain}",
   "account.blocked": "Заблокирован(а)",
@@ -41,7 +41,7 @@
   "bundle_modal_error.retry": "Попробовать снова",
   "column.blocks": "Список блокировки",
   "column.community": "Локальная лента",
-  "column.direct": "Direct messages",
+  "column.direct": "Личные сообщения",
   "column.domain_blocks": "Скрытые домены",
   "column.favourites": "Понравившееся",
   "column.follow_requests": "Запросы на подписку",
@@ -60,7 +60,7 @@
   "column_header.unpin": "Открепить",
   "column_subheading.navigation": "Навигация",
   "column_subheading.settings": "Настройки",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
+  "compose_form.direct_message_warning": "Этот статус будет виден только упомянутым пользователям.",
   "compose_form.hashtag_warning": "Этот пост не будет показывается в поиске по хэштегу, т.к. он непубличный. Только публичные посты можно найти в поиске по хэштегу.",
   "compose_form.lock_disclaimer": "Ваш аккаунт не {locked}. Любой человек может подписаться на Вас и просматривать посты для подписчиков.",
   "compose_form.lock_disclaimer.lock": "закрыт",
@@ -102,7 +102,7 @@
   "emoji_button.symbols": "Символы",
   "emoji_button.travel": "Путешествия",
   "empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.direct": "У Вас пока нет личных сообщений. Когда Вы начнёте их отправлять или получать, они появятся здесь.",
   "empty_column.hashtag": "Статусов с таким хэштегом еще не существует.",
   "empty_column.home": "Пока Вы ни на кого не подписаны. Полистайте {public} или используйте поиск, чтобы освоиться и завести новые знакомства.",
   "empty_column.home.public_timeline": "публичные ленты",
@@ -136,7 +136,7 @@
   "keyboard_shortcuts.mention": "упомянуть автора поста",
   "keyboard_shortcuts.reply": "ответить",
   "keyboard_shortcuts.search": "перейти к поиску",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_hidden": "показать/скрыть текст за предупреждением",
   "keyboard_shortcuts.toot": "начать писать новый пост",
   "keyboard_shortcuts.unfocus": "убрать фокус с поля ввода/поиска",
   "keyboard_shortcuts.up": "вверх по списку",
@@ -158,7 +158,7 @@
   "mute_modal.hide_notifications": "Убрать уведомления от этого пользователя?",
   "navigation_bar.blocks": "Список блокировки",
   "navigation_bar.community_timeline": "Локальная лента",
-  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.direct": "Личные сообщения",
   "navigation_bar.domain_blocks": "Скрытые домены",
   "navigation_bar.edit_profile": "Изменить профиль",
   "navigation_bar.favourites": "Понравившееся",
@@ -224,12 +224,12 @@
   "relative_time.minutes": "{number}м",
   "relative_time.seconds": "{number}с",
   "reply_indicator.cancel": "Отмена",
-  "report.forward": "Forward to {target}",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.forward": "Переслать для {target}",
+  "report.forward_hint": "Этот аккаунт расположен на другом сервере. Отправить туда анонимную копию Вашей жалобы?",
   "report.hint": "Жалоба будет отправлена модераторам Вашего сервера. Вы также можете указать подробную причину жалобы ниже:",
   "report.placeholder": "Комментарий",
   "report.submit": "Отправить",
-  "report.target": "Жалуемся на",
+  "report.target": "Жалуемся на {target}",
   "search.placeholder": "Поиск",
   "search_popout.search_format": "Продвинутый формат поиска",
   "search_popout.tips.full_text": "Возвращает посты, которые Вы написали, отметили как 'избранное', продвинули или в которых были упомянуты, а также содержащие юзернейм, имя и хэштеги.",
@@ -237,16 +237,16 @@
   "search_popout.tips.status": "статус",
   "search_popout.tips.text": "Простой ввод текста покажет совпадающие имена пользователей, отображаемые имена и хэштеги",
   "search_popout.tips.user": "пользователь",
-  "search_results.accounts": "People",
-  "search_results.hashtags": "Hashtags",
-  "search_results.statuses": "Toots",
+  "search_results.accounts": "Люди",
+  "search_results.hashtags": "Хэштеги",
+  "search_results.statuses": "Посты",
   "search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
   "standalone.public_title": "Прямо сейчас",
   "status.block": "Заблокировать @{name}",
-  "status.cancel_reblog_private": "Unboost",
+  "status.cancel_reblog_private": "Не продвигать",
   "status.cannot_reblog": "Этот статус не может быть продвинут",
   "status.delete": "Удалить",
-  "status.direct": "Direct message @{name}",
+  "status.direct": "Написать @{name}",
   "status.embed": "Встроить",
   "status.favourite": "Нравится",
   "status.load_more": "Показать еще",
@@ -257,9 +257,9 @@
   "status.mute_conversation": "Заглушить тред",
   "status.open": "Развернуть статус",
   "status.pin": "Закрепить в профиле",
-  "status.pinned": "Pinned toot",
+  "status.pinned": "Закреплённый статус",
   "status.reblog": "Продвинуть",
-  "status.reblog_private": "Boost to original audience",
+  "status.reblog_private": "Продвинуть для своей аудитории",
   "status.reblogged_by": "{name} продвинул(а)",
   "status.reply": "Ответить",
   "status.replyAll": "Ответить на тред",
@@ -268,21 +268,21 @@
   "status.sensitive_warning": "Чувствительный контент",
   "status.share": "Поделиться",
   "status.show_less": "Свернуть",
-  "status.show_less_all": "Show less for all",
+  "status.show_less_all": "Свернуть для всех",
   "status.show_more": "Развернуть",
-  "status.show_more_all": "Show more for all",
+  "status.show_more_all": "Развернуть для всех",
   "status.unmute_conversation": "Снять глушение с треда",
   "status.unpin": "Открепить от профиля",
   "tabs_bar.federated_timeline": "Глобальная",
   "tabs_bar.home": "Главная",
   "tabs_bar.local_timeline": "Локальная",
   "tabs_bar.notifications": "Уведомления",
-  "tabs_bar.search": "Search",
+  "tabs_bar.search": "Поиск",
   "ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.",
   "upload_area.title": "Перетащите сюда, чтобы загрузить",
   "upload_button.label": "Добавить медиаконтент",
   "upload_form.description": "Описать для людей с нарушениями зрения",
-  "upload_form.focus": "Crop",
+  "upload_form.focus": "Обрезать",
   "upload_form.undo": "Отменить",
   "upload_progress.label": "Загрузка...",
   "video.close": "Закрыть видео",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 1cf7dee80..4f7969bd3 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -283,7 +283,7 @@
   "upload_button.label": "Pridať médiá",
   "upload_form.description": "Opis pre slabo vidiacich",
   "upload_form.focus": "Vystrihni",
-  "upload_form.undo": "Navrátiť",
+  "upload_form.undo": "Vymaž",
   "upload_progress.label": "Nahráva sa...",
   "video.close": "Zavrieť video",
   "video.exit_fullscreen": "Vpnúť zobrazenie na celú obrazovku",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index 202dc4bd0..69b416258 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -1,143 +1,143 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "Robot",
   "account.block": "Blokiraj @{name}",
   "account.block_domain": "Skrij vse iz {domain}",
   "account.blocked": "Blokirano",
   "account.direct": "Neposredno sporočilo @{name}",
-  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
-  "account.domain_blocked": "Domain hidden",
-  "account.edit_profile": "Edit profile",
-  "account.follow": "Follow",
-  "account.followers": "Followers",
-  "account.follows": "Follows",
-  "account.follows_you": "Follows you",
-  "account.hide_reblogs": "Hide boosts from @{name}",
-  "account.media": "Media",
-  "account.mention": "Mention @{name}",
-  "account.moved_to": "{name} has moved to:",
-  "account.mute": "Mute @{name}",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.posts": "Toots",
-  "account.posts_with_replies": "Toots and replies",
-  "account.report": "Report @{name}",
-  "account.requested": "Awaiting approval. Click to cancel follow request",
-  "account.share": "Share @{name}'s profile",
-  "account.show_reblogs": "Show boosts from @{name}",
-  "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
-  "account.unfollow": "Unfollow",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.view_full_profile": "View full profile",
-  "alert.unexpected.message": "An unexpected error occurred.",
-  "alert.unexpected.title": "Oops!",
-  "boost_modal.combo": "You can press {combo} to skip this next time",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Try again",
-  "bundle_column_error.title": "Network error",
-  "bundle_modal_error.close": "Close",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Try again",
-  "column.blocks": "Blocked users",
-  "column.community": "Local timeline",
-  "column.direct": "Direct messages",
-  "column.domain_blocks": "Hidden domains",
-  "column.favourites": "Favourites",
-  "column.follow_requests": "Follow requests",
-  "column.home": "Home",
-  "column.lists": "Lists",
-  "column.mutes": "Muted users",
-  "column.notifications": "Notifications",
-  "column.pins": "Pinned toot",
-  "column.public": "Federated timeline",
-  "column_back_button.label": "Back",
-  "column_header.hide_settings": "Hide settings",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
-  "column_header.pin": "Pin",
-  "column_header.show_settings": "Show settings",
-  "column_header.unpin": "Unpin",
-  "column_subheading.navigation": "Navigation",
-  "column_subheading.settings": "Settings",
-  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
-  "compose_form.lock_disclaimer.lock": "locked",
-  "compose_form.placeholder": "What is on your mind?",
-  "compose_form.publish": "Toot",
+  "account.disclaimer_full": "Spodnje informacije lahko nepopolno prikazujejo profil uporabnika.",
+  "account.domain_blocked": "Skrita domena",
+  "account.edit_profile": "Uredi profil",
+  "account.follow": "Sledi",
+  "account.followers": "Sledilci",
+  "account.follows": "Sledi",
+  "account.follows_you": "Ti sledi",
+  "account.hide_reblogs": "Skrij napuhke od @{name}",
+  "account.media": "Mediji",
+  "account.mention": "Omeni @{name}",
+  "account.moved_to": "{name} se je premaknil na:",
+  "account.mute": "Utišaj @{name}",
+  "account.mute_notifications": "Utišaj obvestila od @{name}",
+  "account.muted": "Utišan",
+  "account.posts": "Tuti",
+  "account.posts_with_replies": "Tuti in odgovori",
+  "account.report": "Prijavi @{name}",
+  "account.requested": "Čakanje na odobritev. Kliknite, da prekličete prošnjo za sledenje",
+  "account.share": "Delite profil osebe @{name}",
+  "account.show_reblogs": "Pokaži delitve osebe @{name}",
+  "account.unblock": "Odblokiraj @{name}",
+  "account.unblock_domain": "Razkrij {domain}",
+  "account.unfollow": "Prenehaj slediti",
+  "account.unmute": "Odtišaj @{name}",
+  "account.unmute_notifications": "Vklopi obvestila od @{name}",
+  "account.view_full_profile": "Ogled celotnega profila",
+  "alert.unexpected.message": "Zgodila se je nepričakovana napaka.",
+  "alert.unexpected.title": "Uups!",
+  "boost_modal.combo": "Če želite naslednjič preskočiti to, lahko pritisnete {combo}",
+  "bundle_column_error.body": "Med nalaganjem te komponente je prišlo do napake.",
+  "bundle_column_error.retry": "Poskusi ponovno",
+  "bundle_column_error.title": "Napaka omrežja",
+  "bundle_modal_error.close": "Zapri",
+  "bundle_modal_error.message": "Med nalaganjem te komponente je prišlo do napake.",
+  "bundle_modal_error.retry": "Poskusi ponovno",
+  "column.blocks": "Blokirani uporabniki",
+  "column.community": "Lokalna časovnica",
+  "column.direct": "Neposredna sporočila",
+  "column.domain_blocks": "Skrite domene",
+  "column.favourites": "Priljubljene",
+  "column.follow_requests": "Sledi prošnjam",
+  "column.home": "Domov",
+  "column.lists": "Seznami",
+  "column.mutes": "Utišani uporabniki",
+  "column.notifications": "Obvestila",
+  "column.pins": "Pripeti tuti",
+  "column.public": "Združena časovnica",
+  "column_back_button.label": "Nazaj",
+  "column_header.hide_settings": "Skrij nastavitve",
+  "column_header.moveLeft_settings": "Premakni stolpec na levo",
+  "column_header.moveRight_settings": "Premakni stolpec na desno",
+  "column_header.pin": "Pripni",
+  "column_header.show_settings": "Prikaži nastavitve",
+  "column_header.unpin": "Odpni",
+  "column_subheading.navigation": "Navigacija",
+  "column_subheading.settings": "Nastavitve",
+  "compose_form.direct_message_warning": "Ta tut bo viden le vsem omenjenim uporabnikom.",
+  "compose_form.hashtag_warning": "Ta tut ne bo naveden pod nobenim hashtagom, ker ni dodan hashtag. Samo javne tute lahko iščete pod hashtagom.",
+  "compose_form.lock_disclaimer": "Vaš račun ni {locked}. Vsakdo vam lahko sledi in si ogleda objave, ki so namenjene samo sledilcem.",
+  "compose_form.lock_disclaimer.lock": "zaklenjen",
+  "compose_form.placeholder": "O čem razmišljaš?",
+  "compose_form.publish": "Tutni",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
-  "compose_form.spoiler.unmarked": "Text is not hidden",
-  "compose_form.spoiler_placeholder": "Write your warning here",
-  "confirmation_modal.cancel": "Cancel",
+  "compose_form.sensitive.marked": "Medij je označen kot občutljiv",
+  "compose_form.sensitive.unmarked": "Medij ni označen kot občutljiv",
+  "compose_form.spoiler.marked": "Besedilo je skrito za opozorilom",
+  "compose_form.spoiler.unmarked": "Besedilo ni skrito",
+  "compose_form.spoiler_placeholder": "Napišite opozorilo tukaj",
+  "confirmation_modal.cancel": "Prekliči",
   "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.block.message": "Ali ste prepričani, da želite blokirati {name}?",
   "confirmations.delete.confirm": "Delete",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete.message": "Ali ste prepričani, da želite izbrisati to stanje?",
   "confirmations.delete_list.confirm": "Delete",
-  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
-  "confirmations.domain_block.confirm": "Hide entire domain",
-  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
-  "confirmations.mute.confirm": "Mute",
-  "confirmations.mute.message": "Are you sure you want to mute {name}?",
-  "confirmations.unfollow.confirm": "Unfollow",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
-  "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.hashtag": "There is nothing in this hashtag yet.",
-  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
-  "empty_column.home.public_timeline": "the public timeline",
-  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
-  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
-  "follow_request.authorize": "Authorize",
-  "follow_request.reject": "Reject",
-  "getting_started.appsshort": "Apps",
+  "confirmations.delete_list.message": "Ali ste prepričani, da želite trajno izbrisati ta seznam?",
+  "confirmations.domain_block.confirm": "Skrij celotno domeno",
+  "confirmations.domain_block.message": "Ali ste res, res prepričani, da želite blokirati celotno {domain}? V večini primerov je nekaj ciljnih blokiranj ali utišanj dovolj in boljše.",
+  "confirmations.mute.confirm": "Utišanje",
+  "confirmations.mute.message": "Ali ste prepričani, da želite utišati {name}?",
+  "confirmations.unfollow.confirm": "Prenehaj slediti",
+  "confirmations.unfollow.message": "Ali ste prepričani, da ne želite več slediti {name}?",
+  "embed.instructions": "Vstavi ta status na svojo spletno stran tako, da kopirate spodnjo kodo.",
+  "embed.preview": "Tukaj je, kako bo izgledalo:",
+  "emoji_button.activity": "Dejavnost",
+  "emoji_button.custom": "Po meri",
+  "emoji_button.flags": "Zastave",
+  "emoji_button.food": "Hrana in Pijača",
+  "emoji_button.label": "Vstavi emojija",
+  "emoji_button.nature": "Narava",
+  "emoji_button.not_found": "Ni emojijev!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Predmeti",
+  "emoji_button.people": "Ljudje",
+  "emoji_button.recent": "Pogosto uporabljeni",
+  "emoji_button.search": "Poišči...",
+  "emoji_button.search_results": "Rezultati iskanja",
+  "emoji_button.symbols": "Simboli",
+  "emoji_button.travel": "Potovanja in Kraji",
+  "empty_column.community": "Lokalna časovnica je prazna. Napišite nekaj javnega, da se bo žoga zakotalila!",
+  "empty_column.direct": "Nimate še nobenih neposrednih sporočil. Ko ga pošljete ali prejmete, se prikaže tukaj.",
+  "empty_column.hashtag": "V tem hashtagu še ni nič.",
+  "empty_column.home": "Vaša domača časovnica je prazna! Obiščite {public} ali uporabite iskanje, da se boste srečali druge uporabnike.",
+  "empty_column.home.public_timeline": "javna časovnica",
+  "empty_column.list": "Na tem seznamu ni ničesar. Ko bodo člani tega seznama objavili nove statuse, se bodo pojavili tukaj.",
+  "empty_column.notifications": "Nimate še nobenih obvestil. Poveži se z drugimi, da začnete pogovor.",
+  "empty_column.public": "Tukaj ni ničesar! Da ga napolnite, napišite nekaj javnega ali pa ročno sledite uporabnikom iz drugih vozlišč",
+  "follow_request.authorize": "Odobri",
+  "follow_request.reject": "Zavrni",
+  "getting_started.appsshort": "Aplikacije",
   "getting_started.faq": "FAQ",
-  "getting_started.heading": "Getting started",
-  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-  "getting_started.userguide": "User Guide",
-  "home.column_settings.advanced": "Advanced",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.filter_regex": "Filter out by regular expressions",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "home.settings": "Column settings",
-  "keyboard_shortcuts.back": "to navigate back",
-  "keyboard_shortcuts.boost": "to boost",
-  "keyboard_shortcuts.column": "to focus a status in one of the columns",
-  "keyboard_shortcuts.compose": "to focus the compose textarea",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.down": "to move down in the list",
-  "keyboard_shortcuts.enter": "to open status",
+  "getting_started.heading": "Prvi koraki",
+  "getting_started.open_source_notice": "Mastodon je odprtokodna programska oprema. V GitHubu na {github} lahko prispevate ali poročate o napakah.",
+  "getting_started.userguide": "Navodila za uporabo",
+  "home.column_settings.advanced": "Napredno",
+  "home.column_settings.basic": "Osnovno",
+  "home.column_settings.filter_regex": "Filtrirajte z navadnimi izrazi",
+  "home.column_settings.show_reblogs": "Pokaži sunke",
+  "home.column_settings.show_replies": "Pokaži odgovore",
+  "home.settings": "Nastavitve stolpcev",
+  "keyboard_shortcuts.back": "za krmarjenje nazaj",
+  "keyboard_shortcuts.boost": "suniti",
+  "keyboard_shortcuts.column": "osredotočiti status v enega od stolpcev",
+  "keyboard_shortcuts.compose": "osredotočiti na sestavljanje besedila",
+  "keyboard_shortcuts.description": "Opis",
+  "keyboard_shortcuts.down": "premakniti navzdol po seznamu",
+  "keyboard_shortcuts.enter": "odpreti status",
   "keyboard_shortcuts.favourite": "to favourite",
-  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
-  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.heading": "Tipkovne bližnjice",
+  "keyboard_shortcuts.hotkey": "Hitra tipka",
   "keyboard_shortcuts.legend": "to display this legend",
   "keyboard_shortcuts.mention": "to mention author",
   "keyboard_shortcuts.reply": "to reply",
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
-  "keyboard_shortcuts.toot": "to start a brand new toot",
+  "keyboard_shortcuts.toot": "da začnete povsem nov tut",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
   "lightbox.close": "Close",
@@ -163,12 +163,12 @@
   "navigation_bar.edit_profile": "Edit profile",
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.follow_requests": "Follow requests",
-  "navigation_bar.info": "Extended information",
+  "navigation_bar.info": "O tem vozlišču",
   "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
   "navigation_bar.lists": "Lists",
   "navigation_bar.logout": "Logout",
   "navigation_bar.mutes": "Muted users",
-  "navigation_bar.pins": "Pinned toots",
+  "navigation_bar.pins": "Pripeti tuti",
   "navigation_bar.preferences": "Preferences",
   "navigation_bar.public_timeline": "Federated timeline",
   "notification.favourite": "{name} favourited your status",
@@ -197,7 +197,7 @@
   "onboarding.page_one.welcome": "Welcome to Mastodon!",
   "onboarding.page_six.admin": "Your instance's admin is {admin}.",
   "onboarding.page_six.almost_done": "Almost done...",
-  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.appetoot": "Bon Appetut!",
   "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
   "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
   "onboarding.page_six.guidelines": "community guidelines",
@@ -239,7 +239,7 @@
   "search_popout.tips.user": "user",
   "search_results.accounts": "People",
   "search_results.hashtags": "Hashtags",
-  "search_results.statuses": "Toots",
+  "search_results.statuses": "Tuti",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "standalone.public_title": "A look inside...",
   "status.block": "Block @{name}",
@@ -257,41 +257,41 @@
   "status.mute_conversation": "Mute conversation",
   "status.open": "Expand this status",
   "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.reblog": "Boost",
-  "status.reblog_private": "Boost to original audience",
-  "status.reblogged_by": "{name} boosted",
-  "status.reply": "Reply",
-  "status.replyAll": "Reply to thread",
-  "status.report": "Report @{name}",
-  "status.sensitive_toggle": "Click to view",
-  "status.sensitive_warning": "Sensitive content",
-  "status.share": "Share",
-  "status.show_less": "Show less",
-  "status.show_less_all": "Show less for all",
-  "status.show_more": "Show more",
-  "status.show_more_all": "Show more for all",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
-  "tabs_bar.federated_timeline": "Federated",
-  "tabs_bar.home": "Home",
-  "tabs_bar.local_timeline": "Local",
-  "tabs_bar.notifications": "Notifications",
-  "tabs_bar.search": "Search",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media",
-  "upload_form.description": "Describe for the visually impaired",
-  "upload_form.focus": "Crop",
-  "upload_form.undo": "Undo",
-  "upload_progress.label": "Uploading...",
-  "video.close": "Close video",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
-  "video.fullscreen": "Full screen",
-  "video.hide": "Hide video",
-  "video.mute": "Mute sound",
-  "video.pause": "Pause",
-  "video.play": "Play",
-  "video.unmute": "Unmute sound"
+  "status.pinned": "Pripeti tut",
+  "status.reblog": "Suni",
+  "status.reblog_private": "Suni v prvotno občinstvo",
+  "status.reblogged_by": "{name} sunjen",
+  "status.reply": "Odgovori",
+  "status.replyAll": "Odgovori na objavo",
+  "status.report": "Prijavi @{name}",
+  "status.sensitive_toggle": "Kliknite za ogled",
+  "status.sensitive_warning": "Občutljiva vsebina",
+  "status.share": "Deli",
+  "status.show_less": "Prikaži manj",
+  "status.show_less_all": "Prikaži manj za vse",
+  "status.show_more": "Prikaži več",
+  "status.show_more_all": "Prikaži več za vse",
+  "status.unmute_conversation": "Odtišaj pogovor",
+  "status.unpin": "Odpni iz profila",
+  "tabs_bar.federated_timeline": "Združeno",
+  "tabs_bar.home": "Domov",
+  "tabs_bar.local_timeline": "Lokalno",
+  "tabs_bar.notifications": "Obvestila",
+  "tabs_bar.search": "Poišči",
+  "ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.",
+  "upload_area.title": "Povlecite in spustite za pošiljanje",
+  "upload_button.label": "Dodaj medij",
+  "upload_form.description": "Opišite za slabovidne",
+  "upload_form.focus": "Obreži",
+  "upload_form.undo": "Izbriši",
+  "upload_progress.label": "Pošiljanje...",
+  "video.close": "Zapri video",
+  "video.exit_fullscreen": "Izhod iz celozaslonskega načina",
+  "video.expand": "Razširi video",
+  "video.fullscreen": "Celozaslonski način",
+  "video.hide": "Skrij video",
+  "video.mute": "Utišaj zvok",
+  "video.pause": "Premor",
+  "video.play": "Predvajaj",
+  "video.unmute": "Vklopi zvok"
 }
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 0c012aa7d..9334b5d20 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -1,5 +1,5 @@
 {
-  "account.badges.bot": "Bot",
+  "account.badges.bot": "機械人",
   "account.block": "封鎖 @{name}",
   "account.block_domain": "隱藏來自 {domain} 的一切文章",
   "account.blocked": "封鎖",
@@ -41,7 +41,7 @@
   "bundle_modal_error.retry": "重試",
   "column.blocks": "封鎖用戶",
   "column.community": "本站時間軸",
-  "column.direct": "Direct messages",
+  "column.direct": "個人訊息",
   "column.domain_blocks": "隱藏的服務站",
   "column.favourites": "最愛的文章",
   "column.follow_requests": "關注請求",
@@ -102,7 +102,7 @@
   "emoji_button.symbols": "符號",
   "emoji_button.travel": "旅遊景物",
   "empty_column.community": "本站時間軸暫時未有內容,快寫一點東西來搶頭香啊!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.direct": "你沒有個人訊息。當你發出或接收個人訊息,就會在這裡出現。",
   "empty_column.hashtag": "這個標籤暫時未有內容。",
   "empty_column.home": "你還沒有關注任何用戶。快看看{public},向其他用戶搭訕吧。",
   "empty_column.home.public_timeline": "公共時間軸",
@@ -136,7 +136,7 @@
   "keyboard_shortcuts.mention": "提及作者",
   "keyboard_shortcuts.reply": "回覆",
   "keyboard_shortcuts.search": "把標示移動到搜索",
-  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_hidden": "顯示或隱藏被標為敏感的文字",
   "keyboard_shortcuts.toot": "新的推文",
   "keyboard_shortcuts.unfocus": "把標示移離文字輸入和搜索",
   "keyboard_shortcuts.up": "在列表往上移動",
@@ -158,7 +158,7 @@
   "mute_modal.hide_notifications": "隱藏來自這用戶的通知嗎?",
   "navigation_bar.blocks": "被你封鎖的用戶",
   "navigation_bar.community_timeline": "本站時間軸",
-  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.direct": "個人訊息",
   "navigation_bar.domain_blocks": "隱藏的服務站",
   "navigation_bar.edit_profile": "修改個人資料",
   "navigation_bar.favourites": "最愛的內容",
@@ -243,7 +243,7 @@
   "search_results.total": "{count, number} 項結果",
   "standalone.public_title": "站點一瞥…",
   "status.block": "封鎖 @{name}",
-  "status.cancel_reblog_private": "Unboost",
+  "status.cancel_reblog_private": "取消轉推",
   "status.cannot_reblog": "這篇文章無法被轉推",
   "status.delete": "刪除",
   "status.direct": "私訊 @{name}",
@@ -259,7 +259,7 @@
   "status.pin": "置頂到資料頁",
   "status.pinned": "置頂文章",
   "status.reblog": "轉推",
-  "status.reblog_private": "Boost to original audience",
+  "status.reblog_private": "轉推到原讀者",
   "status.reblogged_by": "{name} 轉推",
   "status.reply": "回應",
   "status.replyAll": "回應所有人",
@@ -283,7 +283,7 @@
   "upload_button.label": "上載媒體檔案",
   "upload_form.description": "為視覺障礙人士添加文字說明",
   "upload_form.focus": "裁切",
-  "upload_form.undo": "還原",
+  "upload_form.undo": "刪除",
   "upload_progress.label": "上載中……",
   "video.close": "關閉影片",
   "video.exit_fullscreen": "退出全熒幕",
diff --git a/app/javascript/mastodon/service_worker/entry.js b/app/javascript/mastodon/service_worker/entry.js
index 5ad03caf2..5955e9146 100644
--- a/app/javascript/mastodon/service_worker/entry.js
+++ b/app/javascript/mastodon/service_worker/entry.js
@@ -10,9 +10,12 @@ function openWebCache() {
 }
 
 function fetchRoot() {
-  return fetch('/', { credentials: 'include' });
+  return fetch('/', { credentials: 'include', redirect: 'manual' });
 }
 
+const firefox = navigator.userAgent.match(/Firefox\/(\d+)/);
+const invalidOnlyIfCached = firefox && firefox[1] < 60;
+
 // Cause a new version of a registered Service Worker to replace an existing one
 // that is already installed, and replace the currently active worker on open pages.
 self.addEventListener('install', function(event) {
@@ -28,14 +31,10 @@ self.addEventListener('fetch', function(event) {
     const asyncResponse = fetchRoot();
     const asyncCache = openWebCache();
 
-    event.respondWith(asyncResponse.then(response => {
-      if (response.ok) {
-        return asyncCache.then(cache => cache.put('/', response))
-                         .then(() => response.clone());
-      }
-
-      throw null;
-    }).catch(() => asyncCache.then(cache => cache.match('/'))));
+    event.respondWith(asyncResponse.then(
+      response => asyncCache.then(cache => cache.put('/', response.clone()))
+                            .then(() => response),
+      () => asyncCache.then(cache => cache.match('/'))));
   } else if (url.pathname === '/auth/sign_out') {
     const asyncResponse = fetch(event.request);
     const asyncCache = openWebCache();
@@ -54,19 +53,22 @@ self.addEventListener('fetch', function(event) {
     event.respondWith(openSystemCache().then(cache => {
       return cache.match(event.request.url).then(cached => {
         if (cached === undefined) {
-          return fetch(event.request).then(fetched => {
-            if (fetched.ok) {
-              const put = cache.put(event.request.url, fetched.clone());
+          const asyncResponse = invalidOnlyIfCached && event.request.cache === 'only-if-cached' ?
+            fetch(event.request, { cache: 'no-cache' }) : fetch(event.request);
+
+          return asyncResponse.then(response => {
+            if (response.ok) {
+              const put = cache.put(event.request.url, response.clone());
 
               put.catch(() => freeStorage());
 
               return put.then(() => {
                 freeStorage();
-                return fetched;
+                return response;
               });
             }
 
-            return fetched;
+            return response;
           });
         }
 
diff --git a/app/javascript/mastodon/storage/modifier.js b/app/javascript/mastodon/storage/modifier.js
index db1d16058..a42b6ab12 100644
--- a/app/javascript/mastodon/storage/modifier.js
+++ b/app/javascript/mastodon/storage/modifier.js
@@ -184,7 +184,8 @@ export function putStatuses(records) {
 export function freeStorage() {
   // navigator.storage is not present on:
   // Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.100 Safari/537.36 Edge/16.16299
-  return 'storage' in navigator && navigator.storage.estimate().then(({ quota, usage }) => {
+  // estimate method is not present on Chrome 57.0.2987.98 on Linux.
+  return 'storage' in navigator && 'estimate' in navigator.storage && navigator.storage.estimate().then(({ quota, usage }) => {
     if (usage + storageMargin < quota) {
       return null;
     }
diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js
index 54459de3e..279a858ca 100644
--- a/app/javascript/mastodon/utils/resize_image.js
+++ b/app/javascript/mastodon/utils/resize_image.js
@@ -44,36 +44,25 @@ const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
 
 const processImage = (img, { width, height, orientation, type = 'image/png' }) => new Promise(resolve => {
   const canvas  = document.createElement('canvas');
-  [canvas.width, canvas.height] = orientation < 5 ? [width, height] : [height, width];
+
+  if (4 < orientation && orientation < 9) {
+    canvas.width  = height;
+    canvas.height = width;
+  } else {
+    canvas.width  = width;
+    canvas.height = height;
+  }
 
   const context = canvas.getContext('2d');
 
   switch (orientation) {
-  case 2:
-    context.translate(width, 0);
-    break;
-  case 3:
-    context.translate(width, height);
-    break;
-  case 4:
-    context.translate(0, height);
-    break;
-  case 5:
-    context.rotate(0.5 * Math.PI);
-    context.translate(1, -1);
-    break;
-  case 6:
-    context.rotate(0.5 * Math.PI);
-    context.translate(0, -height);
-    break;
-  case 7:
-    context.rotate(0.5, Math.PI);
-    context.translate(width, -height);
-    break;
-  case 8:
-    context.rotate(-0.5, Math.PI);
-    context.translate(-width, 0);
-    break;
+  case 2: context.transform(-1, 0, 0, 1, width, 0); break;
+  case 3: context.transform(-1, 0, 0, -1, width, height); break;
+  case 4: context.transform(1, 0, 0, -1, 0, height); break;
+  case 5: context.transform(0, 1, 1, 0, 0, 0); break;
+  case 6: context.transform(0, 1, -1, 0, height, 0); break;
+  case 7: context.transform(0, -1, -1, 0, height, width); break;
+  case 8: context.transform(0, -1, 1, 0, 0, width); break;
   }
 
   context.drawImage(img, 0, 0, width, height);
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 8d17a4ebe..ab1d63cd4 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       if lock.acquired?
         @status = find_existing_status
         process_status if @status.nil?
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb
index dbccc8330..d3a303a0c 100644
--- a/app/lib/ostatus/activity/creation.rb
+++ b/app/lib/ostatus/activity/creation.rb
@@ -15,6 +15,8 @@ class OStatus::Activity::Creation < OStatus::Activity::Base
         @status = find_status(id)
         return [@status, false] unless @status.nil?
         @status = process_status
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 721c9c928..453253db4 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -23,6 +23,8 @@ class ActivityPub::ProcessAccountService < BaseService
         create_account if @account.nil?
         update_account
         process_tags
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
@@ -44,7 +46,6 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.protocol    = :activitypub
     @account.username    = @username
     @account.domain      = @domain
-    @account.uri         = @uri
     @account.suspended   = true if auto_suspend?
     @account.silenced    = true if auto_silence?
     @account.private_key = nil
@@ -67,6 +68,7 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.followers_url           = @json['followers'] || ''
     @account.featured_collection_url = @json['featured'] || ''
     @account.url                     = url || @uri
+    @account.uri                     = @uri
     @account.display_name            = @json['name'] || ''
     @account.note                    = @json['summary'] || ''
     @account.locked                  = @json['manuallyApprovesFollowers'] || false
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index f9b1b2f0c..86d0f9971 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -23,6 +23,8 @@ class FetchLinkCardService < BaseService
       if lock.acquired?
         @card = PreviewCard.find_by(url: @url)
         process_url if @card.nil? || @card.updated_at <= 2.weeks.ago
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index de8d1151d..4323e7f06 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -49,6 +49,8 @@ class ResolveAccountService < BaseService
         else
           handle_ostatus
         end
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
diff --git a/app/services/update_remote_profile_service.rb b/app/services/update_remote_profile_service.rb
index aca1185de..68d36addf 100644
--- a/app/services/update_remote_profile_service.rb
+++ b/app/services/update_remote_profile_service.rb
@@ -41,24 +41,24 @@ class UpdateRemoteProfileService < BaseService
         account.header.destroy
       end
 
-      save_emojis(account) if remote_profile.emojis.present?
+      save_emojis if remote_profile.emojis.present?
     end
   end
 
-  def save_emojis(parent)
-    do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media?
+  def save_emojis
+    do_not_download = DomainBlock.find_by(domain: account.domain)&.reject_media?
 
     return if do_not_download
 
-    remote_account.emojis.each do |link|
+    remote_profile.emojis.each do |link|
       next unless link['href'] && link['name']
 
       shortcode = link['name'].delete(':')
-      emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: parent.account.domain)
+      emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: account.domain)
 
       next unless emoji.nil?
 
-      emoji = CustomEmoji.new(shortcode: shortcode, domain: parent.account.domain)
+      emoji = CustomEmoji.new(shortcode: shortcode, domain: account.domain)
       emoji.image_remote_url = link['href']
       emoji.save
     end