From 402c19a92475014e04df91eca759225f8a89d2ac Mon Sep 17 00:00:00 2001
From: Atsushi Yamamoto <yamaatsushi927@gmail.com>
Date: Mon, 29 May 2017 11:56:13 -0400
Subject: [PATCH] Add preference setting for delete toot modal (#3368)

* Set delete_modal preference to true by default
* Does not show confirmation modal if delete_modal is false
* Add ja translation for preference setting page
---
 .../settings/preferences_controller.rb           |  1 +
 .../mastodon/containers/status_container.js      | 15 ++++++++++-----
 app/javascript/mastodon/features/status/index.js | 16 +++++++++++-----
 app/lib/user_settings_decorator.rb               |  5 +++++
 app/models/user.rb                               |  4 ++++
 app/views/home/initial_state.json.rabl           |  1 +
 app/views/settings/preferences/show.html.haml    |  1 +
 config/locales/simple_form.en.yml                |  1 +
 config/locales/simple_form.ja.yml                |  1 +
 config/settings.yml                              |  1 +
 .../settings/preferences_controller_spec.rb      |  3 +++
 spec/lib/user_settings_decorator_spec.rb         |  7 +++++++
 12 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 3dc3013c352..71f5a7c04be 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -35,6 +35,7 @@ class Settings::PreferencesController < ApplicationController
     params.require(:user).permit(
       :setting_default_privacy,
       :setting_boost_modal,
+      :setting_delete_modal,
       :setting_auto_play_gif,
       notification_emails: %i(follow follow_request reblog favourite mention digest),
       interactions: %i(must_be_follower must_be_following)
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index 141f287afff..2592e9a69c8 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -37,6 +37,7 @@ const makeMapStateToProps = () => {
     status: getStatus(state, props.id),
     me: state.getIn(['meta', 'me']),
     boostModal: state.getIn(['meta', 'boost_modal']),
+    deleteModal: state.getIn(['meta', 'delete_modal']),
     autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
   });
 
@@ -74,11 +75,15 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
   },
 
   onDelete (status) {
-    dispatch(openModal('CONFIRM', {
-      message: intl.formatMessage(messages.deleteMessage),
-      confirm: intl.formatMessage(messages.deleteConfirm),
-      onConfirm: () => dispatch(deleteStatus(status.get('id'))),
-    }));
+    if (!this.deleteModal) {
+      dispatch(deleteStatus(status.get('id')));
+    } else {
+      dispatch(openModal('CONFIRM', {
+        message: intl.formatMessage(messages.deleteMessage),
+        confirm: intl.formatMessage(messages.deleteConfirm),
+        onConfirm: () => dispatch(deleteStatus(status.get('id'))),
+      }));
+    }
   },
 
   onMention (account, router) {
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index 24cf3d1089b..7fc55b795c4 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -48,6 +48,7 @@ const makeMapStateToProps = () => {
     descendantsIds: state.getIn(['timelines', 'descendants', Number(props.params.statusId)]),
     me: state.getIn(['meta', 'me']),
     boostModal: state.getIn(['meta', 'boost_modal']),
+    deleteModal: state.getIn(['meta', 'delete_modal']),
     autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
   });
 
@@ -68,6 +69,7 @@ class Status extends ImmutablePureComponent {
     descendantsIds: ImmutablePropTypes.list,
     me: PropTypes.number,
     boostModal: PropTypes.bool,
+    deleteModal: PropTypes.bool,
     autoPlayGif: PropTypes.bool,
     intl: PropTypes.object.isRequired,
   };
