about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--app/javascript/mastodon/components/status_content.js2
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.js10
-rw-r--r--app/javascript/mastodon/features/compose/containers/sensitive_button_container.js5
-rw-r--r--app/javascript/mastodon/locales/ar.json3
-rw-r--r--app/javascript/mastodon/locales/bg.json3
-rw-r--r--app/javascript/mastodon/locales/ca.json3
-rw-r--r--app/javascript/mastodon/locales/de.json3
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json17
-rw-r--r--app/javascript/mastodon/locales/en.json3
-rw-r--r--app/javascript/mastodon/locales/eo.json3
-rw-r--r--app/javascript/mastodon/locales/es.json3
-rw-r--r--app/javascript/mastodon/locales/fa.json3
-rw-r--r--app/javascript/mastodon/locales/fi.json3
-rw-r--r--app/javascript/mastodon/locales/fr.json3
-rw-r--r--app/javascript/mastodon/locales/gl.json3
-rw-r--r--app/javascript/mastodon/locales/he.json3
-rw-r--r--app/javascript/mastodon/locales/hr.json3
-rw-r--r--app/javascript/mastodon/locales/hu.json3
-rw-r--r--app/javascript/mastodon/locales/hy.json3
-rw-r--r--app/javascript/mastodon/locales/id.json3
-rw-r--r--app/javascript/mastodon/locales/io.json3
-rw-r--r--app/javascript/mastodon/locales/it.json3
-rw-r--r--app/javascript/mastodon/locales/ja.json3
-rw-r--r--app/javascript/mastodon/locales/ko.json3
-rw-r--r--app/javascript/mastodon/locales/nl.json3
-rw-r--r--app/javascript/mastodon/locales/no.json3
-rw-r--r--app/javascript/mastodon/locales/oc.json3
-rw-r--r--app/javascript/mastodon/locales/pl.json3
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json3
-rw-r--r--app/javascript/mastodon/locales/pt.json3
-rw-r--r--app/javascript/mastodon/locales/ru.json3
-rw-r--r--app/javascript/mastodon/locales/sk.json3
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json3
-rw-r--r--app/javascript/mastodon/locales/sr.json3
-rw-r--r--app/javascript/mastodon/locales/sv.json3
-rw-r--r--app/javascript/mastodon/locales/th.json3
-rw-r--r--app/javascript/mastodon/locales/tr.json3
-rw-r--r--app/javascript/mastodon/locales/uk.json3
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json3
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json3
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json3
-rw-r--r--app/javascript/mastodon/reducers/compose.js14
-rw-r--r--app/javascript/mastodon/reducers/statuses.js22
-rw-r--r--app/javascript/styles/mastodon/rtl.scss16
-rw-r--r--app/views/about/show.html.haml2
-rw-r--r--app/workers/backup_worker.rb11
-rw-r--r--boxfile.yml2
-rw-r--r--lib/mastodon/version.rb2
-rw-r--r--lib/tasks/mastodon.rake55
50 files changed, 190 insertions, 81 deletions
diff --git a/.travis.yml b/.travis.yml
index 61d51ca21..576659aaf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,5 +55,5 @@ before_script:
 
 script:
   - travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
-  - yarn test
+  - yarn run test:jest
   - bundle exec i18n-tasks check-normalized && bundle exec i18n-tasks unused
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 701b5702c..b6082f008 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -154,7 +154,7 @@ export default class StatusContent extends React.PureComponent {
       }
 
       return (
-        <div className={classNames} ref={this.setRef} tabIndex='0' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
+        <div className={classNames} ref={this.setRef} tabIndex='0' style={directionStyle} onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}>
           <p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
             <span dangerouslySetInnerHTML={spoilerContent} />
             {' '}
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index f5f2475ea..5e21cf7c6 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -17,7 +17,7 @@ const mapStateToProps = (state, { params: { accountId }, withReplies = false })
 
   return {
     statusIds: state.getIn(['timelines', `account:${path}`, 'items'], ImmutableList()),
-    featuredStatusIds: state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], ImmutableList()),
+    featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], ImmutableList()),
     isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']),
     hasMore: !!state.getIn(['timelines', `account:${path}`, 'next']),
   };
