Web: Files: Hotkeys: added support for copying from desktop, removed useless files-converter
This commit is contained in:
parent
7051e55778
commit
35a4287e03
@ -61,8 +61,8 @@ const withHotkeys = (Component) => {
|
||||
setInviteUsersWarningDialogVisible,
|
||||
|
||||
security,
|
||||
setHotkeysClipboard,
|
||||
moveFilesFromClipboard,
|
||||
copyToClipboard,
|
||||
uploadClipboardFiles,
|
||||
} = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
@ -118,13 +118,21 @@ const withHotkeys = (Component) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onPaste = async (e) => {
|
||||
e.preventDefault();
|
||||
uploadClipboardFiles(t, e);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const throttledKeyDownEvent = throttle(onKeyDown, 300);
|
||||
|
||||
window.addEventListener("keydown", throttledKeyDownEvent);
|
||||
document.addEventListener("paste", onPaste);
|
||||
|
||||
return () =>
|
||||
return () => {
|
||||
window.removeEventListener("keypress", throttledKeyDownEvent);
|
||||
document.removeEventListener("paste", onPaste);
|
||||
};
|
||||
});
|
||||
|
||||
//Select/deselect item
|
||||
@ -333,9 +341,8 @@ const withHotkeys = (Component) => {
|
||||
hotkeysFilter
|
||||
);
|
||||
|
||||
useHotkeys("Ctrl+c", () => setHotkeysClipboard(), hotkeysFilter);
|
||||
useHotkeys("Ctrl+x", () => setHotkeysClipboard(true), hotkeysFilter);
|
||||
useHotkeys("Ctrl+v", () => moveFilesFromClipboard(t), hotkeysFilter);
|
||||
useHotkeys("Ctrl+c", () => copyToClipboard(t), hotkeysFilter);
|
||||
useHotkeys("Ctrl+x", () => copyToClipboard(t, true), hotkeysFilter);
|
||||
|
||||
//Upload file
|
||||
useHotkeys(
|
||||
@ -401,8 +408,8 @@ const withHotkeys = (Component) => {
|
||||
selectAll,
|
||||
activateHotkeys,
|
||||
uploadFile,
|
||||
setHotkeysClipboard,
|
||||
moveFilesFromClipboard,
|
||||
copyToClipboard,
|
||||
uploadClipboardFiles,
|
||||
} = hotkeyStore;
|
||||
|
||||
const {
|
||||
@ -489,8 +496,9 @@ const withHotkeys = (Component) => {
|
||||
setInviteUsersWarningDialogVisible,
|
||||
|
||||
security,
|
||||
setHotkeysClipboard,
|
||||
moveFilesFromClipboard,
|
||||
copyToClipboard,
|
||||
|
||||
uploadClipboardFiles,
|
||||
};
|
||||
}
|
||||
)(observer(WithHotkeys));
|
||||
|
@ -1,128 +0,0 @@
|
||||
export const onConvertFiles = (e, resolve) => {
|
||||
const items = e.dataTransfer.items;
|
||||
const files = [];
|
||||
|
||||
const callItemFromQueue = (queue, callback) => {
|
||||
let i = 0;
|
||||
let queueLength = queue.length;
|
||||
|
||||
if (!queue || !queue.length) {
|
||||
callback();
|
||||
}
|
||||
|
||||
const callNext = (i) => {
|
||||
queue[i]((error) => {
|
||||
if (!error && i + 1 < queueLength) {
|
||||
i++;
|
||||
callNext(i);
|
||||
} else {
|
||||
callback(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
callNext(i);
|
||||
};
|
||||
|
||||
const readDirEntry = (dirEntry, callback) => {
|
||||
const entries = [];
|
||||
const dirReader = dirEntry.createReader();
|
||||
|
||||
const getEntries = (entriesCallback) => {
|
||||
dirReader.readEntries((moreEntries) => {
|
||||
if (moreEntries.length) {
|
||||
Array.prototype.push.apply(entries, moreEntries);
|
||||
getEntries(entriesCallback);
|
||||
} else {
|
||||
entriesCallback();
|
||||
}
|
||||
}, entriesCallback);
|
||||
};
|
||||
|
||||
getEntries(() => {
|
||||
readEntries(entries, callback);
|
||||
});
|
||||
};
|
||||
|
||||
const readEntry = (entry, callback) => {
|
||||
if (entry.isFile) {
|
||||
entry.file(
|
||||
(file) => {
|
||||
addItem(file, entry.fullPath);
|
||||
callback();
|
||||
},
|
||||
() => {
|
||||
callback();
|
||||
}
|
||||
);
|
||||
} else if (entry.isDirectory) {
|
||||
readDirEntry(entry, callback);
|
||||
}
|
||||
};
|
||||
|
||||
const readEntries = (entries, callback) => {
|
||||
const queue = [];
|
||||
loop(entries, (entry) => {
|
||||
queue.push((func) => {
|
||||
readEntry(entry, func);
|
||||
});
|
||||
});
|
||||
callItemFromQueue(queue, () => callback());
|
||||
};
|
||||
|
||||
const addFile = (file, relativePath) => {
|
||||
file.path = relativePath || "";
|
||||
files.push(file);
|
||||
};
|
||||
|
||||
const loop = (items, callback) => {
|
||||
let itemsLength;
|
||||
|
||||
if (items) {
|
||||
try {
|
||||
itemsLength = items.length;
|
||||
} catch (err) {
|
||||
itemsLength = null;
|
||||
}
|
||||
|
||||
if (itemsLength === null || typeof itemsLength !== "number") {
|
||||
// Loop object items
|
||||
for (let key in items) {
|
||||
if (items.hasOwnProperty(key)) {
|
||||
if (callback(items[key], key) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Loop array items
|
||||
for (let i = 0; i < itemsLength; i++) {
|
||||
if (callback(items[i], i) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const readItems = (items, callback) => {
|
||||
const entries = [];
|
||||
loop(items, (item) => {
|
||||
const entry = item.webkitGetAsEntry();
|
||||
if (entry) {
|
||||
if (entry.isFile) {
|
||||
addItem(item.getAsFile(), entry.fullPath);
|
||||
} else {
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (entries.length) {
|
||||
readEntries(entries, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
readItems(items, () => resolve(files));
|
||||
};
|
@ -6,6 +6,7 @@ import { getCategoryUrl } from "SRC_DIR/helpers/utils";
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
import { RoomsType } from "@docspace/common/constants";
|
||||
import { encryptionUploadDialog } from "../helpers/desktop";
|
||||
import getFilesFromEvent from "@docspace/components/drag-and-drop/get-files-from-event";
|
||||
|
||||
class HotkeyStore {
|
||||
filesStore;
|
||||
@ -611,12 +612,38 @@ class HotkeyStore {
|
||||
.catch((e) => {
|
||||
toastr.error(e);
|
||||
clearActiveOperations(fileIds, folderIds);
|
||||
})
|
||||
.finally(() => {
|
||||
this.filesStore.setHotkeysClipboard([]);
|
||||
});
|
||||
} else {
|
||||
toastr.error(t("Common:ErrorEmptyList"));
|
||||
}
|
||||
};
|
||||
|
||||
uploadClipboardFiles = async (t, event) => {
|
||||
const { uploadEmptyFolders } = this.filesActionsStore;
|
||||
const { startUpload } = this.uploadDataStore;
|
||||
const currentFolderId = this.selectedFolderStore.id;
|
||||
|
||||
if (this.filesStore.hotkeysClipboard.length) {
|
||||
return this.moveFilesFromClipboard(t);
|
||||
}
|
||||
|
||||
const files = await getFilesFromEvent(event);
|
||||
|
||||
const emptyFolders = files.filter((f) => f.isEmptyDirectory);
|
||||
|
||||
if (emptyFolders.length > 0) {
|
||||
uploadEmptyFolders(emptyFolders, currentFolderId).then(() => {
|
||||
const onlyFiles = files.filter((f) => !f.isEmptyDirectory);
|
||||
if (onlyFiles.length > 0) startUpload(onlyFiles, currentFolderId, t);
|
||||
});
|
||||
} else {
|
||||
startUpload(files, currentFolderId, t);
|
||||
}
|
||||
};
|
||||
|
||||
get countTilesInRow() {
|
||||
const isDesktopView = isDesktop();
|
||||
const tileGap = isDesktopView ? 16 : 14;
|
||||
|
@ -30,8 +30,8 @@ const FILES_TO_IGNORE = [
|
||||
* @param evt
|
||||
*/
|
||||
export default async function getFilesFromEvent(evt) {
|
||||
return isDragEvt(evt) && evt.dataTransfer
|
||||
? getDataTransferFiles(evt.dataTransfer, evt.type)
|
||||
return (isDragEvt(evt) && evt.dataTransfer) || evt.clipboardData
|
||||
? getDataTransferFiles(evt.dataTransfer ?? evt.clipboardData, evt.type)
|
||||
: getInputFiles(evt);
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ async function getDataTransferFiles(dt, type) {
|
||||
const items = fromList(dt.items).filter((item) => item.kind === "file");
|
||||
// According to https://html.spec.whatwg.org/multipage/dnd.html#dndevents,
|
||||
// only 'dragstart' and 'drop' has access to the data (source node)
|
||||
if (type !== "drop") {
|
||||
if (type !== "drop" && type !== "paste") {
|
||||
return items;
|
||||
}
|
||||
const files = await Promise.all(items.map(toFilePromises));
|
||||
|
Loading…
Reference in New Issue
Block a user