From 3810f5c3b5d601d07d8ac1419c19bb89c1f3e0b7 Mon Sep 17 00:00:00 2001 From: GitSquared Date: Tue, 29 Jan 2019 19:32:18 +0100 Subject: [PATCH] :art: Reduce callback hell in fsDisp & fix #408 Sweet async/await --- src/classes/filesystem.class.js | 284 +++++++++++++++++--------------- 1 file changed, 152 insertions(+), 132 deletions(-) diff --git a/src/classes/filesystem.class.js b/src/classes/filesystem.class.js index e431b13..4e07b0e 100644 --- a/src/classes/filesystem.class.js +++ b/src/classes/filesystem.class.js @@ -52,6 +52,25 @@ class FilesystemDisplay { } }, 1000); + this._asyncFSwrapper = new Proxy(fs, { + get: function(fs, prop) { + if (prop in fs) { + return function(...args) { + return new Promise((resolve, reject) => { + fs[prop](...args, (err, d) => { + if (typeof err !== "undefined" && err !== null) reject(err); + if (typeof d !== "undefined") resolve(d); + if (typeof d === "undefined" && typeof err === "undefined") resolve(); + }); + }); + } + } + }, + set: function() { + return false; + } + }); + this.setFailedState = () => { this.failed = true; container.innerHTML = ` @@ -88,151 +107,152 @@ class FilesystemDisplay { }); }; - this.readFS = (dir) => { + this.readFS = async dir => { if (this.failed === true) return false; let tcwd = dir; - fs.readdir(tcwd, (err, content) => { - if (err !== null) { - console.warn(err); - if (this._noTracking === true && this.dirpath) { // #262 - this.setFailedState(); - setTimeout(() => { - this.readFS(this.dirpath); - }, 1000); - } else { - this.setFailedState(); - } + let content = await this._asyncFSwrapper.readdir(tcwd).catch(err => { + console.warn(err); + if (this._noTracking === true && this.dirpath) { // #262 + this.setFailedState(); + setTimeout(() => { + this.readFS(this.dirpath); + }, 1000); } else { - this.cwd = []; - this._tmp = { - dirs: [], - symlinks: [], - files: [], - others: [] - }; - let i = 0; - content.forEach(file => { - fs.lstat(path.join(tcwd, file), (err, fstat) => { - if (err !== null) { - this.setFailedState(); - } else { - if (fstat.isDirectory()) { - this._tmp.dirs.push(file); - } else if (fstat.isSymbolicLink()) { - this._tmp.symlinks.push(file); - } else if (fstat.isFile()) { - this._tmp.files.push(file); - } else { - this._tmp.others.push(file); - } - - i++; - if (i === content.length) { - this.cwd.push({ - name: "Show disks", - type: "showDisks" - }); - - if (tcwd !== "/" && tcwd !== "\\") { - this.cwd.push({ - name: "Go up", - type: "up" - }); - } - - this._tmp.dirs.forEach(e => { - if (tcwd === settingsDir && e === "themes") { - this.cwd.push({ - name: window._escapeHtml(e), - type: "edex-themesDir" - }); - } else if (tcwd === settingsDir && e === "keyboards") { - this.cwd.push({ - name: window._escapeHtml(e), - type: "edex-kblayoutsDir" - }); - } else { - this.cwd.push({ - name: window._escapeHtml(e), - type: "dir" - }); - } - }); - this._tmp.symlinks.forEach(e => { - this.cwd.push({ - name: window._escapeHtml(e), - type: "symlink" - }); - }); - this._tmp.files.forEach(e => { - if (tcwd === themesDir && e.endsWith(".json")) { - this.cwd.push({ - name: window._escapeHtml(e), - type: "edex-theme" - }); - } else if (tcwd === keyboardsDir && e.endsWith(".json")) { - this.cwd.push({ - name: window._escapeHtml(e), - type: "edex-kblayout" - }); - } else if (tcwd === settingsDir && e === "settings.json") { - this.cwd.push({ - name: window._escapeHtml(e), - type: "edex-settings" - }); - } else { - this.cwd.push({ - name: window._escapeHtml(e), - type: "file" - }); - } - }); - this._tmp.others.forEach(e => { - this.cwd.push({ - name: window._escapeHtml(e), - type: "other" - }); - }); - - window.si.fsSize().then(d => { - d.forEach(fsBlock => { - if (tcwd.startsWith(fsBlock.mount)) { - this.fsBlock = fsBlock; - } - }); - - this.dirpath = tcwd; - this.render(this.cwd); - }); - } - } + this.setFailedState(); + } + }); + + this.cwd = []; + + await new Promise((resolve, reject) => { + if (content.length === 0) resolve(); + + content.forEach(async (file, i) => { + let fstat = await this._asyncFSwrapper.lstat(path.join(tcwd, file)).catch(reject); + + if (fstat.isDirectory()) { + if (tcwd === settingsDir && file === "themes") { + this.cwd.push({ + name: window._escapeHtml(file), + type: "edex-themesDir", + category: "dir" + }); + } else if (tcwd === settingsDir && file === "keyboards") { + this.cwd.push({ + name: window._escapeHtml(file), + type: "edex-kblayoutsDir", + category: "dir" + }); + } else { + this.cwd.push({ + name: window._escapeHtml(file), + type: "dir", + category: "dir" + }); + } + } else if (fstat.isSymbolicLink()) { + this.cwd.push({ + name: window._escapeHtml(file), + type: "symlink", + category: "symlink" }); - }); + } else if (fstat.isFile()) { + if (tcwd === themesDir && file.endsWith(".json")) { + this.cwd.push({ + name: window._escapeHtml(file), + type: "edex-theme", + category: "file" + }); + } else if (tcwd === keyboardsDir && file.endsWith(".json")) { + this.cwd.push({ + name: window._escapeHtml(file), + type: "edex-kblayout", + category: "file" + }); + } else if (tcwd === settingsDir && file === "settings.json") { + this.cwd.push({ + name: window._escapeHtml(file), + type: "edex-settings", + category: "file" + }); + } else { + this.cwd.push({ + name: window._escapeHtml(file), + type: "file", + category: "file" + }); + } + } else { + this.cwd.push({ + name: window._escapeHtml(file), + type: "other", + category: "other" + }); + } + + if (i === content.length-1) resolve(); + }); + }).catch(() => { this.setFailedState() }); + + if (this.failed) return false; + + let ordering = { + dir: 0, + symlink: 1, + file: 2, + other: 3 + }; + + this.cwd.sort((a, b) => { + return (ordering[a.category] - ordering[b.category] || a.name.localeCompare(b.name)); + }); + + this.cwd.splice(0, 0, { + name: "Show disks", + type: "showDisks" + }); + + if (tcwd !== "/" && tcwd !== "\\") { + this.cwd.splice(1, 0, { + name: "Go up", + type: "up" + }); + } + + let d = await window.si.fsSize().catch(() => { + this.setFailedState(); + }); + d.forEach(fsBlock => { + if (tcwd.startsWith(fsBlock.mount)) { + this.fsBlock = fsBlock; } }); + + this.dirpath = tcwd; + this.render(this.cwd); }; - this.readDevices = () => { + this.readDevices = async () => { if (this.failed === true) return false; - window.si.blockDevices().then(blocks => { - let devices = []; - blocks.forEach(block => { - if (fs.existsSync(block.mount)) { - let type = (block.type === "rom") ? "rom" : "disk"; - if (block.removable && block.type !== "rom") { - type = "usb"; - } - devices.push({ - name: (block.label !== "") ? `${block.label} (${block.name})` : `${block.mount} (${block.name})`, - type, - path: block.mount - }); + let blocks = await window.si.blockDevices(); + let devices = []; + blocks.forEach(block => { + if (fs.existsSync(block.mount)) { + let type = (block.type === "rom") ? "rom" : "disk"; + if (block.removable && block.type !== "rom") { + type = "usb"; } - }); - this.render(devices); + devices.push({ + name: (block.label !== "") ? `${block.label} (${block.name})` : `${block.mount} (${block.name})`, + type, + path: block.mount + }); + } }); + + this.render(devices); }; this.render = async blockList => { -- GitLab