@@ -40,14 +40,18 @@ export default class AccountTimeline extends ImmutablePureComponent {
     const { params: { accountId }, withReplies } = this.props;
 
     this.props.dispatch(fetchAccount(accountId));
-    this.props.dispatch(refreshAccountFeaturedTimeline(accountId));
+    if (!withReplies) {
+      this.props.dispatch(refreshAccountFeaturedTimeline(accountId));
+    }
     this.props.dispatch(refreshAccountTimeline(accountId, withReplies));
   }
 
   componentWillReceiveProps (nextProps) {
     if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
       this.props.dispatch(fetchAccount(nextProps.params.accountId));
-      this.props.dispatch(refreshAccountFeaturedTimeline(nextProps.params.accountId));
+      if (!nextProps.withReplies) {
+        this.props.dispatch(refreshAccountFeaturedTimeline(nextProps.params.accountId));
+      }
       this.props.dispatch(refreshAccountTimeline(nextProps.params.accountId, nextProps.params.withReplies));
     }
   }
diff --git a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
index c8e74f5a1..43de8f213 100644
--- a/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
+++ b/app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
@@ -9,7 +9,8 @@ import spring from 'react-motion/lib/spring';
 import { injectIntl, defineMessages } from 'react-intl';
 
 const messages = defineMessages({
-  title: { id: 'compose_form.sensitive', defaultMessage: 'Mark media as sensitive' },
+  marked: { id: 'compose_form.sensitive.marked', defaultMessage: 'Media is marked as sensitive' },
+  unmarked: { id: 'compose_form.sensitive.unmarked', defaultMessage: 'Media is not marked as sensitive' },
 });
 
 const mapStateToProps = state => ({
@@ -50,7 +51,7 @@ class SensitiveButton extends React.PureComponent {
             <div className={className} style={{ transform: `scale(${scale})` }}>
               <IconButton
                 className='compose-form__sensitive-button__icon'
-                title={intl.formatMessage(messages.title)}
+                title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
                 icon={icon}
                 onClick={onClick}
                 size={18}
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index c7734d72e..4928930fe 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "فيمَ تفكّر؟",
   "compose_form.publish": "بوّق",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "ضع علامة على الوسيط باعتباره حسّاس",
+  "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": "تنبيه عن المحتوى",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index b596d25a0..1dee16748 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Какво си мислиш?",
   "compose_form.publish": "Раздумай",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Отбележи съдържанието като деликатно",
+  "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": "Content warning",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 729d29876..4923c1032 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "En què estàs pensant?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marca el contingut multimèdia com a sensible",
+  "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": "Escriu l'avís aquí",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 15ede8262..e0fc0ee85 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Worüber möchtest du schreiben?",
   "compose_form.publish": "Tröt",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Medien als heikel markieren",
+  "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": "Inhaltswarnung",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 4466d2ff6..5bb7b85d6 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -322,6 +322,15 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Media",
+        "id": "account.media"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/account_gallery/index.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "Toots",
         "id": "account.posts"
       },
@@ -768,8 +777,12 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Mark media as sensitive",
-        "id": "compose_form.sensitive"
+        "defaultMessage": "Media is marked as sensitive",
+        "id": "compose_form.sensitive.marked"
+      },
+      {
+        "defaultMessage": "Media is not marked as sensitive",
+        "id": "compose_form.sensitive.unmarked"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/containers/sensitive_button_container.json"
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index d32e94129..d0d863f79 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "What is on your mind?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Mark media as sensitive",
+  "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",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 6dd9ed133..fd687e8b1 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Pri kio vi pensas?",
   "compose_form.publish": "Hup",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marki aŭdovidaĵon tikla",
+  "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": "Skribu vian averton ĉi tie",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 9a219f951..92b37dbf0 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "¿En qué estás pensando?",
   "compose_form.publish": "Tootear",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marcar contenido como sensible",
+  "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": "Advertencia de contenido",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 9a925c320..455dc5d9f 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "تازه چه خبر؟",
   "compose_form.publish": "بوق",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "تصاویر حساس هستند",
+  "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": "هشدار محتوا",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index c8775c78d..1dea42ed4 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Mitä sinulla on mielessä?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Merkitse media herkäksi",
+  "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": "Content warning",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index 202d0f7ce..2613fe56d 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Qu’avez-vous en tête ?",
   "compose_form.publish": "Pouet",
   "compose_form.publish_loud": "{publish} !",
-  "compose_form.sensitive": "Marquer le média comme sensible",
+  "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": "Écrivez ici votre avertissement",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 404253b7f..edfb9cfcb 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "A qué andas?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marcar medios como sensibles",
+  "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": "Escriba o aviso aquí",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index c9dcd088d..b637ae414 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "מה עובר לך בראש?",
   "compose_form.publish": "ללחוש",
   "compose_form.publish_loud": "לחצרץ!",
-  "compose_form.sensitive": "סימון תוכן כרגיש",
+  "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": "אזהרת תוכן",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 6c8283870..4b64d796d 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Što ti je na umu?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Označi media sadržaj kao osjetljiv",
+  "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": "Upozorenje o sadržaju",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index 1d635490c..79888e41e 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Mire gondolsz?",
   "compose_form.publish": "Tülk",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Tartalom érzékenynek jelölése",
+  "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": "Figyelmeztetését írja ide",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 6e1002487..932ff1565 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Ի՞նչ կա մտքիդ",
   "compose_form.publish": "Թթել",
   "compose_form.publish_loud": "Թթե՜լ",
-  "compose_form.sensitive": "Նշել բովանդակությունը որպես կասկածելի",
+  "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": "Գրիր նախազգուշացումդ այստեղ",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index 923dee919..14261f199 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Apa yang ada di pikiran anda?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Tandai media sensitif",
+  "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": "Peringatan konten",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index f174a0c7d..5ea982f46 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Quo esas en tua spirito?",
   "compose_form.publish": "Siflar",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Markizar kontenajo kom trubliva",
+  "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": "Averto di kontenajo",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 72e8381f1..068598de2 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "A cosa stai pensando?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Segnala file come sensibile",
+  "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": "Content warning",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 1001c196e..514a5bf42 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "今なにしてる?",
   "compose_form.publish": "トゥート",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "メディアを閲覧注意としてマークする",
+  "compose_form.sensitive.marked": "メディアに閲覧注意が設定されています",
+  "compose_form.sensitive.unmarked": "メディアに閲覧注意が設定されていません",
   "compose_form.spoiler.marked": "Text is hidden behind warning",
   "compose_form.spoiler.unmarked": "Text is not hidden",
   "compose_form.spoiler_placeholder": "ここに警告を書いてください",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 039f3a403..532c1f04d 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "지금 무엇을 하고 있나요?",
   "compose_form.publish": "툿",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "이 미디어를 민감한 미디어로 취급",
+  "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": "경고",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index f58d0314b..d508d9412 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Wat wil je kwijt?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Media als gevoelig markeren (nsfw)",
+  "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": "Waarschuwingstekst",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index b82476b0c..aaad033e2 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Hva har du på hjertet?",
   "compose_form.publish": "Tut",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Merk media som følsomt",
+  "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": "Innholdsadvarsel",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index d6308b864..c7a26c1c6 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "A de qué pensatz ?",
   "compose_form.publish": "Tut",
   "compose_form.publish_loud": "{publish} !",
-  "compose_form.sensitive": "Marcar lo mèdia coma sensible",
+  "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": "Escrivètz l’avertiment aquí",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index b7523f6d8..2d6f0c01b 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Co Ci chodzi po głowie?",
   "compose_form.publish": "Wyślij",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Oznacz treści jako wrażliwe",
+  "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": "Wprowadź swoje ostrzeżenie o zawartości",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 6416f2598..6bf24c52a 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "No que você está pensando?",
   "compose_form.publish": "Publicar",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marcar mídia como conteúdo sensível",
+  "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": "Aviso de conteúdo",
diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json
index 5f87fabd7..3b20cf4e6 100644
--- a/app/javascript/mastodon/locales/pt.json
+++ b/app/javascript/mastodon/locales/pt.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Em que estás a pensar?",
   "compose_form.publish": "Publicar",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Marcar media como conteúdo sensível",
+  "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": "Aviso de conteúdo",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 690b8e28a..ec21b5d55 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "О чем Вы думаете?",
   "compose_form.publish": "Трубить",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Отметить как чувствительный контент",
+  "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": "Напишите свое предупреждение здесь",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index ead0e8e29..2cb249d2a 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Na čo myslíš?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Označ médiá ako chúlostivé",
+  "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": "Sem napíšte vaše varovanie",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index 7f4e64c20..c6512cda4 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Šta Vam je na umu?",
   "compose_form.publish": "Tutni",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Obeleži multimediju kao osetljivu",
+  "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": "Ovde upišite upozorenje",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 52f756a70..93fbe5960 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Шта Вам је на уму?",
   "compose_form.publish": "Тутни",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Обележи мултимедију као осетљиву",
+  "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": "Овде упишите упозорење",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 1436d23b8..3451212d0 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Vad funderar du på?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Markera media som känslig",
+  "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": "Skriv din varning här",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 5fdbb848a..95a933b40 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "What is on your mind?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Mark media as sensitive",
+  "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": "Content warning",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index f7903584a..baaa5c97a 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Ne düşünüyorsun?",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Görseli hassas olarak işaretle",
+  "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": "İçerik uyarısı",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index c2601797a..1755c55b4 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "Що у Вас на думці?",
   "compose_form.publish": "Дмухнути",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "Відмітити як непристойний зміст",
+  "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": "Попередження щодо прихованого тексту",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index bfc4c682a..d031c85f3 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "在想啥?",
   "compose_form.publish": "嘟嘟",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "将媒体文件标记为敏感内容",
+  "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": "折叠部分的警告消息",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 403f40eef..d3ad238ad 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "你在想甚麼?",
   "compose_form.publish": "發文",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "將媒體檔案標示為「敏感內容」",
+  "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": "敏感警告訊息",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 1a1b8f378..3a5eade41 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -60,7 +60,8 @@
   "compose_form.placeholder": "在想些什麼?",
   "compose_form.publish": "貼掉",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive": "將此媒體標為敏感",
+  "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": "內容警告",
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 532f4b2a7..5eadebb81 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -35,6 +35,8 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrde
 import uuid from '../uuid';
 import { me } from '../initial_state';
 
+const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
+
 const initialState = ImmutableMap({
   mounted: 0,
   sensitive: false,
@@ -135,12 +137,14 @@ const updateSuggestionTags = (state, token) => {
 };
 
 const insertEmoji = (state, position, emojiData) => {
-  const emoji = emojiData.native;
+  const oldText = state.get('text');
+  const needsSpace = emojiData.custom && position > 0 && !allowedAroundShortCode.includes(oldText[position - 1]);
+  const emoji = needsSpace ? ' ' + emojiData.native : emojiData.native;
 
-  return state.withMutations(map => {
-    map.update('text', oldText => `${oldText.slice(0, position)}${emoji} ${oldText.slice(position)}`);
-    map.set('focusDate', new Date());
-    map.set('idempotencyKey', uuid());
+  return state.merge({
+    text: `${oldText.slice(0, position)}${emoji} ${oldText.slice(position)}`,
+    focusDate: new Date(),
+    idempotencyKey: uuid(),
   });
 };
 
diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js
index 5a47e7272..7b3141623 100644
--- a/app/javascript/mastodon/reducers/statuses.js
+++ b/app/javascript/mastodon/reducers/statuses.js
@@ -56,17 +56,21 @@ const normalizeStatus = (state, status) => {
     normalStatus.reblog = status.reblog.id;
   }
 
-  const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
+  // Only calculate these values when status first encountered
+  // Otherwise keep the ones already in the reducer
+  if (!state.has(status.id)) {
+    const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n');
 
-  const emojiMap = normalStatus.emojis.reduce((obj, emoji) => {
-    obj[`:${emoji.shortcode}:`] = emoji;
-    return obj;
-  }, {});
+    const emojiMap = normalStatus.emojis.reduce((obj, emoji) => {
+      obj[`:${emoji.shortcode}:`] = emoji;
+      return obj;
+    }, {});
 
-  normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
-  normalStatus.contentHtml  = emojify(normalStatus.content, emojiMap);
-  normalStatus.spoilerHtml  = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap);
-  normalStatus.hidden       = normalStatus.sensitive;
+    normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
+    normalStatus.contentHtml  = emojify(normalStatus.content, emojiMap);
+    normalStatus.spoilerHtml  = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap);
+    normalStatus.hidden       = normalStatus.sensitive;
+  }
 
   return state.update(status.id, ImmutableMap(), map => map.mergeDeep(fromJS(normalStatus)));
 };
diff --git a/app/javascript/styles/mastodon/rtl.scss b/app/javascript/styles/mastodon/rtl.scss
index 77420c84b..e9099a9e9 100644
--- a/app/javascript/styles/mastodon/rtl.scss
+++ b/app/javascript/styles/mastodon/rtl.scss
@@ -1,6 +1,22 @@
 body.rtl {
   direction: rtl;
 
+  .column-header > button {
+    text-align: right;
+    padding-left: 0;
+    padding-right: 15px;
+  }
+
+  .landing-page__logo {
+    margin-right: 0;
+    margin-left: 20px;
+  }
+
+  .landing-page .features-list .features-list__row .visual {
+    margin-left: 0;
+    margin-right: 15px;
+  }
+
   .column-link__icon,
   .column-header__icon {
     margin-right: 0;
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index dbb914f11..85e5442af 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -50,7 +50,7 @@
 
               %p= @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)
 
-          .landing-page__call-to-action
+          .landing-page__call-to-action{ dir: 'ltr' }
             .row
               .row__information-board
                 .information-board__section
diff --git a/app/workers/backup_worker.rb b/app/workers/backup_worker.rb
index ec6db4e9e..e4c609d70 100644
--- a/app/workers/backup_worker.rb
+++ b/app/workers/backup_worker.rb
@@ -3,7 +3,16 @@
 class BackupWorker
   include Sidekiq::Worker
 
-  sidekiq_options queue: 'pull'
+  sidekiq_options queue: 'pull', backtrace: true, retry: 5, dead: false
+
+  sidekiq_retries_exhausted do |msg|
+    backup_id = msg['args'].first
+
+    ActiveRecord::Base.connection_pool.with_connection do
+      backup = Backup.find(backup_id)
+      backup&.destroy
+    end
+  end
 
   def perform(backup_id)
     backup = Backup.find(backup_id)
diff --git a/boxfile.yml b/boxfile.yml
index bb4149e70..70774dac9 100644
--- a/boxfile.yml
+++ b/boxfile.yml
@@ -193,7 +193,7 @@ data.db:
     - id: backup
       schedule: '0 3 * * *'
       command: |
-        PGPASSWORD=${DATA_POSTGRES_PASS} pg_dump -U ${DATA_POSTGRES_USER} -w -Fc -O gonano |
+        PGPASSWORD=${DATA_DB_PASS} pg_dump -U ${DATA_DB_USER} -w -Fc -O gonano |
         gzip |
         curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).sql.gz --data-binary @- &&
         curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ |
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 50498be1d..4241ffe32 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -21,7 +21,7 @@ module Mastodon
     end
 
     def flags
-      'rc1'
+      'rc2'
     end
 
     def to_a
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index d6c9e2d01..13df76f91 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -224,24 +224,43 @@ namespace :mastodon do
       prompt.say "\n"
 
       loop do
-        env['SMTP_SERVER'] = prompt.ask('SMTP server:') do |q|
-          q.required true
-          q.default 'smtp.mailgun.org'
-          q.modify :strip
-        end
+        if prompt.yes?('Do you want to send e-mails from localhost?', default: false)
+          env['SMTP_SERVER'] = 'localhost'
+          env['SMTP_PORT'] = 25
+          env['SMTP_AUTH_METHOD'] = 'none'
+          env['SMTP_OPENSSL_VERIFY_MODE'] = 'none'
+        else
+          env['SMTP_SERVER'] = prompt.ask('SMTP server:') do |q|
+            q.required true
+            q.default 'smtp.mailgun.org'
+            q.modify :strip
+          end
 
-        env['SMTP_PORT'] = prompt.ask('SMTP port:') do |q|
-          q.required true
-          q.default 587
-          q.convert :int
-        end
+          env['SMTP_PORT'] = prompt.ask('SMTP port:') do |q|
+            q.required true
+            q.default 587
+            q.convert :int
+          end
 
-        env['SMTP_LOGIN'] = prompt.ask('SMTP username:') do |q|
-          q.modify :strip
-        end
+          env['SMTP_LOGIN'] = prompt.ask('SMTP username:') do |q|
+            q.modify :strip
+          end
 
-        env['SMTP_PASSWORD'] = prompt.ask('SMTP password:') do |q|
-          q.echo false
+          env['SMTP_PASSWORD'] = prompt.ask('SMTP password:') do |q|
+            q.echo false
+          end
+
+          env['SMTP_AUTH_METHOD'] = prompt.ask('SMTP authentication:') do |q|
+            q.required
+            q.default 'plain'
+            q.modify :strip
+          end
+
+          env['SMTP_OPENSSL_VERIFY_MODE'] = prompt.ask('SMTP OpenSSL verify mode:') do |q|
+            q.required
+            q.default 'peer'
+            q.modify :strip
+          end
         end
 
         env['SMTP_FROM_ADDRESS'] = prompt.ask('E-mail address to send e-mails "from":') do |q|
@@ -261,7 +280,8 @@ namespace :mastodon do
             :user_name            => env['SMTP_LOGIN'].presence,
             :password             => env['SMTP_PASSWORD'].presence,
             :domain               => env['LOCAL_DOMAIN'],
-            :authentication       => :plain,
+            :authentication       => env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain,
+            :openssl_verify_mode  => env['SMTP_OPENSSL_VERIFY_MODE'],
             :enable_starttls_auto => true,
           }
 
@@ -271,6 +291,7 @@ namespace :mastodon do
 
           mail = ActionMailer::Base.new.mail to: send_to, subject: 'Test', body: 'Mastodon SMTP configuration works!'
           mail.deliver
+          break
         rescue StandardError => e
           prompt.error 'E-mail could not be sent with this configuration, try again.'
           prompt.error e.message
@@ -302,7 +323,7 @@ namespace :mastodon do
           prompt.say 'Running `RAILS_ENV=production rails db:setup` ...'
           prompt.say "\n"
 
-          if cmd.run!({ RAILS_ENV: 'production' }, :rails, 'db:setup').failure?
+          if cmd.run!({ RAILS_ENV: 'production', SAFETY_ASSURED: 1 }, :rails, 'db:setup').failure?
             prompt.say "\n"
             prompt.error 'That failed! Perhaps your configuration is not right'
           else