feat(remote): 下载改成本地面板选择目录
This commit is contained in:
@@ -351,13 +351,15 @@ ipcMain.handle("remote-upload-file", async (_event, serverHost, port, filePath,
|
|||||||
return { success: false, error: error.message };
|
return { success: false, error: error.message };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ipcMain.handle("remote-download-file", async (_event, serverHost, port, fileName, remotePath, password) => {
|
ipcMain.handle("remote-download-file", async (_event, serverHost, port, fileName, remotePath, localPath, password) => {
|
||||||
try {
|
try {
|
||||||
|
log2.info("Remote download params:", { serverHost, port, fileName, remotePath, localPath, password });
|
||||||
const win = electronState.getMainWindow();
|
const win = electronState.getMainWindow();
|
||||||
if (!win) {
|
if (!win) {
|
||||||
throw new Error("No window found");
|
throw new Error("No window found");
|
||||||
}
|
}
|
||||||
let url = `http://${serverHost}:${port}/api/files/${encodeURIComponent(fileName)}`;
|
const fullRemotePath = remotePath ? `${remotePath}\\${fileName}` : fileName;
|
||||||
|
let url = `http://${serverHost}:${port}/api/files/${encodeURIComponent(fullRemotePath)}`;
|
||||||
if (password) {
|
if (password) {
|
||||||
url += `?password=${encodeURIComponent(password)}`;
|
url += `?password=${encodeURIComponent(password)}`;
|
||||||
}
|
}
|
||||||
@@ -366,15 +368,13 @@ ipcMain.handle("remote-download-file", async (_event, serverHost, port, fileName
|
|||||||
throw new Error(`Download failed: ${response.statusText}`);
|
throw new Error(`Download failed: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
const buffer = await response.arrayBuffer();
|
const buffer = await response.arrayBuffer();
|
||||||
const { filePath } = await dialog2.showSaveDialog(win, {
|
const targetDir = localPath || "C:\\";
|
||||||
title: "\u4FDD\u5B58\u6587\u4EF6",
|
const targetPath = path2.join(targetDir, fileName);
|
||||||
defaultPath: fileName
|
if (!fs2.existsSync(targetDir)) {
|
||||||
});
|
fs2.mkdirSync(targetDir, { recursive: true });
|
||||||
if (!filePath) {
|
|
||||||
return { success: false, canceled: true };
|
|
||||||
}
|
}
|
||||||
fs2.writeFileSync(filePath, Buffer.from(buffer));
|
fs2.writeFileSync(targetPath, Buffer.from(buffer));
|
||||||
return { success: true, filePath };
|
return { success: true, filePath: targetPath };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log2.error("Remote download failed:", error);
|
log2.error("Remote download failed:", error);
|
||||||
return { success: false, error: error.message };
|
return { success: false, error: error.message };
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -23,6 +23,6 @@ import_electron.contextBridge.exposeInMainWorld("electronAPI", {
|
|||||||
remoteFetchDrives: (serverHost, port, password) => import_electron.ipcRenderer.invoke("remote-fetch-drives", serverHost, port, password),
|
remoteFetchDrives: (serverHost, port, password) => import_electron.ipcRenderer.invoke("remote-fetch-drives", serverHost, port, password),
|
||||||
remoteFetchFiles: (serverHost, port, filePath, password) => import_electron.ipcRenderer.invoke("remote-fetch-files", serverHost, port, filePath, password),
|
remoteFetchFiles: (serverHost, port, filePath, password) => import_electron.ipcRenderer.invoke("remote-fetch-files", serverHost, port, filePath, password),
|
||||||
remoteUploadFile: (serverHost, port, filePath, remotePath, password) => import_electron.ipcRenderer.invoke("remote-upload-file", serverHost, port, filePath, remotePath, password),
|
remoteUploadFile: (serverHost, port, filePath, remotePath, password) => import_electron.ipcRenderer.invoke("remote-upload-file", serverHost, port, filePath, remotePath, password),
|
||||||
remoteDownloadFile: (serverHost, port, fileName, remotePath, password) => import_electron.ipcRenderer.invoke("remote-download-file", serverHost, port, fileName, remotePath, password)
|
remoteDownloadFile: (serverHost, port, fileName, remotePath, localPath, password) => import_electron.ipcRenderer.invoke("remote-download-file", serverHost, port, fileName, remotePath, localPath, password)
|
||||||
});
|
});
|
||||||
//# sourceMappingURL=preload.cjs.map
|
//# sourceMappingURL=preload.cjs.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sources":["../electron/preload.ts"],"sourcesContent":["import { contextBridge, ipcRenderer } from 'electron'\r\n\r\nconsole.log('--- PRELOAD SCRIPT LOADED SUCCESSFULLY ---')\r\n\r\ncontextBridge.exposeInMainWorld('electronAPI', {\r\n exportPDF: (title: string, htmlContent?: string) => ipcRenderer.invoke('export-pdf', title, htmlContent),\r\n selectHtmlFile: () => ipcRenderer.invoke('select-html-file'),\r\n updateTitlebarButtons: (symbolColor: string) => ipcRenderer.invoke('update-titlebar-buttons', symbolColor),\r\n onRemoteClipboardSyncToRemote: (callback: () => void) => {\r\n ipcRenderer.on('remote-clipboard-sync-to-remote', callback);\r\n return () => ipcRenderer.removeListener('remote-clipboard-sync-to-remote', callback);\r\n },\r\n onRemoteClipboardSyncFromRemote: (callback: () => void) => {\r\n ipcRenderer.on('remote-clipboard-sync-from-remote', callback);\r\n return () => ipcRenderer.removeListener('remote-clipboard-sync-from-remote', callback);\r\n },\r\n onRemoteClipboardAutoSync: (callback: (text: string) => void) => {\r\n const handler = (_event: Electron.IpcRendererEvent, text: string) => callback(text);\r\n ipcRenderer.on('remote-clipboard-auto-sync', handler);\r\n return () => ipcRenderer.removeListener('remote-clipboard-auto-sync', handler);\r\n },\r\n clipboardReadText: () => ipcRenderer.invoke('clipboard-read-text'),\r\n clipboardWriteText: (text: string) => ipcRenderer.invoke('clipboard-write-text', text),\r\n remoteFetchDrives: (serverHost: string, port: number, password?: string) => \r\n ipcRenderer.invoke('remote-fetch-drives', serverHost, port, password),\r\n remoteFetchFiles: (serverHost: string, port: number, filePath: string, password?: string) => \r\n ipcRenderer.invoke('remote-fetch-files', serverHost, port, filePath, password),\r\n remoteUploadFile: (serverHost: string, port: number, filePath: string, remotePath: string, password?: string) => \r\n ipcRenderer.invoke('remote-upload-file', serverHost, port, filePath, remotePath, password),\r\n remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, password?: string) => \r\n ipcRenderer.invoke('remote-download-file', serverHost, port, fileName, remotePath, password),\r\n})\r\n"],"mappings":";AAAA,sBAA2C;AAE3C,QAAQ,IAAI,4CAA4C;AAExD,8BAAc,kBAAkB,eAAe;AAAA,EAC7C,WAAW,CAAC,OAAe,gBAAyB,4BAAY,OAAO,cAAc,OAAO,WAAW;AAAA,EACvG,gBAAgB,MAAM,4BAAY,OAAO,kBAAkB;AAAA,EAC3D,uBAAuB,CAAC,gBAAwB,4BAAY,OAAO,2BAA2B,WAAW;AAAA,EACzG,+BAA+B,CAAC,aAAyB;AACvD,gCAAY,GAAG,mCAAmC,QAAQ;AAC1D,WAAO,MAAM,4BAAY,eAAe,mCAAmC,QAAQ;AAAA,EACrF;AAAA,EACA,iCAAiC,CAAC,aAAyB;AACzD,gCAAY,GAAG,qCAAqC,QAAQ;AAC5D,WAAO,MAAM,4BAAY,eAAe,qCAAqC,QAAQ;AAAA,EACvF;AAAA,EACA,2BAA2B,CAAC,aAAqC;AAC/D,UAAM,UAAU,CAAC,QAAmC,SAAiB,SAAS,IAAI;AAClF,gCAAY,GAAG,8BAA8B,OAAO;AACpD,WAAO,MAAM,4BAAY,eAAe,8BAA8B,OAAO;AAAA,EAC/E;AAAA,EACA,mBAAmB,MAAM,4BAAY,OAAO,qBAAqB;AAAA,EACjE,oBAAoB,CAAC,SAAiB,4BAAY,OAAO,wBAAwB,IAAI;AAAA,EACrF,mBAAmB,CAAC,YAAoB,MAAc,aACpD,4BAAY,OAAO,uBAAuB,YAAY,MAAM,QAAQ;AAAA,EACtE,kBAAkB,CAAC,YAAoB,MAAc,UAAkB,aACrE,4BAAY,OAAO,sBAAsB,YAAY,MAAM,UAAU,QAAQ;AAAA,EAC/E,kBAAkB,CAAC,YAAoB,MAAc,UAAkB,YAAoB,aACzF,4BAAY,OAAO,sBAAsB,YAAY,MAAM,UAAU,YAAY,QAAQ;AAAA,EAC3F,oBAAoB,CAAC,YAAoB,MAAc,UAAkB,YAAoB,aAC3F,4BAAY,OAAO,wBAAwB,YAAY,MAAM,UAAU,YAAY,QAAQ;AAC/F,CAAC;","names":[]}
|
{"version":3,"sources":["../electron/preload.ts"],"sourcesContent":["import { contextBridge, ipcRenderer } from 'electron'\r\n\r\nconsole.log('--- PRELOAD SCRIPT LOADED SUCCESSFULLY ---')\r\n\r\ncontextBridge.exposeInMainWorld('electronAPI', {\r\n exportPDF: (title: string, htmlContent?: string) => ipcRenderer.invoke('export-pdf', title, htmlContent),\r\n selectHtmlFile: () => ipcRenderer.invoke('select-html-file'),\r\n updateTitlebarButtons: (symbolColor: string) => ipcRenderer.invoke('update-titlebar-buttons', symbolColor),\r\n onRemoteClipboardSyncToRemote: (callback: () => void) => {\r\n ipcRenderer.on('remote-clipboard-sync-to-remote', callback);\r\n return () => ipcRenderer.removeListener('remote-clipboard-sync-to-remote', callback);\r\n },\r\n onRemoteClipboardSyncFromRemote: (callback: () => void) => {\r\n ipcRenderer.on('remote-clipboard-sync-from-remote', callback);\r\n return () => ipcRenderer.removeListener('remote-clipboard-sync-from-remote', callback);\r\n },\r\n onRemoteClipboardAutoSync: (callback: (text: string) => void) => {\r\n const handler = (_event: Electron.IpcRendererEvent, text: string) => callback(text);\r\n ipcRenderer.on('remote-clipboard-auto-sync', handler);\r\n return () => ipcRenderer.removeListener('remote-clipboard-auto-sync', handler);\r\n },\r\n clipboardReadText: () => ipcRenderer.invoke('clipboard-read-text'),\r\n clipboardWriteText: (text: string) => ipcRenderer.invoke('clipboard-write-text', text),\r\n remoteFetchDrives: (serverHost: string, port: number, password?: string) => \r\n ipcRenderer.invoke('remote-fetch-drives', serverHost, port, password),\r\n remoteFetchFiles: (serverHost: string, port: number, filePath: string, password?: string) => \r\n ipcRenderer.invoke('remote-fetch-files', serverHost, port, filePath, password),\r\n remoteUploadFile: (serverHost: string, port: number, filePath: string, remotePath: string, password?: string) => \r\n ipcRenderer.invoke('remote-upload-file', serverHost, port, filePath, remotePath, password),\r\n remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) => \r\n ipcRenderer.invoke('remote-download-file', serverHost, port, fileName, remotePath, localPath, password),\r\n})\r\n"],"mappings":";AAAA,sBAA2C;AAE3C,QAAQ,IAAI,4CAA4C;AAExD,8BAAc,kBAAkB,eAAe;AAAA,EAC7C,WAAW,CAAC,OAAe,gBAAyB,4BAAY,OAAO,cAAc,OAAO,WAAW;AAAA,EACvG,gBAAgB,MAAM,4BAAY,OAAO,kBAAkB;AAAA,EAC3D,uBAAuB,CAAC,gBAAwB,4BAAY,OAAO,2BAA2B,WAAW;AAAA,EACzG,+BAA+B,CAAC,aAAyB;AACvD,gCAAY,GAAG,mCAAmC,QAAQ;AAC1D,WAAO,MAAM,4BAAY,eAAe,mCAAmC,QAAQ;AAAA,EACrF;AAAA,EACA,iCAAiC,CAAC,aAAyB;AACzD,gCAAY,GAAG,qCAAqC,QAAQ;AAC5D,WAAO,MAAM,4BAAY,eAAe,qCAAqC,QAAQ;AAAA,EACvF;AAAA,EACA,2BAA2B,CAAC,aAAqC;AAC/D,UAAM,UAAU,CAAC,QAAmC,SAAiB,SAAS,IAAI;AAClF,gCAAY,GAAG,8BAA8B,OAAO;AACpD,WAAO,MAAM,4BAAY,eAAe,8BAA8B,OAAO;AAAA,EAC/E;AAAA,EACA,mBAAmB,MAAM,4BAAY,OAAO,qBAAqB;AAAA,EACjE,oBAAoB,CAAC,SAAiB,4BAAY,OAAO,wBAAwB,IAAI;AAAA,EACrF,mBAAmB,CAAC,YAAoB,MAAc,aACpD,4BAAY,OAAO,uBAAuB,YAAY,MAAM,QAAQ;AAAA,EACtE,kBAAkB,CAAC,YAAoB,MAAc,UAAkB,aACrE,4BAAY,OAAO,sBAAsB,YAAY,MAAM,UAAU,QAAQ;AAAA,EAC/E,kBAAkB,CAAC,YAAoB,MAAc,UAAkB,YAAoB,aACzF,4BAAY,OAAO,sBAAsB,YAAY,MAAM,UAAU,YAAY,QAAQ;AAAA,EAC3F,oBAAoB,CAAC,YAAoB,MAAc,UAAkB,YAAoB,WAAmB,aAC9G,4BAAY,OAAO,wBAAwB,YAAY,MAAM,UAAU,YAAY,WAAW,QAAQ;AAC1G,CAAC;","names":[]}
|
||||||
@@ -255,15 +255,17 @@ ipcMain.handle('remote-upload-file', async (_event, serverHost: string, port: nu
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('remote-download-file', async (_event, serverHost: string, port: number, fileName: string, remotePath: string, password?: string) => {
|
ipcMain.handle('remote-download-file', async (_event, serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) => {
|
||||||
try {
|
try {
|
||||||
|
log.info('Remote download params:', { serverHost, port, fileName, remotePath, localPath, password });
|
||||||
|
|
||||||
const win = electronState.getMainWindow();
|
const win = electronState.getMainWindow();
|
||||||
if (!win) {
|
if (!win) {
|
||||||
throw new Error('No window found');
|
throw new Error('No window found');
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullPath = remotePath ? `${remotePath}\\${fileName}` : fileName;
|
const fullRemotePath = remotePath ? `${remotePath}\\${fileName}` : fileName;
|
||||||
let url = `http://${serverHost}:${port}/api/files/${encodeURIComponent(fullPath)}`;
|
let url = `http://${serverHost}:${port}/api/files/${encodeURIComponent(fullRemotePath)}`;
|
||||||
if (password) {
|
if (password) {
|
||||||
url += `?password=${encodeURIComponent(password)}`;
|
url += `?password=${encodeURIComponent(password)}`;
|
||||||
}
|
}
|
||||||
@@ -275,18 +277,16 @@ ipcMain.handle('remote-download-file', async (_event, serverHost: string, port:
|
|||||||
|
|
||||||
const buffer = await response.arrayBuffer();
|
const buffer = await response.arrayBuffer();
|
||||||
|
|
||||||
const { filePath } = await dialog.showSaveDialog(win, {
|
const targetDir = localPath || 'C:\\';
|
||||||
title: '保存文件',
|
const targetPath = path.join(targetDir, fileName);
|
||||||
defaultPath: fileName,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!filePath) {
|
if (!fs.existsSync(targetDir)) {
|
||||||
return { success: false, canceled: true };
|
fs.mkdirSync(targetDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(filePath, Buffer.from(buffer));
|
fs.writeFileSync(targetPath, Buffer.from(buffer));
|
||||||
|
|
||||||
return { success: true, filePath };
|
return { success: true, filePath: targetPath };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
log.error('Remote download failed:', error);
|
log.error('Remote download failed:', error);
|
||||||
return { success: false, error: error.message };
|
return { success: false, error: error.message };
|
||||||
|
|||||||
@@ -27,6 +27,6 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
ipcRenderer.invoke('remote-fetch-files', serverHost, port, filePath, password),
|
ipcRenderer.invoke('remote-fetch-files', serverHost, port, filePath, password),
|
||||||
remoteUploadFile: (serverHost: string, port: number, filePath: string, remotePath: string, password?: string) =>
|
remoteUploadFile: (serverHost: string, port: number, filePath: string, remotePath: string, password?: string) =>
|
||||||
ipcRenderer.invoke('remote-upload-file', serverHost, port, filePath, remotePath, password),
|
ipcRenderer.invoke('remote-upload-file', serverHost, port, filePath, remotePath, password),
|
||||||
remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, password?: string) =>
|
remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) =>
|
||||||
ipcRenderer.invoke('remote-download-file', serverHost, port, fileName, remotePath, password),
|
ipcRenderer.invoke('remote-download-file', serverHost, port, fileName, remotePath, localPath, password),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -115,11 +115,12 @@ export const downloadFileFromRemote = async (
|
|||||||
port: number,
|
port: number,
|
||||||
fileName: string,
|
fileName: string,
|
||||||
remotePath: string,
|
remotePath: string,
|
||||||
|
localPath: string,
|
||||||
password?: string,
|
password?: string,
|
||||||
onProgress?: (progress: number) => void
|
onProgress?: (progress: number) => void
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
onProgress?.(50)
|
onProgress?.(50)
|
||||||
const result = await window.electronAPI.remoteDownloadFile(serverHost, port, fileName, remotePath, password)
|
const result = await window.electronAPI.remoteDownloadFile(serverHost, port, fileName, remotePath, localPath, password)
|
||||||
onProgress?.(100)
|
onProgress?.(100)
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
if (result.canceled) {
|
if (result.canceled) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
|
|||||||
const [localSelected, setLocalSelected] = useState<FileItem | null>(null)
|
const [localSelected, setLocalSelected] = useState<FileItem | null>(null)
|
||||||
const [remoteSelected, setRemoteSelected] = useState<RemoteFileItem | null>(null)
|
const [remoteSelected, setRemoteSelected] = useState<RemoteFileItem | null>(null)
|
||||||
const [remotePath, setRemotePath] = useState('')
|
const [remotePath, setRemotePath] = useState('')
|
||||||
|
const [localPath, setLocalPath] = useState('')
|
||||||
const [transfers, setTransfers] = useState<TransferItem[]>([])
|
const [transfers, setTransfers] = useState<TransferItem[]>([])
|
||||||
const [transferring, setTransferring] = useState(false)
|
const [transferring, setTransferring] = useState(false)
|
||||||
const [transferQueueHeight, setTransferQueueHeight] = useState(128)
|
const [transferQueueHeight, setTransferQueueHeight] = useState(128)
|
||||||
@@ -67,7 +68,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
|
|||||||
}, [localSelected, serverHost, port, remotePath, password])
|
}, [localSelected, serverHost, port, remotePath, password])
|
||||||
|
|
||||||
const handleDownload = useCallback(async () => {
|
const handleDownload = useCallback(async () => {
|
||||||
if (!remoteSelected) return
|
if (!remoteSelected || !localPath) return
|
||||||
|
|
||||||
setTransferring(true)
|
setTransferring(true)
|
||||||
const transferId = Date.now().toString()
|
const transferId = Date.now().toString()
|
||||||
@@ -82,7 +83,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
|
|||||||
setTransfers((prev) => [...prev, newTransfer])
|
setTransfers((prev) => [...prev, newTransfer])
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await downloadFileFromRemote(serverHost, port, remoteSelected.name, remotePath, password, (progress) => {
|
await downloadFileFromRemote(serverHost, port, remoteSelected.name, remotePath, localPath, password, (progress) => {
|
||||||
setTransfers((prev) =>
|
setTransfers((prev) =>
|
||||||
prev.map((t) => (t.id === transferId ? { ...t, progress } : t))
|
prev.map((t) => (t.id === transferId ? { ...t, progress } : t))
|
||||||
)
|
)
|
||||||
@@ -106,7 +107,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
|
|||||||
} finally {
|
} finally {
|
||||||
setTransferring(false)
|
setTransferring(false)
|
||||||
}
|
}
|
||||||
}, [remoteSelected, serverHost, port])
|
}, [remoteSelected, serverHost, port, remotePath, localPath, password])
|
||||||
|
|
||||||
const handleClearTransfers = () => {
|
const handleClearTransfers = () => {
|
||||||
setTransfers((prev) => prev.filter((t) => t.status === 'transferring'))
|
setTransfers((prev) => prev.filter((t) => t.status === 'transferring'))
|
||||||
@@ -153,6 +154,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
|
|||||||
selectedFile={localSelected}
|
selectedFile={localSelected}
|
||||||
onSelect={setLocalSelected}
|
onSelect={setLocalSelected}
|
||||||
onUpload={handleUpload}
|
onUpload={handleUpload}
|
||||||
|
onPathChange={setLocalPath}
|
||||||
disabled={transferring}
|
disabled={transferring}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ interface LocalFilePanelProps {
|
|||||||
selectedFile: FileItem | null
|
selectedFile: FileItem | null
|
||||||
onSelect: (file: FileItem | null) => void
|
onSelect: (file: FileItem | null) => void
|
||||||
onUpload: () => void
|
onUpload: () => void
|
||||||
|
onPathChange?: (path: string) => void
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ export const LocalFilePanel: React.FC<LocalFilePanelProps> = ({
|
|||||||
selectedFile,
|
selectedFile,
|
||||||
onSelect,
|
onSelect,
|
||||||
onUpload,
|
onUpload,
|
||||||
|
onPathChange,
|
||||||
disabled,
|
disabled,
|
||||||
}) => {
|
}) => {
|
||||||
const [currentPath, setCurrentPath] = useState('')
|
const [currentPath, setCurrentPath] = useState('')
|
||||||
@@ -50,6 +52,7 @@ export const LocalFilePanel: React.FC<LocalFilePanelProps> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAtDrives) {
|
if (isAtDrives) {
|
||||||
loadDrives()
|
loadDrives()
|
||||||
|
onPathChange?.('')
|
||||||
} else {
|
} else {
|
||||||
loadFiles(currentPath)
|
loadFiles(currentPath)
|
||||||
}
|
}
|
||||||
@@ -64,6 +67,9 @@ export const LocalFilePanel: React.FC<LocalFilePanelProps> = ({
|
|||||||
setCurrentPath(prevPath)
|
setCurrentPath(prevPath)
|
||||||
if (prevPath === '') {
|
if (prevPath === '') {
|
||||||
setIsAtDrives(true)
|
setIsAtDrives(true)
|
||||||
|
onPathChange?.('')
|
||||||
|
} else {
|
||||||
|
onPathChange?.(prevPath)
|
||||||
}
|
}
|
||||||
onSelect(null)
|
onSelect(null)
|
||||||
}
|
}
|
||||||
@@ -74,6 +80,7 @@ export const LocalFilePanel: React.FC<LocalFilePanelProps> = ({
|
|||||||
setPathHistory([...pathHistory, file.path])
|
setPathHistory([...pathHistory, file.path])
|
||||||
setCurrentPath(file.path)
|
setCurrentPath(file.path)
|
||||||
onSelect(null)
|
onSelect(null)
|
||||||
|
onPathChange?.(file.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRefresh = () => {
|
const handleRefresh = () => {
|
||||||
|
|||||||
2
src/types/electron.d.ts
vendored
2
src/types/electron.d.ts
vendored
@@ -30,7 +30,7 @@ export interface ElectronAPI {
|
|||||||
success: boolean
|
success: boolean
|
||||||
error?: string
|
error?: string
|
||||||
}>
|
}>
|
||||||
remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, password?: string) => Promise<{
|
remoteDownloadFile: (serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) => Promise<{
|
||||||
success: boolean
|
success: boolean
|
||||||
filePath?: string
|
filePath?: string
|
||||||
error?: string
|
error?: string
|
||||||
|
|||||||
Reference in New Issue
Block a user