diff --git a/apps/contacts/ChangeLog b/apps/contacts/ChangeLog index b09594212..a0be5eaf6 100644 --- a/apps/contacts/ChangeLog +++ b/apps/contacts/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Minor code improvements 0.03: Minor code improvements +0.04: Allow calling contacts from the app, Refactoring diff --git a/apps/contacts/contacts.app.js b/apps/contacts/contacts.app.js index 8d20e8646..34e40927a 100644 --- a/apps/contacts/contacts.app.js +++ b/apps/contacts/contacts.app.js @@ -2,108 +2,102 @@ var Layout = require("Layout"); -//const W = g.getWidth(); -//const H = g.getHeight(); - var wp = require('Storage').readJSON("contacts.json", true) || []; -// Use this with corrupted contacts -//var wp = []; -var key; /* Shared between functions, typically wp name */ - -function writeContact() { +function writeContacts() { require('Storage').writeJSON("contacts.json", wp); } +function callNumber (number) { + Bluetooth.println(JSON.stringify({ + t:"intent", + target:"activity", + action:"android.intent.action.CALL", + flags:["FLAG_ACTIVITY_NEW_TASK"], + categories:["android.intent.category.DEFAULT"], + data: 'tel:' + number, + })) + +} + function mainMenu() { var menu = { "< Back" : Bangle.load }; - if (Object.keys(wp).length==0) Object.assign(menu, {"NO Contacts":""}); - else for (let id in wp) { - let i = id; - menu[wp[id]["name"]]=()=>{ decode(i); }; + if (!wp.length) { + menu['No Contacts'] = () => {}; + } else { + for (const e of wp) { + const closureE = e; + menu[e.name] = () => showContact(closureE); + } } - menu["Add"]=addCard; - menu["Remove"]=removeCard; + menu["Add"] = addContact; + menu["Remove"] = removeContact; g.clear(); E.showMenu(menu); } -function decode(pin) { - var i = wp[pin]; - var l = i["name"] + "\n" + i["number"]; - var la = new Layout ({ - type:"v", c: [ - {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: l}, - {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label:"OK", cb:l=>{mainMenu();}} - ], lazy:true}); +function showContact(i) { g.clear(); - la.render(); + (new Layout ({ + type:"v", + c: [ + {type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: i["name"] + "\n" + i["number"]}, + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "Call", cb: l => callNumber(i['number'])}, + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "Back to list", cb: mainMenu} + ], + lazy:true + })).render(); } -function showNumpad(text, key_, callback) { - key = key_; - E.showMenu(); - function addDigit(digit) { - key+=digit; - if (1) { - l = text[key.length]; - switch (l) { - case '.': case ' ': case "'": - key+=l; - break; - case 'd': case 'D': default: - break; - } +function showNumpad() { + return new Promise((resolve, reject) => { + let number = '' + E.showMenu(); + function addDigit(digit) { + number += digit; + Bangle.buzz(20); + update(); } - Bangle.buzz(20); - update(); - } - function update() { - g.reset(); - g.clearRect(0,0,g.getWidth(),23); - s = key + text.substr(key.length, 999); - g.setFont("Vector:24").setFontAlign(1,0).drawString(s,g.getWidth(),12); - } - const ds="12%"; - var numPad = new Layout ({ - type:"v", c: [{ - type:"v", c: [ - {type:"", height:24}, - {type:"h",filly:1, c: [ - {type:"btn", font:ds, width:58, label:"7", cb:l=>{addDigit("7");}}, - {type:"btn", font:ds, width:58, label:"8", cb:l=>{addDigit("8");}}, - {type:"btn", font:ds, width:58, label:"9", cb:l=>{addDigit("9");}} - ]}, - {type:"h",filly:1, c: [ - {type:"btn", font:ds, width:58, label:"4", cb:l=>{addDigit("4");}}, - {type:"btn", font:ds, width:58, label:"5", cb:l=>{addDigit("5");}}, - {type:"btn", font:ds, width:58, label:"6", cb:l=>{addDigit("6");}} - ]}, - {type:"h",filly:1, c: [ - {type:"btn", font:ds, width:58, label:"1", cb:l=>{addDigit("1");}}, - {type:"btn", font:ds, width:58, label:"2", cb:l=>{addDigit("2");}}, - {type:"btn", font:ds, width:58, label:"3", cb:l=>{addDigit("3");}} - ]}, - {type:"h",filly:1, c: [ - {type:"btn", font:ds, width:58, label:"0", cb:l=>{addDigit("0");}}, - {type:"btn", font:ds, width:58, label:"C", cb:l=>{key=key.slice(0,-1); update();}}, - {type:"btn", font:ds, width:58, id:"OK", label:"OK", cb:callback} + function removeDigit() { + number = number.slice(0, -1); + Bangle.buzz(20); + update(); + } + function update() { + g.reset(); + g.clearRect(0,0,g.getWidth(),23); + g.setFont("Vector:24").setFontAlign(1,0).drawString(number, g.getWidth(),12); + } + const ds="12%"; + const digitBtn = (digit) => ({type:"btn", font:ds, width:58, label:digit, cb:l=>{addDigit(digit);}}); + var numPad = new Layout ({ + type:"v", c: [{ + type:"v", c: [ + {type:"", height:24}, + {type:"h",filly:1, c: [digitBtn("1"), digitBtn("2"), digitBtn("3")]}, + {type:"h",filly:1, c: [digitBtn("4"), digitBtn("5"), digitBtn("6")]}, + {type:"h",filly:1, c: [digitBtn("7"), digitBtn("8"), digitBtn("9")]}, + {type:"h",filly:1, c: [ + {type:"btn", font:ds, width:58, label:"C", cb: removeDigit}, + digitBtn('0'), + {type:"btn", font:ds, width:58, id:"OK", label:"OK", cb: l => resolve(number)} + ]} ]} - ]} - ], lazy:true}); - g.clear(); - numPad.render(); - update(); + ], lazy:true}); + g.clear(); + numPad.render(); + update(); + }); } -function removeCard() { +function removeContact() { var menu = { "" : {title : "Select Contact"}, "< Back" : mainMenu }; - if (Object.keys(wp).length==0) Object.assign(menu, {"No Contacts":""}); + if (wp.length===0) Object.assign(menu, {"No Contacts":""}); else { wp.forEach((val, card) => { const name = wp[card].name; @@ -116,7 +110,7 @@ function removeCard() { {type:"h", c: [ {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ wp.splice(card, 1); - writeContact(); + writeContacts(); mainMenu(); }}, {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{mainMenu();}} @@ -130,54 +124,42 @@ function removeCard() { E.showMenu(menu); } -function askPosition(callback) { - showNumpad("dddDDDddd", "", function() { - callback(key, ""); - }); -} -function createContact(lat, name) { - let n = {}; - n["name"] = name; - n["number"] = lat; - wp.push(n); - print("add -- contacts", wp); - writeContact(); -} - -function addCardName2(key) { +function addNewContact(name) { g.clear(); - askPosition(function(lat, lon) { - print("position -- ", lat, lon); - createContact(lat, result); + showNumpad().then((number) => { + wp.push({name: name, number: number}); + writeContacts(); mainMenu(); - }); + }) + + + } -function addCardName(key) { - result = key; - if (wp[result]!=undefined) { - E.showMenu(); - var alreadyExists = new Layout ( - {type:"v", c: [ - {type:"txt", font:Math.min(15,100/result.length)+"%", pad:1, fillx:1, filly:1, label:result}, - {type:"txt", font:"12%", pad:1, fillx:1, filly:1, label:"already exists."}, - {type:"h", c: [ - {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{ addCardName2(key); }}, - {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "CANCEL", cb:l=>{mainMenu();}} - ]} - ], lazy:true}); - g.clear(); - alreadyExists.render(); +function tryAddContact(name) { + if (wp.filter((e) => e.name === name).length) { + E.showMenu(); + var alreadyExists = new Layout ( + {type:"v", c: [ + {type:"txt", font:Math.min(15,100/name.length)+"%", pad:1, fillx:1, filly:1, label:name}, + {type:"txt", font:"12%", pad:1, fillx:1, filly:1, label:"already exists."}, + {type:"h", c: [ + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{ addNewContact(name); }}, + {type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "CANCEL", cb:l=>{mainMenu();}} + ]} + ], lazy:true}); + g.clear(); + alreadyExists.render(); return; } - addCardName2(key); + addNewContact(name); } -function addCard() { - require("textinput").input({text:""}).then(result => { - if (result != "") { - addCardName(result); +function addContact() { + require("textinput").input({text:""}).then(name => { + if (name !== "") { + tryAddContact(name); } else mainMenu(); }); diff --git a/apps/contacts/metadata.json b/apps/contacts/metadata.json index 525c7ef6e..50354f74f 100644 --- a/apps/contacts/metadata.json +++ b/apps/contacts/metadata.json @@ -1,6 +1,6 @@ { "id": "contacts", "name": "Contacts", - "version": "0.03", + "version": "0.04", "description": "Provides means of storing user contacts, viewing/editing them on device and from the App loader", "icon": "app.png", "tags": "tool",