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