From f5e6842019a22cf3b14234921bb752984a01379d Mon Sep 17 00:00:00 2001 From: tonykakuuu Date: Tue, 4 Feb 2025 18:56:20 +0100 Subject: [PATCH] New app! --- apps/txtreader/ChangeLog | 1 + apps/txtreader/README.md | 20 ++++++ apps/txtreader/app-icon.js | 1 + apps/txtreader/app.js | 88 +++++++++++++++++++++++ apps/txtreader/metadata.json | 16 +++++ apps/txtreader/screenshot_txtreader.png | Bin 0 -> 7168 bytes apps/txtreader/txtreader.png | Bin 0 -> 1549 bytes apps/txtreader/txtreader_transparent.png | Bin 0 -> 1549 bytes 8 files changed, 126 insertions(+) create mode 100644 apps/txtreader/ChangeLog create mode 100644 apps/txtreader/README.md create mode 100644 apps/txtreader/app-icon.js create mode 100644 apps/txtreader/app.js create mode 100644 apps/txtreader/metadata.json create mode 100644 apps/txtreader/screenshot_txtreader.png create mode 100644 apps/txtreader/txtreader.png create mode 100644 apps/txtreader/txtreader_transparent.png diff --git a/apps/txtreader/ChangeLog b/apps/txtreader/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/txtreader/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/txtreader/README.md b/apps/txtreader/README.md new file mode 100644 index 000000000..1cede764c --- /dev/null +++ b/apps/txtreader/README.md @@ -0,0 +1,20 @@ +# txtreader + +Very basic text reader with an integrated file selector. + +## Features + +- select files from storage (.txt) +- display their contents +- browse pages + +## Controls + +Bangle.js 2 +- tap the right side of the screen to flip to the next page +- tap the left side of the screen to flip to the previous page +- exit by pressing the physical button + +## Creator + + diff --git a/apps/txtreader/app-icon.js b/apps/txtreader/app-icon.js new file mode 100644 index 000000000..a8c210baf --- /dev/null +++ b/apps/txtreader/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkCkQA/AH4A/AAcosd2m9jw04AQlyC5WL1e63YCG3lUC5WPj/x/8f+H/h4CBj/3jYXLv/3/4CCt4FC/IXM/4AI/YXk/WZzOfCgWfAoIXN/F3u9/C4V/AoIvUI6H3F4p3oC6/73e734XTR4wXQ/vd7vfC6f85gAG55HQAAppBC5n5xAAGz4vmzIAGF/33F49/C5v6F4+vC5rrFd6JHCv4XTI4WfF6lms1vF6mq1WvC6Z3WxfdABHVugXKlFUogAHoVCC5QA/AH4A6A")) \ No newline at end of file diff --git a/apps/txtreader/app.js b/apps/txtreader/app.js new file mode 100644 index 000000000..890b4254c --- /dev/null +++ b/apps/txtreader/app.js @@ -0,0 +1,88 @@ +function showFileSelector() { + let files = require("Storage").list().filter(f => f.endsWith('.txt')); + + let menuItems = {}; + files.forEach(file => { + menuItems[file] = () => { + E.showPrompt(`Select ${file}?`).then(confirm => { + if (confirm) { + onFileSelected(file); + } else { + showFileSelector(); + } + }); + }; + }); + + menuItems['< Back'] = () => { load(); }; // Go back to the launcher or previous screen + E.showMenu(menuItems); +} + +function onFileSelected(file) { + + var text = require("Storage").read(file); + + function displayText(text, startLine, pageNumber) { + g.clear(); + g.setFont("6x8", 1); + g.setColor(1); + g.drawString("Page " + pageNumber, 10, 2); + g.drawString(file, g.getWidth()-file.length*6, 2); + + var lines = text.split("\n"); + var y = 15; // Text start, top row reserved for page number + var currentLine = startLine || 0; + var linesDisplayed = 0; //Per page + + for (var i = currentLine; i < lines.length; i++) { + var wrappedLines = g.wrapString(lines[i], g.getWidth() - 20); + for (var j = 0; j < wrappedLines.length; j++) { + g.drawString(wrappedLines[j], 10, y); + y += 10; // Move down for the next line + linesDisplayed++; + if (y >= g.getHeight() - 10) { + // If we run out of space, stop drawing + return { nextStartLine: i , linesDisplayed: linesDisplayed }; + } + } + } + return null; // No more lines to display + } + + var currentStartLine = 0; + var currentPage = 1; + var history = []; // Track the start line and lines displayed for each page + + // Initial display + var result = displayText(text, currentStartLine, currentPage); + history.push({ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }); + + // Handle touch events + Bangle.on('touch', function(button) { + if (button === 2) { // Right side of the screen (next page) + var nextStartLine = displayText(text, currentStartLine, currentPage + 1); + if (nextStartLine !== null) { + currentStartLine = nextStartLine.nextStartLine; + currentPage++; + history.push({ startLine: currentStartLine, linesDisplayed: nextStartLine.linesDisplayed }); + displayText(text, currentStartLine, currentPage); + } else { + currentStartLine = 0; + currentPage = 1; + history = [{ startLine: currentStartLine, linesDisplayed: result.linesDisplayed }]; + displayText(text, currentStartLine, currentPage); + } + } else if (button === 1) { // Left side of the screen (previous page) + if (currentPage > 1) { + // Go back to the previous page + history.pop(); // Remove the current page from history + var previousPage = history[history.length - 1]; + currentStartLine = previousPage.startLine; + currentPage--; + displayText(text, currentStartLine, currentPage); + } + } + }); +} + +showFileSelector(); \ No newline at end of file diff --git a/apps/txtreader/metadata.json b/apps/txtreader/metadata.json new file mode 100644 index 000000000..985b8e5ea --- /dev/null +++ b/apps/txtreader/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "txtreader", + "name": "txtreader", + "shortName": "txtreader", + "version": "0.01", + "description": "Basic text reader with pages and a file selector.", + "icon": "txtreader.png", + "screenshots": [{"url":"screenshot_txtreader.png"}], + "tags": "app,tool", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"txtreader.app.js","url":"app.js"}, + {"name":"txtreader.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/txtreader/screenshot_txtreader.png b/apps/txtreader/screenshot_txtreader.png new file mode 100644 index 0000000000000000000000000000000000000000..1b565024aa69b1dde87b3fe1fb703fdb8c007583 GIT binary patch literal 7168 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 SR1MzD^O+i&8{{8yIsZS{p3)Tn literal 0 HcmV?d00001 diff --git a/apps/txtreader/txtreader.png b/apps/txtreader/txtreader.png new file mode 100644 index 0000000000000000000000000000000000000000..a60ee864722a913e9f359abe54bdce504f32634e GIT binary patch literal 1549 zcmYLJdpMM76o0>Q8RRl9VOx!H7d@I}_mPbmX2eL->?D+F4ZEx)j8r0Kh^=?RMA{;jen*bkbv}O14oGWy0-e^4&Ip+wR%5bohJMtD;B1+D2h zmxuL=UghRr8nQZgJgR_wsL%d2;Y`BILr<34t(~3M$T!O?XlAw()nVyV_oh zDa&$-YmfQHzm|VlS&_?qHrM@@*|iI?5o2N{mv3iGlRitUcL_>o^8cijt#oj_9%f2h zB=H_k7HUTtcJPKbB}OGH8%>EzwA6Z`Z!Yi6f#HAd2&>XsNA-y_K_P)1XS3XLA`MeW zR}vnn<%O{mdnT&ubNjG_ZF?&dc*iO1a_Wl-uPOWonQUlN$#MoL98YR+WsRnwQ_)WJ z-+d5(RmSij;DW#$jw+e9-4{ECQ8RI0yT}rc1E9W^M)eL#c`3WlBNT<1h>MTVjuyL` zP?nLezAsExAe~_|W^C&pt!@0|B*(2D;?AHFzF|4FD{aQ8Zff|8=YmK{f1lJW=46PM zAD2coHT}%J)cE{$+5w=edHeyJXs)X{8zYJD=eVsoz4eNg9y9_;+_x8d?0G6T_^l(d zHWaAb2pcM!)|4&yTydckMn&_U#-K(pK9}0^1GeS`YSSwlnp#*==E~mQ4i@&uHZtc` z3amFpQz7R1C)(cN$o2(YKe_U#)_MN6F%2X-FBE!le~l%3l<2cXESKVK;4;I}LP}D<7V7L@_kIu+)J|`p3Cs5E^{h=W#TLs9QOVP@b#5V4!4lXPakD%|e zZ@rQoZmyhEfwzKKt{O)<*z;4pEYL;}E7(n<X=M2fqV`2qLCf%8U88EU^vm;LLUoYSy7=By;v>)Qdz&QSydARLNLt3mtfP^HWal( zI+wY3B^wN8QI>BO*A*y5Xo*+Kdo4bYB@&@Z@evs+fq?ObPLO9gHWj=Zipc0ELrlGD zxQz=*OR8}XohZ*G6im)S*+eGbwA3-+Jgmr&b@Kg|mx-89un3lH+cx3wX;0@o+H&6* zqZbyG-7_10vxQvAM2U_)dW4g%2&-!`-^R7;gTz-lra^xC+||7y1FxE9fk4d#2PvAK zGfq1&DaNq0YwxxROPjSBFy08%?ra%c9)qI&-@2`DU3n){$)W`re?0>6(pKd{PSy*$ zW!%Mft_ZY0RR^_m_XqExV-oiFu2@#oK*R$iK0uQ)t5}v<@fw_fMIMGPEK8fBS{`-? zG>!f!Lkyh3ZjQB%%R*X2dCe^9ZhSqJuZE`sRYNyPzqjG1yZB9pHP}HKfJ-2(#SU%< zb$_1`6##TojZUGd^U=jUugD0Wv~=d7dl=(3Fp#~n-&c24A~NGdxN%ZS0}xhhLWuE0 z467AxG+mH>Yy6C-`>o}aCPSAM}`!ssj7DX9r`gZE(z&eROhhh oS5&jfmUOGcM&0}W@3vo|vF~W8IN-EfJo@hdG+#RPh7UXIU&u?`tN;K2 literal 0 HcmV?d00001 diff --git a/apps/txtreader/txtreader_transparent.png b/apps/txtreader/txtreader_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..a60ee864722a913e9f359abe54bdce504f32634e GIT binary patch literal 1549 zcmYLJdpMM76o0>Q8RRl9VOx!H7d@I}_mPbmX2eL->?D+F4ZEx)j8r0Kh^=?RMA{;jen*bkbv}O14oGWy0-e^4&Ip+wR%5bohJMtD;B1+D2h zmxuL=UghRr8nQZgJgR_wsL%d2;Y`BILr<34t(~3M$T!O?XlAw()nVyV_oh zDa&$-YmfQHzm|VlS&_?qHrM@@*|iI?5o2N{mv3iGlRitUcL_>o^8cijt#oj_9%f2h zB=H_k7HUTtcJPKbB}OGH8%>EzwA6Z`Z!Yi6f#HAd2&>XsNA-y_K_P)1XS3XLA`MeW zR}vnn<%O{mdnT&ubNjG_ZF?&dc*iO1a_Wl-uPOWonQUlN$#MoL98YR+WsRnwQ_)WJ z-+d5(RmSij;DW#$jw+e9-4{ECQ8RI0yT}rc1E9W^M)eL#c`3WlBNT<1h>MTVjuyL` zP?nLezAsExAe~_|W^C&pt!@0|B*(2D;?AHFzF|4FD{aQ8Zff|8=YmK{f1lJW=46PM zAD2coHT}%J)cE{$+5w=edHeyJXs)X{8zYJD=eVsoz4eNg9y9_;+_x8d?0G6T_^l(d zHWaAb2pcM!)|4&yTydckMn&_U#-K(pK9}0^1GeS`YSSwlnp#*==E~mQ4i@&uHZtc` z3amFpQz7R1C)(cN$o2(YKe_U#)_MN6F%2X-FBE!le~l%3l<2cXESKVK;4;I}LP}D<7V7L@_kIu+)J|`p3Cs5E^{h=W#TLs9QOVP@b#5V4!4lXPakD%|e zZ@rQoZmyhEfwzKKt{O)<*z;4pEYL;}E7(n<X=M2fqV`2qLCf%8U88EU^vm;LLUoYSy7=By;v>)Qdz&QSydARLNLt3mtfP^HWal( zI+wY3B^wN8QI>BO*A*y5Xo*+Kdo4bYB@&@Z@evs+fq?ObPLO9gHWj=Zipc0ELrlGD zxQz=*OR8}XohZ*G6im)S*+eGbwA3-+Jgmr&b@Kg|mx-89un3lH+cx3wX;0@o+H&6* zqZbyG-7_10vxQvAM2U_)dW4g%2&-!`-^R7;gTz-lra^xC+||7y1FxE9fk4d#2PvAK zGfq1&DaNq0YwxxROPjSBFy08%?ra%c9)qI&-@2`DU3n){$)W`re?0>6(pKd{PSy*$ zW!%Mft_ZY0RR^_m_XqExV-oiFu2@#oK*R$iK0uQ)t5}v<@fw_fMIMGPEK8fBS{`-? zG>!f!Lkyh3ZjQB%%R*X2dCe^9ZhSqJuZE`sRYNyPzqjG1yZB9pHP}HKfJ-2(#SU%< zb$_1`6##TojZUGd^U=jUugD0Wv~=d7dl=(3Fp#~n-&c24A~NGdxN%ZS0}xhhLWuE0 z467AxG+mH>Yy6C-`>o}aCPSAM}`!ssj7DX9r`gZE(z&eROhhh oS5&jfmUOGcM&0}W@3vo|vF~W8IN-EfJo@hdG+#RPh7UXIU&u?`tN;K2 literal 0 HcmV?d00001