Skip to content

Commit 6286912

Browse files
authored
Merge pull request espruino#3701 from devsnd/contacts-0.05
Contacts 0.05: Nicer UI, Refactoring, new icon
2 parents f76b9e8 + 6ad70f3 commit 6286912

File tree

7 files changed

+75
-99
lines changed

7 files changed

+75
-99
lines changed

apps/contacts/ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
0.02: Minor code improvements
33
0.03: Minor code improvements
44
0.04: Allow calling contacts from the app, Refactoring
5+
0.05: Nicer UI, Refactoring, new icon

apps/contacts/README.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Contacts
22

3-
This app provides a common way to set up the `contacts.json` file.
3+
View, edit and call contacts on your bangle.js. Calling is done via the bluetooth connection to your android phone.
44

55
## Contacts JSON file
66

@@ -11,12 +11,14 @@ has the following contents:
1111
```
1212
[
1313
{
14-
"name":"NONE"
14+
"name":"First Last",
15+
"number":"123456789",
1516
},
1617
{
17-
"name":"First Last",
18-
"number":"123456789",
19-
}
18+
"name": "James Bond",
19+
"number":"555-007",
20+
},
21+
...
2022
]
2123
```
2224

@@ -26,4 +28,12 @@ Clicking on the download icon of `Contents` in the app loader invokes
2628
the contact editor. The editor downloads and displays the current
2729
`contacts.json` file. Clicking the `Edit` button beside an entry
2830
causes the entry to be deleted from the list and displayed in the edit
29-
boxes. It can be restored - by clicking the `Add` button.
31+
boxes. It can be restored - by clicking the `Add` button.
32+
33+
# Icons
34+
35+
<a target="_blank" href="https://icons8.com/icon/85059/phone">Phone</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
36+
37+
<a target="_blank" href="https://icons8.com/icon/362/trash-can">Delete Button</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>
38+
39+
<a target="_blank" href="https://icons8.com/icon/iwE4yCawoyKM/call-list">Call List</a> icon by <a target="_blank" href="https://icons8.com">Icons8</a>

apps/contacts/app-icon.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/contacts/app.png

-10.7 KB
Loading

apps/contacts/contacts.app.js

Lines changed: 54 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
/* contacts.js */
2-
31
var Layout = require("Layout");
42

5-
var wp = require('Storage').readJSON("contacts.json", true) || [];
3+
var contacts = require('Storage').readJSON("contacts.json", true) || [];
64

75
function writeContacts() {
8-
require('Storage').writeJSON("contacts.json", wp);
6+
require('Storage').writeJSON("contacts.json", contacts);
97
}
108

119
function callNumber (number) {
10+
E.showMessage('Calling ' + number + '...');
11+
setTimeout(() => mainMenu(), 2000);
1212
Bluetooth.println(JSON.stringify({
1313
t:"intent",
1414
target:"activity",
@@ -17,35 +17,49 @@ function callNumber (number) {
1717
categories:["android.intent.category.DEFAULT"],
1818
data: 'tel:' + number,
1919
}))
20-
2120
}
2221

2322
function mainMenu() {
2423
var menu = {
24+
"": {
25+
"title": "Contacts",
26+
},
2527
"< Back" : Bangle.load
2628
};
27-
if (!wp.length) {
29+
if (!contacts.length) {
2830
menu['No Contacts'] = () => {};
29-
} else {
30-
for (const e of wp) {
31-
const closureE = e;
32-
menu[e.name] = () => showContact(closureE);
33-
}
3431
}
35-
menu["Add"] = addContact;
36-
menu["Remove"] = removeContact;
32+
contacts.forEach((e, idx) => {
33+
menu[e.name] = () => showContact(idx)
34+
})
35+
menu["Add Contact"] = addContact;
3736
g.clear();
3837
E.showMenu(menu);
3938
}
4039

41-
function showContact(i) {
40+
function showContact(idx) {
4241
g.clear();
42+
var name = contacts[idx].name;
43+
let longName = g.setFont("6x8:2").stringWidth(name) >= g.getWidth();
44+
var number = contacts[idx].number;
45+
let longNumber = g.setFont("6x8:2").stringWidth(number) >= g.getWidth();
4346
(new Layout ({
4447
type:"v",
4548
c: [
46-
{type:"txt", font:"10%", pad:1, fillx:1, filly:1, label: i["name"] + "\n" + i["number"]},
47-
{type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "Call", cb: l => callNumber(i['number'])},
48-
{type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "Back to list", cb: mainMenu}
49+
{type: 'h', filly: 3, fillx:1, c: [
50+
{type:"btn", font:"6x8", pad:1, fillx:1, filly:1, label: "<- Back to list", cb: mainMenu},
51+
{type:"btn", pad:1, fillx:1, filly:3, src: require("heatshrink").decompress(atob("jUawYGDgVJkgQGBAOSBAsJkALBBIoaCDogaCAQYXBgIIFkmAC4IIFyVAgAIGGQUJHwo4FAo2QBwICDNAVAkgCEEAYUFEAQUFE34mRPwgmEcYgmDUg8AgjLGgAA==")),
52+
cb: () => (
53+
E.showPrompt("Delete Contact '" + name + "'?", )
54+
.then((res) => { if (res) { deleteContact(idx) } else { mainMenu() } })
55+
)
56+
},
57+
]},
58+
{type:"txt", font:longName ? "6x8" : "6x8:2", pad:1, fillx:2, filly:3, label: longName ? name.slice(0, name.length/2) + '\n' + name.slice(name.length/2) : name},
59+
{type:"txt", font: "6x8:2", pad:1, fillx:2, filly:3, label: longNumber ? number.slice(0, number.length/2) + '\n' + number.slice(number.length/2) : number},
60+
{type: 'h', filly: 3, fillx:1, c: [
61+
{type:"btn", pad:1, fillx:1, filly:3, src:atob("GBiBAAAAAAAAAAAAAB8AAB+AAB+AAB+AAB+AAA+AAA8AAA4AAAYAAAcAAAMAAAGAAAHB8ADz+AA/+AAf+AAH+AAA+AAAAAAAAAAAAA=="), cb: l => callNumber(number)},
62+
]},
4963
],
5064
lazy:true
5165
})).render();
@@ -80,10 +94,10 @@ function showNumpad() {
8094
{type:"h",filly:1, c: [digitBtn("4"), digitBtn("5"), digitBtn("6")]},
8195
{type:"h",filly:1, c: [digitBtn("7"), digitBtn("8"), digitBtn("9")]},
8296
{type:"h",filly:1, c: [
83-
{type:"btn", font:ds, width:58, label:"C", cb: removeDigit},
84-
digitBtn('0'),
85-
{type:"btn", font:ds, width:58, id:"OK", label:"OK", cb: l => resolve(number)}
86-
]}
97+
{type:"btn", font:ds, width:58, label:"C", cb: removeDigit},
98+
digitBtn('0'),
99+
{type:"btn", font:ds, width:58, id:"OK", label:"OK", cb: l => resolve(number)}
100+
]}
87101
]}
88102
], lazy:true});
89103
g.clear();
@@ -92,77 +106,28 @@ function showNumpad() {
92106
});
93107
}
94108

