From d93306a881af9c596d191b56a323de6904c77d0f Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Sun, 5 May 2024 21:54:22 +0530 Subject: [PATCH] fix drag and drop --- .../Components/FileDragNDropProvider.tsx | 23 ++++++++++-- .../NoteView/NoteViewFileDropTarget.tsx | 35 ++++++++++++------- .../EncryptedFilePlugin/FilePlugin.tsx | 15 ++++++-- .../Controllers/FilesController.ts | 20 ++++++++--- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/packages/web/src/javascripts/Components/FileDragNDropProvider.tsx b/packages/web/src/javascripts/Components/FileDragNDropProvider.tsx index 1f57bc8201c..5b90c8b3404 100644 --- a/packages/web/src/javascripts/Components/FileDragNDropProvider.tsx +++ b/packages/web/src/javascripts/Components/FileDragNDropProvider.tsx @@ -8,12 +8,22 @@ import { useMemo, useState, createContext, ReactNode, useRef, useCallback, useEf import Portal from './Portal/Portal' import { ElementIds } from '@/Constants/ElementIDs' -type FileDragTargetData = { +type FileDragTargetCommonData = { tooltipText: string - callback: (files: FileItem) => void note?: SNNote } +type FileDragTargetCallbacks = + | { + callback: (files: FileItem) => void + handleFileUpload?: never + } + | { + handleFileUpload: (fileOrHandle: File | FileSystemFileHandle) => void + callback?: never + } +type FileDragTargetData = FileDragTargetCommonData & FileDragTargetCallbacks + type FileDnDContextData = { isDraggingFiles: boolean addDragTarget: (target: HTMLElement, data: FileDragTargetData) => void @@ -203,6 +213,11 @@ const FileDragNDropProvider = ({ application, children }: Props) => { const dragTarget = closestDragTarget ? dragTargets.current.get(closestDragTarget) : undefined + if (dragTarget?.handleFileUpload) { + dragTarget.handleFileUpload(fileOrHandle) + return + } + const uploadedFile = await application.filesController.uploadNewFile(fileOrHandle, { note: dragTarget?.note, }) @@ -211,7 +226,9 @@ const FileDragNDropProvider = ({ application, children }: Props) => { return } - dragTarget?.callback(uploadedFile) + if (dragTarget?.callback) { + dragTarget.callback(uploadedFile) + } }) dragCounter.current = 0 diff --git a/packages/web/src/javascripts/Components/NoteView/NoteViewFileDropTarget.tsx b/packages/web/src/javascripts/Components/NoteView/NoteViewFileDropTarget.tsx index de418a2e3f5..4c9655ad150 100644 --- a/packages/web/src/javascripts/Components/NoteView/NoteViewFileDropTarget.tsx +++ b/packages/web/src/javascripts/Components/NoteView/NoteViewFileDropTarget.tsx @@ -1,6 +1,6 @@ import { FilesController } from '@/Controllers/FilesController' import { LinkingController } from '@/Controllers/LinkingController' -import { SNNote } from '@standardnotes/snjs' +import { NoteType, SNNote } from '@standardnotes/snjs' import { useEffect } from 'react' import { useApplication } from '../ApplicationProvider' import { useFileDragNDrop } from '../FileDragNDropProvider' @@ -20,17 +20,28 @@ const NoteViewFileDropTarget = ({ note, linkingController, noteViewElement, file const target = noteViewElement if (target) { - addDragTarget(target, { - tooltipText: 'Drop your files to upload and link them to the current note', - callback: async (uploadedFile) => { - await linkingController.linkItems(note, uploadedFile) - void application.changeAndSaveItem.execute(uploadedFile, (mutator) => { - mutator.protected = note.protected - }) - filesController.notifyObserversOfUploadedFileLinkingToCurrentNote(uploadedFile.uuid) - }, - note, - }) + const tooltipText = 'Drop your files to upload and link them to the current note' + if (note.noteType === NoteType.Super) { + addDragTarget(target, { + tooltipText, + handleFileUpload: (fileOrHandle) => { + filesController.uploadAndInsertFileToCurrentNote(fileOrHandle) + }, + note, + }) + } else { + addDragTarget(target, { + tooltipText, + callback: async (uploadedFile) => { + await linkingController.linkItems(note, uploadedFile) + void application.changeAndSaveItem.execute(uploadedFile, (mutator) => { + mutator.protected = note.protected + }) + filesController.notifyObserversOfUploadedFileLinkingToCurrentNote(uploadedFile.uuid) + }, + note, + }) + } } return () => { diff --git a/packages/web/src/javascripts/Components/SuperEditor/Plugins/EncryptedFilePlugin/FilePlugin.tsx b/packages/web/src/javascripts/Components/SuperEditor/Plugins/EncryptedFilePlugin/FilePlugin.tsx index a6e79dfacf4..8bac38a2b7c 100644 --- a/packages/web/src/javascripts/Components/SuperEditor/Plugins/EncryptedFilePlugin/FilePlugin.tsx +++ b/packages/web/src/javascripts/Components/SuperEditor/Plugins/EncryptedFilePlugin/FilePlugin.tsx @@ -158,9 +158,6 @@ export default function FilePlugin({ currentNote }: { currentNote: SNNote }): JS if (!parent) { return } - // if ($isRootOrShadowRoot(parent)) { - // return - // } if (parent.getChildrenSize() === 1) { parent.insertBefore(node) parent.remove() @@ -174,6 +171,18 @@ export default function FilePlugin({ currentNote }: { currentNote: SNNote }): JS if (event === FilesControllerEvent.FileUploadedToNote && data[FilesControllerEvent.FileUploadedToNote]) { const fileUuid = data[FilesControllerEvent.FileUploadedToNote].uuid editor.dispatchCommand(INSERT_FILE_COMMAND, fileUuid) + } else if (event === FilesControllerEvent.UploadAndInsertFile && data[FilesControllerEvent.UploadAndInsertFile]) { + const { fileOrHandle } = data[FilesControllerEvent.UploadAndInsertFile] + if (fileOrHandle instanceof FileSystemFileHandle) { + fileOrHandle + .getFile() + .then((file) => { + editor.dispatchCommand(UPLOAD_AND_INSERT_FILE_COMMAND, file) + }) + .catch(console.error) + } else { + editor.dispatchCommand(UPLOAD_AND_INSERT_FILE_COMMAND, fileOrHandle) + } } }) diff --git a/packages/web/src/javascripts/Controllers/FilesController.ts b/packages/web/src/javascripts/Controllers/FilesController.ts index 06728ed537a..35998571ddc 100644 --- a/packages/web/src/javascripts/Controllers/FilesController.ts +++ b/packages/web/src/javascripts/Controllers/FilesController.ts @@ -53,6 +53,12 @@ const NonMutatingFileActions = [FileItemActionType.DownloadFile, FileItemActionT type FileContextMenuLocation = { x: number; y: number } +export enum FilesControllerEvent { + FileUploadedToNote = 'FileUploadedToNote', + FileUploadFinished = 'FileUploadFinished', + UploadAndInsertFile = 'UploadAndInsertFile', +} + export type FilesControllerEventData = { [FilesControllerEvent.FileUploadedToNote]?: { uuid: string @@ -60,11 +66,9 @@ export type FilesControllerEventData = { [FilesControllerEvent.FileUploadFinished]?: { uploadedFile: FileItem } -} - -export enum FilesControllerEvent { - FileUploadedToNote = 'FileUploadedToNote', - FileUploadFinished = 'FileUploadFinished', + [FilesControllerEvent.UploadAndInsertFile]?: { + fileOrHandle: File | FileSystemFileHandle + } } export class FilesController extends AbstractViewController { @@ -680,6 +684,12 @@ export class FilesController extends AbstractViewController { const title = Strings.trashItemsTitle const text = files.length === 1 ? StringUtils.deleteFile(files[0].name) : Strings.deleteMultipleFiles