diff --git a/apps/astrocalc/ChangeLog b/apps/astrocalc/ChangeLog index ee9c7bbe4..df039ba0e 100644 --- a/apps/astrocalc/ChangeLog +++ b/apps/astrocalc/ChangeLog @@ -6,3 +6,4 @@ 0.06: Fix azimuth (bug #2651), only show degrees 0.07: Minor code improvements 0.08: Minor code improvements +0.09: Fix: Handle when the moon rise/set do not occur on the current day diff --git a/apps/astrocalc/astrocalc-app.js b/apps/astrocalc/astrocalc-app.js index cd1965290..283c5aab7 100644 --- a/apps/astrocalc/astrocalc-app.js +++ b/apps/astrocalc/astrocalc-app.js @@ -180,8 +180,8 @@ function drawMoonTimesPage(gps, title) { const moonColor = g.theme.dark ? {r: 1, g: 1, b: 1} : {r: 0, g: 0, b: 0}; const pageData = { - Rise: dateToTimeString(times.rise), - Set: dateToTimeString(times.set), + Rise: times.rise ? dateToTimeString(times.rise) : "Not today", + Set: times.set ? dateToTimeString(times.set) : "Not today", }; drawData(title, pageData, null, g.getHeight()/2 - Object.keys(pageData).length/2*20 + 5); @@ -240,7 +240,7 @@ function sunIndexPageMenu(gps) { "title": "-- Sun --", }, "Current Pos": () => { - m = E.showMenu(); + E.showMenu(); drawSunShowPage(gps, "Current Pos", new Date()); }, }; @@ -248,13 +248,13 @@ function sunIndexPageMenu(gps) { Object.keys(sunTimes).sort().reduce((menu, key) => { const title = titlizeKey(key); menu[title] = () => { - m = E.showMenu(); + E.showMenu(); drawSunShowPage(gps, key, sunTimes[key]); }; return menu; }, sunMenu); - sunMenu["< Back"] = () => m = indexPageMenu(gps); + sunMenu["< Back"] = () => indexPageMenu(gps); return E.showMenu(sunMenu); } @@ -266,18 +266,18 @@ function moonIndexPageMenu(gps) { "title": "-- Moon --", }, "Times": () => { - m = E.showMenu(); + E.showMenu(); drawMoonTimesPage(gps, /*LANG*/"Times"); }, "Position": () => { - m = E.showMenu(); + E.showMenu(); drawMoonPositionPage(gps, /*LANG*/"Position"); }, "Illumination": () => { - m = E.showMenu(); + E.showMenu(); drawMoonIlluminationPage(gps, /*LANG*/"Illumination"); }, - "< Back": () => m = indexPageMenu(gps), + "< Back": () => indexPageMenu(gps), }; return E.showMenu(moonMenu); @@ -289,10 +289,10 @@ function indexPageMenu(gps) { "title": /*LANG*/"Select", }, /*LANG*/"Sun": () => { - m = sunIndexPageMenu(gps); + sunIndexPageMenu(gps); }, /*LANG*/"Moon": () => { - m = moonIndexPageMenu(gps); + moonIndexPageMenu(gps); }, "< Back": () => { load(); } }; @@ -300,9 +300,9 @@ function indexPageMenu(gps) { return E.showMenu(menu); } -function getCenterStringX(str) { - return (g.getWidth() - g.stringWidth(str)) / 2; -} +//function getCenterStringX(str) { +// return (g.getWidth() - g.stringWidth(str)) / 2; +//} function init() { let location = require("Storage").readJSON("mylocation.json",1)||{"lat":51.5072,"lon":0.1276,"location":"London"}; @@ -311,5 +311,4 @@ function init() { Bangle.drawWidgets(); } -let m; init(); diff --git a/apps/astrocalc/metadata.json b/apps/astrocalc/metadata.json index a43534325..d88037d09 100644 --- a/apps/astrocalc/metadata.json +++ b/apps/astrocalc/metadata.json @@ -1,7 +1,7 @@ { "id": "astrocalc", "name": "Astrocalc", - "version": "0.08", + "version": "0.09", "description": "Calculates interesting information on the sun like sunset and sunrise and moon cycles for the current day based on your location from MyLocation app", "icon": "astrocalc.png", "tags": "app,sun,moon,cycles,tool,outdoors", diff --git a/apps/burn/.gitignore b/apps/burn/.gitignore new file mode 100644 index 000000000..656b79624 --- /dev/null +++ b/apps/burn/.gitignore @@ -0,0 +1 @@ +.prettierignore \ No newline at end of file diff --git a/apps/burn/ChangeLog b/apps/burn/ChangeLog new file mode 100644 index 000000000..66c4f98bd --- /dev/null +++ b/apps/burn/ChangeLog @@ -0,0 +1,7 @@ +0.01: New App! +0.02: Added README.md +0.03: Icon update +0.04: Icon Fix +0.05: Misc cleanup for PR +0.06: Implementing fixes from PR comments +0.07: Bug fix diff --git a/apps/burn/README.md b/apps/burn/README.md new file mode 100644 index 000000000..44f1e260f --- /dev/null +++ b/apps/burn/README.md @@ -0,0 +1,30 @@ +# Burn: Calorie Counter + +Burn is a simple calorie counter application. It is based on the original Counter app and has been enhanced with additional features (I recommend using +it with the "Digital Clock Widget", if you intend to keep it running). + +## Features + +- **Persistent counter**: The counter value is saved to flash, so it persists even when the app is closed or the device is restarted. +- **Daily reset**: The counter resets each day, allowing you to track your calorie intake on a daily basis. +- **Adjustable increment value**: You can adjust the increment value to suit your needs. + +## Controls + +### Bangle.js 1 + +- **BTN1**: Increase (or tap right) +- **BTN3**: Decrease (or tap left) +- **Press BTN2**: Change increment + +### Bangle.js 2 + +- **Swipe up**: Increase +- **Swipe down**: Decrease +- **Press BTN**: Change increment + +## How it Works + +The counter value and the date are stored in a file named "kcal.txt". The counter value is read from the file when the app starts and written to the file whenever the counter value is updated. + +The app uses the current date to determine whether to reset the counter. If the date has changed since the last time the counter was updated, the counter is reset to 0. diff --git a/apps/burn/app-icon.js b/apps/burn/app-icon.js new file mode 100644 index 000000000..8cd3b7ca1 --- /dev/null +++ b/apps/burn/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4f/gUA///j32o8h9v6glA+P9+/3tu27YCLvICBgEGCJlFmwRBgALFxQRIgIdF28JmIIEknG7cMyVJk4nBC4PJk4dBC4OJkmSrYRCkuACQM26/88wRGgQHB2iGCm33//8GoXtonbraYGgwRB/+bNY4AEg9/CIPbth3BxYRJn4RB/YRBgEUTwIRGne275IBCIQABjYRGrpCB+VK1gJDgYQFgXN23YQwIjEAA0WMwPQ0mSqgRK2QRBy6cBCJUFGIO12wjBpgRMlsAqmSqTOCAA0sCINogEIyVKCJdLoEAhQRNpQFCyVII5IRGqARQNZUECIcGyRLBPpPSCIQWBsCzK3VJoEB0mTCBUAitplEA0WYCJb7B1EBCYIAsjJjCknDpMkyUAmlKNwuEyEAgMSwwQBpNhAQM4CAcDkgRBe4ODogOB4MT0MldgcxCIXEyWAi3axNgykECIcBxIRBEwIRBYoK3BykGkw1DxPEyEZksSCIMEpcDjAIBGocbhMQiMzCIUyqALB5KmFhMghMk0VLQANYPoLeBCI0SRgOKJYOAgOSpihFCIMaCIOTgMk4ACBqVICIyTBKIMZkkAhpyBo4RHgOk4EZPAIjByVFNYYIBAoU2AoOwAQO5kmMf7QALpMg2VJ23Mn////8OIVThmUCIs27FvCIP+eQOSpUIyXAgFNEYfQCIX8P4OSp0MCIVZgEWFoNgrMktuwgdt23YOIQ")) \ No newline at end of file diff --git a/apps/burn/app-icon.png b/apps/burn/app-icon.png new file mode 100644 index 000000000..23d4a13e6 Binary files /dev/null and b/apps/burn/app-icon.png differ diff --git a/apps/burn/app-screenshot.png b/apps/burn/app-screenshot.png new file mode 100644 index 000000000..fef0e701e Binary files /dev/null and b/apps/burn/app-screenshot.png differ diff --git a/apps/burn/app.js b/apps/burn/app.js new file mode 100644 index 000000000..348a19153 --- /dev/null +++ b/apps/burn/app.js @@ -0,0 +1,243 @@ +/* + * Burn: Calories Counter for Bangle.js (Espruino). Based on the original Counter app. + * Features: + * - Persistent counter: saved to a file. + * - Daily reset: counter resets each day. + * - Adjustable increment value. + * + * Bangle.js 1 Controls: + * - BTN1: Increase (or tap right) + * - BTN3: Decrease (or tap left) + * - Press BTN2: Change increment + * + * Bangle.js 2 Controls: + * - Swipe up: Increase + * - Swipe down: Decrease + * - Press BTN: Change increment + */ + +// File variable to handle file operations +let file; + +// Check if the hardware version is Bangle.js 2 +const BANGLEJS2 = process.env.HWVERSION == 2; + +// Importing the Storage module for file operations +const Storage = require("Storage"); + +// File path for the counter data +const PATH = "kcal.txt"; + +// Function to get the current date as a string +function dayString() { + const date = new Date(); + // Month is 0-indexed, so we add 1 to get the correct month number + return `${date.getMonth() + 1}-${date.getDate()}-${date.getFullYear()}`; +} + +// Counter object to keep track of the count and the date +let counter = { count: 0, date: dayString() }; + +// Function to read the counter from the file +function readCounterFromFile() { + try { + // Open the file in read mode + file = Storage.open(PATH, "r"); + let line = file.readLine(); + + // If the file has content, parse it and update the counter + if (line) { + let splitLine = line.trim().split(","); + counter = { count: parseInt(splitLine[0]), date: splitLine[1] }; + } + } catch (err) { + // If the file does not exist, the counter will remain 0 + } +} + +// Function to write the counter to the file +function writeCounterToFile() { + // Open the file in write mode + file = Storage.open(PATH, "w"); + // Write the counter and date to the file + file.write(counter.count.toString() + "," + counter.date + "\n"); +} + +// Function to reset the counter +function resetCounter() { + // Reset the counter to 0 and update the date + counter = { count: 0, date: dayString() }; +} + +// Function to update the counter value +function updateCounterValue(value) { + // Update the counter with the new value, ensuring it's not less than 0 + counter = { count: Math.max(0, value), date: dayString() }; +} + +// Function to update the counter +function updateCounter(value) { + // If the date has changed, reset the counter + if (counter.date != dayString()) { + resetCounter(); + } else { + // Otherwise, update the counter value + updateCounterValue(value); + } + + // Write the updated counter to the file + writeCounterToFile(); + // Update the screen with the new counter value + updateScreen(); +} + +// Function to set a watch on a button to update the counter when pressed +function counterButtonWatch(button, increment) { + setWatch( + () => { + // If the button is for incrementing, or the counter is greater than 0, update the counter + if (increment || counter.count > 0) { + updateCounter( + counter.count + (increment ? getInterval() : -getInterval()) + ); + // Update the screen with the new counter value + updateScreen(); + } + }, + button, + { repeat: true } + ); +} + +// Function to create interval functions +const createIntervalFunctions = function () { + // Array of intervals + const intervals = [50, 100, 200, 10]; + // Current location in the intervals array + let location = 0; + + // Function to get the current interval + const getInterval = function () { + return intervals[location]; + }; + + // Function to rotate the increment + const rotateIncrement = function () { + // Update the location to the next index in the intervals array, wrapping around if necessary + location = (location + 1) % intervals.length; + // Update the screen with the new increment + updateScreen(); + }; + + // Return the getInterval and rotateIncrement functions + return { getInterval, rotateIncrement }; +}; + +// Create the interval functions +const intervalFunctions = createIntervalFunctions(); +const getInterval = intervalFunctions.getInterval; +const rotateIncrement = intervalFunctions.rotateIncrement; + +// Function to update the screen +function updateScreen() { + // Clear the screen area for the counter + g.clearRect(0, 50, 250, BANGLEJS2 ? 130 : 150) + .setBgColor(g.theme.bg) + .setColor(g.theme.fg) + .setFont("Vector", 40) + .setFontAlign(0, 0) + // Draw the counter value + .drawString(Math.floor(counter.count), g.getWidth() / 2, 100) + .setFont("6x8") + // Clear the screen area for the increment + .clearRect(g.getWidth() / 2 - 50, 140, g.getWidth() / 2 + 50, 160) + // Draw the increment value + .drawString("Increment: " + getInterval(), g.getWidth() / 2, 150); + + // If the hardware version is Bangle.js 1, draw the increment and decrement buttons + if (!BANGLEJS2) { + g.drawString("-", 45, 100).drawString("+", 185, 100); + } +} + +// If the hardware version is Bangle.js 2, set up the drag handling and button watch + +let drag; + +if (BANGLEJS2) { + // Set up drag handling + Bangle.on("drag", (e) => { + // If this is the start of a drag, record the initial coordinates + if (!drag) { + drag = { x: e.x, y: e.y }; + return; + } + + // If the button is still being pressed, ignore this event + if (e.b) return; + + // Calculate the change in x and y from the start of the drag + const dx = e.x - drag.x; + const dy = e.y - drag.y; + // Reset the drag start coordinates + drag = null; + + // Determine if the drag is primarily horizontal or vertical + const isHorizontalDrag = Math.abs(dx) > Math.abs(dy) + 10; + const isVerticalDrag = Math.abs(dy) > Math.abs(dx) + 10; + + // If the drag is primarily horizontal, ignore it + if (isHorizontalDrag) { + return; + } + + // If the drag is primarily vertical, update the counter + if (isVerticalDrag) { + // If the drag is downwards and the counter is greater than 0, decrease the counter + if (dy > 0 && counter.count > 0) { + updateCounter(counter.count - getInterval()); + } else if (dy < 0) { + // If the drag is upwards, increase the counter + updateCounter(counter.count + getInterval()); + } + // Update the screen with the new counter value + updateScreen(); + } + }); + + // Set a watch on the button to rotate the increment when pressed + setWatch(rotateIncrement, BTN1, { repeat: true }); +} else { + // If the hardware version is Bangle.js 1, set up the button watches + + // Set watch on button to increase the counter + counterButtonWatch(BTN1, true); + counterButtonWatch(BTN5, true); // screen tap + // Set watch on button to decrease the counter + counterButtonWatch(BTN3, false); + counterButtonWatch(BTN4, false); // screen tap + + // Set a watch on button to rotate the increment when pressed + setWatch( + () => { + rotateIncrement(); + }, + BTN2, + { repeat: true } + ); +} + +// clear the screen +g.clear(); + +// Set the background and foreground colors +g.setBgColor(g.theme.bg).setColor(g.theme.fg); + +// Load and draw the widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +// Read the counter from the file +readCounterFromFile(); +// Update the screen with the counter value +updateScreen(); diff --git a/apps/burn/metadata.json b/apps/burn/metadata.json new file mode 100644 index 000000000..c032058c8 --- /dev/null +++ b/apps/burn/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "burn", + "name": "Burn", + "version": "0.07", + "description": "Simple Calorie Counter -- saves to flash and resets at midnight. I often keep mine running while the digital clock widget is at the top", + "icon": "app-icon.png", + "tags": "tool", + "readme":"README.md", + "supports": ["BANGLEJS", "BANGLEJS2"], + "screenshots": [{"url":"app-screenshot.png"}], + "allow_emulator": true, + "storage": [ + {"name":"burn.app.js","url":"app.js"}, + {"name":"burn.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/fileman/manage_files.html b/apps/fileman/manage_files.html index 8501d468a..30726a869 100644 --- a/apps/fileman/manage_files.html +++ b/apps/fileman/manage_files.html @@ -26,6 +26,25 @@ +
+ +