kopia lustrzana https://github.com/elk-zone/elk
Merge aa171a8274
into 9496ffc3e6
commit
fc3ba50b18
|
@ -14,6 +14,7 @@ interface ShortcutDef {
|
|||
interface ShortcutItem {
|
||||
description: string
|
||||
shortcut: ShortcutDef
|
||||
info?: string
|
||||
}
|
||||
|
||||
interface ShortcutItemGroup {
|
||||
|
@ -32,14 +33,16 @@ const shortcutItemGroups = computed<ShortcutItemGroup[]>(() => [
|
|||
description: t('magic_keys.groups.navigation.shortcut_help'),
|
||||
shortcut: { keys: ['?'], isSequence: false },
|
||||
},
|
||||
// {
|
||||
// description: t('magic_keys.groups.navigation.next_status'),
|
||||
// shortcut: { keys: ['j'], isSequence: false },
|
||||
// },
|
||||
// {
|
||||
// description: t('magic_keys.groups.navigation.previous_status'),
|
||||
// shortcut: { keys: ['k'], isSequence: false },
|
||||
// },
|
||||
{
|
||||
description: t('magic_keys.groups.navigation.next_status'),
|
||||
shortcut: { keys: ['j'], isSequence: false },
|
||||
info: t('magic_keys.info.disable_virtual_scrolling'),
|
||||
},
|
||||
{
|
||||
description: t('magic_keys.groups.navigation.previous_status'),
|
||||
shortcut: { keys: ['k'], isSequence: false },
|
||||
info: t('magic_keys.info.disable_virtual_scrolling'),
|
||||
},
|
||||
{
|
||||
description: t('magic_keys.groups.navigation.go_to_search'),
|
||||
shortcut: { keys: ['/'], isSequence: false },
|
||||
|
@ -147,8 +150,11 @@ const shortcutItemGroups = computed<ShortcutItemGroup[]>(() => [
|
|||
:key="item.description"
|
||||
flex my-1 lg:my-2 justify-between place-items-center max-w-full text-base
|
||||
>
|
||||
<div mr-2 break-words overflow-hidden leading-4 h-full inline-block align-middle>
|
||||
<div mr-2 break-words overflow-hidden leading-4 h-full inline-block align-middle flex flex-inline gap-1 items-center>
|
||||
{{ item.description }}
|
||||
<CommonTooltip v-if="item.info" :content="item.info">
|
||||
<div i-ri:information-line />
|
||||
</CommonTooltip>
|
||||
</div>
|
||||
<div>
|
||||
<template
|
||||
|
|
|
@ -262,6 +262,9 @@
|
|||
"title": "Navigation"
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"disable_virtual_scrolling": "Disable the experimental \"Virtual Scrolling\" setting to use this shortcut."
|
||||
},
|
||||
"sequence_then": "then"
|
||||
},
|
||||
"menu": {
|
||||
|
|
|
@ -6,6 +6,8 @@ export default defineNuxtPlugin(({ $scrollToTop }) => {
|
|||
const keys = useMagicKeys()
|
||||
const router = useRouter()
|
||||
const i18n = useNuxtApp().$i18n
|
||||
const { y } = useWindowScroll({ behavior: 'instant' })
|
||||
const virtualScroller = usePreferences('experimentalVirtualScroller')
|
||||
|
||||
// disable shortcuts when focused on inputs (https://vueuse.org/core/usemagickeys/#conditionally-disable)
|
||||
const activeElement = useActiveElement()
|
||||
|
@ -76,4 +78,54 @@ export default defineNuxtPlugin(({ $scrollToTop }) => {
|
|||
?.click()
|
||||
}
|
||||
whenever(logicAnd(isAuthenticated, notUsingInput, keys['.']), showNewItems)
|
||||
|
||||
// TODO: virtual scroller cannot load off-screen post
|
||||
// that prevents focusing next post properly
|
||||
// we disabled this shortcut when enabled virtual scroller
|
||||
if (!virtualScroller.value) {
|
||||
const statusSelector = '[aria-roledescription="status-card"]'
|
||||
|
||||
// find the nearest status element id traversing up from the current active element
|
||||
// `activeElement` can be some of an element within a status element
|
||||
// otherwise, reach to the root `<html>`
|
||||
function getActiveStatueId(element: HTMLElement): string | undefined {
|
||||
if (element.nodeName === 'HTML')
|
||||
return undefined
|
||||
|
||||
if (element.matches(statusSelector))
|
||||
return element.id
|
||||
|
||||
return getActiveStatueId(element.parentNode as HTMLElement)
|
||||
}
|
||||
|
||||
function focusNextOrPreviousStatus(direction: 'next' | 'previous') {
|
||||
const activeStatusId = activeElement.value ? getActiveStatueId(activeElement.value) : undefined
|
||||
const nextOrPreviousStatusId = getNextOrPreviousStatusId(activeStatusId, direction)
|
||||
if (nextOrPreviousStatusId) {
|
||||
const status = document.getElementById(nextOrPreviousStatusId)
|
||||
if (status) {
|
||||
status.focus({ preventScroll: true })
|
||||
const topBarHeight = 58
|
||||
y.value += status.getBoundingClientRect().top - topBarHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNextOrPreviousStatusId(currentStatusId: string | undefined, direction: 'next' | 'previous'): string | undefined {
|
||||
const statusIds = [...document.querySelectorAll(statusSelector)].map(s => s.id)
|
||||
if (currentStatusId === undefined) {
|
||||
// if there is no selection, always focus on the first status
|
||||
return statusIds[0]
|
||||
}
|
||||
|
||||
const currentIndex = statusIds.findIndex(id => id === currentStatusId)
|
||||
const statusId = direction === 'next'
|
||||
? statusIds[Math.min(currentIndex + 1, statusIds.length)]
|
||||
: statusIds[Math.max(0, currentIndex - 1)]
|
||||
return statusId
|
||||
}
|
||||
|
||||
whenever(logicAnd(notUsingInput, keys.j), () => focusNextOrPreviousStatus('next'))
|
||||
whenever(logicAnd(notUsingInput, keys.k), () => focusNextOrPreviousStatus('previous'))
|
||||
}
|
||||
})
|
||||
|
|
Ładowanie…
Reference in New Issue