Merge pull request #3285 from Stuff-etc/master

New App: Counter 2 (dual counter), minor improvement for clockcal
master
thyttan 2024-04-04 22:18:04 +02:00 committed by GitHub
commit 9c69827b48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 232 additions and 18 deletions

View File

@ -5,4 +5,5 @@
0.05: Improved colors (connected vs disconnected) 0.05: Improved colors (connected vs disconnected)
0.06: Tell clock widgets to hide. 0.06: Tell clock widgets to hide.
0.07: Convert Yes/No On/Off in settings to checkboxes 0.07: Convert Yes/No On/Off in settings to checkboxes
0.08: Fixed typo in settings.js for DRAGDOWN to make option work 0.08: Fixed typo in settings.js for DRAGDOWN to make option work
0.09: You can now back out of the calendar using the button

View File

@ -7,23 +7,24 @@ I know that it seems redundant because there already **is** a *time&cal*-app, bu
|:--:|:-| |:--:|:-|
|![locked screen](screenshot.png)|locked: triggers only one minimal update/min| |![locked screen](screenshot.png)|locked: triggers only one minimal update/min|
|![unlocked screen](screenshot2.png)|unlocked: smaller clock, but with seconds| |![unlocked screen](screenshot2.png)|unlocked: smaller clock, but with seconds|
|![big calendar](screenshot3.png)|swipe up for big calendar, (up down to scroll, left/right to exit)| |![big calendar](screenshot3.png)|swipe up for big calendar<br>⬆️/⬇️ to scroll<br> ⬅️/➡️ to exit|
## Configurable Features ## Configurable Features
- Number of calendar rows (weeks) - Number of calendar rows (weeks)
- Buzz on connect/disconnect (I know, this should be an extra widget, but for now, it is included) - Buzz on connect/disconnect (feel free to disable and use a widget)
- Clock Mode (24h/12h). (No am/pm indicator) - Clock Mode (24h/12h). (No am/pm indicator)
- First day of the week - First day of the week
- Red Saturday/Sunday - Red Saturday/Sunday
- Swipe/Drag gestures to launch features or apps. - Swipe/Drag gestures to launch features or apps.
## Auto detects your message/music apps: ## Integrated swipe launcher: (Configure in Settings)
- swiping down will search your files for an app with the string "message" in its filename and launch it. (configurable) - ⬇️ (down) will search your files for an app with the string "**message**"
- swiping right will search your files for an app with the string "music" in its filename and launch it. (configurable) - ➡️ (right) will search your files for an app with the string "**music**"
- ⬅️ (left) will search your files for an app with the string "**agenda**"
- ⬆️ (up) will show the **internal full calendar**
## Feedback ## Feedback
The clock works for me in a 24h/MondayFirst/WeekendFree environment but is not well-tested with other settings. If something isn't working, please tell me: https://github.com/Stuff-etc/BangleApps/issues (I moved my github repo)
So if something isn't working, please tell me: https://github.com/foostuff/BangleApps/issues
## Planned features: ## Planned features:
- Internal lightweight music control, because switching apps has a loading time. - Internal lightweight music control, because switching apps has a loading time.

View File

