diff --git a/__tests__/utils/vfs.js b/__tests__/utils/vfs.js index f37ade9..4cd63ef 100644 --- a/__tests__/utils/vfs.js +++ b/__tests__/utils/vfs.js @@ -88,7 +88,17 @@ describe('utils.vfs#transformReaddir', () => { test('Should remove dotfiles', () => { expect(checkMap({ showHiddenFiles: false - })).toEqual(['..', 'directory', 'xdirectory', 'file', 'xfile']); + })).toEqual(['..', 'directory', 'file', 'xdirectory', 'xfile']); + }); + + test('Should not sort due to server sorting', () => { + const result = checkMap({ + showHiddenFiles: false, + serverSorting: true + }); + + return expect(result) + .toEqual(['..', 'directory', 'xdirectory', 'file', 'xfile']); }); test('Should sort by descending order', () => { @@ -98,7 +108,7 @@ describe('utils.vfs#transformReaddir', () => { }); return expect(result) - .toEqual(['..', 'xdirectory', 'directory', 'xfile', 'file']); + .toEqual(['..', 'xfile', 'xdirectory', 'file', 'directory']); }); test('Should sort by ascending order', () => { @@ -108,7 +118,7 @@ describe('utils.vfs#transformReaddir', () => { }); return expect(result) - .toEqual(['..', 'directory', 'xdirectory', 'file', 'xfile']); + .toEqual(['..', 'directory', 'file', 'xdirectory', 'xfile']); }); test('Should sort by specified column', () => { diff --git a/src/utils/vfs.js b/src/utils/vfs.js index 2bd11e2..7f73372 100644 --- a/src/utils/vfs.js +++ b/src/utils/vfs.js @@ -78,6 +78,13 @@ const sortDefault = (k, d) => (a, b) => ? (d === 'asc' ? 1 : 0) : (d === 'asc' ? 0 : 1)); +/* + * Sort by ascii codes + */ +const sortAscii = (k, d) => (a, b) => d === 'asc' + ? (a[k] < b[k]) ? -1 : 1 + : (a[k] < b[k]) ? 1 : -1; + /* * Sorts an array of files */ @@ -86,6 +93,8 @@ const sortFn = t => { return sortString; } else if (t === 'date') { return sortDate; + } else if (t === 'ascii') { + return sortAscii; } return sortDefault; @@ -187,52 +196,50 @@ export const transformReaddir = ({path}, files, options = {}) => { showHiddenFiles: false, sortBy: 'filename', sortDir: 'asc', + serverSorting: false, ...options }; - let {sortDir, sortBy, filter} = options; + let {sortDir, sortBy, filter, serverSorting} = options; if (typeof filter !== 'function') { filter = () => true; } - if (['asc', 'desc'].indexOf(sortDir) === -1) { - sortDir = 'asc'; - } - const filterHidden = options.showHiddenFiles ? () => true : file => file.filename.substr(0, 1) !== '.'; - const sorter = sortMap[sortBy] - ? sortMap[sortBy] - : sortFn('string'); - const modify = (file) => ({ ...file, humanSize: humanFileSize(file.size) }); - // FIXME: Optimize this to one chain! + let sortedSpecial = []; + let sortedFiles = []; - const sortedSpecial = createSpecials(path) - .sort(sorter(sortBy, sortDir)) + // FIXME: Optimize this to one chain! + sortedSpecial = createSpecials(path) .map(modify); - const sortedDirectories = files.filter(file => file.isDirectory) - .sort(sorter(sortBy, sortDir)) - .filter(filterHidden) + sortedFiles = files.filter(filterHidden) .filter(filter) .map(modify); - const sortedFiles = files.filter(file => !file.isDirectory) - .sort(sorter(sortBy, sortDir)) - .filter(filterHidden) - .filter(filter) - .map(modify); + if(!serverSorting) { + if (['asc', 'desc'].indexOf(sortDir) === -1) { + sortDir = 'asc'; + } + const sorter = sortMap[sortBy] + ? sortMap[sortBy] + : sortFn('ascii'); + sortedSpecial = sortedSpecial + .sort(sorter(sortBy, sortDir)); + sortedFiles = sortedFiles + .sort(sorter(sortBy, sortDir)); + } return [ ...sortedSpecial, - ...sortedDirectories, ...sortedFiles ]; }; diff --git a/src/vfs.js b/src/vfs.js index 79f8782..7ec6824 100644 --- a/src/vfs.js +++ b/src/vfs.js @@ -69,13 +69,20 @@ const pathToObject = path => ({ ...typeof path === 'string' ? {path} : path }); +// Extract the mountpoint of a path +const mountPoint = ({path}) => path.split(':/')[0]; + // Handles directory listing result(s) const handleDirectoryList = (path, options) => result => Promise.resolve(result.map(stat => createFileIter(stat))) - .then(result => transformReaddir(pathToObject(path), result, { - showHiddenFiles: options.showHiddenFiles !== false, - filter: options.filter - })); + .then(result => { + const capability = capabilityCache[mountPoint(pathToObject(path))]; + return transformReaddir(pathToObject(path), result, { + showHiddenFiles: options.showHiddenFiles !== false, + filter: options.filter, + serverSorting: capability.sort || false + }); + }); /** * Get vfs capabilities