Improve documentation for shortcuts

This commit is contained in:
2024-08-14 19:58:25 +02:00
parent 3d128a2960
commit 1382c01a14
9 changed files with 147 additions and 74 deletions

View File

@@ -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 &#8592;</td><td> = View previous item in list</td></tr>
<tr><td>d or &#8594;</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 &#8592;</div><div>Previous file</div></div>
<div><div>d or &#8594;</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>

View File

@@ -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) {

View File

@@ -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">

View File

@@ -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"}

View File

@@ -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}

View File

@@ -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
}

View File

@@ -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>

View File

@@ -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 === ""}

View File

@@ -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) }>