@ -28,11 +28,11 @@ var monthOffset = 0;
* Calendar features * Calendar features
*/ */
function drawFullCalendar(monthOffset) { function drawFullCalendar(monthOffset) {
addMonths = function (_d, _am) { const addMonths = function (_d, _am) {
var ay = 0, m = _d.getMonth(), y = _d.getFullYear(); let ay = 0, m = _d.getMonth(), y = _d.getFullYear();
while ((m + _am) > 11) { ay++; _am -= 12; } while ((m + _am) > 11) { ay++; _am -= 12; }
while ((m + _am) < 0) { ay--; _am += 12; } while ((m + _am) < 0) { ay--; _am += 12; }
n = new Date(_d.getTime()); let n = new Date(_d.getTime());
n.setMonth(m + _am); n.setMonth(m + _am);
n.setFullYear(y + ay); n.setFullYear(y + ay);
return n; return n;
@ -45,7 +45,7 @@ function drawFullCalendar(monthOffset) {
if (typeof dayInterval !== "undefined") clearTimeout(dayInterval); if (typeof dayInterval !== "undefined") clearTimeout(dayInterval);
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval); if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval); if (typeof minuteInterval !== "undefined") clearTimeout(minuteInterval);
d = addMonths(Date(), monthOffset); var d = addMonths(Date(), monthOffset);
tdy = Date().getDate() + "." + Date().getMonth(); tdy = Date().getDate() + "." + Date().getMonth();
newmonth = false; newmonth = false;
c_y = 0; c_y = 0;
@ -124,7 +124,7 @@ function drawMinutes() {
var d = new Date(); var d = new Date();
var hours = s.MODE24 ? d.getHours().toString().padStart(2, ' ') : ((d.getHours() + 24) % 12 || 12).toString().padStart(2, ' '); var hours = s.MODE24 ? d.getHours().toString().padStart(2, ' ') : ((d.getHours() + 24) % 12 || 12).toString().padStart(2, ' ');
var minutes = d.getMinutes().toString().padStart(2, '0'); var minutes = d.getMinutes().toString().padStart(2, '0');
var textColor = NRF.getSecurityStatus().connected ? '#99f' : '#fff'; var textColor = NRF.getSecurityStatus().connected ? '#fff' : '#f00';
var size = 50; var size = 50;
var clock_x = (w - 20) / 2; var clock_x = (w - 20) / 2;
if (dimSeconds) { if (dimSeconds) {
@ -156,7 +156,7 @@ function drawSeconds() {
} }
function drawWatch() { function drawWatch() {
if (DEBUG) console.log("CALENDAR"); if (DEBUG) console.log("DRAWWATCH");
monthOffset = 0; monthOffset = 0;
state = "watch"; state = "watch";
var d = new Date(); var d = new Date();
@ -197,6 +197,7 @@ function drawWatch() {
if (DEBUG) console.log("Next Day:" + (nextday / 3600)); if (DEBUG) console.log("Next Day:" + (nextday / 3600));
if (typeof dayInterval !== "undefined") clearTimeout(dayInterval); if (typeof dayInterval !== "undefined") clearTimeout(dayInterval);
dayInterval = setTimeout(drawWatch, nextday * 1000); dayInterval = setTimeout(drawWatch, nextday * 1000);
if (DEBUG) console.log("ended DRAWWATCH. next refresh in " + nextday + "s");
} }
function BTevent() { function BTevent() {
@ -211,8 +212,11 @@ function action(a) {
g.reset(); g.reset();
if (typeof secondInterval !== "undefined") clearTimeout(secondInterval); if (typeof secondInterval !== "undefined") clearTimeout(secondInterval);
if (DEBUG) console.log("action:" + a); if (DEBUG) console.log("action:" + a);
state = "unknown";
console.log("state -> unknown");
switch (a) { switch (a) {
case "[ignore]": case "[ignore]":
drawWatch();
break; break;
case "[calend.]": case "[calend.]":
drawFullCalendar(); drawFullCalendar();
@ -229,6 +233,12 @@ function action(a) {
load(l[0]); load(l[0]);
} else E.showAlert("Message app not found", "Not found").then(drawWatch); } else E.showAlert("Message app not found", "Not found").then(drawWatch);
break; break;
case "[AI:agenda]":
l = require("Storage").list(RegExp("agenda.*app.js"));
if (l.length > 0) {
load(l[0]);
} else E.showAlert("Agenda app not found", "Not found").then(drawWatch);
break;
default: default:
l = require("Storage").list(RegExp(a + ".app.js")); l = require("Storage").list(RegExp(a + ".app.js"));
if (l.length > 0) { if (l.length > 0) {
@ -276,7 +286,6 @@ function input(dir) {
drawWatch(); drawWatch();
} }
break; break;
} }
} }
@ -309,3 +318,10 @@ NRF.on('disconnect', BTevent);
dimSeconds = Bangle.isLocked(); dimSeconds = Bangle.isLocked();
drawWatch(); drawWatch();
setWatch(function() {
if (state == "watch") {
Bangle.showLauncher()
} else if (state == "calendar") {
drawWatch();
}
}, BTN1, {repeat:true, edge:"falling"});

View File

@ -1,7 +1,7 @@
{ {
"id": "clockcal", "id": "clockcal",
"name": "Clock & Calendar", "name": "Clock & Calendar",
"version": "0.08", "version": "0.09",
"description": "Clock with Calendar", "description": "Clock with Calendar",
"readme":"README.md", "readme":"README.md",
"icon": "app.png", "icon": "app.png",

View File

@ -9,12 +9,12 @@
REDSAT: true, // Use red color for saturday? REDSAT: true, // Use red color for saturday?
DRAGDOWN: "[AI:messg]", DRAGDOWN: "[AI:messg]",
DRAGRIGHT: "[AI:music]", DRAGRIGHT: "[AI:music]",
DRAGLEFT: "[ignore]", DRAGLEFT: "[AI:agenda]",
DRAGUP: "[calend.]" DRAGUP: "[calend.]"
}; };
settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {}); settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {});
actions = ["[ignore]","[calend.]","[AI:music]","[AI:messg]"]; actions = ["[ignore]","[calend.]","[AI:music]","[AI:messg]","[AI:agenda]"];
require("Storage").list(RegExp(".app.js")).forEach(element => actions.push(element.replace(".app.js",""))); require("Storage").list(RegExp(".app.js")).forEach(element => actions.push(element.replace(".app.js","")));
function writeSettings() { function writeSettings() {

2
apps/counter2/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.01: New App!
0.02: Added Settings & readme

24
apps/counter2/README.md Normal file
View File

@ -0,0 +1,24 @@
# Counter2 by Michael
I needed an HP/XP-Tracker for a game, so i made one.
The counter state gets saved. Best to use this with pattern launcher or ClockCal
- Colored Background Mode
- ![color bg](https://stuff-etc.github.io/BangleApps/apps/counter2/counter2-screenshot.png)
- Colored Text Mode
- ![color text](https://stuff-etc.github.io/BangleApps/apps/counter2/counter2dark-screenshot.png)
## Howto
- Tap top side or swipe up to increase counter
- Tap bottom side or swipe down to decrease counter
- Hold (600ms) to reset to default value (configurable)
- Press button to exit
## Configurable Features
- Default value Counter 1
- Default value Counter 2
- Buzz on interact
- Colored Text/Background
## Feedback
If something isn't working, please tell me: https://github.com/Stuff-etc/BangleApps/issues

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwcAyVJkgCFAwwCBAgd5CI+eCI2T/IRH/wR7n//AAPyCIdPBAX8CKpr/CLTpSCOipB8gRFXoPJCIknCJAIBOoYRCagLNCa4f8Q4gREI4tP8mT/41HCKJHFGoQRG+QKBLI4RHLIx9CCJ7zBGpxZCPoyhQYpIIBYor7kCP4R8YoX/WY69DAIM/BAT+BdIYICeYQRTGqKP/CNIA=="))

96
apps/counter2/app.js Normal file
View File

@ -0,0 +1,96 @@
Bangle.loadWidgets();
var s = Object.assign({
counter0:10,
counter1:20,
max0:15,
max1:25,
buzz: true,
colortext: true,
}, require('Storage').readJSON("counter2.json", true) || {});
f1 = (s.colortext) ? "#f00" : "#fff";
f2 = (s.colortext) ? "#00f" : "#fff";
b1 = (s.colortext) ? g.theme.bg : "#f00";
b2 = (s.colortext) ? g.theme.bg : "#00f";
var counter = 0;
var drag;
screenwidth = g.getWidth();
screenheight = g.getHeight();
halfwidth = screenwidth / 2;
halfheight = screenheight / 2;
counter = [];
counter[0] = s.counter0;
counter[1] = s.counter1;
defaults = [];
defaults[0] = s.max0;
defaults[1] = s.max1;
function saveSettings() {
s.counter0 = counter[0];
s.counter1 = counter[1];
s.max0 = defaults[0];
s.max1 = defaults[1];
require('Storage').writeJSON("counter2.json", s);
}
ignoreonce = false;
var dragtimeout;
function updateScreen() {
g.setBgColor(b1);
g.clearRect(0, 0, halfwidth, screenheight);
g.setBgColor(b2);
g.clearRect(halfwidth, 0, screenwidth, screenheight);
g.setFont("Vector", 60).setFontAlign(0, 0);
g.setColor(f1);
g.drawString(Math.floor(counter[0]), halfwidth * 0.5, halfheight);
g.setColor(f2);
g.drawString(Math.floor(counter[1]), halfwidth * 1.5, halfheight);
saveSettings();
if (s.buzz) Bangle.buzz(50,.5);
Bangle.drawWidgets();
}
Bangle.on("drag", e => {
c = (e.x < halfwidth) ? 0 : 1;
if (!drag) {
if (ignoreonce) {
ignoreonce = false;
return;
}
drag = { x: e.x, y: e.y };
dragtimeout = setTimeout(function () { resetcounter(c); }, 600); //if dragging for 500ms, reset counter
}
else if (drag && !e.b) { // released
adjust = 0;
const dx = e.x - drag.x, dy = e.y - drag.y;
if (Math.abs(dy) > Math.abs(dx) + 30) {
adjust = (dy > 0) ? -1 : 1;
} else {
adjust = (e.y > halfwidth) ? -1 : 1;
}
counter[c] += adjust;
updateScreen();
drag = undefined;
clearTimeout(dragtimeout);
}
});
function resetcounter(which) {
counter[which] = defaults[which];
console.log("resetting counter ", which);
updateScreen();
drag = undefined;
ignoreonce = true;
}
updateScreen();
setWatch(function() {
load();
}, BTN1, {repeat:true, edge:"falling"});

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,18 @@
{
"id": "counter2",
"name": "Counter2",
"version": "0.02",
"description": "Dual Counter",
"readme":"README.md",
"icon": "counter2-icon.png",
"tags": "tool",
"supports": ["BANGLEJS2"],
"screenshots": [{"url":"counter2-screenshot.png"},{"url":"counter2dark-screenshot.png"}],
"allow_emulator": true,
"storage": [
{"name":"counter2.app.js","url":"app.js"},
{"name":"counter2.settings.js","url":"settings.js"},
{"name":"counter2.img","url":"app-icon.js","evaluate":true}
],
"data": [{"name":"counter2.json"}]
}

55
apps/counter2/settings.js Normal file
View File

@ -0,0 +1,55 @@
(function (back) {
var FILE = "counter2.json";
defaults={
counter0:12,
counter1:0,
max0:12,
max1:0,
buzz: true,
colortext: true,
};
settings = Object.assign(defaults, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
menu = {
"": { "title": "Counter2" },
"< Back": () => back(),
'Default C1': {
value: settings[0],
min: -99, max: 99,
onchange: v => {
settings.max0 = v;
writeSettings();
}
},
'Default C2': {
value: settings[2],
min: -99, max: 99,
onchange: v => {
settings.max1 = v;
writeSettings();
}
},
'Color': {
value: settings.colortext,
format: v => v?"Text":"Backg",
onchange: v => {
settings.colortext = v;
console.log("Color",v);
writeSettings();
}
},
'Vibrate': {
value: settings.buzz,
onchange: v => {
settings.buzz = v;
writeSettings();
}
}
};
// Show the menu
E.showMenu(menu);
});