fix: file drag-n-drop issue (#923)
This commit is contained in:
@@ -12,7 +12,13 @@ import { FunctionComponent } from 'preact';
|
|||||||
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
|
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { Icon } from '../Icon';
|
import { Icon } from '../Icon';
|
||||||
import { useCloseOnClickOutside } from '../utils';
|
import { useCloseOnClickOutside } from '../utils';
|
||||||
import { ChallengeReason, ContentType, SNFile } from '@standardnotes/snjs';
|
import {
|
||||||
|
ChallengeReason,
|
||||||
|
ContentType,
|
||||||
|
FeatureIdentifier,
|
||||||
|
FeatureStatus,
|
||||||
|
SNFile,
|
||||||
|
} from '@standardnotes/snjs';
|
||||||
import { confirmDialog } from '@/services/alertService';
|
import { confirmDialog } from '@/services/alertService';
|
||||||
import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit';
|
import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit';
|
||||||
import { StreamingFileReader } from '@standardnotes/filepicker';
|
import { StreamingFileReader } from '@standardnotes/filepicker';
|
||||||
@@ -21,6 +27,7 @@ import {
|
|||||||
PopoverFileItemActionType,
|
PopoverFileItemActionType,
|
||||||
} from './PopoverFileItemAction';
|
} from './PopoverFileItemAction';
|
||||||
import { AttachedFilesPopover, PopoverTabs } from './AttachedFilesPopover';
|
import { AttachedFilesPopover, PopoverTabs } from './AttachedFilesPopover';
|
||||||
|
import { usePremiumModal } from '../Premium/usePremiumModal';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication;
|
application: WebApplication;
|
||||||
@@ -28,8 +35,26 @@ type Props = {
|
|||||||
onClickPreprocessing?: () => Promise<void>;
|
onClickPreprocessing?: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const createDragOverlay = () => {
|
||||||
|
if (document.getElementById('drag-overlay')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const overlayElementTemplate =
|
||||||
|
'<div class="sn-component" id="drag-overlay"><div class="absolute top-0 left-0 w-full h-full z-index-1001"></div></div>';
|
||||||
|
const overlayFragment = document
|
||||||
|
.createRange()
|
||||||
|
.createContextualFragment(overlayElementTemplate);
|
||||||
|
document.body.appendChild(overlayFragment);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeDragOverlay = () => {
|
||||||
|
document.getElementById('drag-overlay')?.remove();
|
||||||
|
};
|
||||||
|
|
||||||
export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
||||||
({ application, appState, onClickPreprocessing }) => {
|
({ application, appState, onClickPreprocessing }) => {
|
||||||
|
const premiumModal = usePremiumModal();
|
||||||
const note = Object.values(appState.notes.selectedNotes)[0];
|
const note = Object.values(appState.notes.selectedNotes)[0];
|
||||||
|
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@@ -69,6 +94,14 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
|||||||
}, [application, reloadAttachedFilesCount]);
|
}, [application, reloadAttachedFilesCount]);
|
||||||
|
|
||||||
const toggleAttachedFilesMenu = useCallback(async () => {
|
const toggleAttachedFilesMenu = useCallback(async () => {
|
||||||
|
if (
|
||||||
|
application.features.getFeatureStatus(FeatureIdentifier.Files) !==
|
||||||
|
FeatureStatus.Entitled
|
||||||
|
) {
|
||||||
|
premiumModal.activate('Files');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const rect = buttonRef.current?.getBoundingClientRect();
|
const rect = buttonRef.current?.getBoundingClientRect();
|
||||||
if (rect) {
|
if (rect) {
|
||||||
const { clientHeight } = document.documentElement;
|
const { clientHeight } = document.documentElement;
|
||||||
@@ -98,7 +131,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
|||||||
|
|
||||||
setOpen(newOpenState);
|
setOpen(newOpenState);
|
||||||
}
|
}
|
||||||
}, [onClickPreprocessing, open]);
|
}, [application.features, onClickPreprocessing, open, premiumModal]);
|
||||||
|
|
||||||
const deleteFile = async (file: SNFile) => {
|
const deleteFile = async (file: SNFile) => {
|
||||||
const shouldDelete = await confirmDialog({
|
const shouldDelete = await confirmDialog({
|
||||||
@@ -230,6 +263,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
|||||||
|
|
||||||
if (event.dataTransfer?.items.length) {
|
if (event.dataTransfer?.items.length) {
|
||||||
setIsDraggingFiles(true);
|
setIsDraggingFiles(true);
|
||||||
|
createDragOverlay();
|
||||||
if (!open) {
|
if (!open) {
|
||||||
toggleAttachedFilesMenu();
|
toggleAttachedFilesMenu();
|
||||||
}
|
}
|
||||||
@@ -248,6 +282,8 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDragOverlay();
|
||||||
|
|
||||||
setIsDraggingFiles(false);
|
setIsDraggingFiles(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -257,6 +293,7 @@ export const AttachedFilesButton: FunctionComponent<Props> = observer(
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
setIsDraggingFiles(false);
|
setIsDraggingFiles(false);
|
||||||
|
removeDragOverlay();
|
||||||
|
|
||||||
if (event.dataTransfer?.items.length) {
|
if (event.dataTransfer?.items.length) {
|
||||||
Array.from(event.dataTransfer.items).forEach(async (item) => {
|
Array.from(event.dataTransfer.items).forEach(async (item) => {
|
||||||
|
|||||||
@@ -12,13 +12,10 @@ import {
|
|||||||
ComponentMutator,
|
ComponentMutator,
|
||||||
PayloadSource,
|
PayloadSource,
|
||||||
ComponentViewer,
|
ComponentViewer,
|
||||||
ComponentManagerEvent,
|
|
||||||
TransactionalMutation,
|
TransactionalMutation,
|
||||||
ItemMutator,
|
ItemMutator,
|
||||||
ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction,
|
ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction,
|
||||||
NoteViewController,
|
NoteViewController,
|
||||||
FeatureIdentifier,
|
|
||||||
FeatureStatus,
|
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import { debounce, isDesktopApplication } from '@/utils';
|
import { debounce, isDesktopApplication } from '@/utils';
|
||||||
import { KeyboardModifier, KeyboardKey } from '@/services/ioService';
|
import { KeyboardModifier, KeyboardKey } from '@/services/ioService';
|
||||||
@@ -103,7 +100,6 @@ type State = {
|
|||||||
editorTitle: string;
|
editorTitle: string;
|
||||||
editorText: string;
|
editorText: string;
|
||||||
isDesktop?: boolean;
|
isDesktop?: boolean;
|
||||||
isEntitledToFiles: boolean;
|
|
||||||
lockText: string;
|
lockText: string;
|
||||||
marginResizersEnabled?: boolean;
|
marginResizersEnabled?: boolean;
|
||||||
monospaceFont?: boolean;
|
monospaceFont?: boolean;
|
||||||
@@ -172,9 +168,6 @@ export class NoteView extends PureComponent<Props, State> {
|
|||||||
editorText: '',
|
editorText: '',
|
||||||
editorTitle: '',
|
editorTitle: '',
|
||||||
isDesktop: isDesktopApplication(),
|
isDesktop: isDesktopApplication(),
|
||||||
isEntitledToFiles:
|
|
||||||
this.application.features.getFeatureStatus(FeatureIdentifier.Files) ===
|
|
||||||
FeatureStatus.Entitled,
|
|
||||||
lockText: 'Note Editing Disabled',
|
lockText: 'Note Editing Disabled',
|
||||||
noteStatus: undefined,
|
noteStatus: undefined,
|
||||||
noteLocked: this.controller.note.locked,
|
noteLocked: this.controller.note.locked,
|
||||||
@@ -328,15 +321,6 @@ export class NoteView extends PureComponent<Props, State> {
|
|||||||
/** @override */
|
/** @override */
|
||||||
async onAppEvent(eventName: ApplicationEvent) {
|
async onAppEvent(eventName: ApplicationEvent) {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case ApplicationEvent.FeaturesUpdated:
|
|
||||||
case ApplicationEvent.UserRolesChanged:
|
|
||||||
this.setState({
|
|
||||||
isEntitledToFiles:
|
|
||||||
this.application.features.getFeatureStatus(
|
|
||||||
FeatureIdentifier.Files
|
|
||||||
) === FeatureStatus.Entitled,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case ApplicationEvent.PreferencesChanged:
|
case ApplicationEvent.PreferencesChanged:
|
||||||
this.reloadPreferences();
|
this.reloadPreferences();
|
||||||
break;
|
break;
|
||||||
@@ -1043,18 +1027,17 @@ export class NoteView extends PureComponent<Props, State> {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{this.state.isEntitledToFiles &&
|
{window.enabledUnfinishedFeatures && (
|
||||||
window.enabledUnfinishedFeatures && (
|
<div className="mr-3">
|
||||||
<div className="mr-3">
|
<AttachedFilesButton
|
||||||
<AttachedFilesButton
|
application={this.application}
|
||||||
application={this.application}
|
appState={this.appState}
|
||||||
appState={this.appState}
|
onClickPreprocessing={
|
||||||
onClickPreprocessing={
|
this.ensureNoteIsInsertedBeforeUIAction
|
||||||
this.ensureNoteIsInsertedBeforeUIAction
|
}
|
||||||
}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
<div className="mr-3">
|
<div className="mr-3">
|
||||||
<ChangeEditorButton
|
<ChangeEditorButton
|
||||||
application={this.application}
|
application={this.application}
|
||||||
|
|||||||
@@ -1013,3 +1013,7 @@
|
|||||||
transform: translateY(0%);
|
transform: translateY(0%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.z-index-1001 {
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user