From 66f621049ace45bf06f1b4d618c7cb6dca242506 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Sun, 21 Jan 2024 12:14:05 +1300 Subject: [PATCH] keyboard shortcuts --- app/main/routes.py | 5 ++ app/static/js/scripts.js | 63 +++++++++++++++++++++++-- app/static/styles.css | 11 +++++ app/static/styles.scss | 11 +++++ app/templates/keyboard_shortcuts.html | 68 +++++++++++++++++++++++++++ app/templates/post/post.html | 6 ++- 6 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 app/templates/keyboard_shortcuts.html diff --git a/app/main/routes.py b/app/main/routes.py index 99418ee1..74c7786a 100644 --- a/app/main/routes.py +++ b/app/main/routes.py @@ -215,6 +215,11 @@ def robots(): return resp +@bp.route('/keyboard_shortcuts') +def keyboard_shortcuts(): + return render_template('keyboard_shortcuts.html') + + @bp.route('/test') def test(): return pytesseract.image_to_string(Image.open('test.png').convert('L')) diff --git a/app/static/js/scripts.js b/app/static/js/scripts.js index 0c407d21..e766ae94 100644 --- a/app/static/js/scripts.js +++ b/app/static/js/scripts.js @@ -361,13 +361,17 @@ function setupTimeTracking() { } } -var currentPost; +var currentPost; // keep track of which is the current post. Set by mouse movements (see const votableElements) and by J and K key presses +var showCurrentPost = false; // when true, the currently selected post will be visibly different from the others. Set to true by J and K key presses function setupKeyboardShortcuts() { document.addEventListener('keydown', function(event) { if (document.activeElement.tagName !== 'INPUT' && document.activeElement.tagName !== 'TEXTAREA') { var didSomething = false; - if (event.key === 'a') { + if(event.shiftKey && event.key === '?') { + location.href = '/keyboard_shortcuts'; + didSomething = true; + } else if (event.key === 'a') { if(currentPost) { currentPost.querySelector('.upvote_button').click(); didSomething = true; @@ -392,6 +396,48 @@ function setupKeyboardShortcuts() { currentPost.querySelector('.post_teaser_title_a').click(); didSomething = true; } + } else if (event.key === 'j') { + showCurrentPost = true; + if(currentPost) { + if(currentPost.nextElementSibling) { + var elementToRemoveClass = document.querySelector('.post_teaser.current_post'); + if(elementToRemoveClass) + elementToRemoveClass.classList.remove('current_post'); + currentPost = currentPost.nextElementSibling; + currentPost.classList.add('current_post'); + } + didSomething = true; + } + else { + currentPost = document.querySelector('.post_teaser'); + currentPost.classList.add('current_post'); + } + // Check if the current post is out of the viewport + var rect = currentPost.getBoundingClientRect(); + if (rect.bottom > window.innerHeight || rect.top < 0) { + currentPost.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + } else if (event.key === 'k') { + showCurrentPost = true; + if(currentPost) { + if(currentPost.previousElementSibling) { + var elementToRemoveClass = document.querySelector('.post_teaser.current_post'); + if(elementToRemoveClass) + elementToRemoveClass.classList.remove('current_post'); + currentPost = currentPost.previousElementSibling; + currentPost.classList.add('current_post'); + } + didSomething = true; + } + else { + currentPost = document.querySelector('.post_teaser'); + currentPost.classList.add('current_post'); + } + // Check if the current post is out of the viewport + var rect = currentPost.getBoundingClientRect(); + if (rect.bottom > window.innerHeight || rect.top < 0) { + currentPost.scrollIntoView({ behavior: 'smooth', block: 'end' }); + } } if(didSomething) { event.preventDefault(); @@ -399,13 +445,22 @@ function setupKeyboardShortcuts() { } }); - const votableElements = document.querySelectorAll('.post_teaser, .comments .comment, .post_type_image, .post_type_normal'); + const votableElements = document.querySelectorAll('.post_teaser, .post_type_image, .post_type_normal'); votableElements.forEach(votable => { votable.addEventListener('mouseover', event => { currentPost = event.currentTarget; + if(showCurrentPost) { + var elementToRemoveClass = document.querySelector('.post_teaser.current_post'); + elementToRemoveClass.classList.remove('current_post'); + currentPost.classList.add('current_post'); + } }); votable.addEventListener('mouseout', event => { - currentPost = null; + //currentPost = null; + if(showCurrentPost) { + //var elementToRemoveClass = document.querySelector('.post_teaser.current_post'); + //elementToRemoveClass.classList.remove('current_post'); + } }); }); } diff --git a/app/static/styles.css b/app/static/styles.css index 883c384c..f1f420bf 100644 --- a/app/static/styles.css +++ b/app/static/styles.css @@ -642,6 +642,17 @@ nav.navbar { color: black; } +.current_post { + background-color: aliceblue; +} +.current_post .replies { + background-color: var(--bs-body-bg); +} + +[data-bs-theme=dark] .current_post { + background-color: #424549; +} + @media (min-width: 992px) { .h1, h1 { font-size: 2rem; diff --git a/app/static/styles.scss b/app/static/styles.scss index f9fb90a0..2dbee4f0 100644 --- a/app/static/styles.scss +++ b/app/static/styles.scss @@ -266,6 +266,17 @@ nav.navbar { color: black; } +.current_post { + background-color: aliceblue; + .replies { + background-color: var(--bs-body-bg); + } +} + +[data-bs-theme=dark] .current_post { + background-color: $super-dark-grey; +} + .h1, h1 { @include breakpoint(tablet) { font-size: 2rem; diff --git a/app/templates/keyboard_shortcuts.html b/app/templates/keyboard_shortcuts.html new file mode 100644 index 00000000..10525278 --- /dev/null +++ b/app/templates/keyboard_shortcuts.html @@ -0,0 +1,68 @@ +{% extends "base.html" %} + +{% block app_content %} +
+
+

{{ _('Keyboard shortcuts') }}

+

{{ _('Most shortcuts are the same as what reddit has.') }}

+
+
+

{{ _('Navigation') }}

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Show shortcut helpShift + ?
Next postJ
Previous postK
Open postEnter
Open/close previewX
Go to post linkL
+
+
+

{{ _('Action') }}

+ + + + + + + + + +
{{ _('Upvote') }}A
{{ _('Downvote') }}Z
+
+

{{ _('When viewing a list of posts actions like voting or going to a post depend on which is the current post. The current post is determined by hovering with the mouse or the J and K keys.') }}

+
+ +
+ +
+
+
+

{{ _('About %(site_name)s', site_name=g.site.name) }}

+
+
+

{{ g.site.description|safe }}

+

{{ g.site.sidebar|safe }}

+
+
+
+
+{% endblock %} diff --git a/app/templates/post/post.html b/app/templates/post/post.html index 315725cd..739cfef2 100644 --- a/app/templates/post/post.html +++ b/app/templates/post/post.html @@ -201,5 +201,9 @@ {% include "_inoculation_links.html" %} - + {% endblock %}