|
982 | 982 | const con = $('content'); |
983 | 983 | con.style.display = ''; |
984 | 984 | con.innerHTML = ''; |
985 | | - const folders = vault.listFolders(); |
| 985 | + const folders = natsort(vault.listFolders()); |
986 | 986 | const currentPath = vault.getPath(); |
987 | 987 | const items = $c('div', { className: 'items' }); |
988 | 988 | let needBreak = false; |
|
1012 | 1012 | } |
1013 | 1013 | const others = []; |
1014 | 1014 | const images = []; |
1015 | | - for (const name of vault.listFiles()) { |
| 1015 | + for (const name of natsort(vault.listFiles())) { |
1016 | 1016 | if (getExt(name) in config.imageMIMEs) { |
1017 | 1017 | images.push(name); |
1018 | 1018 | } else { |
|
1264 | 1264 | cancel.innerText = 'Close'; |
1265 | 1265 | const nv = await Vault.create(io); |
1266 | 1266 | for (const sh of shareList) { |
| 1267 | + let name = sh.name; |
| 1268 | + // find a unique name by trying foo.txt, foo (2).txt, foo (3).txt, etc |
| 1269 | + let namei = 1; |
| 1270 | + while (nv.getType(name) !== 'notfound') { |
| 1271 | + let pre = name; |
| 1272 | + let post = ''; |
| 1273 | + const exti = name.lastIndexOf('.'); |
| 1274 | + if (exti >= 0) { |
| 1275 | + pre = name.substr(0, exti); |
| 1276 | + post = name.substr(exti); |
| 1277 | + } |
| 1278 | + let cstr = ` (${namei})`; |
| 1279 | + if (pre.endsWith(cstr)) { |
| 1280 | + pre = pre.substr(0, pre.length - cstr.length); |
| 1281 | + } |
| 1282 | + namei++; |
| 1283 | + pre += ` (${namei})`; |
| 1284 | + name = pre + post; |
| 1285 | + } |
1267 | 1286 | switch (sh.kind) { |
1268 | 1287 | case 'folder': |
1269 | | - await nv.putFolderLink(sh.name, sh.itemPath, vault).catch(() => {}); |
| 1288 | + await nv.putFolderLink(name, sh.itemPath, vault).catch(() => {}); |
1270 | 1289 | break; |
1271 | 1290 | case 'file': |
1272 | | - await nv.putFileLink(sh.name, sh.itemPath, vault).catch(() => {}); |
| 1291 | + await nv.putFileLink(name, sh.itemPath, vault).catch(() => {}); |
1273 | 1292 | break; |
1274 | 1293 | } |
1275 | 1294 | } |
|
1330 | 1349 | return p; |
1331 | 1350 | } |
1332 | 1351 |
|
| 1352 | +function nattok(str) { |
| 1353 | + return ( |
| 1354 | + str |
| 1355 | + .toLowerCase() |
| 1356 | + .trim() |
| 1357 | + .replace(/^([^.]*) \((\d+)\)$/g, '$1$2') // `filename (5)` => `filename5` |
| 1358 | + .replace(/^(.*) \((\d+)\)(\.[^.]*)$/g, '$1$2$3') // `file.name (5).txt` => `file.name5.txt` |
| 1359 | + .replace(/^([^.]*) copy$/g, '$11') // `filename copy` => `filename1` |
| 1360 | + .replace(/^([^.]*) copy (\d+)/g, '$1$2') // `filename copy 5` => `filename5` |
| 1361 | + .replace(/^(.*) copy(\.[^.]*)$/g, '$11$2') // `file.name copy.txt` => file.name1.txt` |
| 1362 | + .replace(/^(.*) copy (\d+)(\.[^.]*)$/g, '$1$2$3') // `file.name copy 5.txt` => file.name5.txt` |
| 1363 | + .replace(/(\d+)/g, '/$1/') // `file123.456.txt` => `file/123/./456/.txt` |
| 1364 | + .replace(/^\/|\/$/g, '') // `/1/.txt` => `1/.txt` |
| 1365 | + .split('/') |
| 1366 | + .map(p => /^\d+$/.test(p) ? parseFloat(p) : p) |
| 1367 | + ); |
| 1368 | +} |
| 1369 | + |
| 1370 | +function natsort(ar) { |
| 1371 | + return ar.sort((astr, bstr) => { |
| 1372 | + const a = nattok(astr); |
| 1373 | + const b = nattok(bstr); |
| 1374 | + for (let i = 0; i < Math.max(a.length, b.length); i++) { |
| 1375 | + const av = i < a.length ? a[i] : ''; |
| 1376 | + const bv = i < b.length ? b[i] : ''; |
| 1377 | + if (av === bv) continue; |
| 1378 | + let r = 0; |
| 1379 | + if (typeof av === 'string') { |
| 1380 | + if (typeof bv === 'string') { |
| 1381 | + if (av && bv) { |
| 1382 | + // check for shared prefix ('readme.txt' vs 'readme') |
| 1383 | + if (av.startsWith(bv)) { |
| 1384 | + a.splice(i + 1, 0, a[i].substr(bv.length)); |
| 1385 | + a[i] = a[i].substr(0, bv.length); |
| 1386 | + continue; |
| 1387 | + } else if (bv.startsWith(av)) { |
| 1388 | + b.splice(i + 1, 0, b[i].substr(av.length)); |
| 1389 | + b[i] = b[i].substr(0, av.length); |
| 1390 | + continue; |
| 1391 | + } |
| 1392 | + } |
| 1393 | + r = av.localeCompare(bv); |
| 1394 | + } else { // number |
| 1395 | + r = -1; |
| 1396 | + } |
| 1397 | + } else { // number |
| 1398 | + if (typeof bv === 'string') { |
| 1399 | + r = 1; |
| 1400 | + } else { // number |
| 1401 | + r = av - bv; |
| 1402 | + } |
| 1403 | + } |
| 1404 | + if (r !== 0) return r; |
| 1405 | + } |
| 1406 | + let r = astr.toLowerCase().trim().localeCompare(bstr.toLowerCase().trim()); |
| 1407 | + if (r !== 0) return r; |
| 1408 | + r = astr.trim().localeCompare(bstr.trim()); |
| 1409 | + if (r !== 0) return r; |
| 1410 | + return astr.localeCompare(bstr); |
| 1411 | + }); |
| 1412 | +} |
| 1413 | + |
1333 | 1414 | window.addEventListener('load', () => { |
1334 | 1415 | $('loading').style.display = 'none'; |
1335 | 1416 | $('password').style.display = ''; |
|
0 commit comments