feat: improved file drag-n-drop experience (#1848)

This commit is contained in:
Aman Harwara
2022-10-20 02:18:52 +05:30
committed by GitHub
parent 0282a7958a
commit e99c7b7c51
20 changed files with 534 additions and 1022 deletions

View File

@@ -30,7 +30,6 @@ import ComponentView from '@/Components/ComponentView/ComponentView'
import PanelResizer, { PanelSide, PanelResizeType } from '@/Components/PanelResizer/PanelResizer'
import { ElementIds } from '@/Constants/ElementIDs'
import ChangeEditorButton from '@/Components/ChangeEditor/ChangeEditorButton'
import AttachedFilesButton from '@/Components/AttachedFilesPopover/AttachedFilesButton'
import EditingDisabledBanner from './EditingDisabledBanner'
import {
transactionForAssociateComponentWithCurrentNote,
@@ -46,6 +45,7 @@ import LinkedItemBubblesContainer from '../LinkedItems/LinkedItemBubblesContaine
import NoteStatusIndicator, { NoteStatus } from './NoteStatusIndicator'
import { PrefDefaults } from '@/Constants/PrefDefaults'
import LinkedItemsButton from '../LinkedItems/LinkedItemsButton'
import NoteViewFileDropTarget from './NoteViewFileDropTarget'
const MinimumStatusDuration = 400
const TextareaDebounce = 100
@@ -118,6 +118,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
private protectionTimeoutId: ReturnType<typeof setTimeout> | null = null
private noteViewElementRef: RefObject<HTMLDivElement>
private editorContentRef: RefObject<HTMLDivElement>
constructor(props: NoteViewProps) {
@@ -159,6 +160,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
noteType: this.controller.item.noteType,
}
this.noteViewElementRef = createRef<HTMLDivElement>()
this.editorContentRef = createRef<HTMLDivElement>()
window.addEventListener('scroll', this.handleWindowScroll)
@@ -949,7 +951,15 @@ class NoteView extends PureComponent<NoteViewProps, State> {
}
return (
<div aria-label="Note" className="section editor sn-component">
<div aria-label="Note" className="section editor sn-component" ref={this.noteViewElementRef}>
{this.note && (
<NoteViewFileDropTarget
note={this.note}
linkingController={this.viewControllerManager.linkingController}
noteViewElement={this.noteViewElementRef.current}
/>
)}
{this.state.noteLocked && (
<EditingDisabledBanner
onMouseLeave={() => {
@@ -1014,16 +1024,6 @@ class NoteView extends PureComponent<NoteViewProps, State> {
linkingController={this.viewControllerManager.linkingController}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/>
<AttachedFilesButton
application={this.application}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
featuresController={this.viewControllerManager.featuresController}
filePreviewModalController={this.viewControllerManager.filePreviewModalController}
filesController={this.viewControllerManager.filesController}
navigationController={this.viewControllerManager.navigationController}
notesController={this.viewControllerManager.notesController}
selectionController={this.viewControllerManager.selectionController}
/>
<ChangeEditorButton
application={this.application}
viewControllerManager={this.viewControllerManager}

View File

@@ -0,0 +1,42 @@
import { LinkingController } from '@/Controllers/LinkingController'
import { SNNote } from '@standardnotes/snjs'
import { useEffect } from 'react'
import { useFileDragNDrop } from '../FileDragNDropProvider/FileDragNDropProvider'
type Props = {
note: SNNote
linkingController: LinkingController
noteViewElement: HTMLElement | null
}
const NoteViewFileDropTarget = ({ note, linkingController, noteViewElement }: Props) => {
const { isDraggingFiles, addDragTarget, removeDragTarget } = useFileDragNDrop()
useEffect(() => {
const target = noteViewElement
if (target) {
addDragTarget(target, {
tooltipText: 'Drop your files to upload and link them to the current note',
callback(files) {
files.forEach(async (uploadedFile) => {
await linkingController.linkItems(uploadedFile, note)
})
},
})
}
return () => {
if (target) {
removeDragTarget(target)
}
}
}, [addDragTarget, linkingController, note, noteViewElement, removeDragTarget])
return isDraggingFiles ? (
// Required to block drag events to editor iframe
<div id="file-drag-iframe-overlay" className="absolute top-0 left-0 z-dropdown-menu h-full w-full" />
) : null
}
export default NoteViewFileDropTarget