@beauraines/rtm-cli 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +12 -0
- package/LICENSE +21 -0
- package/README.md +143 -0
- package/build.js +86 -0
- package/config.json +40 -0
- package/package.json +58 -0
- package/screens/ls.png +0 -0
- package/screens/lsd.png +0 -0
- package/screens/lsp.png +0 -0
- package/screens/planner.png +0 -0
- package/src/cli.js +434 -0
- package/src/cmd/add.js +100 -0
- package/src/cmd/addList.js +92 -0
- package/src/cmd/addTags.js +85 -0
- package/src/cmd/archiveList.js +78 -0
- package/src/cmd/comp.js +82 -0
- package/src/cmd/decPri.js +82 -0
- package/src/cmd/due.js +82 -0
- package/src/cmd/edit.js +82 -0
- package/src/cmd/incPri.js +82 -0
- package/src/cmd/lists.js +60 -0
- package/src/cmd/login.js +27 -0
- package/src/cmd/logout.js +31 -0
- package/src/cmd/ls.js +181 -0
- package/src/cmd/lsd.js +193 -0
- package/src/cmd/lsp.js +171 -0
- package/src/cmd/move.js +83 -0
- package/src/cmd/notes.js +150 -0
- package/src/cmd/planner.js +510 -0
- package/src/cmd/postpone.js +82 -0
- package/src/cmd/pri.js +82 -0
- package/src/cmd/remove.js +82 -0
- package/src/cmd/removeList.js +79 -0
- package/src/cmd/removeTags.js +85 -0
- package/src/cmd/renameList.js +80 -0
- package/src/cmd/reset.js +35 -0
- package/src/cmd/setUrl.js +99 -0
- package/src/cmd/tags.js +101 -0
- package/src/cmd/uncomp.js +82 -0
- package/src/cmd/url.js +92 -0
- package/src/cmd/whoami.js +36 -0
- package/src/interactive.js +65 -0
- package/src/utils/config.js +236 -0
- package/src/utils/filter.js +43 -0
- package/src/utils/finish.js +21 -0
- package/src/utils/index.js +10 -0
- package/src/utils/log.js +163 -0
- package/src/utils/login.js +69 -0
- package/src/utils/printIndicator.js +43 -0
- package/src/utils/prompt.js +126 -0
- package/src/utils/sort.js +283 -0
package/src/utils/log.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const spinner = require('ora')();
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Log the specified text
|
|
9
|
+
* @param {string} text The text to log
|
|
10
|
+
* @param {boolean} [newline=true] End the log with a newline
|
|
11
|
+
*/
|
|
12
|
+
function log(text="", newline=true) {
|
|
13
|
+
let nl = newline ? '\n' : '';
|
|
14
|
+
process.stdout.write(text + nl);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Log the specified text as an Info block
|
|
19
|
+
* @param {string} text The text to log
|
|
20
|
+
* @param {boolean} [newline=true] End the log with a newline
|
|
21
|
+
*/
|
|
22
|
+
log.info = function(text, newline=true) {
|
|
23
|
+
if ( _plain() ) {
|
|
24
|
+
return log(text, newline);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let nl = newline ? '\n' : '';
|
|
28
|
+
process.stdout.write(chalk.bgYellow.black(" " + text + " " + nl));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Log the specified text with the specified `chalk` style
|
|
34
|
+
* @param {string} text The text to log
|
|
35
|
+
* @param {string} [style=reset] The chalk style attributes (ex: bgYellow.black)
|
|
36
|
+
* @param {boolean} [newline=false] End the log with a newline
|
|
37
|
+
*/
|
|
38
|
+
log.style = function(text, style, newline) {
|
|
39
|
+
if ( style === undefined && newline === undefined ) {
|
|
40
|
+
style = 'reset';
|
|
41
|
+
newline = false;
|
|
42
|
+
}
|
|
43
|
+
else if ( newline === undefined && typeof style === 'boolean' ) {
|
|
44
|
+
newline = style;
|
|
45
|
+
style = 'reset';
|
|
46
|
+
}
|
|
47
|
+
else if ( newline === undefined ) {
|
|
48
|
+
newline = false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if ( _plain() ) {
|
|
52
|
+
return log(text, newline);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let nl = newline ? '\n' : '';
|
|
56
|
+
let ch = chalk;
|
|
57
|
+
let parts = style.split('.');
|
|
58
|
+
for ( let i = 0; i < parts.length; i++ ) {
|
|
59
|
+
let part = parts[i];
|
|
60
|
+
ch = ch[part];
|
|
61
|
+
}
|
|
62
|
+
process.stdout.write(ch(text + nl));
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Log an Error: use the spinner fail function
|
|
68
|
+
* @param {string} text The text to log
|
|
69
|
+
*/
|
|
70
|
+
log.error = function(text) {
|
|
71
|
+
log.spinner.error(text);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Spinner-related functions
|
|
77
|
+
* @type {{start: log.spinner.start, stop: log.spinner.stop, success: log.spinner.success, error: log.spinner.error}}
|
|
78
|
+
*/
|
|
79
|
+
log.spinner = {
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Start the spinner with the specified text
|
|
83
|
+
* @param {string} text The text to log
|
|
84
|
+
*/
|
|
85
|
+
start: function(text) {
|
|
86
|
+
if ( !_plain() && _status() ) {
|
|
87
|
+
spinner.start(text);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Stop and clear the spinner
|
|
93
|
+
*/
|
|
94
|
+
stop: function() {
|
|
95
|
+
if ( !_plain() && _status() ) {
|
|
96
|
+
spinner.stop();
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Set the spinner as a success with the specified text
|
|
102
|
+
* @param {string} text The text to log
|
|
103
|
+
*/
|
|
104
|
+
success: function(text) {
|
|
105
|
+
if ( _status() ) {
|
|
106
|
+
if ( !_plain() ) {
|
|
107
|
+
spinner.succeed(text);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
log("[ok] " + text);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Set the spinner as an error with the specified text
|
|
117
|
+
* @param {string} text The text to log
|
|
118
|
+
*/
|
|
119
|
+
error: function(text) {
|
|
120
|
+
if ( _status() ) {
|
|
121
|
+
if ( !_plain() ) {
|
|
122
|
+
spinner.fail(text);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
log("[error] " + text);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Set the spinner as a warning with the specified text
|
|
132
|
+
* @param {string} text The text to log
|
|
133
|
+
*/
|
|
134
|
+
warn: function(text) {
|
|
135
|
+
if ( _status() ) {
|
|
136
|
+
if ( !_plain() ) {
|
|
137
|
+
spinner.warn(text);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
log("[warning] " + text);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check for a --plain flag
|
|
150
|
+
* @returns {boolean}
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
function _plain() {
|
|
154
|
+
return require('./config.js').get().plain;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function _status() {
|
|
158
|
+
return require('./config.js').get().status;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
module.exports = log;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const cp = require('copy-paste');
|
|
4
|
+
const log = require('./log.js');
|
|
5
|
+
const finish = require('../utils/finish.js');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Start the Login Process.
|
|
10
|
+
*
|
|
11
|
+
* This will save the logged in user to a configuration file.
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
function login(callback) {
|
|
15
|
+
const config = require('./config.js');
|
|
16
|
+
let client = config.client;
|
|
17
|
+
|
|
18
|
+
log.info("Authorization Required:");
|
|
19
|
+
|
|
20
|
+
// Get the Auth URL
|
|
21
|
+
log.spinner.start('Getting Login URL...');
|
|
22
|
+
client.auth.getAuthUrl(function(err, url, frob) {
|
|
23
|
+
if ( err ) {
|
|
24
|
+
log.spinner.error('Could not get Login URL (' + err.msg + ')');
|
|
25
|
+
return finish();
|
|
26
|
+
}
|
|
27
|
+
log.spinner.stop();
|
|
28
|
+
|
|
29
|
+
// Copy URL to clipboard
|
|
30
|
+
cp.copy(url);
|
|
31
|
+
|
|
32
|
+
// Display the URL
|
|
33
|
+
log.style('Please open the following URL (');
|
|
34
|
+
log.style('copied to clipboard', 'bold.underline');
|
|
35
|
+
log.style(') and authorize RTM CLI:', true);
|
|
36
|
+
log.style(url, 'blue.underline', true);
|
|
37
|
+
|
|
38
|
+
// Wait for User Input
|
|
39
|
+
global._rl.question('Press [enter] when done: ', function() {
|
|
40
|
+
log.spinner.start('Logging In...');
|
|
41
|
+
|
|
42
|
+
// Get the Authorized User
|
|
43
|
+
client.auth.getAuthToken(frob, function(err, user) {
|
|
44
|
+
if ( err ) {
|
|
45
|
+
log.spinner.error('Could not Log In (' + err.msg + ')');
|
|
46
|
+
return finish();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Display success
|
|
50
|
+
log.spinner.success('Logged in As: ' + user.username);
|
|
51
|
+
|
|
52
|
+
// Save the User to the config
|
|
53
|
+
config.saveUser(user);
|
|
54
|
+
|
|
55
|
+
// Return the User
|
|
56
|
+
if ( callback ) {
|
|
57
|
+
return callback(user);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return finish();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
module.exports = login;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const config = require('./config.js');
|
|
4
|
+
const log = require('./log.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {string} type note|url|recurring
|
|
9
|
+
* @param {object} task the task to print the indicator
|
|
10
|
+
* @param {string} style emoji|text
|
|
11
|
+
*/
|
|
12
|
+
function printIndicator(type,task) {
|
|
13
|
+
let styles = config.get().styles;
|
|
14
|
+
let iconType = config.get().iconType;
|
|
15
|
+
|
|
16
|
+
let indicatorStyle = task.isCompleted ? styles.completed : styles[type];
|
|
17
|
+
let notesIndicator,urlIndicator,recurringIndicator,subTaskIndicator;
|
|
18
|
+
iconType = iconType || 'text'; // defaults to text if nothing included
|
|
19
|
+
switch (iconType) {
|
|
20
|
+
case 'emoji':
|
|
21
|
+
notesIndicator = '📓';
|
|
22
|
+
urlIndicator = '🔗';
|
|
23
|
+
recurringIndicator = '🔁';
|
|
24
|
+
subTaskIndicator = '⤴️ '
|
|
25
|
+
break;
|
|
26
|
+
case 'text':
|
|
27
|
+
default:
|
|
28
|
+
notesIndicator = '*';
|
|
29
|
+
urlIndicator = '+';
|
|
30
|
+
recurringIndicator = 'r';
|
|
31
|
+
subTaskIndicator = '(s) '
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
let indicators = {
|
|
35
|
+
notes: notesIndicator,
|
|
36
|
+
url: urlIndicator,
|
|
37
|
+
recurring: recurringIndicator,
|
|
38
|
+
subtask: subTaskIndicator
|
|
39
|
+
}
|
|
40
|
+
log.style(indicators[type], indicatorStyle);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = printIndicator;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const finish = require('./finish.js');
|
|
4
|
+
const log = require('./log.js');
|
|
5
|
+
const promptSync = require('prompt-sync')();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Prompt the User for a set of answers
|
|
9
|
+
* @param {string} prompt One or more prompts to question the User
|
|
10
|
+
* @param {function} callback Callback function(answers)
|
|
11
|
+
* @deprecated Use indexPrompt
|
|
12
|
+
instead
|
|
13
|
+
*/
|
|
14
|
+
function prompt(prompt, callback) {
|
|
15
|
+
|
|
16
|
+
// Set callback
|
|
17
|
+
callback = arguments[arguments.length-1];
|
|
18
|
+
|
|
19
|
+
// Set prompts
|
|
20
|
+
let prompts = [];
|
|
21
|
+
for ( let i = 0; i < arguments.length-1; i++ ) {
|
|
22
|
+
prompts.push(arguments[i]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Start first prompt
|
|
26
|
+
log.style("[Enter a blank line when finished]", "dim", true);
|
|
27
|
+
_prompt(0, prompts, 0, [], callback);
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Display the current prompt
|
|
34
|
+
* @param promptIndex Current prompt
|
|
35
|
+
* @param prompts Set of prompts
|
|
36
|
+
* @param answerIndex Current Answer
|
|
37
|
+
* @param answers Set of accumulated Answers
|
|
38
|
+
* @param callback Final Callback
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
function _prompt(promptIndex, prompts, answerIndex, answers, callback) {
|
|
42
|
+
global._rl.question(prompts[promptIndex] + " ", function(answer) {
|
|
43
|
+
|
|
44
|
+
// Return with the answers
|
|
45
|
+
if ( promptIndex === 0 && answer === '' ) {
|
|
46
|
+
return _finish(answers, prompts.length, callback);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Keep prompting
|
|
50
|
+
else {
|
|
51
|
+
|
|
52
|
+
// Set Answer
|
|
53
|
+
if ( !answers[answerIndex] ) {
|
|
54
|
+
answers[answerIndex] = [];
|
|
55
|
+
}
|
|
56
|
+
answers[answerIndex][promptIndex] = answer;
|
|
57
|
+
|
|
58
|
+
// Next Prompt
|
|
59
|
+
if ( promptIndex < prompts.length - 1 ) {
|
|
60
|
+
promptIndex++;
|
|
61
|
+
_prompt(promptIndex, prompts, answerIndex, answers, callback);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Next Answer
|
|
65
|
+
else {
|
|
66
|
+
answerIndex++;
|
|
67
|
+
_prompt(0, prompts, answerIndex, answers, callback);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Remove any incomplete answers. Then return to the final callback
|
|
79
|
+
* @param answers
|
|
80
|
+
* @param promptcount
|
|
81
|
+
* @param callback
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
function _finish(answers, promptcount, callback) {
|
|
85
|
+
let rtn = [];
|
|
86
|
+
for ( let i = 0; i < answers.length; i++ ) {
|
|
87
|
+
let answer = answers[i];
|
|
88
|
+
if ( answer.length === promptcount ) {
|
|
89
|
+
rtn.push(answer);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if ( rtn.length === 0 ) {
|
|
93
|
+
return finish();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
return callback(rtn);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Prompts user for integer input until they enter a blank line
|
|
103
|
+
* @param {string} Prompt text to display
|
|
104
|
+
* @returns {number[]} array of user input integers
|
|
105
|
+
*/
|
|
106
|
+
function indexPrompt(text) {
|
|
107
|
+
let tasks = []
|
|
108
|
+
let n
|
|
109
|
+
log.style('[Enter a blank line when finished]', 'dim', true);
|
|
110
|
+
while ( n != '' ) {
|
|
111
|
+
n = promptSync(text)
|
|
112
|
+
if (parseInt(n) ) {
|
|
113
|
+
tasks.push(n)
|
|
114
|
+
} else if (n == '') {
|
|
115
|
+
break
|
|
116
|
+
} else {
|
|
117
|
+
log.style('Enter a task index number, please.','red',true)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return tasks
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
module.exports = {prompt,indexPrompt};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// ==== LIST SORTING FUNCTIONS ==== //
|
|
8
|
+
|
|
9
|
+
lists: {
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sort the RTM Lists by the rtm-api added index field
|
|
13
|
+
* @param {RTMList} a RTM List a
|
|
14
|
+
* @param {RTMList} b RTM List b
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
index: function(a, b) {
|
|
18
|
+
return a.index - b.index;
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Sort the RTM Lists by the RTM List id
|
|
24
|
+
* @param {RTMList} a RTM List a
|
|
25
|
+
* @param {RTMList} b RTM List b
|
|
26
|
+
* @returns {number}
|
|
27
|
+
*/
|
|
28
|
+
id: function(a, b) {
|
|
29
|
+
return a.id - b.id;
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sort the RTM Lists by the RTM List name
|
|
35
|
+
* @param {RTMList} a RTM List a
|
|
36
|
+
* @param {RTMList} b RTM List b
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
name: function(a, b) {
|
|
40
|
+
if ( a.name.toLowerCase() < b.name.toLowerCase() ) {
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
else if ( a.name.toLowerCase() > b.name.toLowerCase() ) {
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// ==== TASK SORTING FUNCTIONS ==== //
|
|
55
|
+
|
|
56
|
+
tasks: {
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Sort Tasks by Index
|
|
60
|
+
* @param a
|
|
61
|
+
* @param b
|
|
62
|
+
* @returns {number}
|
|
63
|
+
*/
|
|
64
|
+
index: function(a, b) {
|
|
65
|
+
return a.index - b.index;
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Sort Tasks By Priority: 1,2,3,0
|
|
70
|
+
* @param a
|
|
71
|
+
* @param b
|
|
72
|
+
* @returns {number}
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
priority: function(a, b) {
|
|
76
|
+
let ap = a.priority === 0 ? 4 : a.priority;
|
|
77
|
+
let bp = b.priority === 0 ? 4 : b.priority;
|
|
78
|
+
|
|
79
|
+
return ap - bp;
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Sort by Task Due Date (no due date first)
|
|
84
|
+
* @param a
|
|
85
|
+
* @param b
|
|
86
|
+
*/
|
|
87
|
+
due: function(a, b) {
|
|
88
|
+
if ( a.due && !b.due ) {
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
else if ( !a.due && b.due ) {
|
|
92
|
+
return -1;
|
|
93
|
+
}
|
|
94
|
+
else if ( a.due < b.due ) {
|
|
95
|
+
return -1;
|
|
96
|
+
}
|
|
97
|
+
else if ( a.due > b.due ) {
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Sort by Task Due Date (no due date last)
|
|
107
|
+
* @param a
|
|
108
|
+
* @param b
|
|
109
|
+
*/
|
|
110
|
+
dueLast: function(a, b) {
|
|
111
|
+
if ( a.due && !b.due ) {
|
|
112
|
+
return -1;
|
|
113
|
+
}
|
|
114
|
+
else if ( !a.due && b.due ) {
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
else if ( a.due < b.due ) {
|
|
118
|
+
return -1;
|
|
119
|
+
}
|
|
120
|
+
else if ( a.due > b.due ) {
|
|
121
|
+
return 1;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sort by task completed status: uncompleted, completed
|
|
130
|
+
* @param a
|
|
131
|
+
* @param b
|
|
132
|
+
* @returns {number}
|
|
133
|
+
*/
|
|
134
|
+
completed: function(a, b) {
|
|
135
|
+
if ( a.isCompleted && !b.isCompleted ) {
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
138
|
+
else if ( !a.isCompleted && b.isCompleted ) {
|
|
139
|
+
return -1;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Sort Tasks By List Name (case insensitive)
|
|
148
|
+
* @param a
|
|
149
|
+
* @param b
|
|
150
|
+
* @returns {number}
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
listName: function(a, b) {
|
|
154
|
+
if ( a._list && b._list ) {
|
|
155
|
+
if ( a._list.name.toLowerCase() < b._list.name.toLowerCase() ) {
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
else if ( a._list.name.toLowerCase() > b._list.name.toLowerCase() ) {
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return 0;
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Sort Tasks for `ls` display (list name, priority)
|
|
170
|
+
* @param a
|
|
171
|
+
* @param b
|
|
172
|
+
* @returns {number}
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
ls: function(a, b) {
|
|
176
|
+
let sort = require(__filename);
|
|
177
|
+
|
|
178
|
+
// Sort by list
|
|
179
|
+
let list = sort.tasks.listName(a, b);
|
|
180
|
+
if ( list === 0 ) {
|
|
181
|
+
|
|
182
|
+
// Sort by completed status
|
|
183
|
+
let comp = sort.tasks.completed(a, b);
|
|
184
|
+
if ( comp === 0 ) {
|
|
185
|
+
|
|
186
|
+
// Sort by priority
|
|
187
|
+
let pri = sort.tasks.priority(a, b);
|
|
188
|
+
if ( pri === 0 ) {
|
|
189
|
+
|
|
190
|
+
// Sort by Due date
|
|
191
|
+
return sort.tasks.dueLast(a, b);
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
return pri;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
return comp;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
return list;
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Sort tasks for `lsd` display (due date, priority, list name)
|
|
210
|
+
* @param a
|
|
211
|
+
* @param b
|
|
212
|
+
* @returns {number}
|
|
213
|
+
* @private
|
|
214
|
+
*/
|
|
215
|
+
lsd: function(a, b) {
|
|
216
|
+
let sort = require(__filename);
|
|
217
|
+
|
|
218
|
+
// Sort by Due Date
|
|
219
|
+
let due = sort.tasks.dueLast(a, b);
|
|
220
|
+
if ( due === 0 ) {
|
|
221
|
+
|
|
222
|
+
// Sort by Completed Status
|
|
223
|
+
let comp = sort.tasks.completed(a, b);
|
|
224
|
+
if ( comp === 0 ) {
|
|
225
|
+
|
|
226
|
+
// Sort By Priority
|
|
227
|
+
let pri = sort.tasks.priority(a, b);
|
|
228
|
+
if ( pri === 0 ) {
|
|
229
|
+
|
|
230
|
+
// Sort by List Name
|
|
231
|
+
return sort.tasks.listName(a, b);
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return pri;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
return comp;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
return due;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Sort tasks for `lsp` display (priority, due date)
|
|
251
|
+
* @param a
|
|
252
|
+
* @param b
|
|
253
|
+
* @returns {*}
|
|
254
|
+
*/
|
|
255
|
+
lsp: function(a, b) {
|
|
256
|
+
let sort = require(__filename);
|
|
257
|
+
|
|
258
|
+
// Sort by Completed Status
|
|
259
|
+
let comp = sort.tasks.completed(a, b);
|
|
260
|
+
if ( comp === 0 ) {
|
|
261
|
+
|
|
262
|
+
// Sort by Priority
|
|
263
|
+
let pri = sort.tasks.priority(a, b);
|
|
264
|
+
if ( pri === 0 ) {
|
|
265
|
+
|
|
266
|
+
// Sort by Due Date
|
|
267
|
+
return sort.tasks.dueLast(a, b);
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
return pri;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
return comp;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
};
|