|
@ -0,0 +1,3 @@
|
|||
0.1: (2024-02-23) initial alpha upload
|
||||
0.2: (2024-02-23) fixed minor issues with settings
|
||||
0.3: (2024-03-01) advanced settings, rearanged ui elements, fixed rendering problems
|
|
@ -0,0 +1,74 @@
|
|||
# Regatta Timer 5-4-1 countdown
|
||||
|
||||
## Modes
|
||||
|
||||
* **Idle**
|
||||
On startup the application is in idle mode showing a large 5 in the centre of the screen and the time of day below.
|
||||
`Button` switches to start mode.
|
||||
* **Start**
|
||||
During the countdown, the screen changes the layout several times to use as much space as
|
||||
possible to display the numbers.
|
||||
When time is up the buzzer sounds and the application switches to race mode.
|
||||
`Button` switches to idle mode.
|
||||
* **Race**
|
||||
Race time, local time, SOA, number reachable GPS satellites and battery level are shown.
|
||||
`Button` switches to "stopped mode".
|
||||
* **Stoped**
|
||||
The race counter stops.
|
||||
`Button` switches to idle mode.
|
||||
|
||||
## Screenshots
|
||||
|
||||
*Idle mode: showing a big 5 and time of day below*
|
||||
|
||||

|
||||
|
||||
*Start mode: minutes and seconds*
|
||||
|
||||

|
||||
|
||||
*Start mode: seconds*
|
||||
|
||||

|
||||
|
||||
*Race mode: elapsed time, time of day, speed, satellites, battery*
|
||||
|
||||

|
||||
|
||||
*Race mode: with german abbreviations*
|
||||
|
||||

|
||||
|
||||
*Settings page: main*
|
||||
|
||||

|
||||
|
||||
*Settings page: choose the theme*
|
||||
|
||||

|
||||
|
||||
## Localization
|
||||
|
||||
Localization is done by the Bangle.js 2 app "Languages"
|
||||
* Go to [banglejs.com/apps](https://banglejs.com/apps/)
|
||||
* Search for app "Languages"
|
||||
* Click the "arrow up" or "burger" icon
|
||||
* Choose your language from the dropdown
|
||||
* Click `upload`
|
||||
|
||||
**Some nautical abbreviations which are not part of the Bangle.js 2 app "Languages" app are stored in `translations.json`.**
|
||||
|
||||
## Feedback
|
||||
|
||||
Report bugs or request a feature at [github.com/naden](https://github.com/naden)
|
||||
|
||||
## Roadmap
|
||||
* add a seconds coundown layout; mimic a classic regatta chronograph
|
||||
* add recording of gps course and race time
|
||||
* add icons for light mode
|
||||
* add flag icons
|
||||
|
||||
## Created by
|
||||
© 2021 - 2024 [naden.de](https://naden.de)
|
||||
|
||||
Icons by [Icons8](https://icons8.com/)
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4f/8H/A4NgtfgzkgoVg50g40Awg5lnmSpMk4ARMkMkCQNgCJkJCKM////0AQLgNJkBZP5OACB0B5OKjJqNgGJLINOEZprDCJ0rmVJoARMzfAg1JLh8AQCIRNGQPghg1NhQgBghZOhMmoR9ClmSqDXJR4NLAwMhknQEhEsCINwboQRKgG59RuDCJYADLgIRPqVnCJ9CuYROgOSwYjPyUDCJ0IzwRP4mQCIsRlARH8mZWYPJbgK/BCJOSR4OTCIMGCJ8MAoIRIi3btUk3UACJYABLIcapMJCJxZLCKbMFCP4R/COQAo"))
|
After Width: | Height: | Size: 980 B |
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"id": "regattatimer",
|
||||
"name": "Regatta Timer",
|
||||
"shortName": "RegattaTimer",
|
||||
"version": "0.3",
|
||||
"description": "Regatta Timer with 5-4-1 Countdown",
|
||||
"icon": "icon.png",
|
||||
"tags": "tool,outdoors,sailing,race,regatta,boat,timer",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name": "regattatimer.app.js", "url": "app.js"},
|
||||
{"name": "regattatimer.settings.js", "url": "settings.js"},
|
||||
{"name": "regattatimer.img", "url": "app-icon.js", "evaluate": true}
|
||||
],
|
||||
"data": [{"name": "regattatimer.json"}],
|
||||
"screenshots": [{"url": "screenshot.png"},{"url": "screenshot-1.png"},{"url": "screenshot-2.png"},{"url": "screenshot-3.png"},{"url": "screenshot-4.png"},{"url": "screenshot-5.png"},{"url": "screenshot-6.png"},{"url": "screenshot-7.png"}]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"debug": false,
|
||||
"buzzer": true,
|
||||
"dial": "Numeric",
|
||||
"gps": true,
|
||||
"record": false,
|
||||
"theme": "Dark"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"de": {
|
||||
"speed": "FüG",
|
||||
"speed_unit": "kn"
|
||||
},
|
||||
"en": {
|
||||
"speed": "SOA",
|
||||
"speed_unit": "kn"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,78 @@
|
|||
(function(back) {
|
||||
var
|
||||
file = "regattatimer.json",
|
||||
|
||||
storage = require("Storage"),
|
||||
|
||||
dials = ["Numeric", "Discs"],
|
||||
|
||||
themes = ["Light", "Dark"],
|
||||
|
||||
settings = Object.assign({
|
||||
"debug": false,
|
||||
"buzzer": true,
|
||||
"dial": "Numeric",
|
||||
"gps": true,
|
||||
"record": false,
|
||||
"theme": "Dark",
|
||||
}, storage.readJSON(file, true) || {});
|
||||
|
||||
function save(key, value) {
|
||||
settings[key] = value;
|
||||
storage.writeJSON(file, settings);
|
||||
}
|
||||
|
||||
E.showMenu({
|
||||
"" : { "title" : "Regatta Timer" },
|
||||
"< Back" : () => back(),
|
||||
"GPS": {
|
||||
value: !!settings.gps, // !! converts undefined to false
|
||||
onchange: v => {
|
||||
save("gps", v);
|
||||
}
|
||||
},
|
||||
"THEME": {
|
||||
value: themes.indexOf(settings.theme),
|
||||
min: 0,
|
||||
max: themes.length - 1,
|
||||
step: 1,
|
||||
wrap: true,
|
||||
format: v => themes[v],
|
||||
onchange: (d) => {
|
||||
save("theme", themes[d]);
|
||||
}
|
||||
},
|
||||
"BUZZER": {
|
||||
value: !!settings.buzzer, // !! converts undefined to false
|
||||
onchange: v => {
|
||||
save("buzzer", v);
|
||||
}
|
||||
},
|
||||
/*
|
||||
"DIAL": {
|
||||
value: dials.indexOf(settings.dial),
|
||||
min: 0,
|
||||
max: dials.length - 1,
|
||||
step: 1,
|
||||
wrap: true,
|
||||
format: v => dials[v],
|
||||
onchange: (d) => {
|
||||
save("dial", dials[d]);
|
||||
}
|
||||
},
|
||||
"RECORD": {
|
||||
value: !!settings.record, // 0| converts undefined to 0
|
||||
onchange: v => {
|
||||
settings.record = v;
|
||||
save("record", v);
|
||||
}
|
||||
},
|
||||
*/
|
||||
"DEBUG": {
|
||||
value: !!settings.debug, // 0| converts undefined to 0
|
||||
onchange: v => {
|
||||
save("debug", v);
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|