95-
function removeContact() {
96-
var menu = {
97-
"" : {title : "Select Contact"},
98-
"< Back" : mainMenu
99-
};
100-
if (wp.length===0) Object.assign(menu, {"No Contacts":""});
101-
else {
102-
wp.forEach((val, card) => {
103-
const name = wp[card].name;
104-
menu[name]=()=>{
105-
E.showMenu();
106-
var confirmRemove = new Layout (
107-
{type:"v", c: [
108-
{type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Delete"},
109-
{type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:name},
110-
{type:"h", c: [
111-
{type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{
112-
wp.splice(card, 1);
113-
writeContacts();
114-
mainMenu();
115-
}},
116-
{type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{mainMenu();}}
117-
]}
118-
], lazy:true});
119-
g.clear();
120-
confirmRemove.render();
121-
};
122-
});
123-
}
124-
E.showMenu(menu);
125-
}
126-
127-
128-
function addNewContact(name) {
129-
g.clear();
130-
showNumpad().then((number) => {
131-
wp.push({name: name, number: number});
132-
writeContacts();
133-
mainMenu();
134-
})
135-
136-
137-
138-
}
139-
140-
function tryAddContact(name) {
141-
if (wp.filter((e) => e.name === name).length) {
142-
E.showMenu();
143-
var alreadyExists = new Layout (
144-
{type:"v", c: [
145-
{type:"txt", font:Math.min(15,100/name.length)+"%", pad:1, fillx:1, filly:1, label:name},
146-
{type:"txt", font:"12%", pad:1, fillx:1, filly:1, label:"already exists."},
147-
{type:"h", c: [
148-
{type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "REPLACE", cb:l=>{ addNewContact(name); }},
149-
{type:"btn", font:"10%", pad:1, fillx:1, filly:1, label: "CANCEL", cb:l=>{mainMenu();}}
150-
]}
151-
], lazy:true});
152-
g.clear();
153-
alreadyExists.render();
154-
return;
155-
}
156-
addNewContact(name);
109+
function deleteContact(idx) {
110+
contacts.splice(idx, 1);
111+
writeContacts();
112+
mainMenu();
157113
}
158114

159115
function addContact() {
160-
require("textinput").input({text:""}).then(name => {
161-
if (name !== "") {
162-
tryAddContact(name);
163-
} else
164-
mainMenu();
165-
});
116+
require("textinput").input({text:""})
117+
.then(name => {
118+
name = name.trim();
119+
if (name !== "") {
120+
g.clear();
121+
showNumpad().then((number) => {
122+
contacts.push({name: name, number: number});
123+
writeContacts();
124+
mainMenu();
125+
})
126+
} else {
127+
E.showMessage("Invalid name");
128+
setTimeout(() => mainMenu(), 1000);
129+
}
130+
});
166131
}
167132

168133
g.reset();

apps/contacts/interface.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</style>
3434
</head>
3535
<body>
36-
<h1>Contacts v.2</h1>
36+
<h1>Contacts</h1>
3737
<div class="flex-col">
3838
<div id="statusarea">
3939
<button id="download" class="btn btn-error">Reload</button> <button id="upload" class="btn btn-primary">Upload</button>

apps/contacts/metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{ "id": "contacts",
22
"name": "Contacts",
3-
"version": "0.04",
4-
"description": "Provides means of storing user contacts, viewing/editing them on device and from the App loader",
3+
"version": "0.05",
4+
"description": "View, edit and call contacts on device and from the App loader",
55
"icon": "app.png",
66
"tags": "tool",
77
"supports" : ["BANGLEJS2"],

0 commit comments

Comments
 (0)