Skip to content

Commit

Permalink
feat(#39): adds useMagicSequence composable + shortcuts for nav
Browse files Browse the repository at this point in the history
  • Loading branch information
hartmut-co-uk committed Dec 4, 2022
1 parent 432a79e commit becb1cb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
28 changes: 27 additions & 1 deletion components/magickeys/MagickeysKeyboardShortcuts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,36 @@ const emit = defineEmits(['close'])
<span mr-2>Shortcut help</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>?</code>
</div>
<div>
<span mr-2>Command mode</span>
<!-- TODO: diff Mac vs. Non-Mac (command vs. strg) -->
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>cmd</code>
<span mx1 text-sm op80>+</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>/</code>
</div>
<div>
<span mr-2>Compose</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>c</code>
</div>
<div>
<span mr-2>Compose</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>c</code>
<span mx1 text-sm op80 italic>or</span>
<span mx1 text-sm op80>or</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>n</code>
</div>
<h3 font-700 mt-3>
Navigation
</h3>
<div>
<span mr-2>Home</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>g</code>
<span mx1 text-sm op80>then</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>h</code>
</div>
<div>
<span mr-2>Notifications</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>g</code>
<span mx1 text-sm op80>then</span>
<code class="px2 py-0.5 " rounded bg-code border="px $c-border-code" shadow-sm my1 font-mono font-600>n</code>
</div>
</div>
Expand Down
16 changes: 13 additions & 3 deletions components/modal/ModalContainer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { logicOr } from '@vueuse/math'
import type { RouteLocationRaw } from 'vue-router'
import {
isEditHistoryDialogOpen,
isKeyboardShortcutsDialogOpen,
Expand All @@ -8,10 +9,13 @@ import {
isPublishDialogOpen,
isSigninDialogOpen,
} from '~/composables/dialog'
import { useMagicSequence } from '~/composables/magickeys'
// TODO: move all global keyboard bindings elsewhere?!? plugin? composable?
const keys = useMagicKeys()
const router = useRouter()
const { $scrollToTop } = useNuxtApp()
// disable shortcuts when focused on inputs (https://vueuse.org/core/usemagickeys/#conditionally-disable)
const activeElement = useActiveElement()
Expand All @@ -20,16 +24,22 @@ const notUsingInput = computed(() =>
&& activeElement.value?.tagName !== 'TEXTAREA'
&& !activeElement.value?.isContentEditable,
)
const isAuthenticated = currentUser.value !== undefined
const isAuthenticated = currentUser
const navigateTo = (to: string | RouteLocationRaw) => {
closeKeyboardShortcuts()
$scrollToTop() // is this really required?
router.push(to)
}
whenever(logicAnd(notUsingInput, keys['?']), toggleKeyboardShortcuts)
// TODO: is this the correct way of using openPublishDialog()?
const defaultPublishDialog = () => openPublishDialog('dialog', getDefaultDraft())
whenever(logicAnd(isAuthenticated, notUsingInput, logicOr(keys.c)), defaultPublishDialog)
// shortcut enabled only if authenticated
whenever(logicAnd(notUsingInput, isAuthenticated, logicOr(keys.c, keys.n)), defaultPublishDialog)
whenever(logicAnd(notUsingInput, useMagicSequence(['g', 'h'])), () => navigateTo('/home'))
whenever(logicAnd(isAuthenticated, notUsingInput, useMagicSequence(['g', 'n'])), () => navigateTo('/notifications'))
</script>

<template>
Expand Down
40 changes: 40 additions & 0 deletions composables/magickeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { ComputedRef } from 'vue'

// TODO: consider to allow combinations similar to useMagicKeys using proxy?
// e.g. `const magicSequence = useMagicSequence()`
// `magicSequence['Shift+Ctrl+A']`
// `const { Ctrl_A_B } = useMagicSequence()`

export function useMagicSequence(keys: string[]): ComputedRef<boolean> {
const magicKeys = useMagicKeys()

const success = ref(false)
const i = ref(0)
let down = false

watch(
() => magicKeys.current,
() => {
if (magicKeys[keys[i.value]].value && !down) {
down = true
i.value += 1
}
else if (i.value > 0 && !magicKeys[keys[i.value - 1]].value && down) {
down = false
}
else {
i.value = 0
down = false
success.value = false
}
if (i.value >= keys.length && !down) {
i.value = 0
down = false
success.value = true
}
}, {
deep: true,
})

return computed(() => success.value)
}

0 comments on commit becb1cb

Please sign in to comment.