From abd489932d26978aa2b40b07ff80f7545f53922b Mon Sep 17 00:00:00 2001 From: frigis1 <63980066+frigis1@users.noreply.github.com> Date: Sun, 3 Apr 2022 22:46:04 -0700 Subject: [PATCH] Create app.js --- apps/noteify/app.js | 461 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 apps/noteify/app.js diff --git a/apps/noteify/app.js b/apps/noteify/app.js new file mode 100644 index 000000000..7c3fd9d4c --- /dev/null +++ b/apps/noteify/app.js @@ -0,0 +1,461 @@ +var notes = require("Storage").readJSON("noteify.json", true) || []; +var alarms = require("Storage").readJSON("alarm.json",1)||[]; + +var note = ""; +var textbox = ""; +var pad = []; +var layer = 0; +var enableNote = 0; +var iniNote = 0; +var editNote; +var textBound = 0; +var msg = ""; +var enableAlarms = (!require('Storage').read("alarm.js")) ? 0 : 1; + +function saveNote() { + return { + note : note + }; +} + +class keyPad { + constructor(x1, y1, x2, y2, func) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + this.func = func; + } + get funcName() { + this.func = func; + } + set funcName(a) { + this.func = a; + } + draw() { + g.drawRect(this.x1, this.y1, this.x2, this.y2).setFont("12x20",1).setFontAlign(0, 0, 0).drawString(this.func, (((this.x2-this.x1)/2)+this.x1), (((this.y2-this.y1)/2)+this.y1)); + } + onTouch() { + //prevent keypad from working on menu + if (enableNote == 1) { + Bangle.on("touch", (button, xy) => { + if ((xy.x >= this.x1) && (xy.x <= this.x2) && (xy.y >= this.y1) && (xy.y <= this.y2) && (this.func) && (enableNote == 1)) { + if (this.func == "space") this.func = " "; + if (this.func == "<-") { + note = note.slice(0, -1); + this.func = ""; + } + else if ((this.func == "SAVE") || this.func == "BACK") { + if (note != "") { + //save edits to existing note + if (editNote != undefined) { + notes[editNote].note = note; + } + //push new note + else notes.push(saveNote()); + require("Storage").write("noteify.json",JSON.stringify(notes)); + } + //exit to menu, reset to default settings + enableNote = 0; + g.clear(); + note = ""; + layer = 0; + textBound = 0; + //prevent main menu from detecting save tap?? + setTimeout(function(){ + (editNote != undefined) ? showEditMenu(editNote) : showMainMenu(); + editNote = undefined; + }, 0); + return; + } + else note += this.func; + //scroll textbox if > 170 pixels or < 165 pixels + textbox = note.substring(textBound, note.length); + while ((g.setFont("12x20", 1).stringWidth(textbox)) > 165) { + textBound++; + textbox = note.substring(textBound, note.length); + } + while (((g.setFont("12x20", 1).stringWidth(textbox)) < 160) && textBound > 0) { + textBound--; + textbox = note.substring(textBound, note.length); + } + renderKeys(); + } + }); + } + } +} + +function renderKeys() { + g.clear(); + if ((editNote == undefined) && (note.length == 0)) { + g.setFont("Vector", 14).setFontAlign(-1, 0).drawString(textbox, 4, 11); + g.setFont("12x20", 1); + } + else g.setFont("12x20", 1).setFontAlign(-1, 0).drawString(textbox, 4, 11); + + if (layer == 0) { + var a = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "SAVE", "space", "<-"]; + if (note == "") a[9] = "BACK"; + for (var i = 0; i < a.length; i++) { + pad[i].funcName = a[i]; + } + } + else if (layer == 1) { + var a = ["J", "K", "L", "M", "N", "O", "P", "Q", "R", "SAVE", "space", "<-"]; + if (note == "") a[9] = "BACK"; + for (var i = 0; i < a.length; i++) { + pad[i].funcName = a[i]; + } + } + else if (layer == 2) { + var a = ["S", "T", "U", "V", "W", "X", "Y", "Z", "0", "SAVE", "space", "<-"]; + if (note == "") a[9] = "BACK"; + for (var i = 0; i < a.length; i++) { + pad[i].funcName = a[i]; + } + } + else if (layer == 3) { + var a = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "SAVE", "space", "<-"]; + if (note == "") a[9] = "BACK"; + for (var i = 0; i < a.length; i++) { + pad[i].funcName = a[i]; + } + } + else if (layer == 4) { + var a = [".", ",", "?", "!", "(", ")", "-", "\'", ":", "SAVE", "space", "<-"]; + if (note == "") a[9] = "BACK"; + for (var i = 0; i < a.length; i++) { + pad[i].funcName = a[i]; + } + } + + for (var j = 0; j < pad.length; j++) { + pad[j].draw(); + } +} + +function startNote() { + //edit note + if (editNote != undefined) { + note = notes[editNote].note; + //textbox start at end of note + textbox = note.substring(textBound - 14); + while ((g.setFont("12x20", 1).stringWidth(textbox)) > 165) { + textBound++; + textbox = note.substring(textBound, note.length); + } + } + //new note + else textbox = "SWIPE ANY DIRECTION"; + //prevent keypad being drawn multiple times + if (iniNote == 0) { + pad[0] = new keyPad(0, 21, 57, 58); + pad[1] = new keyPad(59, 21, 116, 58); + pad[2] = new keyPad(118, 21, 175, 58); + pad[3] = new keyPad(0, 60, 57, 97); + pad[4] = new keyPad(59, 60, 116, 97); + pad[5] = new keyPad(118, 60, 175, 97); + pad[6] = new keyPad(0, 99, 57, 136); + pad[7] = new keyPad(59, 99, 116, 136); + pad[8] = new keyPad(118, 99, 175, 136); + pad[9] = new keyPad(0, 138, 57, 175); + pad[10] = new keyPad(59, 138, 116, 175); + pad[11] = new keyPad(118, 138, 175, 175); + + var drag; + var e; + + Bangle.on("drag", e => { + if (enableNote == 1) { + if (!drag) { // start dragging + drag = {x: e.x, y: e.y}; + } + else if (!e.b) { // released + const dx = e.x-drag.x, dy = e.y-drag.y; + drag = null; + //horizontal swipes + if (Math.abs(dx)>Math.abs(dy)+10) { + //swipe left + if (dx<0) layer == 4 ? layer = 0 : layer++; + //swipe right + if (dx>0) layer == 0 ? layer = 4 : layer--; + } + //vertical swipes + else if (Math.abs(dy)>Math.abs(dx)+10) { + //swipe down, hide keypad + if (dy>0) { + enableNote = 2; + g.clear(); + g.setFontAlign(-1, -1).drawString(g.wrapString(note, g.getWidth()).join("\n"), 0, 0); + return; + } + } + } + renderKeys(); + } + else if (enableNote == 2) { + if (!drag) { // start dragging + drag = {x: e.x, y: e.y}; + } + else if (!e.b) { // released + const dx = e.x-drag.x, dy = e.y-drag.y; + drag = null; + //vertical swipes + if (Math.abs(dy)>Math.abs(dx)+10) { + //swipe up, reveal keypad + if ((dy<0) && (enableNote == 2)) { + enableNote = 1; + renderKeys(); + } + } + } + } + }); + } + renderKeys(); + for (var i = 0; i < pad.length; i++) { + pad[i].draw(); + //prevent tap zones being activated multiple times + if (iniNote == 0) { + pad[i].onTouch(); + } + } + iniNote = 1; +} + +function showMainMenu() { + var mainMenu = { + "" : { "title" : "Noteify" }, + "< Back" : function() { load(); }, + "New note" : function() { + enableNote = 1; + E.showMenu(); + startNote(); + }, + "Edit alarms/timers" : function() { showAlarmMenu(); }, + }; + + notes.forEach((a, idx) => { + mainMenu[notes[idx].note.length > 15 ? notes[idx].note.substring(0, 15)+"..." : notes[idx].note] = function () { showEditMenu(idx);}; + }); + E.showMenu(mainMenu); +} + +function showEditMenu(idx) { + var moveNote = notes[idx].note; + var newPos = idx+1; + var editMenu = { + "" : { "title" : notes[idx].note.length > 15 ? notes[idx].note.substring(0, 15)+"..." : notes[idx].note }, + "View/edit note" : function() { + editNote = idx; + enableNote = 1; + E.showMenu(); + startNote(); + }, + "Delete note" : function() { + notes.splice(idx,1); + require("Storage").write("noteify.json",JSON.stringify(notes)); + showMainMenu(); + }, + "Set as alarm" : function() { + //limit alarm msg to 30 chars + msg = moveNote.substring(0, 30); + editAlarm(-1); + }, + "Set as timer" : function () { + msg = moveNote.substring(0, 30); + editTimer(-1); + }, + "Change position" : { + value : newPos, + min : 1, + max : notes.length, + wrap : true, + onchange : function(v) { + newPos = v; + }, + }, + "< Back" : function() { + //save changes from change position + if (newPos-1 != idx) { + var moveNote = notes[idx]; + notes.splice(newPos-1, 0, notes.splice(idx, 1)[0]); + require("Storage").write("noteify.json",JSON.stringify(notes)); + } + showMainMenu(); + }, + }; + E.showMenu(editMenu); +} + +function getCurrentHr() { + var time = new Date(); + return time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600); +} + +function formatTime(t) { + var hrs = 0|t; + var mins = Math.round((t-hrs)*60); + return hrs+":"+("0"+mins).substr(-2); +} + +function formatMins(t) { + mins = (0|t)%60; + hrs = 0|(t/60); + return hrs+":"+("0"+mins).substr(-2); +} + +function showAlarmMenu() { + const menu = { + '': { 'title': 'Alarm/Timer' }, + '< Back' : ()=>{showMainMenu();}, + 'New Alarm': ()=>editAlarm(-1), + 'New Timer': ()=>editTimer(-1) + }; + alarms.forEach((alarm,idx)=>{ + if (alarm.timer) { + txt = "TIMER "+(alarm.on?"on ":"off ")+formatMins(alarm.timer); + } else { + txt = "ALARM "+(alarm.on?"on ":"off ")+formatTime(alarm.hr); + if (alarm.rp) txt += " (repeat)"; + } + menu[txt] = function() { + if (alarm.timer) editTimer(idx); + else editAlarm(idx); + }; + }); + msg = ""; + if (enableAlarms == 1) return E.showMenu(menu); +} + +function editAlarm(alarmIndex) { + var newAlarm = alarmIndex<0; + var hrs = 12; + var mins = 0; + var en = true; + var repeat = true; + var as = false; + if (!newAlarm) { + var a = alarms[alarmIndex]; + hrs = 0|a.hr; + mins = Math.round((a.hr-hrs)*60); + en = a.on; + repeat = a.rp; + as = a.as; + msg = (!a.msg) ? "" : a.msg; + } + var alarmTitle = (msg == "") ? 'Alarm' : (msg.length > 15) ? msg.substring(0, 15)+"..." : msg; + + const menu = { + '': { 'title': alarmTitle }, + '< Back' : showAlarmMenu, + 'Hours': { + value: hrs, min : 0, max : 23, wrap : true, + onchange: v => hrs=v + }, + 'Minutes': { + value: mins, min : 0, max : 59, wrap : true, + onchange: v => mins=v + }, + 'Enabled': { + value: en, + format: v=>v?"On":"Off", + onchange: v=>en=v + }, + 'Repeat': { + value: en, + format: v=>v?"Yes":"No", + onchange: v=>repeat=v + }, + 'Auto snooze': { + value: as, + format: v=>v?"Yes":"No", + onchange: v=>as=v + } + }; + function getAlarm() { + var hr = hrs+(mins/60); + var day = 0; + // If alarm is for tomorrow not today (eg, in the past), set day + if (hr < getCurrentHr()) + day = (new Date()).getDate(); + // Save alarm + return { + on : en, hr : hr, + last : day, rp : repeat, as: as, msg: msg + }; + } + menu["> Save"] = function() { + if (newAlarm) alarms.push(getAlarm()); + else alarms[alarmIndex] = getAlarm(); + require("Storage").write("alarm.json",JSON.stringify(alarms)); + showAlarmMenu(); + }; + if (!newAlarm) { + menu["> Delete"] = function() { + alarms.splice(alarmIndex,1); + require("Storage").write("alarm.json",JSON.stringify(alarms)); + showAlarmMenu(); + }; + } + if (enableAlarms == 1) return E.showMenu(menu); +} + +function editTimer(alarmIndex) { + var newAlarm = alarmIndex<0; + var hrs = 0; + var mins = 5; + var en = true; + if (!newAlarm) { + var a = alarms[alarmIndex]; + mins = (0|a.timer)%60; + hrs = 0|(a.timer/60); + en = a.on; + msg = (!a.msg) ? "" : a.msg; + } + var timerTitle = (msg == "") ? 'Alarm' : (msg.length > 15) ? msg.substring(0, 15)+"..." : msg; + const menu = { + '': { 'title': timerTitle }, + 'Hours': { + value: hrs, min : 0, max : 23, wrap : true, + onchange: v => hrs=v + }, + 'Minutes': { + value: mins, min : 0, max : 59, wrap : true, + onchange: v => mins=v + }, + 'Enabled': { + value: en, + format: v=>v?"On":"Off", + onchange: v=>en=v + } + }; + function getTimer() { + var d = new Date(Date.now() + ((hrs*60)+mins)*60000); + var hr = d.getHours() + (d.getMinutes()/60) + (d.getSeconds()/3600); + // Save alarm + return { + on : en, + timer : (hrs*60)+mins, + hr : hr, + rp : false, as: false, msg: msg + }; + } + menu["> Save"] = function() { + if (newAlarm) alarms.push(getTimer()); + else alarms[alarmIndex] = getTimer(); + require("Storage").write("alarm.json",JSON.stringify(alarms)); + showAlarmMenu(); + }; + if (!newAlarm) { + menu["> Delete"] = function() { + alarms.splice(alarmIndex,1); + require("Storage").write("alarm.json",JSON.stringify(alarms)); + showAlarmMenu(); + }; + } + if (enableAlarms == 1) return E.showMenu(menu); +} + +showMainMenu();