From 85fdc4be5cfad91d53168023d4c9909272b5e3bb Mon Sep 17 00:00:00 2001 From: user Date: Mon, 9 Dec 2024 23:56:33 +0100 Subject: [PATCH] A Tea Timer application --- apps/ateatimer/ChangeLog | 1 + apps/ateatimer/app-icon.js | 1 + apps/ateatimer/app.js | 122 +++++++++++++++++++++++++++++++++++ apps/ateatimer/app.json | 1 + apps/ateatimer/app.png | Bin 0 -> 5053 bytes apps/ateatimer/metadata.json | 13 ++++ 6 files changed, 138 insertions(+) create mode 100644 apps/ateatimer/ChangeLog create mode 100644 apps/ateatimer/app-icon.js create mode 100644 apps/ateatimer/app.js create mode 100644 apps/ateatimer/app.json create mode 100644 apps/ateatimer/app.png create mode 100644 apps/ateatimer/metadata.json diff --git a/apps/ateatimer/ChangeLog b/apps/ateatimer/ChangeLog new file mode 100644 index 000000000..b0b91b94a --- /dev/null +++ b/apps/ateatimer/ChangeLog @@ -0,0 +1 @@ +0.01: First release \ No newline at end of file diff --git a/apps/ateatimer/app-icon.js b/apps/ateatimer/app-icon.js new file mode 100644 index 000000000..49ce16c2f --- /dev/null +++ b/apps/ateatimer/app-icon.js @@ -0,0 +1 @@ +atob("LjCI/hsbGxsbGxsbGxsbGxsbGwcHBwccHBwcHBwcHBwHBxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsHBwccHR0eHh4PDw8PDx4eHh0cBwcHGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsHBxwdHg8PDw8PDw8eHg8PDw8PDx4dHAcbGxsHGxsbGxsbGxsbGxsbGxsbGxsHHB0eDw8PHh0cGxoaGhoaGxwdHg8PDx4dHAcbGxsbGxsbGxsbGxsbGxsbGwcHHR4PDx4dGxkZGRkZGRkZGRkYGRkbHR4PDx4dBxsbGxsbGwcbGxsbGxsbGwccHQ8PHh0bGRkaGhsbGxoaGhoaGRkZGRkaHB4PDx0cBxsbGxsHGxsbGxsbGwccHg8PHhsZGRsHBxsbGhoaGhkZGRkZGRkZGRkaHg8PHhwHBwcbGxsbGxsbGwccHg8eHBkZGxwHGxoaGxoZBx4aGRsbGRkZGRkZGRkcHg8eHAcbGxsHGxsbGwccHg8eHBkaBxwHGxoZGx4bGR0dGRkdBxkZGRkZGRkZGQceHh4cBxsbBwcbGxscHg8PHBkaBwcbGhkZGRseGhkcHhkZHgcZGRkZGRkZGRkZBx4eHQcbBwcbGxsHHQ8PHBkaBwcaGRkZGRkZHR0ZGR0cGBseGRkZGRkZGRkZGRkcHh4dBwcHGxsHHA8PHRkaBxsaGRkZGRkZGQcdGRkdHBgbHhoZGRkZGRkZGRkZGh0eHhwHBxsbBx4PHhoZGxsaGRkZGRkZGRkcBxkaHBoZBxwZGRkZGRkZGRkZGRkaHR4dBwcbBx0PDxwZGwcaGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQceHhwbGwceDx4ZGhsbGhkZGhoaGxoaGhoaGhoaGhoaGhoaGhoaGRkZGRkZGRkaHR4dBwcdHg8HGRobGhkZGRsdHh4eHh4eHh4eHh4eHh4eHh4eHh0aGRkZGRkZGQceHhwHHQ8eGRkaGhkZGRodDw8PDw8PHg8PHBkeDx4eDw8PDw8PGxkZGRkZGRkaHh4cHB4PHBgaGhkZGRkaHQ8PDw8PHZQcDxr0HR4YGA8PDw8PDwcZGRkZGRkZGRweHRwPDxsZGhkZGRkZGh0PDw8PDx4HHg8a9B0PHBwPDw8PDw8dHAcaGRkZGRkbHh4dDx4aGRkZGRkZGRodDw8PBxwPDw8PGvQdDw8PHgcdDw8PDw8eHRsZGRkZGh4eHQ8dGRkZGRkZGRkaHQ8PHqwZHg8PDxr0HQ8PDx2rBw8PDx0dHg8eGhkZGRodHh4PHRkZGRkZGRkZGh0PDw8eHg8PDw8a3B0PDw8eHh4PDw8HGRodDxwZGRkaHR4eDxwZGRkZGRkZGRodDw8PDw8PDw8erNwaHh4eHh4eDw8PBxkZBx4dGRkZGRweHg8cGRkZGRkZGRkaHQ8PGxsPDw8PG5YY3KysrKwYGB0PDxsZGRseHhkZGRkcHh4eHBkZGRkZGRkZGh0PDxoaHg8PDxv0rNyVlZOrrKwcDx4bGRkdDx0ZGRkZHB4eHhwZGRkZGRkZGRkcDw8eHg8PDw8dGJMaHR4eHh4eDw8eBwcdHg8bGRkZGRweHR4cGRkZGRkZGRkZBx4PDx4eDw8PDx4dHg8PDw8eHg8PHh4eDx4cGRkZGRodHh0eHRkZGRkZGRkZGRoeDx4ZGh4PDw8PDw8PDw8drAcPHh4eHh0HGRkZGRkaHR4cHh4aGRkZGRkZGRkZHA8PHB0PDw8PDw8PDw8PHgcdDx0bGRkZGRkZGRkZGx4eHB4eGxkZGRkZGRkZGRoeDw8PHgceDw8PDw8dHQ8PDx4cGRkZGRkZGRkZGQceHgceHhwZGRkZGRkZGRkZGx4PDx2sHA8dGg8eGRkPDx4dGhgZGRkZGRkZGRkdHh0HHR4eGhkZGRkZGRkZGRkbHh4PHg8PG5MeDx4eDx4dGhkZGRkZGRkZGRkaHh4HBxweHhwZGRkZGRkZGRkZGRsdHh4PDx4cDw8PHh0HGRkZGRkZGRkZGRkZHA8eGgcHHR4dGhkZGRkZGRkZGRkZGhscHh4eHh4eHQcaGRkZGRkZGRkZGRkZGx4PHBkHBxweHhwaGRkZGhwdHR0dHR0dHR4eHh4eHh4dHR0dHR0dHRwZGRkZGh0PHhoYGxsHHR4eBxkZGRodDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8dGRkZGRweDxwYGRsbBwceHh0aGRkZGx4eHh4eHh4eHh4eHh4eHh4eHh4eHh4dGhkZGRseDx4ZGBkHBwcHHB4eHRoZGRkaBwcHBwcHBwcHBwcHBwcHBwcHBwcbGhkZGRoeHh4aGBkZBwcHGxscHh4dGhkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRodHh4bGBgZGQcHBwcbGxweHh0bGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRsdHh4HGBgZGRoHBwcHGxsbHB4eHRsZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQceHh4HGBgZGRoaBwcHBxsbGxsHHR4eHBoZGRkZGRkZGRkZGRkZGRkZGRkZGx0eHh0bGBgZGRoaGgcHBwcHGxsbGhsdHh4dHBsZGRkZGRkZGRkZGRkZGRobHB4eHh0aGBgZGRkaGhoHBwcHBwcHGxsaGgcdHh4dHQcbGhkZGRkZGRkaGxwdHh4eHRsZGBgZGRkaGhobGxsHGxsHBwcbGxoaGgcdHh4eHh0dHRwcHB0dHh4eHh4dGxkYGBgZGRkaGhobGxsbGxsbBwcHGxsbGhoZGRscHR0eHh4eHh4eHh4dHRwaGBgYGBkZGRoaGhobGxsbGxsbGwcHBwcbGxsaGhoZGRkaGwcHHBwcBxsaGRkYGBgYGRkZGhoaGhobGxsbGxsHBwcHBwcHBxsbGxsaGhoZGRkZGRgYGBgYGBgYGBkZGRkZGhoaGhsbGxsbGw==") \ No newline at end of file diff --git a/apps/ateatimer/app.js b/apps/ateatimer/app.js new file mode 100644 index 000000000..52af806a5 --- /dev/null +++ b/apps/ateatimer/app.js @@ -0,0 +1,122 @@ +// Tea Timer Application for Bangle.js 2 +let timerDuration = (() => { + let file = require("Storage").open("ateatimer.data", "r"); + let data = file.read(4); // Assuming 4 bytes for storage + return data ? parseInt(data, 10) : 4 * 60; // Default to 4 minutes +})(); +let timeRemaining = timerDuration; +let timerRunning = false; +let buzzInterval = null; // Interval for buzzing when timer reaches 0 +let timerInterval = null; // Interval for timer countdown + +function saveDefaultDuration() { + let file = require("Storage").open("ateatimer.data", "w"); + file.write(timerDuration.toString()); +} + +function drawTime() { + g.clear(); + g.setFont("Vector", 40); + g.setFontAlign(0, 0); // Center align + + const minutes = Math.floor(Math.abs(timeRemaining) / 60); + const seconds = Math.abs(timeRemaining) % 60; + const sign = timeRemaining < 0 ? "-" : ""; + const timeStr = `${sign}${minutes}:${seconds.toString().padStart(2, '0')}`; + + g.drawString(timeStr, g.getWidth() / 2, g.getHeight() / 2); + + // Draw Increase button (triangle pointing up) + g.fillPoly([ + g.getWidth() / 2, g.getHeight() / 2 - 80, // Top vertex + g.getWidth() / 2 - 20, g.getHeight() / 2 - 60, // Bottom-left vertex + g.getWidth() / 2 + 20, g.getHeight() / 2 - 60 // Bottom-right vertex + ]); + + // Draw Decrease button (triangle pointing down) + g.fillPoly([ + g.getWidth() / 2, g.getHeight() / 2 + 80, // Bottom vertex + g.getWidth() / 2 - 20, g.getHeight() / 2 + 60, // Top-left vertex + g.getWidth() / 2 + 20, g.getHeight() / 2 + 60 // Top-right vertex + ]); + + g.flip(); +} + +function startTimer() { + if (timerRunning) return; + timerRunning = true; + + // Save the default duration on timer start + timerDuration = timeRemaining; + saveDefaultDuration(); + + timerInterval = setInterval(() => { + timeRemaining--; + drawTime(); + + if (timeRemaining === 0 && !buzzInterval) { + // Start continuous vibration when timer reaches 0 + buzzInterval = setInterval(() => Bangle.buzz(500), 1000); + } + }, 1000); +} + +function resetTimer() { + if (timerInterval) { + clearInterval(timerInterval); + timerInterval = null; + } + timerRunning = false; + timeRemaining = timerDuration; + stopBuzzing(); + drawTime(); +} + +function stopBuzzing() { + if (buzzInterval) { + clearInterval(buzzInterval); + buzzInterval = null; + } +} + +function adjustTime(amount) { + if (!timerRunning) { + timeRemaining += amount; + timeRemaining = Math.floor(timeRemaining / 60) * 60; // Round to full minutes + } else { + timeRemaining += amount; // Allow adjustments during running + } + drawTime(); +} + +function handleTouch(x, y) { + const centerY = g.getHeight() / 2; + + if (y < centerY - 40) { + // Increase button area + adjustTime(60); + } else if (y > centerY + 40) { + // Decrease button area + adjustTime(-60); + } else { + // Center area + if (!timerRunning) { + startTimer(); + } + } +} + +// Handle physical button press for resetting timer +setWatch(() => { + resetTimer(); +}, BTN1, { repeat: true, edge: "falling" }); + +// Handle touch +Bangle.on("touch", (zone, xy) => { + handleTouch(xy.x, xy.y, false); +}); + +// Draw the initial timer display +drawTime(); + diff --git a/apps/ateatimer/app.json b/apps/ateatimer/app.json new file mode 100644 index 000000000..7304a3d42 --- /dev/null +++ b/apps/ateatimer/app.json @@ -0,0 +1 @@ +{ "duration": 240 } \ No newline at end of file diff --git a/apps/ateatimer/app.png b/apps/ateatimer/app.png new file mode 100644 index 0000000000000000000000000000000000000000..4c25f7d33b11a258ffef18af9b3419c9b80719d2 GIT binary patch literal 5053 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