Skip to content

Commit

Permalink
Refactor controller.menu (Replace terminal-menu with inquirer.prompt).
Browse files Browse the repository at this point in the history
…Closes gh-355
  • Loading branch information
rwaldron committed Oct 1, 2015
1 parent 85b1138 commit 85db49d
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 195 deletions.
190 changes: 64 additions & 126 deletions lib/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ var sprintf = require('sprintf-js').sprintf;
var cp = require('child_process');
var async = require('async');
var updates = require('./update-fetch');
var inquirer = require('inquirer');
var colors = require('colors');
var controller = {};
var Menu = require('terminal-menu');

Tessel.list = function(opts) {

Expand Down Expand Up @@ -108,7 +109,7 @@ Tessel.get = function(opts) {
reject('No Tessels Found.');
return;
}
// The name match for a given Tessel happens upon discovery, not at
// The name match for a given Tessel happens upon discovery, not at
// the completion of discovery. So if we got to this point, no Tessel
// was found with that name
else if (opts.name !== undefined) {
Expand All @@ -128,6 +129,7 @@ Tessel.get = function(opts) {
// Run the heuristics to pick which Tessel to use
return controller.runHeuristics(opts, tessels)
.then(function finalSection(tessel) {
var map = {};
// If the heuristics were able to narrow it down to a single Tessel
if (tessel) {
// Log we found it and return it to the caller
Expand All @@ -136,12 +138,38 @@ Tessel.get = function(opts) {
// If we couldn't narrow it down
else {
// Open up an interactive menu for the user to choose
return controller.menu.create(tessels, {}, 'Which Tessel did you mean to use?')
// Once they choose
.then(function(tessel) {
return controller.menu({
prefix: colors.grey('INFO '),
prompt: {
name: 'selected',
type: 'list',
message: 'Which Tessel do want to use?',
choices: tessels.map(function(tessel, i) {
var isLAN = !!tessel.lanConnection;
var isAuthorized = isLAN && tessel.lanConnection.authorized;
var authorization = isAuthorized ? '' : '(not authorized)';
var display = [tessel.name, tessel.lanConnection, authorization].join(' ');

// Map displayed name to tessel index
map[display] = i;

return display;
})
},
translate: function(answer) {
return tessels[map[answer.selected]];
}
}).then(function(tessel) {
if (!tessel) {
return controller.closeTesselConnections(tessels)
.then(function() {
reject('No Tessel selected, mission aborted!');
});
} else {
// Log we found it and return it to the caller
return logAndFinish(tessel);
});
}
});
}
});
});
Expand Down Expand Up @@ -652,135 +680,45 @@ controller.tesselFirmwareVerion = function(opts) {
});
});
};

/*
Usage:
controller.menu.create(tessels)
.then(function(tessel) {
return resolve(tessel);
});
controller.menu({
// Custom prefix
prefix: colors.grey('INFO '),
prompt: [inquirer.prompt options],
// Custom answer -> data translation
translate: function(answer) {
// answer =>
// { [prompt.name]: ... }
return answer[prompt.name];
}
}) => Promise
*/
controller.menu = {
create: function(tessels, opts, title) {
return new Promise(function(resolve) {
var rtm = new Menu({
width: process.stdout.columns - 4,
//width: 46,
x: 1,
y: 2,
bg: 'red'
});
// create menu entries
if (!global.IS_TEST_ENV) {
controller.menu.make(tessels, rtm, title)
.then(controller.menu.show(rtm))
.then(function(index) {
resolve(tessels[index]);
});
} else {
resolve(tessels[0]); // due to old tests what expect a single tessel returned by Tessel.get
}
});
},
make: function(tessels, rtm, title) {
return new Promise(function(resolve, reject) {
if (!global.IS_TEST_ENV) {
rtm.reset();
}
if (!title) {
title = 'MENU';
}
rtm.once('select', function(label, index) {
if (!global.IS_TEST_ENV) {
process.stdin.setRawMode(false);
process.stdin.end();
}
// Identify the Exit command by first letter (all other entries start with numbers/index)
if (label[0] !== 'E') {
controller.menu.clear()
.then(resolve(index));
} else {
// going to clear screen and calling exit to resolve promise
if (!global.IS_TEST_ENV) {
controller.menu.clear()
.then(process.exit());
}
}
});
if (!global.IS_TEST_ENV) {
rtm._draw();
rtm.write(title + '\n');
rtm.write(' \n');
}
async.forEachOf(tessels, function addItem(tessel, index, done) {
var columns = process.stdout.columns - 4;
var calcLength = columns - tessel.name.length;
var fillbase = Array(calcLength - 10).join(' ');

if (tessel.lanConnection) {
controller.menu = function(setup) {
var options = setup.prompt;

if (!tessel.lanConnection.authorized) {
fillbase = Array(calcLength - 27).join(' ');
rtm.add(index + ') ' + tessel.name + ': ' + '[LAN] (not authorized)' + fillbase + ' \n');
} else {
rtm.add(index + ') ' + tessel.name + ': [LAN]' + fillbase + ' \n');
}
if (options.type === 'list') {
options.choices.push('Exit');
}

} else if (tessel.usbConnection) {
rtm.add(index + ') ' + tessel.name + ': [USB]' + fillbase + ' \n');
} else {
if (!global.IS_TEST_ENV) {
reject('Type of Tessel unknown: ', tessel);
}
}
done();
},
function closed(err) {
if (err) {
reject(err);
} else {
if (!global.IS_TEST_ENV) {
var fillexit = Array(process.stdout.columns - 7).join(' ');
rtm.add('EXIT' + fillexit + '\n');
}
return;
}
}
);
});
},
show: function(rtm) {
return new Promise(function(resolve) {
if (global.IS_TEST_ENV) {
resolve();
// Enforce a customized prompt prefix
inquirer.prompt.prompts[options.type].prototype.prefix = function(str) {
// String() used to coerce an `undefined` to ''. Do not change.
return String(setup.prefix) + str;
};

return new Promise(function(resolve) {
inquirer.prompt([options], function(answer) {
if (setup.translate) {
resolve(setup.translate(answer));
} else {
// Menu navigation
process.stdin.pipe(rtm.createStream()).pipe(process.stdout);

// raw mode for gain ability to navigate up and down within the menu
process.stdin.setRawMode(true);
rtm.on('close', function() {
process.stdin.setRawMode(false);
process.stdin.end();
resolve();
});
rtm.on('error', function(e) {
process.stdin.setRawMode(false);
logs.warn(e);
process.exit();
});
resolve(answer);
}
});
},
clear: function() {
return new Promise(function(resolve) {
// selected exit!
if (!global.IS_TEST_ENV) {
process.stdout.write('\u001b[2J\u001b[0;0H');
}
resolve();
});
}
});
};

module.exports = controller;

// Shared exports
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"envfile": "^1.0.0",
"fs-extra": "^0.18.0",
"fstream-ignore": "^1.0.2",
"inquirer": "^0.8.5",
"keypress": "^0.2.1",
"lodash": "^3.5.0",
"mdns-js": "^0.4.0",
Expand All @@ -65,7 +66,6 @@
"stream-to-buffer": "^0.1.0",
"tar": "^2.1.1",
"tar-stream": "^1.2.1",
"terminal-menu": "^2.1.1",
"url-join": "0.0.1",
"usb": "^1.0.5",
"usb-daemon-parser": "0.0.1"
Expand Down

0 comments on commit 85db49d

Please sign in to comment.