mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
keyboard shortcuts
This commit is contained in:
parent
16eb228052
commit
66f621049a
6 changed files with 159 additions and 5 deletions
|
@ -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'))
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
68
app/templates/keyboard_shortcuts.html
Normal file
68
app/templates/keyboard_shortcuts.html
Normal file
|
@ -0,0 +1,68 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 position-relative main_pane">
|
||||
<h1>{{ _('Keyboard shortcuts') }}</h1>
|
||||
<p>{{ _('Most shortcuts are the same as what reddit has.') }}</p>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6">
|
||||
<h3>{{ _('Navigation') }}</h3>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<td>Show shortcut help</td>
|
||||
<td>Shift + ?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Next post</td>
|
||||
<td>J</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Previous post</td>
|
||||
<td>K</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Open post</td>
|
||||
<td>Enter</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Open/close preview</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Go to post link</td>
|
||||
<td>L</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<h3>{{ _('Action') }}</h3>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<td>{{ _('Upvote') }}</td>
|
||||
<td>A</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ _('Downvote') }}</td>
|
||||
<td>Z</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p>{{ _('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.') }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4 side_pane">
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h2>{{ _('About %(site_name)s', site_name=g.site.name) }}</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><strong>{{ g.site.description|safe }}</strong></p>
|
||||
<p>{{ g.site.sidebar|safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -201,5 +201,9 @@
|
|||
{% include "_inoculation_links.html" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="{{ session['nonce'] }}">
|
||||
window.addEventListener("load", function () {
|
||||
currentPost = document.querySelector('.post_col'); // set the current post, so A and Z voting keys work when viewing a post page
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in a new issue