From 537842a32109bcc0ab69d5cd2474a87518bbcd41 Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 08:05:41 -0500 Subject: [PATCH 1/3] Added emojuino v0.01 --- apps.json | 15 ++++ apps/emojuino/ChangeLog | 1 + apps/emojuino/README.md | 23 ++++++ apps/emojuino/emojuino-icon.js | 1 + apps/emojuino/emojuino.js | 145 +++++++++++++++++++++++++++++++++ apps/emojuino/emojuino.png | Bin 0 -> 1966 bytes 6 files changed, 185 insertions(+) create mode 100644 apps/emojuino/ChangeLog create mode 100644 apps/emojuino/README.md create mode 100644 apps/emojuino/emojuino-icon.js create mode 100644 apps/emojuino/emojuino.js create mode 100644 apps/emojuino/emojuino.png diff --git a/apps.json b/apps.json index f307a6feb..a0d543cd8 100644 --- a/apps.json +++ b/apps.json @@ -4215,5 +4215,20 @@ { "name": "qalarm.wid.js", "url": "widget.js" } ], "data": [{ "name": "qalarm.json" }] + }, + { + "id": "emojuno", + "name": "Emoji Broadcaster", + "shortName": "Emojuino", + "version": "0.01", + "description": "Emojis & Espruino: advertise Unicode emojis via BLE", + "icon": "emojuino.png", + "tags": "emoji", + "supports" : [ "BANGLEJS2" ], + "readme": "README.md", + "storage": [ + { "name": "emojuno.app.js", "url": "emojuino.js" }, + { "name": "emojuno.img", "url": "emojuino-icon.js", "evaluate": true } + ] } ] diff --git a/apps/emojuino/ChangeLog b/apps/emojuino/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/emojuino/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/emojuino/README.md b/apps/emojuino/README.md new file mode 100644 index 000000000..13879437e --- /dev/null +++ b/apps/emojuino/README.md @@ -0,0 +1,23 @@ +# Emojuino + +Emojis & Espruino! + +## Usage + +Select an emoji and then tap to transmit! + +## Features + +Currently implements a tiny subset of possible Unicode emojis. + +## Controls + +Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting. + +## Requests + +[Contact reelyActive](https://www.reelyactive.com/contact/) for support/updates. + +## Creator + +Developed by [jeffyactive](https://github.com/jeffyactive) of [reelyActive](https://www.reelyactive.com) diff --git a/apps/emojuino/emojuino-icon.js b/apps/emojuino/emojuino-icon.js new file mode 100644 index 000000000..d56749250 --- /dev/null +++ b/apps/emojuino/emojuino-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkBiIAHkUoxGIwUiBxAAGiQVCAAeCkIWNCooADDBYWKDBYWEkc////+cyDBhxDCoQAD+YLDCw0YBQQVFAAYYCwIXFHQRDElGCJYgOCFw8vBwPyOgoJFGAg4BIoQWGDAhJCIwoLBHgYAGJQIjCIwguCnCRFRoeDGAZICAgOPFwaRGDAQfB/AwDBAYuCX44wDAgTrDBoIDBGYP/manBmYFBFYQPDwJeBD4iRGRoQ/FC4QqBEYIbERooTBCAeBNAIjBBQIDDAAggBG4IDDwQXBEQIDDUAgcCHASaBAYQTFMQpcFDYp+EEII9DAARRDFIIfDHIwXBVISlDC4YzD9wA0osFpwIF8lQqgWK8kAgEEBItABIIhGAAfgBoMABIoIChwX0jwED8oNBgoXFqAJBrwHD8IXEBwQNEEIYgFC4wAQ8MRC6sRC+BgULwIwHSINVpwuLC43kaAQABqgaHC4bZHAAkFqhGHGAovFAAYyDCwgwFL4IwGFxAwNFxIwG8lVCoSTEFw7bPCxAYNCxT0LIpIxMCpoyHFhI")) \ No newline at end of file diff --git a/apps/emojuino/emojuino.js b/apps/emojuino/emojuino.js new file mode 100644 index 000000000..3de92fa6c --- /dev/null +++ b/apps/emojuino/emojuino.js @@ -0,0 +1,145 @@ +/** + * Copyright reelyActive 2021 + * We believe in an open Internet of Things + */ + + +// Emojis are integer pairs with the form [ image, Unicode code point ] +// For code points see https://unicode.org/emoji/charts/emoji-list.html +const EMOJIS = [ + [ ':)', 0x1f642 ], // Slightly smiling + [ ':|', 0x1f610 ], // Neutral + [ ':(', 0x1f641 ], // Slightly frowning + [ '+1', 0x1f44d ], // Thumbs up + [ '-1', 0x1f44e ], // Thumbs down + [ '<3', 0x02764 ], // Heart +]; +const EMOJI_TRANSMISSION_MILLISECONDS = 5000; +const BLINK_PERIOD_MILLISECONDS = 500; +const TRANSMIT_BUZZ_MILLISECONDS = 200; +const CYCLE_BUZZ_MILLISECONDS = 50; + +// Non-user-configurable constants +const IMAGE_INDEX = 0; +const CODE_POINT_INDEX = 1; +const BTN_WATCH_OPTIONS = { repeat: true, debounce: 20, edge: "falling" }; +const UNICODE_CODE_POINT_ELIDED_UUID = [ 0x49, 0x6f, 0x49, 0x44, 0x55, + 0x54, 0x46, 0x2d, 0x33, 0x32 ]; + + +// Global variables +let emojiIndex = 0; +let isToggleOn = false; +let isTransmitting = false; +let lastDragX = 0; +let lastDragY = 0; + + +// Cycle through emojis +function cycleEmoji(isForward) { + if(isTransmitting) { return; } + + if(isForward) { + emojiIndex = (emojiIndex + 1) % EMOJIS.length; + } + else if(--emojiIndex < 0) { + emojiIndex = EMOJIS.length - 1; + } + + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + Bangle.buzz(CYCLE_BUZZ_MILLISECONDS); +} + + +// Handle a touch: transmit displayed emoji +function handleTouch(zone, event) { + if(isTransmitting) { return; } + + let emoji = EMOJIS[emojiIndex]; + transmitEmoji(emoji[IMAGE_INDEX], emoji[CODE_POINT_INDEX], + EMOJI_TRANSMISSION_MILLISECONDS); + Bangle.buzz(TRANSMIT_BUZZ_MILLISECONDS); +} + + +// Transmit the given code point for the given duration in milliseconds, +// blinking the image once per second. +function transmitEmoji(image, codePoint, duration) { + let instance = [ 0x00, 0x00, (codePoint >> 24) & 0xff, + (codePoint >> 16) & 0xff, (codePoint >> 8) & 0xff, + codePoint & 0xff ]; + + require('ble_eddystone_uid').advertise(UNICODE_CODE_POINT_ELIDED_UUID, + instance); + isTransmitting = true; + + let displayIntervalId = setInterval(toggleImage, BLINK_PERIOD_MILLISECONDS, + image); + + setTimeout(terminateEmoji, duration, displayIntervalId); +} + + +// Terminate the emoji transmission +function terminateEmoji(displayIntervalId) { + NRF.setAdvertising({ }); + isTransmitting = false; + clearInterval(displayIntervalId); + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); +} + + +// Toggle the display between image/off +function toggleImage(image) { + if(isToggleOn) { + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + } + else { + g.clear(); + } + isToggleOn = !isToggleOn; +} + + +// Draw the given emoji +function drawImage(image) { + g.clear(); + g.drawString(image, g.getWidth() / 2, g.getHeight() / 2); + g.flip(); +} + + +// Handle a drag event +function handleDrag(event) { + let isFingerReleased = (event.b === 0); + + if(isFingerReleased) { + let isHorizontalDrag = (Math.abs(lastDragX) >= Math.abs(lastDragY)) && + (lastDragX !== 0); + + if(isHorizontalDrag) { + cycleEmoji(lastDragX > 0); + } + } + else { + lastDragX = event.dx; + lastDragY = event.dy; + } +} + + +// Special function to handle display switch on +Bangle.on('lcdPower', (on) => { + if(on) { + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + } +}); + + +// On start: display the first emoji and handle drag and touch events +g.clear(); +g.setFont('Vector', 80); +g.setFontAlign(0, 0); +drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); +Bangle.on('touch', handleTouch); +Bangle.on('drag', handleDrag); diff --git a/apps/emojuino/emojuino.png b/apps/emojuino/emojuino.png new file mode 100644 index 0000000000000000000000000000000000000000..614cc025ea17ad4bb68c1530e7d6b62022c908fd GIT binary patch literal 1966 zcmV;f2T}NmP)LJKHJpZ9o4v%hLat-R-v2z)RjTneY4Fdow%p&un4r31H@y zrNicKUz;%@IsV@vQ7PsAVX4*rp{e9G-Din61uZJhvzO?@M=O-}>hp74uh7s#me>E^N;h`F)z8tX1 za(~$Bm19-ECx)I88+!Kp-kPr(KWX-fh|TL564_1luRBJjHR``SHo<#lyk_R0_sj(P zV9kCC%{Wb4PG6%7w;s^dyM_ZJb=*5hxQ=@04zDw6{g0~vSGX%u6>ai#; zM>TM8P}E*ZIh9KVWfkNpFoW5_Ttn4$@Xhd;OUR(csujGZ#C7gC-&&}Of*-EkPp7Wu ztC{MIlUxg$st?#9IPM{`sQFx?*^EscI|RoUsba5wmrk2cUse4LlvLPg?_dAWj4dbV z<8=qCBCL^jYjL)G{zpGj_%oW+fUkm{pNiP-=Qv@q@UHY-(N&T|z9!)#0%T zN2#)^S~AMXFQkzh4{1i85*oQ&O9Z^&srGgZ-grdKE1~tAxLNAZXv?o;Q^IdObB)@} zP1X!lzQlW4&vD-eEoh2>C%n~OpIIBHtGNv{pPbyzXI8vTY<_oT236RqBw;LrswjwM z5oa^zw@Z|j_khZUIc#GYMGZYIoGhWx76ET$kPpCWLsm6E>k<~XRcveSgXaRbw{%# zA*>M10%Sw1FvoIkOMRXIv;JH|)P#q+(yc#wQR*?Wic4$Pu(-8iL-$47q?`7BNjYDS z(@z!9X!KmNUDAfvgVLIZBeEcq*wa2} z!zz3FkdWuv&r2u~i?PSD1q(9PcCn5#f8#;1)Prk$Nc29b&y46nuLx*CQ|yDMh`7vb zsorj$r3l$sv+0(%#X_suNz$vq?ZQ&+TE)Xi#IAFH8*^${XGHIAJ|hB}Vh=pw?Eo^V z9>~t#Sz(P7cYYpsSdi7PzfWU+mg*<2-Z6cMVWsICv6K2N-C_FThKCtuML=8Zfwu@` z6YE{W)+}IyBIB=!JEIR@kcM#miuFCh*~hhskYXJ-WzxwU>Df`uHqS(!=U zSz#H&he^RHlad(q?#-x03;VyRsd`UsnUcb&PoEksXsbPLXdFPTFQLdtM*P{Wam^aN z*Bw`{)^)(BD81JO@9od-XUUgn1ywn*d%;2AFrAa|!NeQFIjde4yX;Vg}rTUCBq8Br&4hRo; zsWVQvl7F&MCIwSYo~#>!)28XY?uZ#x2ZV>(>w=^BCu_r5ZBo>TGY8{FjcU$TKmemM ztOX|hu80}TI=)qCLfeCH5}DgDfNx})G&m(pE?n@)%qi=km1%^3bO4h~8lHAe5)Ysi zXOT(M(@JEO|7OZ}EH`Ob|L6ePaTc01yJU4Wqk{(-W#f@zQf~kvqyBdxfENNy z2AmQr$?)MdOQ5$mqkjDuO`OOmI-1duBaH6f*XQcVKsEPc@M06rKTL*986K{$<7VvC z$$p@7<}gZ2V|4Z`qpB)huNFkMCXWM~fj9VbJ~SEDICQ8Uwzl;0V$`b_qcLL`tysb6 z#0gzrAu{=9{RfV6=EKqt>nUVD9Ma%P1nkui^?Z3k~=G``C~m z`;Q|0vcu2Q-DLkm!A&73wy_U2^q|-NW2Bz=507j4%;>`Us{jB107*qoM6N<$f~a%V AC;$Ke literal 0 HcmV?d00001 From a0837cbecf58a4732e7ea1e17623e8940bed2ede Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 08:12:12 -0500 Subject: [PATCH 2/3] Changed id from emojuno to emojuino to make links work --- apps.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index a0d543cd8..560e3d949 100644 --- a/apps.json +++ b/apps.json @@ -4217,7 +4217,7 @@ "data": [{ "name": "qalarm.json" }] }, { - "id": "emojuno", + "id": "emojuino", "name": "Emoji Broadcaster", "shortName": "Emojuino", "version": "0.01", @@ -4227,8 +4227,8 @@ "supports" : [ "BANGLEJS2" ], "readme": "README.md", "storage": [ - { "name": "emojuno.app.js", "url": "emojuino.js" }, - { "name": "emojuno.img", "url": "emojuino-icon.js", "evaluate": true } + { "name": "emojuino.app.js", "url": "emojuino.js" }, + { "name": "emojuino.img", "url": "emojuino-icon.js", "evaluate": true } ] } ] From 2d76d0bd132e992068ad322a51393c1593e54c68 Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 10:04:55 -0500 Subject: [PATCH 3/3] Improved naming/documentation --- apps.json | 4 ++-- apps/emojuino/README.md | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 560e3d949..b02517aea 100644 --- a/apps.json +++ b/apps.json @@ -4218,10 +4218,10 @@ }, { "id": "emojuino", - "name": "Emoji Broadcaster", + "name": "Emojuino", "shortName": "Emojuino", "version": "0.01", - "description": "Emojis & Espruino: advertise Unicode emojis via BLE", + "description": "Emojis & Espruino: broadcast Unicode emojis via Bluetooth Low Energy.", "icon": "emojuino.png", "tags": "emoji", "supports" : [ "BANGLEJS2" ], diff --git a/apps/emojuino/README.md b/apps/emojuino/README.md index 13879437e..568d06dfb 100644 --- a/apps/emojuino/README.md +++ b/apps/emojuino/README.md @@ -2,22 +2,27 @@ Emojis & Espruino! + ## Usage -Select an emoji and then tap to transmit! +Select an emoji and then tap to transmit! The emoji will be recognised by [Pareto Anywhere](https://www.reelyactive.com/pareto/anywhere/) open source middleware and any other program which observes the [InteroperaBLE Identifier](https://reelyactive.github.io/interoperable-identifier/) open standard. + ## Features -Currently implements a tiny subset of possible Unicode emojis. +Currently implements a tiny subset of possible [Unicode emojis](https://unicode.org/emoji/charts/full-emoji-list.html) which are advertised as an [InteroperaBLE Identifier](https://reelyactive.github.io/interoperable-identifier/) encapsulated as Eddystone UID. + ## Controls -Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting. +Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting, which lasts for 5 seconds. + ## Requests [Contact reelyActive](https://www.reelyactive.com/contact/) for support/updates. + ## Creator Developed by [jeffyactive](https://github.com/jeffyactive) of [reelyActive](https://www.reelyactive.com)