fix drop target

This commit is contained in:
Michael Peters 2022-02-13 00:53:36 -06:00
parent 3849d6b447
commit b2b849695b
7 changed files with 92 additions and 24 deletions

View File

@ -15,7 +15,7 @@
// TODO: make this nicer
color: theme.$text-normal;
background-color: theme.$background-primary;
padding: 16px;
padding: 32px;
border-radius: 8px;
display: flex;
@ -28,9 +28,15 @@
margin-right: 16px;
}
.drop-message {
font-size: 2em;
.drop-description {
color: theme.$header-primary;
.drop-title {
font-size: 2em;
font-weight: 600;
}
.drop-message {
font-size: 1.5em;
}
}
}
}

View File

@ -26,7 +26,7 @@ $borderRadius: 8px;
.attachment-preview {
position: relative;
margin: 16px 16px 0 16px;
padding: 8px;
padding: 12px;
border-radius: 8px;
box-sizing: border-box;
max-width: calc(100% - 32px);
@ -40,6 +40,8 @@ $borderRadius: 8px;
}
.name {
color: theme.$interactive-hover;
/* font-weight: 600; */
line-height: 1;
overflow: hidden;
white-space: nowrap;

View File

@ -6,6 +6,7 @@ const LOG = Logger.create(__filename, electronConsole);
import React, { Dispatch, DragEvent, FC, SetStateAction, useCallback, useRef } from 'react';
export interface FileDropTargetProps {
title: string;
message: string;
setBuff: Dispatch<SetStateAction<Buffer | null>>;
setName: Dispatch<SetStateAction<string | null>>;
@ -13,7 +14,7 @@ export interface FileDropTargetProps {
}
const FileDropTarget: FC<FileDropTargetProps> = (props: FileDropTargetProps) => {
const { setBuff, setName, close, message } = props;
const { setBuff, setName, close, title, message } = props;
const rootRef = useRef<HTMLDivElement>(null);
@ -64,7 +65,10 @@ const FileDropTarget: FC<FileDropTargetProps> = (props: FileDropTargetProps) =>
<div className="file-drop" ref={rootRef} onDrop={onDrop} onDragOver={onDragOver} onDragLeave={onDragLeave}>
<div className="panel">
<img className="drop-icon" src="./img/file-improved.svg" alt="file" />
<div className="drop-message">{message}</div>
<div className="drop-description">
<div className="drop-title">{title}</div>
<div className="drop-message">{message}</div>
</div>
</div>
</div>
);

View File

@ -21,7 +21,7 @@ export interface ImageContextMenuProps {
const ImageContextMenu: FC<ImageContextMenuProps> = (props: ImageContextMenuProps) => {
const { relativeToPos, close, resourceName, resourceBuff, isPreview } = props;
const previewText = isPreview ? ' Preview' : '';
const previewText = isPreview ? ' Preview' : ' Image';
// TODO: Integrate shaking
@ -44,23 +44,33 @@ const ImageContextMenu: FC<ImageContextMenuProps> = (props: ImageContextMenuProp
},
[resourceBuff],
{
start: 'Copy Image' + previewText,
start: 'Copy ' + previewText,
pending: 'Copying' + previewText,
error: 'Copy Failed. Click to Try Again',
done: 'Copied to Clipboard',
},
);
const [saveCallable, saveText, _saveShaking] = useDownloadButton(resourceName + (isPreview ? '-preview.jpg' : ''), async () => resourceBuff, [resourceBuff], {
start: 'Save Image' + previewText,
pendingSave: 'Saving' + previewText + '...',
errorSave: 'Save Failed. Click to Try Again',
});
const [saveCallable, saveText, _saveShaking] = useDownloadButton(
resourceName + (isPreview ? '-preview.jpg' : ''),
async () => resourceBuff,
[resourceBuff],
{
start: 'Save ' + previewText,
pendingSave: 'Saving' + previewText + '...',
errorSave: 'Save Failed. Click to Try Again',
},
);
const alignment = useMemo(() => ({ top: 'centerY', left: 'centerX' }), []);
return (
<ContextMenu alignment={alignment} relativeToPos={relativeToPos} realignDeps={[copyText, saveText]} close={close}>
<ContextMenu
alignment={alignment}
relativeToPos={relativeToPos}
realignDeps={[copyText, saveText]}
close={close}
>
<div className="image">
<div className="item copy-image" onClick={copyCallable}>
{copyText}

View File

@ -573,6 +573,7 @@ export function useContextHover(
/** creates a drop target element that will appear when you drag a file over the document */
export function useDocumentDropTarget(
title: string,
message: string,
setBuff: Dispatch<SetStateAction<Buffer | null>>,
setName: Dispatch<SetStateAction<string | null>>,
@ -599,8 +600,16 @@ export function useDocumentDropTarget(
const dropTarget = useMemo(() => {
if (!dragEnabled) return null;
return <FileDropTarget close={closeDragOverlay} message={message} setBuff={setBuff} setName={setName} />;
}, [closeDragOverlay, dragEnabled, message, setBuff, setName]);
return (
<FileDropTarget
close={closeDragOverlay}
title={title}
message={message}
setBuff={setBuff}
setName={setName}
/>
);
}, [closeDragOverlay, dragEnabled, title, message, setBuff, setName]);
return [dropTarget];
}

View File

@ -1,8 +1,23 @@
import React, { ClipboardEvent, FC, FormEvent, KeyboardEvent, RefObject, useCallback, useMemo, useRef, useState } from 'react';
import React, {
ClipboardEvent,
FC,
FormEvent,
KeyboardEvent,
RefObject,
useCallback,
useMemo,
useRef,
useState,
} from 'react';
import { Channel } from '../../data-types';
import CombinedGuild from '../../guild-combined';
import BaseElements from '../require/base-elements';
import { useAsyncVoidCallback, useDocumentDropTarget, useIsMountedRef, useOneTimeAsyncAction } from '../require/react-helper';
import {
useAsyncVoidCallback,
useDocumentDropTarget,
useIsMountedRef,
useOneTimeAsyncAction,
} from '../require/react-helper';
import * as FileType from 'file-type';
import ElementsUtil from '../require/elements-util';
import FileInput from '../components/input-file';
@ -66,7 +81,12 @@ const SendMessage: FC<SendMessageProps> = (props: SendMessageProps) => {
// TODO: Deal with errors (toasts are probably the best way)
if (attachmentBuff && attachmentName) {
await guild.requestSendMessageWithResource(channel.id, text === '' ? null : text, attachmentBuff, attachmentName);
await guild.requestSendMessageWithResource(
channel.id,
text === '' ? null : text,
attachmentBuff,
attachmentName,
);
if (!isMounted.current) return;
setAttachmentBuff(null);
setAttachmentName(null);
@ -122,11 +142,22 @@ const SendMessage: FC<SendMessageProps> = (props: SendMessageProps) => {
setAttachmentName(null);
}, []);
const [attachmentDropTarget] = useDocumentDropTarget('Upload to #' + channel.name, setAttachmentBuff, setAttachmentName);
const [attachmentDropTarget] = useDocumentDropTarget(
'Drop to Attach',
'#' + channel.name,
setAttachmentBuff,
setAttachmentName,
);
const attachmentPreview = useMemo(() => {
if (!attachmentBuff || !attachmentName) return null;
return <AttachmentPreview attachmentBuff={attachmentBuff} attachmentName={attachmentName} remove={removeAttachment} />;
return (
<AttachmentPreview
attachmentBuff={attachmentBuff}
attachmentName={attachmentName}
remove={removeAttachment}
/>
);
}, [attachmentBuff, attachmentName, removeAttachment]);
// WARNING: The types on this are funky because of react's lack of explicit support for 'plaintext-only'
@ -149,7 +180,15 @@ const SendMessage: FC<SendMessageProps> = (props: SendMessageProps) => {
{BaseElements.SEND_MESSAGE_ATTACH}
</FileInput>
</div>
<div ref={contentEditableRef} className={textInputClassName} contentEditable={contentEditableType} data-placeholder={`Message #${channel.name}`} onInput={onTextInput} onKeyDown={onTextKeyDown} onPaste={onPaste} />
<div
ref={contentEditableRef}
className={textInputClassName}
contentEditable={contentEditableType}
data-placeholder={`Message #${channel.name}`}
onInput={onTextInput}
onKeyDown={onTextKeyDown}
onPaste={onPaste}
/>
</div>
</div>
{attachmentDropTarget}

View File

@ -9,7 +9,5 @@
</head>
<body class="preload">
<div id="react-root"></div>
<!-- it's important that this comes at the end so that these take prescedence over the other absolutely positioned objects-->
<div id="react-overlays"></div>
</body>
</html>