UX: Discard selected post if it is not in viewport. (#7869)

UX: Discard selected post if it is not in viewport. (#7869)

This way, users can combine keyboard shortcuts with mouse scrolling.

diff --git a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6 b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
index 11e7ca7..5e0a399 100644
--- a/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
+++ b/app/assets/javascripts/discourse/lib/keyboard-shortcuts.js.es6
@@ -439,9 +439,22 @@ export default {
       $selected = $articles.filter("[data-islastviewedtopic=true]");
     }
 
+    // Discard selection if it is not in viewport, so users can combine
+    // keyboard shortcuts with mouse scrolling.
+    if ($selected.length !== 0) {
+      const offset = minimumOffset();
+      const beginScreen = $(window).scrollTop() - offset;
+      const endScreen = beginScreen + window.innerHeight + offset;
+      const beginArticle = $selected.offset().top;
+      const endArticle = $selected.offset().top + $selected.height();
+      if (beginScreen > endArticle || beginArticle > endScreen) {
+        $selected = null;
+      }
+    }
+
     // If still nothing is selected, select the first post that is
     // visible and cancel move operation.
-    if ($selected.length === 0) {
+    if (!$selected || $selected.length === 0) {
       const offset = minimumOffset();
       $selected = $articles
         .toArray()

GitHub sha: 90fcdad3

1 Like