Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
</template>

<script setup lang="ts">
import { useEventListener } from '@vueuse/core'
import {
ClipboardActions,
FileAction,
Expand All @@ -188,10 +189,8 @@ import {
useResourcesStore,
useRoute,
useSpacesStore,
useUserStore
} from '@opencloud-eu/web-pkg'
import { useActiveLocation } from '@opencloud-eu/web-pkg'
import {
useUserStore,
useActiveLocation,
useFileActionsCreateNewFile,
useFileActionsCreateNewFolder,
useFileActionsPaste,
Expand Down Expand Up @@ -318,7 +317,7 @@ const isActionDisabled = (action: Action) => {
return action.isDisabled ? action.isDisabled() : false
}

const handlePasteFileEvent = (event: ClipboardEvent) => {
useEventListener(document, 'paste', (event: ClipboardEvent) => {
// Ignore file in clipboard if there are already files from OpenCloud in the clipboard
if (unref(clipboardResources).length || !unref(canUpload)) {
return
Expand All @@ -332,7 +331,7 @@ const handlePasteFileEvent = (event: ClipboardEvent) => {
const file = fileItem.getAsFile()
uppyService.addFiles([file])
event.preventDefault()
}
})

const onUploadComplete = async (result: UploadResult) => {
if (result.successful) {
Expand Down Expand Up @@ -406,14 +405,12 @@ const pasteHereButtonTooltip = computed(() => {

onMounted(() => {
uploadCompletedSub = uppyService.subscribe('uploadCompleted', onUploadComplete)
document.addEventListener('paste', handlePasteFileEvent)
})

onBeforeUnmount(() => {
uppyService.removePlugin(uppyService.getPlugin('HandleUpload'))
uppyService.unsubscribe('uploadCompleted', uploadCompletedSub)
uppyService.removeDropTarget()
document.removeEventListener('paste', handlePasteFileEvent)
})

watch(
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const useKeyboardFileSpaceActions = (
keyActions: KeyboardActions,
space: Ref<SpaceResource>
) => {
const { copyResources, cutResources } = useClipboardStore()
const clipboardStore = useClipboardStore()
const { copyResources, cutResources } = clipboardStore
const resourcesStore = useResourcesStore()

const { actions: pasteFileActions } = useFileActionsPaste()
Expand All @@ -23,9 +24,18 @@ export const useKeyboardFileSpaceActions = (
copyResources(resourcesStore.selectedResources)
})

keyActions.bindKeyAction({ modifier: Modifier.Ctrl, primary: Key.V }, () => {
pasteFileAction({ space: unref(space) })
})
keyActions.bindKeyAction(
{ modifier: Modifier.Ctrl, primary: Key.V },
() => {
if (clipboardStore.resources.length) {
pasteFileAction({ space: unref(space) })
}
},
{
// don't prevent default so the paste event from the local clipboard can still be handled
preventDefault: false
}
)

keyActions.bindKeyAction({ modifier: Modifier.Ctrl, primary: Key.X }, () => {
cutResources(resourcesStore.selectedResources)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,18 @@ export interface KeyboardActions {
selectionCursor: Ref<number>
removeKeyAction: (id: string) => void
resetSelectionCursor: () => void
bindKeyAction: (keys: { primary: Key; modifier?: Modifier }, callback: () => void) => string
bindKeyAction: (
keys: { primary: Key; modifier?: Modifier },
callback: (event: KeyboardEvent) => void,
options?: { preventDefault?: boolean }
) => string
}

export interface KeyboardAction {
id: string
primary: Key
modifier: Modifier | null
preventDefault: boolean
callback: (event: KeyboardEvent) => void
}

Expand Down Expand Up @@ -108,19 +113,23 @@ export const useKeyboardActions = (options?: KeyboardActionsOptions): KeyboardAc
return action.primary === key && action.modifier === modifier
})
.forEach((action) => {
event.preventDefault()
if (action.preventDefault) {
event.preventDefault()
}
action.callback(event)
})
}
const bindKeyAction = (
keys: { primary: Key; modifier?: Modifier },
callback: () => void
callback: (event: KeyboardEvent) => void,
{ preventDefault = true }: { preventDefault?: boolean } = {}
Copy link

Copilot AI Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The destructuring parameter with default value should be extracted to a separate parameter for better readability and consistency with the function signature above.

Copilot uses AI. Check for mistakes.
): string => {
const id = uuidV4()
actions.value.push({
id,
...keys,
modifier: keys.modifier ?? null,
preventDefault,
callback
})
return id
Expand Down
4 changes: 2 additions & 2 deletions packages/web-pkg/src/composables/piniaStores/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const useClipboardStore = defineStore('clipboard', () => {
const resources = ref<Resource[]>([])

const copyResources = (r: Resource[]) => {
if (!r[0].canDownload()) {
if (!r[0]?.canDownload()) {
return
}

Expand All @@ -24,7 +24,7 @@ export const useClipboardStore = defineStore('clipboard', () => {
}

const cutResources = (r: Resource[]) => {
if (!r[0].canDownload()) {
if (!r[0]?.canDownload()) {
return
}

Expand Down