aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x_notes_cli.js167
-rw-r--r--notes.js173
2 files changed, 340 insertions, 0 deletions
diff --git a/_notes_cli.js b/_notes_cli.js
new file mode 100755
index 0000000..904f493
--- /dev/null
+++ b/_notes_cli.js
@@ -0,0 +1,167 @@
+const fs = require('fs')
+const { homedir } = require('os')
+
+let conf
+
+const https = require('https')
+const readline = require("readline")
+// const spawn = require('child_process').spawn
+
+const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout
+})
+
+const cl = (m, c) => console.log(c ? `\x1b[${c}m${m}\x1b[0m` : m)
+const cls = () => console.clear()
+
+const configPath = `${homedir}/.local/share/notes_cli`
+console.log(configPath)
+
+const setConf = (c, callback) => {
+ fs.writeFile(configPath, JSON.stringify(c), function(err) {
+ if(err) {
+ cl(err, 32)
+ cl('Error writting configuration file', 32)
+ return null
+ }
+
+ conf = c
+ return callback()
+ })
+}
+
+const getConf = () => {
+ fs.readFile(configPath, function(err, f){
+ if (err) {
+ cl('Configuration file not found', 33)
+ return login()
+ }
+
+ try {
+ const r = JSON.parse(f.toString())
+
+ console.log(r)
+
+ if (!r.session || !r.userId || !r.email || !r.list) {
+ cl('Error parsing configuration', 31)
+ process.exit(1)
+ }
+
+ conf = r
+ return console.log('here handle config')
+
+ //
+
+ } catch (e) {
+ cl('Error reading configuration', 31)
+ process.exit(1)
+ }
+ })
+}
+
+const post = (path, data, callback) => {
+ const dataString = JSON.stringify(data)
+ const options = {
+ hostname: 'apps.pruss.it',
+ port: 443,
+ path,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Content-Length': dataString.length
+ },
+ timeout: 1000
+ };
+
+ const req = https.request(options, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ return callback(JSON.parse(data), res.headers, res.statusCode);
+ });
+
+ }).on("error", () => {
+ callback(null)
+ });
+
+ req.write(dataString);
+ req.end();
+}
+
+const login = () => {
+ cl('\nLogin to My Apps\n', 32)
+ cl('+-------------------------------------------------------+\n'+
+ '|Account can be created through apps.pruss.it website.|\n'+
+ '|To quit type "q" and press enter. |\n'+
+ '+-------------------------------------------------------+\n', 32)
+ rl.resume()
+ rl.question('Email: ', e => {
+ if (e === 'q') {
+ cl('\nExiting My Apps', 31)
+ rl.close()
+ process.exit(1)
+ } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)) {
+ cls()
+ cl('\nNot a valid email address, try again.', 31)
+ rl.pause()
+ return login()
+ }
+
+ rl.stdoutMuted = true
+
+ rl.question('Password: ', p => {
+ if (p === 'q') {
+ cl('\nExiting My Apps', 31)
+ rl.close()
+ process.exit(1)
+ }
+
+ rl.pause()
+
+ post(
+ '/api/login',
+ {"email": e, "password": p},
+ (o, h, s) => {
+ if (!o || s !== 201) {
+ cl('Could not log in, try again', 31)
+ return login()
+ }
+
+ const {_id, email, isVerified, noteList} = o
+ const session = h['set-cookie']
+
+ if (!_id || !email || !noteList) {
+ cl('Could not log in', 31)
+ process.exit(1)
+ } else if (!isVerified) {
+ cl('User not verified.\nPlease first verify the user using apps.pruss.it', 32)
+ return 1
+ }
+
+ const c = {userId: _id, email, list: noteList, session}
+
+ setConf(c, () => {
+ cl('Successfully saved configuration', 32)
+ cl('saved config: ', conf)
+ })
+ })
+ })
+
+ rl._writeToOutput = function _writeToOutput(stringToWrite) {
+ if (rl.stdoutMuted)
+ rl.output.write("*")
+ else
+ rl.output.write(stringToWrite)
+ };
+
+ rl.history = rl.history.slice(1)
+ })
+}
+
+cls()
+getConf()
diff --git a/notes.js b/notes.js
new file mode 100644
index 0000000..5aa7c2f
--- /dev/null
+++ b/notes.js
@@ -0,0 +1,173 @@
+const rl = require('readline');
+
+const list_mock = [
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ '10',
+ '11',
+ '12',
+ '13',
+ '14',
+ '15',
+ '16',
+ '17',
+ '18',
+ '19',
+ '20',
+ '21',
+ '22',
+ '23',
+ '24',
+ '25',
+ '26',
+ '27',
+ '28',
+ '29',
+ '30',
+ '31',
+ '32',
+ '33',
+ '34',
+ '35',
+ '36',
+ '37',
+ '38',
+ '39',
+ '40',
+ '41',
+ '42',
+ '43',
+ '44',
+ '45',
+ '46',
+ '47',
+ '48',
+ '49',
+ '50'
+]
+
+let active = 0; scroll = 0; draw = { t: 'p', v: ['Loading Notes App...'] }, appTitle = '', menu = ''
+const pr = t => process.stdout.write(t)
+const cls = () => console.clear()
+const cursor = {
+ hide: () => pr('\u001B[?25l'),
+ show: () => pr('\u001B[?25h')
+}
+
+// =========== DRAW APP =============
+
+const drawApp = () => {
+ const lines = process.stdout.rows
+ const columns = process.stdout.columns
+ // process.stdout.write('\x1Bc')
+ cls()
+ for (var i = 0; i < lines - 1; i++) {
+ const dist = t => [Math.floor((columns - t) / 2), Math.ceil((columns - t) / 2) - 2]
+ switch(i){
+ case 0:
+ pr('╔'+'═'.repeat(columns - 2)+'╗')
+ break
+ case 1:
+ pr('║'+' '.repeat(dist(appTitle.length)[0])+appTitle+' '.repeat(dist(appTitle.length)[1])+'║')
+ break
+ case 2:
+ pr('╠'+'═'.repeat(columns - 2) +'╣')
+ break
+ case lines - 3:
+ pr('╟'+'─'.repeat(columns - 2) +'╢')
+ break
+ case lines - 2:
+ pr('║'+' '+menu.substring(0,columns-4)+' '.repeat(columns-menu.length-3)+'║')
+ break
+ default:
+ const max = Math.max(...(draw.v.map(el => el.length)))
+ if (draw.t === 'p') {
+ if (i === (Math.floor((lines - draw.v.length) / 2) - 2)){
+ pr('║'+' '.repeat(dist(max+4)[0])+'┌'+'─'.repeat(max+2)+'┐'+' '.repeat(dist(max+4)[1])+'║')
+ } else if (i === (Math.floor((lines + draw.v.length) / 2) + 1)) {
+ pr('║'+' '.repeat(dist(max+4)[0])+'└'+'─'.repeat(max+2)+'┘'+' '.repeat(dist(max+4)[1])+'║')
+ } else if (i === (Math.floor((lines - draw.v.length) / 2) - 1) || i === (Math.floor((lines + draw.v.length) / 2))) {
+ pr('║'+' '.repeat(dist(max+4)[0])+'│'+' '.repeat(max+2)+'│'+' '.repeat(dist(max+4)[1])+'║')
+ } else if (i < (Math.floor((lines - draw.v.length) / 2) - 1) || (i > (Math.floor((lines + draw.v.length) / 2)))) {
+ pr('║'+' '.repeat(columns - 2)+'║')
+ } else {
+ const n = i - (Math.floor((lines - draw.v.length) / 2))
+ const t = draw.v[n]
+ const s = [Math.floor((max+2-t.length) / 2), Math.ceil((max+2-t.length) / 2)]
+ pr('║'+' '.repeat(dist(max+4)[0])+'│'+' '.repeat(s[0])+t+' '.repeat(s[1])+'│'+' '.repeat(dist(max+4)[1])+'║')
+ }
+ } else if (draw.t === 'l') {
+ const l = draw.v[i-3+scroll] && draw.v[i-3+scroll].substring(0,columns-4)
+
+ pr(l
+ ? ('║'+(active===i-3+scroll?'\x1b[7m ':' ')+l+' '.repeat(columns-l.length-3)+'\x1b[0m║')
+ : ('║'+' '.repeat(columns - 2)+'║')
+ )
+ }
+ }
+ }
+
+ pr('╚'+'═'.repeat(columns - 2)+'╝')
+}
+
+// ============ GET KEY =================
+
+const getKey = () => {
+ rl.emitKeypressEvents(process.stdin);
+ process.stdin.setRawMode(true);
+ process.stdin.on('keypress', (_, key) => {
+ const lines = process.stdout.rows
+ switch(key.name) {
+ case 'up':
+ case 'k':
+ active > 0 && active--
+ active < scroll && scroll--
+ drawApp()
+ break
+ case 'down':
+ case 'j':
+ if (draw.t === 'l') {
+ active < draw.v.length - 1 && active++
+ active - scroll > lines - 7 && scroll++
+ drawApp()
+ }
+ break
+ case 'return':
+ case 'o':
+ // draw = { t: 'p', v: ['popup test'] }
+ // draw = { t: 'p', v: ['popup test', 'aaaaaaa'] }
+ draw = { t: 'p', v: ['popup test', '', `This will display note nr ${active + 1}.`] }
+ drawApp()
+ // process.stdout.write(draw.v[active]);
+ break
+ case 'q':
+ cursor.show()
+ console.clear()
+ pr('Bye!\n\n')
+ process.exit()
+ default:
+ }
+ })
+}
+
+// ============ EXECUTION ================
+
+cls()
+cursor.hide()
+process.stdout.on('resize', drawApp);
+
+appTitle = "Notes App"
+menu = '[Q]uit [↓/j] Down [↑/k] Up [Enter/o] Open'
+draw = { t: 'l', v: list_mock }
+
+drawApp()
+getKey()
+
+