FilePickerForm.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import {readdir, stat} from 'node:fs/promises'
  2. import path from 'node:path'
  3. import {compare as naturalCompare} from 'natural-orderby'
  4. import {Button, ListScrollForm} from 'tui-lib/ui/controls'
  5. export default class FilePickerForm extends ListScrollForm {
  6. fillItems(dirPath) {
  7. this.inputs = []
  8. this.children = []
  9. const button = new Button('..Loading..')
  10. this.addInput(button)
  11. this.firstInput(false)
  12. readdir(dirPath).then(
  13. async items => {
  14. this.removeInput(button)
  15. const processedItems = await Promise.all(items.map(item => {
  16. const itemPath = path.resolve(dirPath, item)
  17. return stat(itemPath).then(s => {
  18. return {
  19. path: itemPath,
  20. label: item + (s.isDirectory() ? '/' : ''),
  21. isDirectory: s.isDirectory()
  22. }
  23. })
  24. }))
  25. const compare = naturalCompare()
  26. processedItems.sort((a, b) => {
  27. if (a.isDirectory === b.isDirectory) {
  28. return compare(a.label, b.label)
  29. } else {
  30. if (a.isDirectory) {
  31. return -1
  32. } else {
  33. return +1
  34. }
  35. }
  36. })
  37. processedItems.unshift({
  38. path: path.resolve(dirPath, '..'),
  39. label: '../',
  40. isDirectory: true
  41. })
  42. let y = 0
  43. for (const item of processedItems) {
  44. const itemButton = new Button(item.label)
  45. itemButton.y = y
  46. y++
  47. this.addInput(itemButton)
  48. itemButton.on('pressed', () => {
  49. if (item.isDirectory) {
  50. this.emit('browsingDirectory', item.path)
  51. this.fillItems(item.path)
  52. } else {
  53. this.emit('selected', item.path)
  54. }
  55. })
  56. }
  57. console.log('HALLO.', false)
  58. this.firstInput(false)
  59. this.fixLayout()
  60. },
  61. () => {
  62. button.text = 'Failed to read path! (Cancel)'
  63. button.on('pressed', () => {
  64. this.emit('canceled')
  65. })
  66. })
  67. }
  68. }