mirror of
https://github.com/stablyai/orca.git
synced 2026-10-05 16:02:22 +00:00
Fix descendant paths in file explorer multi-drag (#4128)
This commit is contained in:
@@ -64,4 +64,24 @@ describe('getWorkspaceFileDragPaths', () => {
|
||||
})
|
||||
).toEqual(paths)
|
||||
})
|
||||
|
||||
it('drops selected descendants so moving a folder does not also move its children', () => {
|
||||
const paths = ['/repo/src', '/repo/src/components/Button.tsx', '/repo/src-extra/index.ts']
|
||||
expect(
|
||||
getWorkspaceFileDragPaths({
|
||||
getData: (type) =>
|
||||
type === WORKSPACE_FILE_PATHS_MIME ? encodeWorkspaceFilePaths(paths) : ''
|
||||
})
|
||||
).toEqual(['/repo/src', '/repo/src-extra/index.ts'])
|
||||
})
|
||||
|
||||
it('drops selected descendants with Windows separators and case', () => {
|
||||
const paths = ['C:\\Repo\\src', 'c:\\repo\\src\\components\\Button.tsx']
|
||||
expect(
|
||||
getWorkspaceFileDragPaths({
|
||||
getData: (type) =>
|
||||
type === WORKSPACE_FILE_PATHS_MIME ? encodeWorkspaceFilePaths(paths) : ''
|
||||
})
|
||||
).toEqual(['C:\\Repo\\src'])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import {
|
||||
isPathInsideOrEqual,
|
||||
normalizeRuntimePathForComparison
|
||||
} from '../../../shared/cross-platform-path'
|
||||
|
||||
export const WORKSPACE_FILE_PATH_MIME = 'text/x-orca-file-path'
|
||||
export const WORKSPACE_FILE_PATHS_MIME = 'text/x-orca-file-paths'
|
||||
|
||||
@@ -20,10 +25,40 @@ export function decodeWorkspaceFilePaths(data: string): string[] {
|
||||
return [data]
|
||||
}
|
||||
|
||||
function getTopLevelWorkspaceFilePaths(paths: readonly string[]): string[] {
|
||||
const uniquePaths: string[] = []
|
||||
for (const path of paths) {
|
||||
if (
|
||||
path &&
|
||||
!uniquePaths.some(
|
||||
(existing) =>
|
||||
normalizeRuntimePathForComparison(existing) === normalizeRuntimePathForComparison(path)
|
||||
)
|
||||
) {
|
||||
uniquePaths.push(path)
|
||||
}
|
||||
}
|
||||
|
||||
// Why: moving a selected folder already moves its descendants; issuing
|
||||
// extra moves for selected children races against paths that no longer exist.
|
||||
return uniquePaths.filter(
|
||||
(path) =>
|
||||
!uniquePaths.some(
|
||||
(candidateRoot) =>
|
||||
candidateRoot !== path &&
|
||||
normalizeRuntimePathForComparison(candidateRoot) !==
|
||||
normalizeRuntimePathForComparison(path) &&
|
||||
isPathInsideOrEqual(candidateRoot, path)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export function getWorkspaceFileDragPaths(dataTransfer: Pick<DataTransfer, 'getData'>): string[] {
|
||||
const multiPathData = dataTransfer.getData(WORKSPACE_FILE_PATHS_MIME)
|
||||
if (multiPathData) {
|
||||
return decodeWorkspaceFilePaths(multiPathData)
|
||||
return getTopLevelWorkspaceFilePaths(decodeWorkspaceFilePaths(multiPathData))
|
||||
}
|
||||
return decodeWorkspaceFilePaths(dataTransfer.getData(WORKSPACE_FILE_PATH_MIME))
|
||||
return getTopLevelWorkspaceFilePaths(
|
||||
decodeWorkspaceFilePaths(dataTransfer.getData(WORKSPACE_FILE_PATH_MIME))
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user