From 2c64fb51aee50722a9a3189f0f9ddd97cf1d24de Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 3 Nov 2023 15:03:43 +0100 Subject: [PATCH] contacts: Inital version of contacts app. --- apps/contacts/ChangeLog | 1 + apps/contacts/README.md | 29 ++++ apps/contacts/app-icon.js | 1 + apps/contacts/app.png | Bin 0 -> 11828 bytes apps/contacts/contacts.app.js | 189 ++++++++++++++++++++++++++ apps/contacts/contacts.json | 6 + apps/contacts/interface.html | 249 ++++++++++++++++++++++++++++++++++ apps/contacts/metadata.json | 18 +++ 8 files changed, 493 insertions(+) create mode 100644 apps/contacts/ChangeLog create mode 100644 apps/contacts/README.md create mode 100644 apps/contacts/app-icon.js create mode 100644 apps/contacts/app.png create mode 100644 apps/contacts/contacts.app.js create mode 100644 apps/contacts/contacts.json create mode 100644 apps/contacts/interface.html create mode 100644 apps/contacts/metadata.json diff --git a/apps/contacts/ChangeLog b/apps/contacts/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/contacts/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/contacts/README.md b/apps/contacts/README.md new file mode 100644 index 000000000..1bfc99c8e --- /dev/null +++ b/apps/contacts/README.md @@ -0,0 +1,29 @@ +# Contacts + +This app provides a common way to set up the `contacts.json` file. + +## Contacts JSON file + +When the app is loaded from the app loader, a file named +`contacts.json` is loaded along with the javascript etc. The file +has the following contents: + +``` +[ + { + "name":"NONE" + }, + { + "name":"First Last", + "number":"123456789", + } +] +``` + +## Contacts Editor + +Clicking on the download icon of `Contents` in the app loader invokes +the contact editor. The editor downloads and displays the current +`contacts.json` file. Clicking the `Edit` button beside an entry +causes the entry to be deleted from the list and displayed in the edit +boxes. It can be restored - by clicking the `Add` button. \ No newline at end of file diff --git a/apps/contacts/app-icon.js b/apps/contacts/app-icon.js new file mode 100644 index 000000000..3012be8d8 --- /dev/null +++ b/apps/contacts/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcBkmSpIC/AVsJCJ+AQaCZBCOeACKGQLKGQBA0ggARPJ4IRsYo0ggR9IoAIGiRiIpEECJsAiACBBYoRGpEAI4JBFI47CBLIRlDHYJrGYQIRCwQICL4MQOgx9GboUSeQ4RFwAFBiSGHCIo4CiVIWZyPICP4RaRIQROgARHdIwICoIIFkDpGBAKqHgGACI0AyVIggIDoEEMQ1ICINJCIj4CfwIREBwUgQYYOCfYoFDJQKDFCIopEO4RoDKAqJHRhAC/ATA=")) diff --git a/apps/contacts/app.png b/apps/contacts/app.png new file mode 100644 index 0000000000000000000000000000000000000000..147dcc61a2487588c2bd0eaef16e22ec88c1a80b GIT binary patch literal 11828 zcmeHsby$>J*Eii=BAwDOGz<*gEzOY{n4y_LhVB*=k?xR?mXwl~Zcq?Jq$MPkl=2-s z=Q+poz0dc&-*a8x``^QLP26k$)^Dx-+iUH6Zgz~Gjw&G@4IT;#3Zc51l0NbiaQni+ zLcW`zeSd_4a(Bef(9}a8?9Jrn4!3i3fiijcx1gC8Vt@uoo}z?nMv&A&#%7R3^38(?^Ib*_%5^8c_mfv zFYL~Eu<-4@Re<;6C-TFKou}{%%%z;B{h(Ig1N5cv;I!VTE2q3FfqEg?!f#)PZ#J$O z<-cwREgklsjcGB;27m8(D!UkrC1U@ib7Sbd`Kakkk-17X_2}l4KUMwNYm-?88_jq1 zrQTedly`*G4mWLMsz;XwcLF-Nt@`5I!{aBM&2y^36`s2{jomsQcN=%E=)3@Z%c&z* z9xxKxc9Q_F8A4sV2L(N8pZG7oln5xnNGz4d14sLEFW)0t!T932sXRGQK!qXT;&kc! zVo%PW=kv?<;Q>oQff603YlZ^V%k|W6 zgL!iP{IOSU&SM+j3A(5r9t=V%InYe%Wac5&yXK9lfxNvXf_e{SnssnoVqrp>s*Y@7 z2HE>#_I04y*IWBd-Mna|f!{JF4VR*gQ04~n=NJj9tY#0aNvZorla}`g&Ew5m3ixr(Q*L>L^3Y({H`MTYY`OXZf?*Q@sA6vL35&mNj@S3hRuXr}!8tiz}H2%h9A+2K_r~7x(Tvivl1m1b!S3H{+OEGSu z1&b!OC3OfsS6J7<_+PQZo~$b(?Qo=esC}7&Ui4(gF(8(RVq_)wM@;K?hL^ySx#f zsqaB5#JYH2n$>6Hcri)EIiuTLv+4gXg(+j z-QQdDdiV(FN*6e=m_9~%gGaK>|EF?_HwIh}w< zTP&HJlqrt#(gWVVsodF7?8ut>(zd@XyM?@|3D6(+*}wncfYfI4L+>}&>^w`(qiIi6 z7-kbLh2Lr1X`-fg+4rn2t-`li@*P7=a8a(^^T+;KL6Ri-mvdzWmOP^Gj-c*3g<8Wr z-<{7phVuI9SR-ejV50}1;0+3DN{)hdDc@V)Sn2F|V9R3nlr?W+_2y6&cRH)E7a%wrd+DCYXtoI zYRPYwtw3x=R;pG$*b}@2kE^F9WGr%+h8u(Up>*8niQtr%@|vVz%A~4x9PyD)=8vU@ z;}TL;>j&#Uw)aD5uvg>nCAg@i_*ABTV(MtHrmth`l^EZNvYyhgyslBV z9QstLzqXs@ba$wU*M^|?hn|3kUMAmQ^()ig?t$ia`w~h*1N!7rl+?9rrd63oxuOWp zjgOgHTe02>XkJm2PM`Ra2H6X@DMuE2KHpOb)sG&KRTwZ?2MBo3k@!xA`*J{kJY{er zFvItIPEj~n$o3Yke9|jHJ^a`z4HXm}1QW(`3Uy2Y+>gWOX0Bt3j2ETC7H+htYx)?sn7vxBkncMQr$GnxN zloHF!Hc#q>8(y}l6N1Aap=)L(wwnGqAM%^EM)i!&yfDjcq(Z3PJsIqdrP`*Rs~9w^ z=Zjn@a=6o*b>E0>l7ZZg8$!*Vn3)$w`TTtnw#$@F$u*{jg};vc9rp<{Z_lbnylLk{ zWB6@REUkq>%N*gv+vV61I={(4YKrR8*y?C_%4Z6(GYwRZMwAl5+xbkby!j^JCJ{{e zx)O8vwR4h72KNdE8m`nvPaODs?hy&#gAWuj68Fwc_4@Lk}=R9&GYd2m(* z&&>T~)38Ncs!XR4w08bd+Y*ttu@0KDMG|Y)OFU7fw5EOydQ`1<3;VsGNoX-CI>}o0 zTC-{-a_IO&#=sOtz~f#nrnQ)_UIi|nOj2H}=Did+q$;d~r&z=HG8y-{^+Gkpb;^jo z5sgxxq~h3No`(3sqvXA{9~%3X*|P8%iS!__AE0DwfU zE&ELEa|sT>Y>SUmMs23X-KUV!z*pH)E+1g|3`Ay&3ZIA%Tdb$e`z;D~g|_pJ$K+M1 zU(5JSEQASM=PZYx|H!}?9YO277s|3(+m_RfpXU-dO~{rbg7$WoN_?t_IC#zAhYdVF zCNnC8<|7Zb!FmG86=?CMkAYM$bM8*s-q)!ohr%%t?zzkB4r=so@l^6C-t5+Rj&J4N zRE}>Ff=)0>+0i1ea1H#|H$HsrcBTI48$!P65oK5GhSGdOEs0~U!tc^2yOKG#|YzH-5TI4ouK^7O$Y_gq{AjB$1ohZ~L2x zdW-GqFl$j8(f@`s37t03~B_bu)SWcLfpA zl*bu$gFgLZ^t0a>_~bQ=g_7K3%+cOuyaJsh6`%`%q**y|1-Wa_ht7v)Tlf6A@ z)i=0EO1V47)T;SbnP&*@Z+>65cV{&Q%aV1dYYHaUqfD5;ggJTh4@$=E@y9Tu2FZ4g zTErQta^!0D^(Z!nxvQZ|8nUrqNuW@%_y|T}QlY*tF!a+lL79_BzlR_BtjHKl+hk13 zKdpP@ctaGsuNh&{1?;=IU#&Qt_*%WhvZY`3-HZ1MEju&xoH%)Ua;Ph4YPjEMmQlry zq_~%ubu}CE?i2QCQ2IQAJ)S7tnzHn3RaI_G^Fb$wciRzs?4rdsN}y*QPOTwAW^mI` z*8ORWJbJex`C`*qLG1JxZLZ#RuTAY9N1fb2fU>}w$%8SU8hkyO=o(lf3hC&(*_93k zQ_MQJPt;INl;+c+{sD!O!5X!>SF~Bq?5UN<(>Dqt8JsyOs9vSUDieX|TMs${S&s2_ zY_Bjl>TOt$Dlne*?S7DE1q#aa8nuvZEH?dSn`YvlbN)TUd61RYVODDakVz>X?uYtv z?kVJeQw%nn>YvPsai$%^LUh9DMuFcgs#kvjrVa@gtIqOi@7-e~qKi~yV^l%Q!yhz3 zrAK4R#6L@CyOgcONZct&;l%!JGPrwXgHuxOd5KuReb%J(vHL~Dw(dnluq(M;11@27 zh=&b)a%0fL#{MXAqf4c=q%)(IUHi;o5H8fdbo_;Jo+1I`aMsd zlN`5W>#n_Xy4zt9{H2bF)8N(hc7{U}`$ld=Dr-{;i+{_NdU4i>z*q?bKXw(&8i5YS zyd;n@r>DA9Y0zW48+8Bli*?SMAE<;IaDKeYsHoR~aCwrE!O3fz-wr*!=6H6mmAdaZ z-Yc9|9M)~PvGdLi9?}3q#WTFTftdqnKqtDy5~cfzbz+LzjGoq$ zoXYQsC&KZhEi!EmWMU{dT^*oU1T~d zX+nRB8o3TV#`4N(g}8dst4_{078MM15~Z5V0B>&Wr{k5+wqH3!QRqBc-@hL$meYBX z{ftf2;cZsXV1i=*q%P*wVfj04(F6!#n>~87I_Z9yc%#jndd>ycX95SB>=>ALoBPFdG!Bo4dsDLucZy^griH}scv z#|!DioJlaa*Q57UL}k!h&u5VGFfPZGgn-=!a|~9!ZT%snK#m9%-{%cPp!O3`BmeF? zxnRO8(ob?}#(9i)g5Y;>2t`Rxr@u=JbB)aw=-3|+o7z~}lQhyWHW(3qW(?*m`=&2* z=wYyM(lG>q#+_azWf~QO!(`k zAlx%ETnucy(jCBDdBl?a`G|qcp;_Jg2*3jbTv(60Sf(_Qlzw?E9{3Rih%=V zg6~uU{RJcp#6JR>TFV}P_nUA@e`CXtWz(edF-}%LvIFahB>aBEJV9lCPu>t)X%1o0 zTc-2#b6^|a#~{@CbJd4eaUn4CQM&HOC@*X4BF~>vgn)ft+G_ihl$<3nHUh1GR+*#oLbYOh*?tf@fve_S1~nC ztZJaEq7c|^u9!2OSRtZOZZLI}^o%^4p%F#XCC(~;cm_28Iy`QP7&F+cYood(jEYKW z-PEJ$4hFHAH1FiJE%o>lsvSx%FA7@$9E5BgTw<`yZjf>!Umtycf+z-+hCPX0J6R|) zhKg(d1^;;98I(~=`?4VRkx2AYpenixzhyn!%FYeP>p*8KY zYD~J$^H3#^#yE!zSS4uz&1Z8hic_xb6G3Tz_pw8p8sWIAwXet)22^SQLkj zd@Cx2&B%Q`?>vdU2(>p-+opvW;rQ9!c9fn_i#H_$;gTsGQf{Cz5!N}j@g?~dYQ zb_+J*@l4L3n38Qz6vAEAyUZD!R!0FKOYAA0aOL?$}Xf(`= zRj7Slko%iF^E-0+^kMhqshh3hl~}S_7cHiSg7Zh(>&)qoj!&XDLluBVLj{u!J`0>} zuxacp!fv+j${GXaxF1F+#D)uuBknR+&jx-Aehgab%gw|f&Nq5T-8Yhmm|gQ{`qpqE z^oG7{gQ(l=*eQCBYC4$A2X*ty*JW8|(XATRx%>}^;?iO%p45En;WT+Hb0F^BFEOn# z-`es`=J~CHg9@M>bW!kzNfY)MJ9|RMEzan9XUysL{nWWIa5Jk=_0r4jf=0p!JG~Y- z{6a>o+7APhgI_*ClWTk8VL(Ya8m-{ekhX5xZf_UEdEdLLPcvnw(*$G~_>utBmN4B! zT!`#8uL%R0Wn;F^mdeSh>V33mIV(N58d-RJaw&*9W2wh25hkOJ)}`B?YWr}_kqj`H zcDMS0An}pbcS(YQg1k++lXPkZOUn)!*F@8j%bfYuB)=O6gHylt!7rgT0}JCf(j>=V z*iff{o&Px8E~}KeZBe+Vk6nkjtW4*oG3Vw9?Dcm~DT`~7Y=;^)_BSOXpo1ufT7xqQ zJ}*#QqfC@IjjZ`W+X0q;dlrTf;i=})J?G-&>r1wteZNFz^~@Y&PnxOhO=zhKUen4~ zI(da>^ASLn$sQBs3Ych^Yk9-!M%OH5R z#u|KjtR`W9r^%j~N5}uqN?No)!jyqwV`Wa$EV^%b#7T*3f0?&OSYd zlAPebmbOrhEht4BM2HjA+)u!J&q1!B^R!6^L4t7 z{xiw?Gl2Igk-{_gyw9)S6%m!dJu|1371UfA8!X<+B%OQV_~LR-C)J!1%H5h&@iB7QQqludP1 zM>*?hS0#HKA@Wvq=ZjzVSz zB>BGJJ`9XQ3)I)M0ha8aaf~fVXHhPG?D5+?-NgOiw-nZj-xAJnWy3dPZMFH)ctC#k z+m!n2tSACcDBBTe+PCfu!AaZ%;U=&4WvsS*pl!AAKDwy`D?=S%_TE!cjIzAcXxOXt zX_acM?+Rx{97N(dWWRUsGJDkgebd1+wE$;qgB{w1UWH!ak8azCCtA<5ys?z;tp|lA zj7oquFXK04c6!*%x!clVE9jzV?eMCu{U~?K-OSufeRz3t%$`b%%)oRAbxST|Dxt1# zC-2ApG8i31$mYYbvSow7IkwgQ*GCrMqt?cnV2T0BZ6M0EboG3t3ia$6qRMG?BAmZW z8n?NleY`NR=j|4+_KT97DHysa$=-(@sX6+1I=FQJ%t}?9*=fFpFitVo_ zo5OOvS7zQWsr6j>SIXnc6eYml>Lo>L8K3RSUgZ&w2Cw|EJP&qZDsRsGfnP57G`jF) zIvE88HNsI*QBPe_@gK)J$itlMzyy$5j~rc}mB9;r?yyFt)%bj%842aXX>N*qg;L7j zJOM4o_?aSXeEe}?&fVS5`pUzf)K?Kzg)yC@u6|i9+G1h95#V|i{dKvS@n9dczlf?( zI4V-%OgDL4o}tm(r{!ft(8dytbHU8QB0Q3wRKzAdFbfI@Xn*pR_W%(bXDMng*u_CM zA=Fbz1}D*l8xxLS_JWO*jaCt>f=T>pSA(8?pT);9A7SR+6?<3ay9%f^-LifWZZ@;2nx_lfX@A^St zzU>fqr0rtZin!Ooda`(%x|T z@B*c%tYV$e%?&4(iqrqo+9yy>`?Y`Z%o4HNoO|&x$9o703h@(1lEPX;~jPu&p!HgUJSJ?+6329JF?_FgZd%EGDAb0Btu#sDq=LpF7mR zPsh;K&)HTI!Xhh!C+!1761YM=z)U`_E-(bp2gLG|7l{0RYZhQ(`U&xH2CoF<9 z-Jwh({384SK4l+AFCi8gJSJ&(h#gR0N#zd;B{ZaKj=a8C~q3k!0b=?`+` zsI9UO()dS!+v}h72oH#WI`TpUIUgiIKnMVk-~$Np2}uh4>W>`N*8bBQhWJB8q@Dsk zU^f9let>|h>)$*O9?D*S#rvlo2t(v)r+_{b0rzybg(`bNVIHi%26c1sMEn}l69K(7 z{mk11Vkdx1>SyF%eN@%8_5Sp^mC@eO)$OOpE&5j^#P&~|o2R?WPYlFX0O|sDMJ9qk zG7J6LwJB;w$NKDBssq$ zlE+ru4lHITD#2%qeCHDp5rXo8g=}p2#K2HHh>fI(2-H^S7Ybc>M`R~}U4G5#mI{KT zf(nY*fFS@uK0zoL%qIdC7vlqq0ib*kTPPTM%Ooi*{*&r<9f0zB>L3;&e!yQAJr}Tt z9o*d&#G>U0^Yr;^z|heZYTyCB6-`h~Qe09{SV%%xSQsEKA@&!@80wBd7WplwAb?-! z_oN}VKouk-7+GwNu3&qpfE&#Ir_1fK0FjeH3JbpN4J7kVJ8~{SMRzFJ1MY4Jhr57S zZgXY2rTp1aOwxZe3s4Jg`_u6!7z(-Vw?8^g0cDK-SMB4u_V|= zQd~?zj1M4aD~K#(F+o0LDT4V#?F1nrHo~HUU=iWJvm@Yk9^PPgsJuP029WEFY^|T` z%*6S#`ndj%_I7|GYlH_N1OxzBeqUZDX@T1f^&iudzTI-PwSm71AbqjWi z^s%ks;82buHlHst*bd3zN2^ZxipS=@Hc|Ki^t<@UcA0ZILzApe%W|B>rIa{XHh z{9EAvRM&sx`nMGLx4{3YuK#ax;r;c54TT|p=y@ZbpQo{(u_2$mv1~L|l~6EHKqzZ> z5px|#3$B}*83F|bpZxZPijtX4jWl9=sB0@@Z{kssvGCmJoNl3@p!KLL$s0N>?xo8* zkb|lFgQp3UpNx?J6uU#{>F9(Y6b}a{yQjLlnH3X==!N>_aXq&5++IGw!tN%*lrq%Q z+nPiUaowe0Au=A*t9`3ikvnqK{cwTZd+6*l@dCQ|y2Ro^;C^7H+Fbck0Z+@9`o{3sj>`=2`|O{z^r>{x(fTE z#jZ{>AqKeT8Oo$-A;YCn3h2$Qf|l}o+o+q5^BztqRMlXOUYu%Sa_W$W?l7MPwXgw* z7wXiO4VKTOTzxs3v93_ZLyR;9kGeFM#cNo#CAw|dmrxndRJ)w5yY;V{_(7BT#l86S zhW8H`PzNqR2^gtHzY+UTqEb7AY;6Lx;4pkYBwTEILN>#IU#I!pEdRfeZOmykJ+Gs8)#`aNs0I(joL>rLQx z2_J3fxUj&ggk5&-V$p)4OBQ-R-xosvE|{FKrJAUCsN~0a2cj(n_~1^qs^R3(NoQVf zoh#ZND(?EL(gN;}xW_jI+%*6$jMZLk-bMK_b0YC{ddg5qRg7m&6PBcnv)pOPa3o1{U)u9 zUke|;ld~P``Ee-i)lF+?L`BylW>qKU+6P@m%k65sA2ehtn)V}KX<^NsZL@42&gm_r z!f&#MyNLS(#T$Z8V1 zwdM_CojE@$)?L2OSs{AC4zCf7Wr$5*4RYmte5msbb4EM9&9MO;lt+CQV8yU%qfI%Y uV(4fka4!bTV|}LhZO+B(F$EXPA!B|@i!xJ~LpQR*QPh=nl&Tc0!~P4azigcV literal 0 HcmV?d00001 diff --git a/apps/contacts/contacts.app.js b/apps/contacts/contacts.app.js new file mode 100644 index 000000000..85eef625b --- /dev/null +++ b/apps/contacts/contacts.app.js @@ -0,0 +1,189 @@ +/* contacts.js */ + +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() { + require('Storage').writeJSON("contacts.json", wp); +} + +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); }; + } + menu["Add"]=addCard; + menu["Remove"]=removeCard; + 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}); + g.clear(); + la.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; + } + } + 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); + } + 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} + ]} + ]} + ], lazy:true}); + g.clear(); + numPad.render(); + update(); +} + +function removeCard() { + var menu = { + "" : {title : "Select Contact"}, + "< Back" : mainMenu + }; + if (Object.keys(wp).length==0) Object.assign(menu, {"No Contacts":""}); + else { + wp.forEach((val, card) => { + const name = wp[card].name; + menu[name]=()=>{ + E.showMenu(); + var confirmRemove = new Layout ( + {type:"v", c: [ + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:"Delete"}, + {type:"txt", font:"15%", pad:1, fillx:1, filly:1, label:name}, + {type:"h", c: [ + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: "YES", cb:l=>{ + wp.splice(card, 1); + writeContact(); + mainMenu(); + }}, + {type:"btn", font:"15%", pad:1, fillx:1, filly:1, label: " NO", cb:l=>{mainMenu();}} + ]} + ], lazy:true}); + g.clear(); + confirmRemove.render(); + }; + }); + } + E.showMenu(menu); +} + +function askPosition(callback) { + let full = ""; + 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) { + g.clear(); + askPosition(function(lat, lon) { + print("position -- ", lat, lon); + createContact(lat, result); + 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(); + return; + } + addCardName2(key); +} + +function addCard() { + require("textinput").input({text:""}).then(result => { + if (result != "") { + addCardName(result); + } else + mainMenu(); + }); +} + +g.reset(); +Bangle.setUI(); +mainMenu(); diff --git a/apps/contacts/contacts.json b/apps/contacts/contacts.json new file mode 100644 index 000000000..40afa27dd --- /dev/null +++ b/apps/contacts/contacts.json @@ -0,0 +1,6 @@ +[ + { + "name":"EU emergency", + "number":"112" + } +] diff --git a/apps/contacts/interface.html b/apps/contacts/interface.html new file mode 100644 index 000000000..013478960 --- /dev/null +++ b/apps/contacts/interface.html @@ -0,0 +1,249 @@ + + + + + + + + + + + + + +

Contacts v.2

+
+
+ + + +
+
+ +
+
+
+ + + + + + + + + +
NameNumber
+
+

Add a new contact

+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + diff --git a/apps/contacts/metadata.json b/apps/contacts/metadata.json new file mode 100644 index 000000000..5e08c6fdc --- /dev/null +++ b/apps/contacts/metadata.json @@ -0,0 +1,18 @@ +{ "id": "contacts", + "name": "contacts", + "version":"0.01", + "description": "Provides means of storing user contacts, viewing/editing them on device and from the App loader", + "icon": "app.png", + "tags": "tool", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "interface": "interface.html", + "storage": [ + {"name":"contacts.app.js","url":"contacts.app.js"}, + {"name":"contacts.img","url":"app-icon.js","evaluate":true} + ], + "data": [ + {"name":"contacts.json","url":"contacts.json"} + ] +}