FEATURE: shortcuts for quote (q) and fast edit (e)

FEATURE: shortcuts for quote (q) and fast edit (e)

Reimplemented following the revert in ce0daae636727c40ac9b483e0aff8aab034c6f55

This approach uses the global e/q shortcuts, rather than shifting focus to the quote-button component. The current quoteState is used to determine whether the quote-button is currently visible. If yes, an appEvent transmits the intention to the quote-button component. If no, the old behavior is maintained.

Co-authored-by: Joffrey JAFFEUX j.jaffeux@gmail.com

diff --git a/app/assets/javascripts/discourse/app/components/quote-button.js b/app/assets/javascripts/discourse/app/components/quote-button.js
index a41198a..31c2640 100644
--- a/app/assets/javascripts/discourse/app/components/quote-button.js
+++ b/app/assets/javascripts/discourse/app/components/quote-button.js
@@ -277,6 +277,8 @@ export default Component.extend(KeyEnterEscape, {
           onSelectionChanged();
         }
       });
+    this.appEvents.on("quote-button:quote", this, "insertQuote");
+    this.appEvents.on("quote-button:edit", this, "_toggleFastEditForm");
   },
 
   willDestroyElement() {
@@ -284,6 +286,8 @@ export default Component.extend(KeyEnterEscape, {
       .off("mousedown.quote-button")
       .off("mouseup.quote-button")
       .off("selectionchange.quote-button");
+    this.appEvents.off("quote-button:quote", this, "insertQuote");
+    this.appEvents.off("quote-button:edit", this, "_toggleFastEditForm");
   },
 
   @discourseComputed("topic.{isPrivateMessage,invisible,category}")
diff --git a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js
index 8355a93..b97787f 100644
--- a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js
+++ b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js
@@ -29,7 +29,7 @@ const DEFAULT_BINDINGS = {
   "command+]": { handler: "webviewKeyboardForward", anonymous: true },
   "mod+p": { handler: "printTopic", anonymous: true },
   d: { postAction: "deletePost" },
-  e: { postAction: "editPost" },
+  e: { handler: "editPost" },
   end: { handler: "goToLastPost", anonymous: true },
   "command+down": { handler: "goToLastPost", anonymous: true },
   f: { handler: "toggleBookmarkTopic" },
@@ -107,10 +107,10 @@ export default {
     this.searchService = this.container.lookup("search-service:main");
     this.appEvents = this.container.lookup("service:app-events");
     this.currentUser = this.container.lookup("current-user:main");
-    let siteSettings = this.container.lookup("site-settings:main");
+    this.siteSettings = this.container.lookup("site-settings:main");
 
     // Disable the shortcut if private messages are disabled
-    if (!siteSettings.enable_personal_messages) {
+    if (!this.siteSettings.enable_personal_messages) {
       delete DEFAULT_BINDINGS["g m"];
     }
   },
@@ -261,6 +261,11 @@ export default {
   },
 
   quoteReply() {
+    if (this.isPostTextSelected()) {
+      this.appEvents.trigger("quote-button:quote");
+      return false;
+    }
+
     this.sendToSelectedPost("replyToPost");
     // lazy but should work for now
     later(() => $(".d-editor .quote").click(), 500);
@@ -268,6 +273,17 @@ export default {
     return false;
   },
 
+  editPost() {
+    if (this.siteSettings.enable_fast_edit && this.isPostTextSelected()) {
+      this.appEvents.trigger("quote-button:edit");
+      return false;
+    } else {
+      this.sendToSelectedPost("editPost");
+    }
+
+    return false;
+  },
+
   goToNextTopic() {
     nextTopicUrl().then((url) => {
       if (url) {
@@ -489,6 +505,11 @@ export default {
     }
   },
 
+  isPostTextSelected() {
+    const topicController = this.container.lookup("controller:topic");
+    return !!topicController?.get("quoteState")?.postId;
+  },
+
   sendToSelectedPost(action, elem) {
     // TODO: We should keep track of the post without a CSS class
     const selectedPost =
diff --git a/app/assets/javascripts/discourse/app/templates/components/quote-button.hbs b/app/assets/javascripts/discourse/app/templates/components/quote-button.hbs
index 38d4d4d..d486a77 100644
--- a/app/assets/javascripts/discourse/app/templates/components/quote-button.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/quote-button.hbs
@@ -4,7 +4,9 @@
       class="btn-flat insert-quote"
       action=(action "insertQuote")
       icon="quote-left"
-      label="post.quote_reply"}}
+      label="post.quote_reply"
+      title="post.quote_reply_shortcut"
+    }}
   {{/if}}
 
   {{#if siteSettings.enable_fast_edit}}
@@ -14,6 +16,7 @@
         action=(action "_toggleFastEditForm")
         label="post.quote_edit"
         class="btn-flat quote-edit-label"
+        title="post.quote_edit_shortcut"
       }}
     {{/if}}
   {{/if}}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index c3f55f0..044263b 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -3016,7 +3016,9 @@ en:
 
     post:
       quote_reply: "Quote"
+      quote_reply_shortcut: "Or press q"
       quote_edit: "Edit"
+      quote_edit_shortcut: "Or press e"
       quote_share: "Share"
       edit_reason: "Reason: "
       post_number: "post %{number}"

GitHub sha: 9efc57f0c66547cb10ad053e7c82aa5b60b8d4da

This commit appears in #14563 which was approved by eviltrout. It was merged by davidtaylorhq.