From 52e63cd14aa7c6efac8b0c5baa8bd99eecd7dff9 Mon Sep 17 00:00:00 2001 From: troyeguo <13820674+troyeguo@users.noreply.github.com> Date: Wed, 25 Feb 2026 17:27:19 +0800 Subject: [PATCH] feat: enhance drag-and-drop functionality and update styles for better user experience --- public/assets/styles/default.css | 2 +- src/pages/manager/component.tsx | 29 ++++++++++++++++++++++++----- src/pages/manager/index.tsx | 1 + src/pages/manager/interface.tsx | 1 + src/pages/manager/manager.css | 27 ++++++++++++++------------- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/public/assets/styles/default.css b/public/assets/styles/default.css index 1ab64cd9..c1c814e5 100644 --- a/public/assets/styles/default.css +++ b/public/assets/styles/default.css @@ -144,7 +144,7 @@ a { background-color: rgba(75, 75, 75, 0.035); } .drag-background { - background: hsla(0, 0%, 0%, 0.3); + background: hsla(0, 0%, 0%, 0.4); } .action-dialog-container, diff --git a/src/pages/manager/component.tsx b/src/pages/manager/component.tsx index 7309432b..5d2b933a 100644 --- a/src/pages/manager/component.tsx +++ b/src/pages/manager/component.tsx @@ -22,6 +22,8 @@ import { Tooltip } from "react-tooltip"; import { ConfigService } from "../../assets/lib/kookit-extra-browser.min"; import SortShelfDialog from "../../components/dialogs/sortShelfDialog"; import PopupNote from "../../components/popups/popupNote"; +import toast from "react-hot-toast"; +import { supportedFormats } from "../../utils/common"; class Manager extends React.Component { timer!: NodeJS.Timeout; constructor(props: ManagerProps) { @@ -92,9 +94,6 @@ class Manager extends React.Component { className="manager" onDragEnter={() => { !this.props.dragItem && this.handleDrag(true); - ( - document.getElementsByClassName("import-from-local")[0] as any - ).style.zIndex = "50"; }} > @@ -112,7 +111,28 @@ class Manager extends React.Component { {!this.props.dragItem && (
{ + e.preventDefault(); + e.stopPropagation(); + }} + onDrop={async (e) => { + e.preventDefault(); + e.stopPropagation(); + this.handleDrag(false); + const files = e.dataTransfer.files; + if (files && files.length > 0) { + for (let i = 0; i < files.length; i++) { + const file = files[i]; + const ext = "." + file.name.split(".").pop()?.toLowerCase(); + if (!supportedFormats.includes(ext)) { + toast.error("Unsupported file format: " + ext); + continue; + } + await this.props.importBookFunc(file); + } + } + }} onClick={() => { this.props.handleEditDialog(false); this.props.handleDeleteDialog(false); @@ -154,7 +174,6 @@ class Manager extends React.Component { > {this.state.isDrag && (
-

Drop your books here

diff --git a/src/pages/manager/index.tsx b/src/pages/manager/index.tsx index 9953988e..a0c624e2 100644 --- a/src/pages/manager/index.tsx +++ b/src/pages/manager/index.tsx @@ -33,6 +33,7 @@ const mapStateToProps = (state: stateType) => { books: state.manager.books, mode: state.sidebar.mode, dragItem: state.book.dragItem, + importBookFunc: state.book.importBookFunc, shelfTitle: state.sidebar.shelfTitle, isOpenEditDialog: state.book.isOpenEditDialog, isDetailDialog: state.manager.isDetailDialog, diff --git a/src/pages/manager/interface.tsx b/src/pages/manager/interface.tsx index 71543cff..6f3b414f 100644 --- a/src/pages/manager/interface.tsx +++ b/src/pages/manager/interface.tsx @@ -21,6 +21,7 @@ export interface ManagerProps extends RouteComponentProps { isOpenSortShelfDialog: boolean; isOpenLocalFileDialog: boolean; dragItem: string; + importBookFunc: (file: any) => Promise; handleFetchBooks: () => void; handleFetchPlugins: () => void; handleFetchNotes: () => void; diff --git a/src/pages/manager/manager.css b/src/pages/manager/manager.css index ac7a07c0..2d61ea46 100644 --- a/src/pages/manager/manager.css +++ b/src/pages/manager/manager.css @@ -3,7 +3,11 @@ height: 100%; } .arrow-text { - font-size: 20px; + font-size: 26px; + color: rgba(255, 255, 255, 0.95); + font-weight: 600; + margin: 0; + line-height: 1.4; } .auth-page-close-icon { @@ -24,21 +28,18 @@ left: 0px; z-index: 9; } -@keyframes fade-in-out { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} .drag-info { - width: 200px; - height: 300px; position: absolute; - top: 80px; - right: 0px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 360px; + padding: 48px 36px; text-align: center; + border: 3px dashed rgba(255, 255, 255, 0.7); + border-radius: 20px; + background-color: rgba(255, 255, 255, 0.12); + pointer-events: none; } .waring-title { text-align: center;