From eb071190e0ec267f146113aaf0ed48881f0583e4 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 13 Jan 2023 03:29:37 +0100 Subject: [PATCH] Initial import of the inspire breathing app --- apps/inspire/ChangeLog | 1 + apps/inspire/README.md | 17 +++++ apps/inspire/app-icon.js | 1 + apps/inspire/app-icon.png | Bin 0 -> 1683 bytes apps/inspire/app.js | 125 ++++++++++++++++++++++++++++++++++++ apps/inspire/metadata.json | 16 +++++ apps/inspire/screenshot.png | Bin 0 -> 2393 bytes 7 files changed, 160 insertions(+) create mode 100644 apps/inspire/ChangeLog create mode 100644 apps/inspire/README.md create mode 100644 apps/inspire/app-icon.js create mode 100644 apps/inspire/app-icon.png create mode 100644 apps/inspire/app.js create mode 100644 apps/inspire/metadata.json create mode 100644 apps/inspire/screenshot.png diff --git a/apps/inspire/ChangeLog b/apps/inspire/ChangeLog new file mode 100644 index 000000000..267ee22c2 --- /dev/null +++ b/apps/inspire/ChangeLog @@ -0,0 +1 @@ +0.01: First public version diff --git a/apps/inspire/README.md b/apps/inspire/README.md new file mode 100644 index 000000000..f5f8e3aa9 --- /dev/null +++ b/apps/inspire/README.md @@ -0,0 +1,17 @@ +# Inspire + +A minimalistic app that will help you practive breathing. + +Author: Written by pancake in 2022, powered by insomnia + +## Features + +* [x] Practice breathing 3 times +* [x] Tap to start +* [x] Subtle vibrations +* [x] Drag to pause breathing +* [ ] Automatic buzz every hour during day + +## Screenshots + +![](screenshot.png) diff --git a/apps/inspire/app-icon.js b/apps/inspire/app-icon.js new file mode 100644 index 000000000..e40d74718 --- /dev/null +++ b/apps/inspire/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4ACxIAIFlgyjFp4xdEI9lsteAAQFBGLosHFYYAHGQ4uYFpgxKFyotQGJIuTr4uTAANfGCIREFqoADGB4ueGCAufGAouMXazDMF5VlDptlCIRBNCIQvHRp4aC2fX6+zIhxgJLxwuBFoQADGIIWNF4xeNVAOtFooAD1rWLMA5eNLg5iHMCJeMspdKMIhKLF4iOMIYIuNAAJ7KSAqOMRpqROSAovLdgIuPMATyIF5BBJLyBgCSBgvNLyRgCF/6Pwd95BKMCGzPpQvHCRZeQRxgvCYBgwB1ouN1ouJXwqQOSJyNKRwyQOeQRhK1rsJRxBgPI4RiGLgIWNFwxgODIgxCFoIuMLxJgQSgQyCsqKKLxhgFDpoAQawIvKSKAARFxgvEGDggEF5IwfFx4wGYay7EFxowGsouTsouTGAwxRFoouRGA4xNFowuTGJIyBGYgFBB44tVGJYALFrIxTFroyOFkQAfA")) diff --git a/apps/inspire/app-icon.png b/apps/inspire/app-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9b851c860d9806fbe92f60467d4669c20231595a GIT binary patch literal 1683 zcmV;E25k9>P) z_AnY(qp>ZG<23j=zLH-5|L^lY&-;I#*RbRkS;QopHM0y{2dcn2a2Z$yWcL*f*aNnK zEuaQG+^7n>Z;ZfZ%}fEG05^dfb58Ru@Bp~KQ56Qi3W3d~>x|cz}kgv$NYlADq~pAG??cB;cmXTi$K+ys6UCj9*P2v^0a~O_iZN@($l}u}vr7 z9#XfxWA**+Tq~c5MafA?a#E5+EIOAb>ief+?Y4_?Y;oTUpLq|dw%R{az(ykxa_J=5 zR02s%pa@66RntK?hI9u*I(-Z0@G#VTKR3H%Qb})ide6o9)u|wMwawPCJQz6+k9QiO zQ)ND#B%cwir?wt@9y?d0{q zCthvS>}a9DCu32HS&?(Hz_qf-)ryEB#eJD2K}kvQo3hB`y1|dTF;dAm&8~qpa%Rqd zpj$LM8s)-x=UjHN{=**wH@))UWvdqod?hcjR!H&D+cF!N=XbID_2S)AHE}VK@lis zgTL#WHtmy%l3%q|xqO2s(oMp;NlJ_r3oRbCe>EQ1tV7l%l zQ1wdUAXOQSM961Eu9d|zt^6cUTq}#@GvYK=I<~#;0Q=;*Q1ud6KOXJrX5bI!(n&I6 zoU4`j!5`bz%2DRZh46w8+q##)IQwXW;LMXvC3v?a%naDDrbtI=H=9ZXzU#ww*-Kz` z9599zc*06zg0+IMFzK*X5Rk+~;EC_PhkP#~UjZoX)y~A&(j+s&2nBcvZJ~)G+A|f<5ZPw(TXbbv&Ap zg0oAfZ_zVs9@k&J$a!2h=ovPh5bD&2ZOcobHZBn2F;=swnG-pOhqQYJKkgblZOl*N zY2#>)cFzc`5mvJ)e?zS1CGgPuWaV^w>&&09q)bZ5djJfx+Wv^0}M>=$jL znRehIHLca?1OJnYadKbCyxHp#1@fa723I+Mqib(E}002ovPDHLkV1jCXJQn}} literal 0 HcmV?d00001 diff --git a/apps/inspire/app.js b/apps/inspire/app.js new file mode 100644 index 000000000..92b2c4ef2 --- /dev/null +++ b/apps/inspire/app.js @@ -0,0 +1,125 @@ +// inspire breathing app -- by pancake + +var w = g.getWidth(); +var h = g.getHeight(); +var w2 = w/2; +var h2 = h/ 2; +var fs = 24; +var tx = (w/3)-10; +var ty = (h)-fs; +var radius = (w/2)-6; +var breathing = false; +var count = 0; +var mode = 0; +var sin = 0; +var dragged = 0; +var lastTime = Date.now(); +function breath(t) { + var r = Math.abs(Math.sin(t / 100)) * w2; + g.fillCircle(w/2,h/2, r); + return r; +} + +// subtle vibration +Bangle.buzz(100); +setTimeout(()=>{Bangle.buzz(60);}, 500); + +function showTouchScreen() { + g.setColor(1,1,1); + g.fillCircle (w2, h2, h2-5); + g.setColor(0,0,0); + g.setFont("Vector", 32); + g.drawString("Tap to", w/6, h2-fs); + g.drawString("breath", w/4, h2); +} + +g.setBgColor(0,0,0); +g.setColor(0); +g.clear(); + +function animateCircle() { + g.clear(); + g.setColor(1,1,1); + g.fillCircle (w2, h2, radius); + radius-=2; + if (radius < 40) { + breathing = true; + startBreathing(); + return; + } + setTimeout(animateCircle, 50); +} + +Bangle.on("drag", function(pos) { + if (breathing) { + dragged = 1; + if (pos.dx == -pos.dy) { + count += pos.dx; + } else { + count+=(pos.dx + pos.dy); + } + } +}); + +function main() { + var started = false; + function onTouch() { + if (started) { + return; + } + started = true; + animateCircle(); + Bangle.buzz(40); + } + Bangle.on("touch", onTouch); + showTouchScreen(); +} + +main(); + +function startBreathing() { +var cicles = 3; +g.setFont("Vector", fs); + +var interval = setInterval(function() { +if (lastTime + 10 > Date.now()) { + return; +} + lastTime = Date.now(); + g.setColor(0, 0, 0); + g.clear(); + + g.setColor(0, 0.5, 1); + var b = breath(count); + g.setColor(0.5, 0.5, 1); + var c = breath(count + 50); + count++; + g.setColor(1, 1, 1); + if (b < c) { + g.drawString("inspire",8,ty); + if (mode) { + mode = 0; + Bangle.buzz(20); + if (!dragged ) { + cicles--; + } + } + } else { + g.drawString("expire",8,ty); + if (!mode) { + mode = 1; + Bangle.buzz(20); + } + } + g.drawString(cicles, w-fs, ty); + if (cicles < 1) { + clearInterval(interval); + g.clear(); + g.drawString("Thanks for",20,h/3); + g.drawString(" breathing!",20,(h/3) + 16); + Bangle.showClock(); + } + dragged = 0; + +}, 4); +} diff --git a/apps/inspire/metadata.json b/apps/inspire/metadata.json new file mode 100644 index 000000000..7944bda42 --- /dev/null +++ b/apps/inspire/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "inspire", + "name": "Inspire Breathing", + "shortName": "Inspire", + "version": "0.01", + "description": "exercise breathing every now and then", + "icon": "app-icon.png", + "tags": "tools,health", + "screenshots": [{"url":"screenshot.png"}], + "supports": ["BANGLEJS"], + "readme": "README.md", + "storage": [ + {"name":"inspire.app.js","url":"app.js"}, + {"name":"inspire.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/inspire/screenshot.png b/apps/inspire/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..69fbe7d26924bb370190c3fd07ff992e06aee62d GIT binary patch literal 2393 zcmbW(`#;l*9|!PV%-D$8cdYCZj+D#BDRddR#c@KX!sb-laBx%@!kEjDtdnu-l;cF` zqQYE8M21g{IXR+EB55|4RvgV9b1UKae*c8;5AWCW@qRqskJr!d%Rl&e=^}O@Kp>E= z_jevAwygi}XlZU`-Q#Kc7U1|3UT&b;=eUm`kT%-e!_}WnpMNJ$oU+u>kS(qgpKz}A zo{=>1LE7Qs#lcce@hH~W3TpCkWJusV3j(itot`GOIl(~y` z&juON4~ljgb3q^^*@g}htHI|cJ@>_SubsHj%FS^EOIxcA)F5PxsYtCq2o;z&rZQse zg9Abgn7-p5ETVTZBJAPylkQ!swicdwaBIt9Qu2sZEYQFUy)_u02Y z!4@}Lg08-HCh5+)qMu}PKU+jMVL8NO1<9bvSni)w?&RLrig>g90@M@;-J2VD;rQU) z?ve)(bx-c@i|rE3#)yfvxB~1)54TL4W(UD$(u756K zKYomNoq*-rS zZ@I8*Zm_co@I@bJe)e&g9v~}>G^N3oyMPp&wfF-DtD|&a3szI!@^eNuIcAV=ZKVc3 zk|E2AZj;24zR%D=*rg&M$`OyFE67eNxWIg$+EJZX^$&{|kXhHU=c{s)n4_^yq4Cyt z#Z>{AiLgugi&befcG`-^Dpa!{5PT4ARnssnvjaLYI_D+bUDXI{k**Mq6k68nQ+M|M zZ^y9hMzRAkb6OxmOV+?8LXDeCJNg0QboR;;Z9d24RK*XlT2}!=fJklq<4oI&ss`ok zsXca6*?}e(i;^J^-u=AHr&IyT!y}1H5y27b8S|d#kU0-jG$faiS=LgT(a=B$@{c$L zKQuRW=S$OkOL|O*#>Qo^O~vhTov1#@m4eVz9#khVlRD7FV&9r_$1&Ug0IP+j`^8nj zJUM1JdG78QIG2iP!7I<&LC|%|Vr(V~5`Ro=$)i3sM$*u&l^j!B)Een_4@9%1uM(o% zaG1+WNKt5?wq_0?O7M2!GfNXW%~8KDZqnA%=PLB|_^4_*zXm8Tep`@DIqPlpg)+)s zrxN`$leXLLpf0N9Dow#=KKSd8zTIP^@%E!H`tIa+ek%o|ARMP6CqI^qe?>18^qW7k zd02agC{q=z!@Prinnh!8k`sDJch^hdF&QjvSO4&Nr|8OetWG_)I;8W&AuU^~p=XVl zwf|^YC9?Mr$xXjk>$)}pKc@F;gG0<`9KVA&Ewm_Kndw~qJkAcK5_@Z)8ROrk2C)~P z*g1{WK=gQep=KUg*yCMIr*ql|0F^43B7^Dw{%f6T&5o@A8BUHEu}#xrF2!(q<+tEi zc4M28xtwvSpw=n7L3z)6ToNvyzVRKq;3yrn>BQPTKa|?wWN_gI>wBN=#>8EoJjZYo zzw0@Ysatw9^pkJw&TgaY05^wJW&}!X@uNQ!q%K8rZgi`Ff+BwhlQNNZ_>Di=PeJj~ zt@qp&O$WhTBfa`Sb6%kNd*5-;-i2CkHy9$riGS70RQet~C6P z>3Mlu6hksGu;$_EYegnniKBVis%uo{e8?$$i~$hSH|GALJ~zu^j^3{In-{M;Ogk19 zk}hhsT*wUzo9bt~-b@&I2uP~^k4OWiaTv!pmKTHfxbuj0oy|py7F5j+{5@Fck%ktQ zg9r(hGSWl-LYBWPn7+f^OKP9tYbTKfdq5e7<3Ft_s_m7>!^4~(kwTl$HbBH<$9>_> zj|NH7?)AoNLqA?fWHkCXc`bERZzlGN|0>z}w^Y8~*QopJNq<>nQrWqR_X0s-N2jH& z*Qkx^7}v(ET(WP)<>Ro>NC4^I8lg5W*mCqw! z=c724@7%_7R|PwpJs*X@nmfi%-MJVxP&bom2uPNl%1)-h_H&*m>ek?;j*DLhm&NC* zfQnV-_8*QmIrouNBE%Y9Ou`1*ERR9E+z4*^V6e|N65ow?}e$_uy z66{JjIj}m?+-U_p#G$>an#wOHizrcV=sl&we~Q|O4^CHox1>=fJ$@3 z_2|NC