mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-03 16:41:27 +01:00
keys: files and uploads answer the keyboard
`gx` opens the file under the cursor in a tab of its own, as the browser shows it. `:download` (`:dl`) downloads it, after asking for the vault when the file is sealed; on the open document it is `:export`. `:source` turns a markdown file between rendered and as written, which before had only a button. A sealed file asks for the vault before `gx` instead of after, so the browser does not block the late tab as a popup. The media list gets a cursor: `j`/`k` walk it, `i` or `Enter` embeds the highlighted upload at the cursor while writing, `y` copies its address and `x` deletes it. Deleting asks through the `[y/N]` prompt, which names what would break, in place of the browser's confirm(): that one was the last modal on the page and needed the pointer to dismiss. A footer lists the keys, as the agenda's does.
This commit is contained in:
1 parent
54bc333be2
commit
37443cf083
7 files changed
+172
-28
No files matched your search
+55
-2
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { hooks, runCommand } from './lib/commands'
|
||||
import { followLink, hooks, runCommand } from './lib/commands'
|
||||
import { embedSnippet } from './lib/markdown'
|
||||
import Agenda from './lib/Agenda.svelte'
|
||||
import Bar from './lib/Bar.svelte'
|
||||
@@ -13,7 +13,7 @@
|
||||
import Verify from './lib/Verify.svelte'
|
||||
import Login from './lib/Login.svelte'
|
||||
import Overview from './lib/Overview.svelte'
|
||||
import MediaBrowser from './lib/MediaBrowser.svelte'
|
||||
import MediaBrowser, { copyMedia, insertMedia, removeMedia } from './lib/MediaBrowser.svelte'
|
||||
import Actions from './lib/Actions.svelte'
|
||||
import Prompt from './lib/Prompt.svelte'
|
||||
import SecretPrompt from './lib/SecretPrompt.svelte'
|
||||
@@ -329,6 +329,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** The media list's keys: j/k down the files, i inserts, y copies, x deletes. */
|
||||
function mediaKey(event: KeyboardEvent): boolean {
|
||||
const files = workspace.media
|
||||
const last = Math.max(files.length - 1, 0)
|
||||
const file = files[workspace.mediaCursor]
|
||||
switch (event.key) {
|
||||
case 'j':
|
||||
case 'ArrowDown':
|
||||
workspace.mediaCursor = Math.min(workspace.mediaCursor + 1, last)
|
||||
return true
|
||||
case 'k':
|
||||
case 'ArrowUp':
|
||||
workspace.mediaCursor = Math.max(workspace.mediaCursor - 1, 0)
|
||||
return true
|
||||
case 'G':
|
||||
workspace.mediaCursor = last
|
||||
return true
|
||||
case 'Enter':
|
||||
case 'i':
|
||||
if (file) insertMedia(file)
|
||||
return true
|
||||
case 'y':
|
||||
if (file) void copyMedia(file)
|
||||
return true
|
||||
case 'x':
|
||||
if (file) void removeMedia(file)
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/** `gx`: the file as the browser shows it, in a tab of its own. */
|
||||
function openInTab() {
|
||||
const file = workspace.target?.file
|
||||
if (!file) return workspace.say('gx opens a file — put the cursor on one', 'error')
|
||||
// A tab opened after the vault's question would be stopped as a popup, so
|
||||
// a sealed file asks for the vault to be opened first instead.
|
||||
if (file.encrypted && !workspace.vault?.unlocked) return workspace.say('sealed — :unlock first, then gx', 'error')
|
||||
followLink(file.url, true)
|
||||
}
|
||||
|
||||
/** Alt+h / Alt+l: focus moves between the panes, out of the editor too. */
|
||||
function focusPane(pane: 'list' | 'document') {
|
||||
if (pane === 'document' && !workspace.open) return
|
||||
@@ -448,6 +490,12 @@
|
||||
return
|
||||
}
|
||||
}
|
||||
if (workspace.overlay === 'media' && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
if (mediaKey(event)) {
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (workspace.overlay === 'outline' && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
||||
if (outlineKey(event)) {
|
||||
event.preventDefault()
|
||||
@@ -586,6 +634,11 @@
|
||||
void runCommand('outline')
|
||||
return
|
||||
}
|
||||
if (previous === 'g' && key === 'x') {
|
||||
event.preventDefault()
|
||||
openInTab()
|
||||
return
|
||||
}
|
||||
if (previous === 'd' && key === 'd') {
|
||||
event.preventDefault()
|
||||
void runCommand('d')
|
||||
|
||||
Reference in new issue
Block a user