@@ -60,16 +60,30 @@ const DesktopIcon = styled.div`
6060 }
6161` ;
6262
63+ const DragOverlay = styled . div `
64+ position: fixed;
65+ pointer-events: none;
66+ z-index: 9999;
67+ opacity: 0.8;
68+ display: flex;
69+ flex-direction: column;
70+ align-items: center;
71+ color: white;
72+ text-shadow: 1px 1px 2px black;
73+ ` ;
74+
6375const Desktop = ( ) => {
6476 const { t } = useTranslation ( ) ;
65- const { fs } = useFileSystem ( ) ;
77+ const { fs, moveFile } = useFileSystem ( ) ;
6678 const { windows, openWindow, focusWindow } = useWindowManager ( ) ;
6779 const { showModal } = useModal ( ) ;
6880
6981 const [ contextMenu , setContextMenu ] = useState ( { visible : false , x : 0 , y : 0 } ) ;
7082 const [ refreshKey , setRefreshKey ] = useState ( 0 ) ;
7183 const [ isRefreshing , setIsRefreshing ] = useState ( false ) ;
7284 const [ pasteDisabled , setPasteDisabled ] = useState ( true ) ;
85+ const [ draggedItem , setDraggedItem ] = useState ( null ) ;
86+ const [ dragPosition , setDragPosition ] = useState ( { x : 0 , y : 0 } ) ;
7387
7488 const handleIconDoubleClick = ( key , item ) => {
7589 const resolved = resolveFileOpen ( key , item ) ;
@@ -80,6 +94,27 @@ const Desktop = () => {
8094 openWindow ( resolved . appId , item . name , resolved . component , resolved . icon , resolved . windowProps ) ;
8195 } ;
8296
97+ const handleDragStart = ( e , key , item ) => {
98+ setDraggedItem ( { key, item } ) ;
99+ setDragPosition ( { x : e . clientX , y : e . clientY } ) ;
100+ } ;
101+
102+ const handleDrag = ( e ) => {
103+ setDragPosition ( { x : e . clientX , y : e . clientY } ) ;
104+ } ;
105+
106+ const handleDragEnd = ( e , targetKey ) => {
107+ // 如果拖拽到了另一个文件夹上
108+ if ( targetKey && targetKey !== draggedItem ?. key ) {
109+ const targetItem = fs . root . children [ targetKey ] ;
110+ if ( targetItem && targetItem . type === 'folder' ) {
111+ // 将文件移动到目标文件夹
112+ moveFile ( [ ] , draggedItem . key , [ targetKey ] ) ;
113+ }
114+ }
115+ setDraggedItem ( null ) ;
116+ } ;
117+
83118 const handleContextMenu = async ( e ) => {
84119 e . preventDefault ( ) ;
85120 try {
@@ -134,7 +169,17 @@ const Desktop = () => {
134169 ? 'recycle_bin_full'
135170 : item . icon ;
136171 return (
137- < DesktopIcon key = { key } data-testid = { `desktop-icon-${ key } ` } onDoubleClick = { ( ) => handleIconDoubleClick ( key , item ) } >
172+ < DesktopIcon
173+ key = { key }
174+ data-testid = { `desktop-icon-${ key } ` }
175+ onDoubleClick = { ( ) => handleIconDoubleClick ( key , item ) }
176+ draggable
177+ onDragStart = { ( e ) => handleDragStart ( e , key , item ) }
178+ onDrag = { ( e ) => handleDrag ( e ) }
179+ onDragEnd = { ( e ) => handleDragEnd ( e , null ) }
180+ onDragOver = { ( e ) => e . preventDefault ( ) } // 允许放置
181+ onDrop = { ( e ) => handleDragEnd ( e , key ) }
182+ >
138183 < div className = "icon-wrapper" >
139184 < XPIcon name = { iconName } size = { 32 } />
140185 </ div >
0 commit comments