« get me outta code hell

FilePickerForm.js « tools « ui - tui-lib - Pure Node.js library for making visual command-line programs (ala vim, ncdu)
about summary refs log tree commit diff
path: root/ui/tools/FilePickerForm.js
blob: 51d59a9b00da8d8edc8b6a4d9b8c6a324c5be0bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const fs = require('fs')
const util = require('util')
const path = require('path')

const readdir = util.promisify(fs.readdir)
const stat = util.promisify(fs.stat)
const naturalSort = require('node-natural-sort')

const Button = require('../form/Button')
const ListScrollForm = require('../form/ListScrollForm')

module.exports = class FilePickerForm extends ListScrollForm {
  fillItems(dirPath) {
    this.inputs = []
    this.children = []

    const button = new Button('..Loading..')
    this.addInput(button)
    this.firstInput(false)

    readdir(dirPath).then(
      async items => {
        this.removeInput(button)

        const processedItems = await Promise.all(items.map(item => {
          const itemPath = path.resolve(dirPath, item)
          return stat(itemPath).then(s => {
            return {
              path: itemPath,
              label: item + (s.isDirectory() ? '/' : ''),
              isDirectory: s.isDirectory()
            }
          })
        }))

        const sort = naturalSort({
          properties: {
            caseSensitive: false
          }
        })
        processedItems.sort((a, b) => {
          if (a.isDirectory === b.isDirectory) {
            return sort(a.label, b.label)
          } else {
            if (a.isDirectory) {
              return -1
            } else {
              return +1
            }
          }
        })

        processedItems.unshift({
          path: path.resolve(dirPath, '..'),
          label: '../',
          isDirectory: true
        })

        let y = 0
        for (const item of processedItems) {
          const itemButton = new Button(item.label)
          itemButton.y = y
          y++
          this.addInput(itemButton)

          itemButton.on('pressed', () => {
            if (item.isDirectory) {
              this.emit('browsingDirectory', item.path)
              this.fillItems(item.path)
            } else {
              this.emit('selected', item.path)
            }
          })
        }

        console.log('HALLO.', false)
        this.firstInput(false)
        this.fixLayout()
      },
      () => {
        button.text = 'Failed to read path! (Cancel)'
        button.on('pressed', () => {
          this.emit('canceled')
        })
      })
  }
}