Improve documentation for shortcuts
This commit is contained in:
@@ -213,23 +213,39 @@ onMount(() => {
|
||||
</p>
|
||||
|
||||
<h3>Keyboard Controls</h3>
|
||||
<table style="max-width: 100%;">
|
||||
<tr><td colspan="2">File Shortcuts</td></tr>
|
||||
<tr><td>c</td><td> = Copy URL of this page</td></tr>
|
||||
<tr><td>i</td><td> = Toggle details window (this window) (<b><u>i</u></b>nfo)</td></tr>
|
||||
<tr><td>s</td><td> = Download the file you are currently viewing (<b><u>s</u></b>ave)</td></tr>
|
||||
<tr><td>q</td><td> = Close the window (<b><u>q</u></b>uit)</td></tr>
|
||||
<tr><td colspan="2">List Shortcuts</td></tr>
|
||||
<tr><td>a or ←</td><td> = View previous item in list</td></tr>
|
||||
<tr><td>d or →</td><td> = View next item in list</td></tr>
|
||||
<tr><td>r</td><td> = Toggle shuffle (<b><u>r</u></b>andom)</td></tr>
|
||||
<tr><td>SHIFT + s</td><td> = Download all the files in the list as a zip archive</td></tr>
|
||||
<tr><td colspan="2">Video Shortcuts</td></tr>
|
||||
<tr><td>h</td><td> = Skip 20 seconds backward</td></tr>
|
||||
<tr><td>j</td><td> = Skip 5 seconds backward</td></tr>
|
||||
<tr><td>k</td><td> = Skip 5 seconds forward</td></tr>
|
||||
<tr><td>l</td><td> = Skip 20 seconds forward</td></tr>
|
||||
</table>
|
||||
|
||||
<h4>Global</h4>
|
||||
<div class="shortcuts">
|
||||
<div><div>c</div><div>Copy page URL</div></div>
|
||||
<div><div>s</div><div>Download current file</div></div>
|
||||
<div><div>q</div><div>Close window</div></div>
|
||||
<div><div>g</div><div>Grab file (copy to your account)</div></div>
|
||||
<div><div>i</div><div>Show details window</div></div>
|
||||
<div><div>e</div><div>Show edit window</div></div>
|
||||
<div><div>m</div><div>Show embed window</div></div>
|
||||
<div><div>r</div><div>Show abuse report window</div></div>
|
||||
</div>
|
||||
|
||||
<h4>List</h4>
|
||||
<div class="shortcuts">
|
||||
<div><div>a or ←</div><div>Previous file</div></div>
|
||||
<div><div>d or →</div><div>Next file</div></div>
|
||||
<div><div>shift + s</div><div>Download all files as zip</div></div>
|
||||
<div><div>u</div><div>Upload files to album</div></div>
|
||||
</div>
|
||||
|
||||
<h4>Video / audio</h4>
|
||||
<div class="shortcuts">
|
||||
<div><div>space</div><div>Pause / resume playback</div></div>
|
||||
<div><div>f</div><div>Enter fullscreen</div></div>
|
||||
<div><div>esc</div><div>Exit fullscreen</div></div>
|
||||
<div><div>h</div><div>Skip 20 seconds backward</div></div>
|
||||
<div><div>j</div><div>Skip 5 seconds backward</div></div>
|
||||
<div><div>k</div><div>Skip 5 seconds forward</div></div>
|
||||
<div><div>l</div><div>Skip 20 seconds forward</div></div>
|
||||
<div><div>,</div><div>Skip 40ms backward</div></div>
|
||||
<div><div>.</div><div>Skip 40ms forward</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -238,4 +254,25 @@ onMount(() => {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.shortcuts {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
}
|
||||
.shortcuts > div {
|
||||
flex: 0 0 12em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 2px solid var(--card_color);
|
||||
}
|
||||
.shortcuts > div > div:first-child {
|
||||
font-size: 1.4em;
|
||||
padding: 4px;
|
||||
background: var(--card_color);
|
||||
}
|
||||
</style>
|
||||
|
@@ -326,6 +326,24 @@ const keyboard_event = evt => {
|
||||
case " ": // Spacebar pauses / unpauses video and audio playback
|
||||
file_preview.toggle_playback()
|
||||
break
|
||||
case "h":
|
||||
file_preview.seek(-20)
|
||||
break
|
||||
case "j":
|
||||
file_preview.seek(-5)
|
||||
break
|
||||
case "k":
|
||||
file_preview.seek(5)
|
||||
break
|
||||
case "l":
|
||||
file_preview.seek(20)
|
||||
break
|
||||
case ",":
|
||||
file_preview.seek(-0.04) // Roughly a single frame.. assuming 25fps
|
||||
break
|
||||
case ".":
|
||||
file_preview.seek(0.04)
|
||||
break
|
||||
case "s":
|
||||
case "S":
|
||||
if (evt.shiftKey) {
|
||||
|
@@ -52,6 +52,15 @@ export const toggle_playback = () => {
|
||||
playing ? player.pause() : player.play()
|
||||
}
|
||||
|
||||
export const seek = delta => {
|
||||
// fastseek can be pretty imprecise, so we don't use it for small seeks
|
||||
// below 5 seconds
|
||||
if (player.fastSeek && delta > 5) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
|
@@ -52,6 +52,11 @@ export const toggle_playback = () => {
|
||||
viewer.toggle_playback()
|
||||
}
|
||||
}
|
||||
export const seek = delta => {
|
||||
if (viewer && viewer.seek) {
|
||||
viewer.seek(delta)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if viewer_type === "loading"}
|
||||
|
@@ -51,6 +51,16 @@ export const toggle_playback = () => {
|
||||
playing ? player.pause() : player.play()
|
||||
}
|
||||
|
||||
export const seek = delta => {
|
||||
// fastseek can be pretty imprecise, so we don't use it for small seeks
|
||||
// below 5 seconds
|
||||
if (player.fastSeek && delta > 5) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if ('mediaSession' in navigator) {
|
||||
media_session = true
|
||||
@@ -64,14 +74,6 @@ onMount(() => {
|
||||
|
||||
const download = () => { dispatch("download", {}) }
|
||||
|
||||
const seek_relative = delta => {
|
||||
if (player.fastSeek) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
|
||||
const mute = () => {
|
||||
if (player.muted) {
|
||||
player.muted = false
|
||||
@@ -98,14 +100,8 @@ const keypress = e => {
|
||||
return
|
||||
}
|
||||
|
||||
if (e.key === "h") {
|
||||
seek_relative(-20)
|
||||
} else if (e.key === "j") {
|
||||
seek_relative(-5)
|
||||
} else if (e.key === "k") {
|
||||
seek_relative(5)
|
||||
} else if (e.key === "l") {
|
||||
seek_relative(20)
|
||||
if (e.key === "f") {
|
||||
fullscreen()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -150,7 +146,7 @@ const keypress = e => {
|
||||
<i class="icon">skip_previous</i>
|
||||
</button>
|
||||
{/if}
|
||||
<button on:click={() => seek_relative(-10)}>
|
||||
<button on:click={() => seek(-10)}>
|
||||
<i class="icon">replay_10</i>
|
||||
</button>
|
||||
<button on:click={toggle_playback} class="button_highlight">
|
||||
@@ -160,7 +156,7 @@ const keypress = e => {
|
||||
<i class="icon">play_arrow</i>
|
||||
{/if}
|
||||
</button>
|
||||
<button on:click={() => seek_relative(10)}>
|
||||
<button on:click={() => seek(10)}>
|
||||
<i class="icon">forward_10</i>
|
||||
</button>
|
||||
{#if is_list}
|
||||
|
@@ -90,6 +90,24 @@ const keydown = e => {
|
||||
file_preview.toggle_playback()
|
||||
}
|
||||
break
|
||||
case "h":
|
||||
file_preview.seek(-20)
|
||||
break
|
||||
case "j":
|
||||
file_preview.seek(-5)
|
||||
break
|
||||
case "k":
|
||||
file_preview.seek(5)
|
||||
break
|
||||
case "l":
|
||||
file_preview.seek(20)
|
||||
break
|
||||
case ",":
|
||||
file_preview.seek(-0.04) // Roughly a single frame.. assuming 25fps
|
||||
break
|
||||
case ".":
|
||||
file_preview.seek(0.04)
|
||||
break
|
||||
default:
|
||||
action_performed = false
|
||||
}
|
||||
|
@@ -14,6 +14,16 @@ export const toggle_playback = () => {
|
||||
playing ? player.pause() : player.play()
|
||||
}
|
||||
|
||||
export const seek = delta => {
|
||||
// fastseek can be pretty imprecise, so we don't use it for small seeks
|
||||
// below 5 seconds
|
||||
if (player.fastSeek && delta > 5) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
|
||||
export const update = async () => {
|
||||
if (media_session) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
@@ -56,7 +66,7 @@ onMount(() => {
|
||||
</audio>
|
||||
<div style="text-align: center;">
|
||||
<button on:click={() => nav.open_sibling(-1) }><i class="icon">skip_previous</i></button>
|
||||
<button on:click={() => player.currentTime -= 10 }><i class="icon">replay_10</i></button>
|
||||
<button on:click={() => seek(-10) }><i class="icon">replay_10</i></button>
|
||||
<button on:click={toggle_playback}>
|
||||
{#if playing}
|
||||
<i class="icon">pause</i>
|
||||
@@ -64,7 +74,7 @@ onMount(() => {
|
||||
<i class="icon">play_arrow</i>
|
||||
{/if}
|
||||
</button>
|
||||
<button on:click={() => player.currentTime += 10 }><i class="icon">forward_10</i></button>
|
||||
<button on:click={() => seek(10) }><i class="icon">forward_10</i></button>
|
||||
<button on:click={() => nav.open_sibling(1) }><i class="icon">skip_next</i></button>
|
||||
</div>
|
||||
|
||||
|
@@ -45,6 +45,11 @@ export const toggle_playback = () => {
|
||||
viewer.toggle_playback()
|
||||
}
|
||||
}
|
||||
export const seek = delta => {
|
||||
if (viewer && viewer.seek) {
|
||||
viewer.seek(delta)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if viewer_type === ""}
|
||||
|
@@ -41,6 +41,16 @@ export const toggle_playback = () => {
|
||||
playing ? player.pause() : player.play()
|
||||
}
|
||||
|
||||
export const seek = delta => {
|
||||
// fastseek can be pretty imprecise, so we don't use it for small seeks
|
||||
// below 5 seconds
|
||||
if (player.fastSeek && delta > 5) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if ('mediaSession' in navigator) {
|
||||
media_session = true
|
||||
@@ -52,14 +62,6 @@ onMount(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const seek_relative = delta => {
|
||||
if (player.fastSeek) {
|
||||
player.fastSeek(player.currentTime + delta)
|
||||
} else {
|
||||
player.currentTime = player.currentTime + delta
|
||||
}
|
||||
}
|
||||
|
||||
const mute = () => {
|
||||
if (player.muted) {
|
||||
player.muted = false
|
||||
@@ -71,35 +73,8 @@ const mute = () => {
|
||||
const fullscreen = () => {
|
||||
player.requestFullscreen()
|
||||
}
|
||||
|
||||
const keypress = e => {
|
||||
if (
|
||||
(e.ctrlKey || e.altKey || e.metaKey) ||
|
||||
(document.activeElement.type && (
|
||||
document.activeElement.type === "text" ||
|
||||
document.activeElement.type === "email" ||
|
||||
document.activeElement.type === "textarea"))
|
||||
) {
|
||||
// The first check is to prevent our keybindings from triggering then
|
||||
// the user uses a global keybind. The second check is to prevent the
|
||||
// shortcuts from firing if the user is entering text in an input field
|
||||
return
|
||||
}
|
||||
|
||||
if (e.key === "h") {
|
||||
seek_relative(-20)
|
||||
} else if (e.key === "j") {
|
||||
seek_relative(-5)
|
||||
} else if (e.key === "k") {
|
||||
seek_relative(5)
|
||||
} else if (e.key === "l") {
|
||||
seek_relative(20)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keypress={keypress} />
|
||||
|
||||
<div class="container">
|
||||
{#if
|
||||
$nav.base.file_type === "video/x-matroska" ||
|
||||
@@ -137,7 +112,7 @@ const keypress = e => {
|
||||
<button on:click={() => dispatch("open_sibling", -1) }>
|
||||
<i class="icon">skip_previous</i>
|
||||
</button>
|
||||
<button on:click={() => seek_relative(-10)}>
|
||||
<button on:click={() => seek(-10)}>
|
||||
<i class="icon">replay_10</i>
|
||||
</button>
|
||||
<button on:click={toggle_playback} class="button_highlight">
|
||||
@@ -147,7 +122,7 @@ const keypress = e => {
|
||||
<i class="icon">play_arrow</i>
|
||||
{/if}
|
||||
</button>
|
||||
<button on:click={() => seek_relative(10)}>
|
||||
<button on:click={() => seek(10)}>
|
||||
<i class="icon">forward_10</i>
|
||||
</button>
|
||||
<button on:click={() => dispatch("open_sibling", 1) }>
|
||||
|
Reference in New Issue
Block a user