@@ -113,11 +115,15 @@ class Status extends ImmutablePureComponent {
   handleDeleteClick = (status) => {
     const { dispatch, intl } = this.props;
 
-    dispatch(openModal('CONFIRM', {
-      message: intl.formatMessage(messages.deleteMessage),
-      confirm: intl.formatMessage(messages.deleteConfirm),
-      onConfirm: () => dispatch(deleteStatus(status.get('id'))),
-    }));
+    if (!this.props.deleteModal) {
+      dispatch(deleteStatus(status.get('id')));
+    } else {
+      dispatch(openModal('CONFIRM', {
+        message: intl.formatMessage(messages.deleteMessage),
+        confirm: intl.formatMessage(messages.deleteConfirm),
+        onConfirm: () => dispatch(deleteStatus(status.get('id'))),
+      }));
+    }
   }
 
   handleMentionClick = (account, router) => {
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 6104773addc..af264bbd535 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -19,6 +19,7 @@ class UserSettingsDecorator
     user.settings['interactions'] = merged_interactions
     user.settings['default_privacy'] = default_privacy_preference
     user.settings['boost_modal'] = boost_modal_preference
+    user.settings['delete_modal'] = delete_modal_preference
     user.settings['auto_play_gif'] = auto_play_gif_preference
   end
 
@@ -38,6 +39,10 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_boost_modal'
   end
 
+  def delete_modal_preference
+    boolean_cast_setting 'setting_delete_modal'
+  end
+
   def auto_play_gif_preference
     boolean_cast_setting 'setting_auto_play_gif'
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9f2a49b6a8b..f367d74aa64 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -80,6 +80,10 @@ class User < ApplicationRecord
     settings.boost_modal
   end
 
+  def setting_delete_modal
+    settings.delete_modal
+  end
+
   def setting_auto_play_gif
     settings.auto_play_gif
   end
diff --git a/app/views/home/initial_state.json.rabl b/app/views/home/initial_state.json.rabl
index ac0bee2e279..e305f8e7ae2 100644
--- a/app/views/home/initial_state.json.rabl
+++ b/app/views/home/initial_state.json.rabl
@@ -9,6 +9,7 @@ node(:meta) do
     me: current_account.id,
     admin: @admin.try(:id),
     boost_modal: current_account.user.setting_boost_modal,
+    delete_modal: current_account.user.setting_delete_modal,
     auto_play_gif: current_account.user.setting_auto_play_gif,
   }
 end
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index 3771698d190..721ce6a219a 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -40,6 +40,7 @@
 
   .fields-group
     = f.input :setting_boost_modal, as: :boolean, wrapper: :with_label
+    = f.input :setting_delete_modal, as: :boolean, wrapper: :with_label
 
   .fields-group
     = f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 6a888e3fe84..5d1ede96808 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -36,6 +36,7 @@ en:
         password: Password
         setting_auto_play_gif: Auto-play animated GIFs
         setting_boost_modal: Show confirmation dialog before boosting
+        setting_delete_modal: Show confirmation dialog before deleting a toot
         setting_default_privacy: Post privacy
         severity: Severity
         type: Import type
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index fcf0923e018..343139b64bb 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -33,6 +33,7 @@ ja:
         password: パスワード
         setting_auto_play_gif: アニメーションGIFを自動再生する
         setting_boost_modal: ブーストする前に確認ダイアログを表示する
+        setting_delete_modal: トゥートを削除する前に確認ダイアログを表示する
         setting_default_privacy: 投稿の公開範囲
         severity: 重大性
         type: インポートする項目
diff --git a/config/settings.yml b/config/settings.yml
index 9813963b28e..4811213cbdc 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -16,6 +16,7 @@ defaults: &defaults
   closed_registrations_message: ''
   boost_modal: false
   auto_play_gif: true
+  delete_modal: true
   notification_emails:
     follow: false
     reblog: false
diff --git a/spec/controllers/settings/preferences_controller_spec.rb b/spec/controllers/settings/preferences_controller_spec.rb
index 38e43f211b9..60fa423023d 100644
--- a/spec/controllers/settings/preferences_controller_spec.rb
+++ b/spec/controllers/settings/preferences_controller_spec.rb
@@ -28,12 +28,14 @@ describe Settings::PreferencesController do
 
     it 'updates user settings' do
       user.settings['boost_modal'] = false
+      user.settings['delete_modal'] = true
       user.settings['notification_emails'] = user.settings['notification_emails'].merge('follow' => false)
       user.settings['interactions'] = user.settings['interactions'].merge('must_be_follower' => true)
 
       put :update, params: {
         user: {
           setting_boost_modal: '1',
+          setting_delete_modal: '0',
           notification_emails: { follow: '1' },
           interactions: { must_be_follower: '0' },
         }
@@ -42,6 +44,7 @@ describe Settings::PreferencesController do
       expect(response).to redirect_to(settings_preferences_path)
       user.reload
       expect(user.settings['boost_modal']).to be true
+      expect(user.settings['delete_modal']).to be false
       expect(user.settings['notification_emails']['follow']).to be true
       expect(user.settings['interactions']['must_be_follower']).to be false
     end
diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb
index 466c57fa51c..66e42fa0ecc 100644
--- a/spec/lib/user_settings_decorator_spec.rb
+++ b/spec/lib/user_settings_decorator_spec.rb
@@ -35,6 +35,13 @@ describe UserSettingsDecorator do
       expect(user.settings['boost_modal']).to eq true
     end
 
+    it 'updates the user settings value for delete toot modal' do
+      values = { 'setting_delete_modal' => '0' }
+
+      settings.update(values)
+      expect(user.settings['delete_modal']).to eq false
+    end
+
     it 'updates the user settings value for gif auto play' do
       values = { 'setting_auto_play_gif' => '0' }