diff --git a/web/src/api/index.ts b/web/src/api/index.ts index c8f485fd..58c726fa 100644 --- a/web/src/api/index.ts +++ b/web/src/api/index.ts @@ -560,15 +560,15 @@ export const msdApi = { }, downloadDriveFile: (path: string) => - `${API_BASE}/msd/drive/files${path.startsWith('/') ? path : '/' + path}`, + `${API_BASE}/msd/drive/files${encodeDrivePath(path)}`, deleteDriveFile: (path: string) => - request<{ success: boolean }>(`/msd/drive/files${path.startsWith('/') ? path : '/' + path}`, { + request<{ success: boolean }>(`/msd/drive/files${encodeDrivePath(path)}`, { method: 'DELETE', }), createDirectory: (path: string) => - request<{ success: boolean }>(`/msd/drive/mkdir${path.startsWith('/') ? path : '/' + path}`, { + request<{ success: boolean }>(`/msd/drive/mkdir${encodeDrivePath(path)}`, { method: 'POST', }), @@ -599,6 +599,22 @@ interface SerialDeviceOption { name: string } +function encodeDrivePath(path: string): string { + if (path === '' || path === '/') { + return '/' + } + + const hasLeadingSlash = path.startsWith('/') + const hasTrailingSlash = path.endsWith('/') + const encodedSegments = path + .split('/') + .filter(Boolean) + .map(segment => encodeURIComponent(segment)) + .join('/') + + return `${hasLeadingSlash ? '/' : ''}${encodedSegments}${hasTrailingSlash ? '/' : ''}` +} + function getSerialDevicePriority(path: string): number { if (/^\/dev\/ttyUSB/i.test(path)) return 0 if (/^\/dev\/(ttyS|S)/i.test(path)) return 2