mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Changed console to status bar
This commit is contained in:
parent
03facc93f5
commit
7e2b4f7da5
@ -13,7 +13,6 @@ const Renderer = require('tkwidgets/framework/Renderer.js');
|
||||
const BaseWidget = require('tkwidgets/BaseWidget.js');
|
||||
const ListWidget = require('tkwidgets/ListWidget.js');
|
||||
const TextWidget = require('tkwidgets/TextWidget.js');
|
||||
const ConsoleWidget = require('tkwidgets/ConsoleWidget.js');
|
||||
const HLayoutWidget = require('tkwidgets/HLayoutWidget.js');
|
||||
const VLayoutWidget = require('tkwidgets/VLayoutWidget.js');
|
||||
const ReduxRootWidget = require('tkwidgets/ReduxRootWidget.js');
|
||||
@ -23,6 +22,8 @@ const WindowWidget = require('tkwidgets/WindowWidget.js');
|
||||
const NoteWidget = require('./gui/NoteWidget.js');
|
||||
const FolderListWidget = require('./gui/FolderListWidget.js');
|
||||
const NoteListWidget = require('./gui/NoteListWidget.js');
|
||||
const StatusBarWidget = require('./gui/StatusBarWidget.js');
|
||||
const ConsoleWidget = require('./gui/ConsoleWidget.js');
|
||||
|
||||
class AppGui {
|
||||
|
||||
@ -41,7 +42,7 @@ class AppGui {
|
||||
this.renderer_ = new Renderer(this.term(), this.rootWidget_);
|
||||
|
||||
this.renderer_.on('renderDone', async (event) => {
|
||||
if (this.widget('console').hasFocus) this.widget('console').resetCursor();
|
||||
//if (this.widget('console').hasFocus) this.widget('console').resetCursor();
|
||||
});
|
||||
|
||||
this.app_.on('modelAction', async (event) => {
|
||||
@ -58,9 +59,11 @@ class AppGui {
|
||||
this.lastShortcutKeyTime_ = 0;
|
||||
|
||||
cliUtils.setStdout((...object) => {
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
this.widget('console').bufferPush(object[i]);
|
||||
}
|
||||
return this.stdout(...object);
|
||||
|
||||
// for (let i = 0; i < object.length; i++) {
|
||||
// this.widget('console').bufferPush(object[i]);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
@ -127,24 +130,21 @@ class AppGui {
|
||||
|
||||
const consoleWidget = new ConsoleWidget();
|
||||
consoleWidget.hStretch = true;
|
||||
consoleWidget.name = 'console';
|
||||
consoleWidget.prompt = chalk.cyan('Joplin >') + ' ';
|
||||
consoleWidget.on('accept', async (event) => {
|
||||
consoleWidget.promptVisible = false;
|
||||
await this.processCommand(event.input, 'console');
|
||||
consoleWidget.promptVisible = true;
|
||||
});
|
||||
|
||||
const statusBar = new StatusBarWidget();
|
||||
statusBar.hStretch = true;
|
||||
|
||||
const hLayout = new HLayoutWidget();
|
||||
hLayout.name = 'hLayout';
|
||||
hLayout.addChild(folderList, { type: 'stretch', factor: 1 });
|
||||
hLayout.addChild(noteList, { type: 'stretch', factor: 1 });
|
||||
hLayout.addChild(noteText, { type: 'stretch', factor: 1 });
|
||||
hLayout.addChild(noteText, { type: 'stretch', factor: 2 });
|
||||
|
||||
const vLayout = new VLayoutWidget();
|
||||
vLayout.name = 'vLayout';
|
||||
vLayout.addChild(hLayout, { type: 'stretch', factor: 1 });
|
||||
vLayout.addChild(consoleWidget, { type: 'fixed', factor: 6 });
|
||||
vLayout.addChild(consoleWidget, { type: 'fixed', factor: 3 });
|
||||
vLayout.addChild(statusBar, { type: 'fixed', factor: 1 });
|
||||
|
||||
const win1 = new WindowWidget();
|
||||
win1.addChild(vLayout);
|
||||
@ -156,8 +156,6 @@ class AppGui {
|
||||
setupShortcuts() {
|
||||
const shortcuts = {};
|
||||
|
||||
const consoleWidget = this.widget('console');
|
||||
|
||||
shortcuts['DELETE'] = {
|
||||
description: _('Delete a note'),
|
||||
action: 'rm $n',
|
||||
@ -169,9 +167,9 @@ class AppGui {
|
||||
action: 'todo toggle $n',
|
||||
}
|
||||
|
||||
shortcuts['c'] = {
|
||||
shortcuts[':'] = {
|
||||
description: _('Enter the console'),
|
||||
action: () => { consoleWidget.focus(); }
|
||||
isDocOnly: true,
|
||||
};
|
||||
|
||||
shortcuts['ESC'] = {
|
||||
@ -191,24 +189,19 @@ class AppGui {
|
||||
},
|
||||
}
|
||||
|
||||
shortcuts['nt'] = {
|
||||
description: _('Create a new todo'),
|
||||
action: () => { consoleWidget.focus('mktodo '); },
|
||||
}
|
||||
|
||||
shortcuts['nn'] = {
|
||||
description: _('Create a new note'),
|
||||
action: () => { consoleWidget.focus('mknote '); },
|
||||
action: { type: 'prompt', initialText: 'mknote ' },
|
||||
}
|
||||
|
||||
shortcuts['nt'] = {
|
||||
description: _('Create a new todo'),
|
||||
action: () => { consoleWidget.focus('mktodo '); },
|
||||
action: { type: 'prompt', initialText: 'mktodo ' },
|
||||
}
|
||||
|
||||
shortcuts['nb'] = {
|
||||
description: _('Create a new notebook'),
|
||||
action: () => { consoleWidget.focus('mkbook '); },
|
||||
action: { type: 'prompt', initialText: 'mkbook ' },
|
||||
}
|
||||
|
||||
shortcuts['CTRL_JCTRL_Z'] = {
|
||||
@ -225,30 +218,32 @@ class AppGui {
|
||||
}
|
||||
|
||||
maximizeConsole(doMaximize = true) {
|
||||
const consoleWidget = this.widget('console');
|
||||
// const consoleWidget = this.widget('console');
|
||||
|
||||
if (consoleWidget.isMaximized__ === undefined) {
|
||||
consoleWidget.isMaximized__ = false;
|
||||
}
|
||||
// if (consoleWidget.isMaximized__ === undefined) {
|
||||
// consoleWidget.isMaximized__ = false;
|
||||
// }
|
||||
|
||||
if (consoleWidget.isMaximized__ === doMaximize) return;
|
||||
// if (consoleWidget.isMaximized__ === doMaximize) return;
|
||||
|
||||
let constraints = {
|
||||
type: 'fixed',
|
||||
factor: !doMaximize ? 5 : this.widget('vLayout').height - 4,
|
||||
};
|
||||
// let constraints = {
|
||||
// type: 'fixed',
|
||||
// factor: !doMaximize ? 5 : this.widget('vLayout').height - 4,
|
||||
// };
|
||||
|
||||
consoleWidget.isMaximized__ = doMaximize;
|
||||
// consoleWidget.isMaximized__ = doMaximize;
|
||||
|
||||
this.widget('vLayout').setWidgetConstraints(consoleWidget, constraints);
|
||||
// this.widget('vLayout').setWidgetConstraints(consoleWidget, constraints);
|
||||
}
|
||||
|
||||
minimizeConsole() {
|
||||
this.maximizeConsole(false);
|
||||
//this.maximizeConsole(false);
|
||||
}
|
||||
|
||||
consoleIsMaximized() {
|
||||
return this.widget('console').isMaximized__ === true;
|
||||
return false;
|
||||
|
||||
//return this.widget('console').isMaximized__ === true;
|
||||
}
|
||||
|
||||
widget(name) {
|
||||
@ -323,7 +318,7 @@ class AppGui {
|
||||
try {
|
||||
await this.app().execCommand(args);
|
||||
} catch (error) {
|
||||
this.widget('console').bufferPush(error.message);
|
||||
this.stdout(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +341,7 @@ class AppGui {
|
||||
|
||||
// Any key after which a shortcut is not possible.
|
||||
isSpecialKey(name) {
|
||||
return ['ENTER', 'DOWN', 'UP', 'LEFT', 'RIGHT', 'DELETE', 'BACKSPACE', 'ESCAPE', 'TAB', 'SHIFT_TAB', 'PAGE_UP', 'PAGE_DOWN'].indexOf(name) >= 0;
|
||||
return [':', 'ENTER', 'DOWN', 'UP', 'LEFT', 'RIGHT', 'DELETE', 'BACKSPACE', 'ESCAPE', 'TAB', 'SHIFT_TAB', 'PAGE_UP', 'PAGE_DOWN'].indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
fullScreen(enable = true) {
|
||||
@ -360,6 +355,15 @@ class AppGui {
|
||||
}
|
||||
}
|
||||
|
||||
stdout(...object) {
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
const v = typeof object[i] === 'object' ? JSON.stringify(object[i]) : object[i];
|
||||
this.widget('console').addItem(v);
|
||||
}
|
||||
|
||||
if (object.length) this.widget('statusBar').setItemAt(0, object[object.length-1]);
|
||||
}
|
||||
|
||||
async start() {
|
||||
const term = this.term();
|
||||
|
||||
@ -368,7 +372,7 @@ class AppGui {
|
||||
try {
|
||||
this.renderer_.start();
|
||||
|
||||
const consoleWidget = this.widget('console');
|
||||
const statusBar = this.widget('statusBar');
|
||||
|
||||
term.grabInput();
|
||||
|
||||
@ -390,7 +394,7 @@ class AppGui {
|
||||
if (name === 'CTRL_C' ) {
|
||||
const cmd = this.app().currentCommand();
|
||||
if (!cmd || !cmd.cancellable() || this.commandCancelCalled_) {
|
||||
consoleWidget.bufferPush(_('Press Ctrl+D or type "exit" to exit the application'));
|
||||
this.stdout(_('Press Ctrl+D or type "exit" to exit the application'));
|
||||
} else {
|
||||
this.commandCancelCalled_ = true;
|
||||
await cmd.cancel();
|
||||
@ -415,21 +419,34 @@ class AppGui {
|
||||
|
||||
this.lastShortcutKeyTime_ = now;
|
||||
|
||||
// Don't process shortcut keys if the console is active, except if the shortcut
|
||||
// starts with CTRL (eg. CTRL+J CTRL+Z to maximize the console window).
|
||||
if (!consoleWidget.hasFocus || (this.currentShortcutKeys_.length && this.currentShortcutKeys_[0].indexOf('CTRL') === 0)) {
|
||||
this.logger().debug('Now: ' + name + ', Keys: ', this.currentShortcutKeys_);
|
||||
if (name === ':' && !statusBar.promptActive) {
|
||||
const cmd = await statusBar.prompt();
|
||||
await this.processCommand(cmd);
|
||||
} else {
|
||||
// Don't process shortcut keys if the console is active, except if the shortcut
|
||||
// starts with CTRL (eg. CTRL+J CTRL+Z to maximize the console window).
|
||||
if (!statusBar.promptActive || (this.currentShortcutKeys_.length && this.currentShortcutKeys_[0].indexOf('CTRL') === 0)) {
|
||||
this.logger().debug('Now: ' + name + ', Keys: ', this.currentShortcutKeys_);
|
||||
|
||||
const shortcutKey = this.currentShortcutKeys_.join('');
|
||||
if (shortcutKey in this.shortcuts_) {
|
||||
const cmd = this.shortcuts_[shortcutKey].action;
|
||||
if (!cmd.isDocOnly) {
|
||||
this.currentShortcutKeys_ = [];
|
||||
if (typeof cmd === 'function') {
|
||||
cmd();
|
||||
} else {
|
||||
consoleWidget.bufferPush(cmd);
|
||||
await this.processCommand(cmd);
|
||||
const shortcutKey = this.currentShortcutKeys_.join('');
|
||||
if (shortcutKey in this.shortcuts_) {
|
||||
const cmd = this.shortcuts_[shortcutKey].action;
|
||||
if (!cmd.isDocOnly) {
|
||||
this.currentShortcutKeys_ = [];
|
||||
if (typeof cmd === 'function') {
|
||||
await cmd();
|
||||
} else if (typeof cmd === 'object') {
|
||||
if (cmd.type === 'prompt') {
|
||||
const commandString = await statusBar.prompt(cmd.initialText ? cmd.initialText : '');
|
||||
this.stdout(commandString);
|
||||
await this.processCommand(commandString);
|
||||
} else {
|
||||
throw new Error('Unknown command: ' + JSON.stringify(cmd));
|
||||
}
|
||||
} else {
|
||||
this.stdout(cmd);
|
||||
await this.processCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,12 +270,8 @@ class Application {
|
||||
}
|
||||
|
||||
setupCommand(cmd) {
|
||||
const consoleWidget = this.gui_.widget('console');
|
||||
|
||||
cmd.setStdout((...object) => {
|
||||
for (let i = 0; i < object.length; i++) {
|
||||
consoleWidget.bufferPush(object[i]);
|
||||
}
|
||||
this.gui().stdout(...object);
|
||||
});
|
||||
|
||||
cmd.setDispatcher((action) => {
|
||||
@ -283,15 +279,13 @@ class Application {
|
||||
});
|
||||
|
||||
cmd.setPrompt(async (message, options) => {
|
||||
consoleWidget.focus();
|
||||
|
||||
if (options.type == 'boolean') {
|
||||
message += ' (' + options.answers.join('/') + ')';
|
||||
}
|
||||
|
||||
var answer = await consoleWidget.waitForResult(message + ' ');
|
||||
|
||||
if (options.type == 'boolean') {
|
||||
const answer = await this.gui().widget('statusBar').prompt('', message + ' ');
|
||||
|
||||
if (options.type === 'boolean') {
|
||||
if (answer === null) return false;
|
||||
return answer === '' || answer.toLowerCase() == options.answers[0].toLowerCase();
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class Command extends BaseCommand {
|
||||
const notes = await app().loadItems(BaseModel.TYPE_NOTE, pattern);
|
||||
if (!notes.length) throw new Error(_('Cannot find "%s".', pattern));
|
||||
|
||||
const ok = force ? true : await this.prompt(_('%d notes match this pattern. Delete them?', notes.length));
|
||||
const ok = force ? true : await this.prompt(notes.length > 1 ? _('%d notes match this pattern. Delete them?', notes.length) : _('Delete note?'));
|
||||
if (!ok) return;
|
||||
let ids = notes.map((n) => n.id);
|
||||
await Note.batchDelete(ids);
|
||||
|
20
CliClient/app/gui/ConsoleWidget.js
Normal file
20
CliClient/app/gui/ConsoleWidget.js
Normal file
@ -0,0 +1,20 @@
|
||||
const ListWidget = require('tkwidgets/ListWidget.js');
|
||||
|
||||
class ConsoleWidget extends ListWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'console';
|
||||
}
|
||||
|
||||
addItem(v) {
|
||||
super.addItem(v);
|
||||
this.currentIndex = this.items.length - 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ConsoleWidget;
|
112
CliClient/app/gui/StatusBarWidget.js
Normal file
112
CliClient/app/gui/StatusBarWidget.js
Normal file
@ -0,0 +1,112 @@
|
||||
const BaseWidget = require('tkwidgets/BaseWidget.js');
|
||||
const chalk = require('chalk');
|
||||
|
||||
class StatusBarWidget extends BaseWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.promptState_ = null;
|
||||
this.inputEventEmitter_ = null;
|
||||
this.history_ = [];
|
||||
this.items_ = [];
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'statusBar';
|
||||
}
|
||||
|
||||
setItemAt(index, text) {
|
||||
this.items_[index] = text;
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
async prompt(initialText = '', promptString = ':') {
|
||||
if (this.promptState_) throw new Error('Another prompt already active');
|
||||
|
||||
this.root.globalDisableKeyboard(this);
|
||||
|
||||
this.promptState_ = {
|
||||
promise: null,
|
||||
initialText: initialText,
|
||||
promptString: promptString,
|
||||
};
|
||||
|
||||
this.promptState_.promise = new Promise((resolve, reject) => {
|
||||
this.promptState_.resolve = resolve;
|
||||
this.promptState_.reject = reject;
|
||||
});
|
||||
|
||||
this.invalidate();
|
||||
|
||||
return this.promptState_.promise;
|
||||
}
|
||||
|
||||
get promptActive() {
|
||||
return !!this.promptState_;
|
||||
}
|
||||
|
||||
get history() {
|
||||
return this.history_;
|
||||
}
|
||||
|
||||
render() {
|
||||
super.render();
|
||||
this.innerClear();
|
||||
|
||||
const textStyle = chalk.bgBlueBright.white;
|
||||
|
||||
this.term.drawHLine(this.absoluteInnerX, this.absoluteInnerY, this.innerWidth, textStyle(' '));
|
||||
|
||||
this.term.moveTo(this.absoluteInnerX, this.absoluteInnerY);
|
||||
|
||||
if (this.promptActive) {
|
||||
|
||||
this.term.write(textStyle(this.promptState_.promptString));
|
||||
|
||||
this.term.showCursor(true);
|
||||
|
||||
let options = {
|
||||
cancelable: true,
|
||||
history: this.history,
|
||||
default: this.promptState_.initialText,
|
||||
style: this.term.innerStyle.bgBrightBlue.white, // NOTE: Need to use TK style for this as inputField is not compatible with chalk
|
||||
};
|
||||
|
||||
this.inputEventEmitter_ = this.term.inputField(options, (error, input) => {
|
||||
let resolveResult = null;
|
||||
const resolveFn = this.promptState_.resolve;
|
||||
|
||||
if (error) {
|
||||
this.logger().error('StatusBar: inputField error:', error);
|
||||
} else {
|
||||
if (input === undefined) {
|
||||
// User cancel
|
||||
} else {
|
||||
resolveResult = input;
|
||||
if (input && input.trim() != '') this.history_.push(input);
|
||||
}
|
||||
}
|
||||
|
||||
this.inputEventEmitter_ = null;
|
||||
this.term.showCursor(false);
|
||||
this.promptState_ = null;
|
||||
this.root.globalEnableKeyboard(this);
|
||||
this.invalidate();
|
||||
|
||||
// Only callback once everything has been cleaned up and reset
|
||||
resolveFn(resolveResult);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
for (let i = 0; i < this.items_.length; i++) {
|
||||
this.term.write(textStyle(this.items_[i]));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = StatusBarWidget;
|
@ -27,10 +27,10 @@ msgstr ""
|
||||
msgid "Exit the console"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new todo"
|
||||
msgid "Create a new note"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new note"
|
||||
msgid "Create a new todo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new notebook"
|
||||
@ -321,6 +321,9 @@ msgstr ""
|
||||
msgid "%d notes match this pattern. Delete them?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Searches for the given <pattern> in all the notes."
|
||||
msgstr ""
|
||||
|
||||
@ -630,9 +633,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Attach file"
|
||||
msgstr ""
|
||||
|
||||
|
@ -30,14 +30,14 @@ msgstr ""
|
||||
msgid "Exit the console"
|
||||
msgstr "Quitter le logiciel."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Create a new todo"
|
||||
msgstr "Créer une nouvelle tâche."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Create a new note"
|
||||
msgstr "Créer une note."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Create a new todo"
|
||||
msgstr "Créer une nouvelle tâche."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Create a new notebook"
|
||||
msgstr "Créer un carnet."
|
||||
@ -359,6 +359,9 @@ msgstr "Supprime les objets sans demander la confirmation."
|
||||
msgid "%d notes match this pattern. Delete them?"
|
||||
msgstr "%d notes correspondent à ce motif. Les supprimer ?"
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr "Supprimer la note ?"
|
||||
|
||||
msgid "Searches for the given <pattern> in all the notes."
|
||||
msgstr "Chercher le motif <pattern> dans toutes les notes."
|
||||
|
||||
@ -690,9 +693,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Annulation..."
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr "Supprimer la note ?"
|
||||
|
||||
msgid "Attach file"
|
||||
msgstr "Attacher un fichier"
|
||||
|
||||
@ -744,6 +744,10 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Bienvenue"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Last command: %s"
|
||||
#~ msgstr "Commande invalide : \"%s\""
|
||||
|
||||
#~ msgid "Done editing."
|
||||
#~ msgstr "Edition terminée."
|
||||
|
||||
|
@ -27,10 +27,10 @@ msgstr ""
|
||||
msgid "Exit the console"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new todo"
|
||||
msgid "Create a new note"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new note"
|
||||
msgid "Create a new todo"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create a new notebook"
|
||||
@ -321,6 +321,9 @@ msgstr ""
|
||||
msgid "%d notes match this pattern. Delete them?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Searches for the given <pattern> in all the notes."
|
||||
msgstr ""
|
||||
|
||||
@ -630,9 +633,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete note?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Attach file"
|
||||
msgstr ""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user