Signed-off-by: Stepan Grigorovich <gsdstr@gmail.com>
This commit is contained in:
Stepan Grigorovich 2024-03-12 19:57:41 +03:00 committed by GitHub
parent 2e60a8dc23
commit cadde5a4b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 58 deletions

View File

@ -14,7 +14,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import { Analytics } from '@hcengineering/analytics' import { Analytics } from '@hcengineering/analytics'
import core, { Doc, Hierarchy, Ref, TxRemoveDoc } from '@hcengineering/core' import core, { Doc, Hierarchy, Ref, Space, TxRemoveDoc } from '@hcengineering/core'
import { getResource } from '@hcengineering/platform' import { getResource } from '@hcengineering/platform'
import { addTxListener, contextStore, getClient } from '@hcengineering/presentation' import { addTxListener, contextStore, getClient } from '@hcengineering/presentation'
import { AnyComponent, Component } from '@hcengineering/ui' import { AnyComponent, Component } from '@hcengineering/ui'
@ -24,6 +24,8 @@
import { ListSelectionProvider, SelectionStore, focusStore, previewDocument, selectionStore } from '../selection' import { ListSelectionProvider, SelectionStore, focusStore, previewDocument, selectionStore } from '../selection'
import { getObjectPreview, restrictionStore } from '../utils' import { getObjectPreview, restrictionStore } from '../utils'
export let currentSpace: Ref<Space> | undefined
const client = getClient() const client = getClient()
addTxListener((tx) => { addTxListener((tx) => {
@ -131,7 +133,8 @@
$: disableActions = $restrictionStore.disableActions $: disableActions = $restrictionStore.disableActions
async function handleKeys (evt: KeyboardEvent): Promise<void> { async function handleKeys (evt: KeyboardEvent): Promise<void> {
if (disableActions) return // For none we ignore all actions.
if (disableActions || ctx?.mode === 'none') return
const targetTagName = (evt.target as any)?.tagName?.toLowerCase() const targetTagName = (evt.target as any)?.tagName?.toLowerCase()
let elm = evt.target as HTMLElement let elm = evt.target as HTMLElement
@ -165,73 +168,70 @@
} }
} }
// For none we ignore all actions.
if (ctx?.mode === 'none') {
return
}
clearTimeout(timer) clearTimeout(timer)
currentActions = currentActions.filter(({ keyBinding, allowedForEditableContent }) => { async function activateAction (a: Action): Promise<boolean> {
const hasKeyBinding = keyBinding !== undefined && keyBinding.length > 0
const allowed = !isContentEditable || allowedForEditableContent
return hasKeyBinding && allowed
})
if (lastKey !== undefined) {
for (const a of sequences) {
// TODO: Handle multiple keys here
if (a.keyBinding?.find((it) => (lastKey ? matchKeySequence(evt, it, lastKey) : false)) !== undefined) {
const action = await getResource(a.action) const action = await getResource(a.action)
if (action !== undefined) { if (action === undefined) return false
sequences = []
lastKey = undefined lastKey = undefined
delayedAction = undefined delayedAction = undefined
Analytics.handleEvent(a._id) Analytics.handleEvent(a._id)
await action(selectionDocs, evt, a.actionProps) const actionProps = { ...a.actionProps }
return if (!Object.prototype.hasOwnProperty.call(actionProps, 'props')) actionProps.props = {}
} actionProps.props.space = currentSpace
} await action(selectionDocs, evt, actionProps)
} return true
} }
sequences = getSequences(evt, currentActions) // 3 cases for keyBinding
let found = false // matches the sequence - immediately action
// start sequence - postpone other action
// matches the key - execute if there is no start sequence actions
let postpone = false
let nonSequenceAction: Action | undefined
for (const a of currentActions) { for (const a of currentActions) {
// TODO: Handle multiple keys here if (a.keyBinding === undefined || a.keyBinding.length < 1) continue
if (a.keyBinding?.find((it) => matchKey(evt, it)) !== undefined) { if (isContentEditable && a.allowedForEditableContent !== true) continue
const action = await getResource(a.action) const t = lastKey
if (action !== undefined) { if (t !== undefined && a.keyBinding.some((it) => matchKeySequence(evt, it, t)) && (await activateAction(a))) {
if (sequences.length === 0) {
lastKey = undefined
sequences = []
delayedAction = undefined
Analytics.handleEvent(a._id)
await action(selectionDocs, evt, a.actionProps)
return return
} else {
delayedAction = async () => {
Analytics.handleEvent(a._id)
await action(selectionDocs, evt, a.actionProps)
} }
found = true if (!postpone && a.keyBinding.some((p) => findKeySequence(p, evt))) {
postpone = true
continue
}
if (nonSequenceAction === undefined && a.keyBinding.some((it) => matchKey(evt, it))) {
nonSequenceAction = a
} }
} }
}
} if (delayedAction !== undefined) {
if (!found && delayedAction) { await delayedAction()
delayedAction()
delayedAction = undefined delayedAction = undefined
} }
const t = nonSequenceAction
if (t !== undefined) {
if (!postpone) {
await activateAction(t)
return
}
delayedAction = async () => {
await activateAction(t)
}
}
lastKey = evt lastKey = evt
timer = setTimeout(() => { timer = setTimeout(() => {
lastKey = undefined lastKey = undefined
sequences = [] sequences = []
if (delayedAction !== undefined) { if (delayedAction !== undefined) {
delayedAction() void delayedAction()
delayedAction = undefined
} }
}, 300) }, 300)
} }

View File

@ -634,7 +634,7 @@
/> />
</div> </div>
{:else if employee?.active || account.role === AccountRole.Owner || isAdminUser()} {:else if employee?.active || account.role === AccountRole.Owner || isAdminUser()}
<ActionHandler /> <ActionHandler {currentSpace} />
<svg class="svg-mask"> <svg class="svg-mask">
<clipPath id="notify-normal"> <clipPath id="notify-normal">
<path d="M12,14c0-3.3,2.7-6,6-6c0.7,0,1.4,0.1,2,0.4V0H0v20h18C14.7,20,12,17.3,12,14z" /> <path d="M12,14c0-3.3,2.7-6,6-6c0.7,0,1.4,0.1,2,0.4V0H0v20h18C14.7,20,12,17.3,12,14z" />