open-notepad 1.0.7 → 1.0.8
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/bin/note.js +59 -11
- package/package.json +1 -1
package/bin/note.js
CHANGED
|
@@ -157,6 +157,10 @@ async function handleLogin(apiUrlArg) {
|
|
|
157
157
|
|
|
158
158
|
const choice = await selectMenuOption(loginOptions, titleCallback);
|
|
159
159
|
|
|
160
|
+
if (choice === -1) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
160
164
|
if (choice === 0) {
|
|
161
165
|
// Google Login (Browser flow)
|
|
162
166
|
clearScreen();
|
|
@@ -192,11 +196,31 @@ async function handleLogin(apiUrlArg) {
|
|
|
192
196
|
|
|
193
197
|
// Poll for completion
|
|
194
198
|
info('Waiting for browser authorization...');
|
|
199
|
+
log(`${colors.dim}Press Esc at any time to cancel and return to menu.${colors.reset}\n`);
|
|
195
200
|
const maxAttempts = 120; // 2 minutes (polling every 1.5s)
|
|
196
201
|
let attempts = 0;
|
|
202
|
+
let cancelled = false;
|
|
203
|
+
|
|
204
|
+
// Listen to Esc keypress during polling
|
|
205
|
+
const hasTTY = process.stdin.isTTY && typeof process.stdin.setRawMode === 'function';
|
|
206
|
+
const onPollKeypress = (str, key) => {
|
|
207
|
+
if (key && (key.name === 'escape' || (key.ctrl && key.name === 'c'))) {
|
|
208
|
+
cancelled = true;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
if (hasTTY) {
|
|
213
|
+
readline.emitKeypressEvents(process.stdin);
|
|
214
|
+
try {
|
|
215
|
+
process.stdin.setRawMode(true);
|
|
216
|
+
} catch (e) {}
|
|
217
|
+
process.stdin.resume();
|
|
218
|
+
process.stdin.on('keypress', onPollKeypress);
|
|
219
|
+
}
|
|
197
220
|
|
|
198
|
-
while (attempts < maxAttempts) {
|
|
221
|
+
while (attempts < maxAttempts && !cancelled) {
|
|
199
222
|
await new Promise(r => setTimeout(r, 1500));
|
|
223
|
+
if (cancelled) break;
|
|
200
224
|
attempts++;
|
|
201
225
|
|
|
202
226
|
try {
|
|
@@ -205,7 +229,7 @@ async function handleLogin(apiUrlArg) {
|
|
|
205
229
|
if (pollRes.status === 404) {
|
|
206
230
|
if (attempts > 10) {
|
|
207
231
|
error('Session expired. Please try again.');
|
|
208
|
-
|
|
232
|
+
break;
|
|
209
233
|
}
|
|
210
234
|
continue;
|
|
211
235
|
}
|
|
@@ -223,7 +247,8 @@ async function handleLogin(apiUrlArg) {
|
|
|
223
247
|
});
|
|
224
248
|
success(`Linked to room: ${colors.bold}${data.room_id}.notepad.web.id${colors.reset}`);
|
|
225
249
|
info('You can now use all CLI commands. Try: note list');
|
|
226
|
-
|
|
250
|
+
cancelled = false; // Reset to indicate success
|
|
251
|
+
break;
|
|
227
252
|
}
|
|
228
253
|
}
|
|
229
254
|
} catch (pollErr) {
|
|
@@ -231,12 +256,27 @@ async function handleLogin(apiUrlArg) {
|
|
|
231
256
|
}
|
|
232
257
|
|
|
233
258
|
if (attempts % 4 === 0) {
|
|
234
|
-
process.stdout.write(`\r${colors.dim} Polling... (${attempts}s elapsed, waiting for browser auth)${colors.reset} `);
|
|
259
|
+
process.stdout.write(`\r${colors.dim} Polling... (${Math.round(attempts * 1.5)}s elapsed, waiting for browser auth)${colors.reset} `);
|
|
235
260
|
}
|
|
236
261
|
}
|
|
237
262
|
|
|
238
|
-
|
|
239
|
-
|
|
263
|
+
if (hasTTY) {
|
|
264
|
+
try {
|
|
265
|
+
process.stdin.off('keypress', onPollKeypress);
|
|
266
|
+
process.stdin.setRawMode(false);
|
|
267
|
+
} catch (e) {}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (cancelled) {
|
|
271
|
+
process.stdout.write('\n');
|
|
272
|
+
warning('Browser authorization cancelled by user.');
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (attempts >= maxAttempts) {
|
|
277
|
+
process.stdout.write('\n');
|
|
278
|
+
warning('Browser authorization timed out.');
|
|
279
|
+
}
|
|
240
280
|
} catch (e) {
|
|
241
281
|
error(`Browser login unavailable: ${e.message}`);
|
|
242
282
|
}
|
|
@@ -647,7 +687,7 @@ function selectMenuOption(options, titleCallback) {
|
|
|
647
687
|
log(` ${colors.dim}${opt}${colors.reset}`);
|
|
648
688
|
}
|
|
649
689
|
});
|
|
650
|
-
log(`\n${colors.dim}Use Up/Down arrows to navigate, Enter to select.${colors.reset}`);
|
|
690
|
+
log(`\n${colors.dim}Use Up/Down arrows to navigate, Enter to select, Esc to go back.${colors.reset}`);
|
|
651
691
|
};
|
|
652
692
|
|
|
653
693
|
readline.emitKeypressEvents(process.stdin);
|
|
@@ -679,6 +719,12 @@ function selectMenuOption(options, titleCallback) {
|
|
|
679
719
|
} catch (e) {}
|
|
680
720
|
process.stdin.off('keypress', onKeypress);
|
|
681
721
|
resolve(activeIndex);
|
|
722
|
+
} else if (key && key.name === 'escape') {
|
|
723
|
+
try {
|
|
724
|
+
process.stdin.setRawMode(false);
|
|
725
|
+
} catch (e) {}
|
|
726
|
+
process.stdin.off('keypress', onKeypress);
|
|
727
|
+
resolve(-1);
|
|
682
728
|
}
|
|
683
729
|
};
|
|
684
730
|
|
|
@@ -708,6 +754,12 @@ async function startMainMenu() {
|
|
|
708
754
|
|
|
709
755
|
const choice = await selectMenuOption(options, titleCallback);
|
|
710
756
|
|
|
757
|
+
if (choice === -1 || choice === 6) {
|
|
758
|
+
clearScreen();
|
|
759
|
+
log('Goodbye!');
|
|
760
|
+
process.exit(0);
|
|
761
|
+
}
|
|
762
|
+
|
|
711
763
|
switch (choice) {
|
|
712
764
|
case 0:
|
|
713
765
|
await handleList();
|
|
@@ -733,10 +785,6 @@ async function startMainMenu() {
|
|
|
733
785
|
await handleLogin();
|
|
734
786
|
await ask('Press Enter to return to menu');
|
|
735
787
|
break;
|
|
736
|
-
case 6:
|
|
737
|
-
clearScreen();
|
|
738
|
-
log('Goodbye!');
|
|
739
|
-
process.exit(0);
|
|
740
788
|
}
|
|
741
789
|
}
|
|
742
790
|
}
|