Bladeren bron

Add shortcuts for focusing next and previous without opening articles. (#1767)

* add skipping option to toggleContent to use later for 'i' and 'o' hotkeys

* in English config j,k are now 'open' and not 'skip', i,o are called 'focus .. without opening'
Matt DeMoss 7 jaren geleden
bovenliggende
commit
f3a88614ef
5 gewijzigde bestanden met toevoegingen van 62 en 12 verwijderingen
  1. 9 4
      app/i18n/en/conf.php
  2. 14 0
      app/views/configure/shortcut.phtml
  3. 2 0
      app/views/helpers/javascript_vars.phtml
  4. 2 0
      config-user.default.php
  5. 35 8
      p/scripts/main.js

+ 9 - 4
app/i18n/en/conf.php

@@ -151,25 +151,30 @@ return array(
 		'auto_share_help' => 'If there is only one sharing mode, it is used. Otherwise, modes are accessible by their number.',
 		'close_dropdown' => 'Close menus',
 		'collapse_article' => 'Collapse',
-		'first_article' => 'Skip to the first article',
+		'first_article' => 'Open the first article',
 		'focus_search' => 'Access search box',
 		'global_view' => 'Switch to global view',
 		'help' => 'Display documentation',
 		'javascript' => 'JavaScript must be enabled in order to use shortcuts',
-		'last_article' => 'Skip to the last article',
+		'last_article' => 'Open the last article',
 		'load_more' => 'Load more articles',
 		'mark_favorite' => 'Mark as favourite',
 		'mark_read' => 'Mark as read',
 		'navigation' => 'Navigation',
 		'navigation_help' => 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',
-		'next_article' => 'Skip to the next article',
+		'next_article' => 'Open the next article',
+		'other_action' => 'Other actions',
+		'previous_article' => 'Open the previous article',
+		'next_article' => 'Open the next article',
 		'normal_view' => 'Switch to normal view',
 		'other_action' => 'Other actions',
-		'previous_article' => 'Skip to the previous article',
+		'previous_article' => 'Open the previous article',
 		'reading_view' => 'Switch to reading view',
 		'rss_view' => 'Open RSS view in a new tab',
 		'see_on_website' => 'See on original website',
 		'shift_for_all_read' => '+ <code>shift</code> to mark all articles as read',
+		'skip_next_article' => 'Focus next without opening',
+		'skip_previous_article' => 'Focus previous without opening',
 		'title' => 'Shortcuts',
 		'user_filter' => 'Access user queries',
 		'user_filter_help' => 'If there is only one user query, it is used. Otherwise, queries are accessible by their number.',

+ 14 - 0
app/views/configure/shortcut.phtml

@@ -64,6 +64,20 @@
 				<input type="text" id="prev_entry" name="shortcuts[prev_entry]" list="keys" value="<?php echo $s['prev_entry']; ?>" data-leave-validation="<?php echo $s['prev_entry']; ?>"/>
 			</div>
 		</div>
+		
+		<div class="form-group">
+			<label class="group-name" for="skip_next_entry"><?php echo _t('conf.shortcut.skip_next_article'); ?></label>
+			<div class="group-controls">
+				<input type="text" id="skip_next_entry" name="shortcuts[skip_next_entry]" list="keys" value="<?php echo $s['skip_next_entry']; ?>" data-leave-validation="<?php echo $s['skip_next_entry']; ?>"/>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="skip_prev_entry"><?php echo _t('conf.shortcut.skip_previous_article'); ?></label>
+			<div class="group-controls">
+				<input type="text" id="skip_prev_entry" name="shortcuts[skip_prev_entry]" list="keys" value="<?php echo $s['skip_prev_entry']; ?>" data-leave-validation="<?php echo $s['skip_prev_entry']; ?>"/>
+			</div>
+		</div>
 
 		<div class="form-group">
 			<label class="group-name" for="first_entry"><?php echo _t('conf.shortcut.first_article'); ?></label>

+ 2 - 0
app/views/helpers/javascript_vars.phtml

@@ -26,6 +26,8 @@ echo htmlspecialchars(json_encode(array(
 		'go_website' => @$s['go_website'],
 		'prev_entry' => @$s['prev_entry'],
 		'next_entry' => @$s['next_entry'],
+		'skip_prev_entry' => @$s['skip_prev_entry'],
+		'skip_next_entry' => @$s['skip_next_entry'],
 		'first_entry' => @$s['first_entry'],
 		'last_entry' => @$s['last_entry'],
 		'collapse_entry' => @$s['collapse_entry'],

+ 2 - 0
config-user.default.php

@@ -49,6 +49,8 @@ return array (
 		'go_website' => 'space',
 		'next_entry' => 'j',
 		'prev_entry' => 'k',
+		'skip_next_entry' => 'n',
+		'skip_prev_entry' => 'p',
 		'first_entry' => 'home',
 		'last_entry' => 'end',
 		'collapse_entry' => 'c',

+ 35 - 8
p/scripts/main.js

@@ -237,12 +237,13 @@ function mark_favorite(active) {
 	});
 }
 
-function toggleContent(new_active, old_active) {
+function toggleContent(new_active, old_active, skipping = false) {
+	// If skipping, move current without activating or marking as read
 	if (new_active.length === 0) {
 		return;
 	}
 
-	if (context.does_lazyload) {
+	if (context.does_lazyload && !skipping) {
 		new_active.find('img[data-original], iframe[data-original]').each(function () {
 			this.onload = function () { $(document.body).trigger("sticky_kit:recalc"); };
 			this.setAttribute('src', this.getAttribute('data-original'));
@@ -251,15 +252,15 @@ function toggleContent(new_active, old_active) {
 	}
 
 	if (old_active[0] !== new_active[0]) {
-		if (isCollapsed) {
+		if (isCollapsed && !skipping) { // BUG?: isCollapsed can only ever be true 
 			new_active.addClass("active");
 		}
 		old_active.removeClass("active current");
 		new_active.addClass("current");
-		if (context.auto_remove_article && !old_active.hasClass('not_read')) {
+		if (context.auto_remove_article && !old_active.hasClass('not_read') && !skipping) {
 			auto_remove(old_active);
 		}
-	} else {
+	} else { // collapse_entry calls toggleContent(flux_current, flux_current)
 		new_active.toggleClass('active');
 	}
 
@@ -278,6 +279,10 @@ function toggleContent(new_active, old_active) {
 			}
 		}
 
+		if (skipping){
+			// when skipping, this feels more natural if it's not so near the top
+			new_pos -= $(window).height()/4
+		}
 		if (context.hide_posts) {
 			if (relative_move) {
 				new_pos += old_scroll;
@@ -295,7 +300,7 @@ function toggleContent(new_active, old_active) {
 		}
 	}
 
-	if (context.auto_mark_article && new_active.hasClass('active')) {
+	if (context.auto_mark_article && new_active.hasClass('active') && !skipping) {
 		mark_read(new_active, true);
 	}
 }
@@ -313,13 +318,29 @@ function auto_remove(element) {
 function prev_entry() {
 	var old_active = $(".flux.current"),
 		new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first");
-	toggleContent(new_active, old_active);
+	toggleContent(new_active, old_active, false);
 }
 
 function next_entry() {
 	var old_active = $(".flux.current"),
 		new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first");
-	toggleContent(new_active, old_active);
+	toggleContent(new_active, old_active, false);
+
+	if (new_active.nextAll().length < 3) {
+		load_more_posts();
+	}
+}
+
+function skip_prev_entry() {
+	var old_active = $(".flux.current"),
+		new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first");
+	toggleContent(new_active, old_active, true);
+}
+
+function skip_next_entry() {
+	var old_active = $(".flux.current"),
+		new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first");
+	toggleContent(new_active, old_active, true);
 
 	if (new_active.nextAll().length < 3) {
 		load_more_posts();
@@ -637,6 +658,9 @@ function init_shortcuts() {
 	shortcut.add(shortcuts.prev_entry, prev_entry, {
 		'disable_in_input': true
 	});
+	shortcut.add(shortcuts.skip_prev_entry, skip_prev_entry, {
+		'disable_in_input': true
+	});
 	shortcut.add(shortcuts.first_entry, function () {
 		var old_active = $(".flux.current"),
 			first = $(".flux:first");
@@ -650,6 +674,9 @@ function init_shortcuts() {
 	shortcut.add(shortcuts.next_entry, next_entry, {
 		'disable_in_input': true
 	});
+	shortcut.add(shortcuts.skip_next_entry, skip_next_entry, {
+		'disable_in_input': true
+	});
 	shortcut.add(shortcuts.last_entry, function () {
 		var old_active = $(".flux.current"),
 			last = $(".flux:last");