-
-
Just a "Known issues" link (only if there are any) would be nice, so you can quickly click through to see known issues before installing.
I doubt manual tagging of issues would be workable, but maybe there is some nifty way to link to the "create a new issue" page with[app:<appid>]:
pre-filled in the title? I think you can probably create an "app" issue template asking people to put[app:<appid>]:
in the title?I think the problem with download/favourite stats is not so much that they would be abused, but that people will try the most "popular" apps, so when an app gets a few "lucky" downloads it'll cause a self inflating spiral.
I agree that having the newest changelog entry at the top and adding dates makes sense.
-
-
-
If it does look worse, wouldn't it be better to leave it out?
Because otherwise code that tries to do the "right" thing actually makes things worse:if (g.drawLineAA) g.drawLineAA(...) else g.drawLine(...) // for devices without AntiAliasing
And if you end up writing this
if (device_is_B2) g.drawLine(...) // AntiAliasing looks bad on 3-bit screen else g.drawLineAA(...)
You wonder why the Bangle.js 2 even implements AA functions.
I guess you could just make it so
*AA
functions don't actually AntiAlias, so more code will run on both devices seemlessly, but that just seems Wrong... -
As it is a watch, how about having
Bangle
emit time events?Bangle.on('hour', function(time) { // time is a Date object // fires exactly once per hour, with minutes/seconds/milliseconds = 0 }) Bangle.on('minute', function(time) { // time is a Date object // fires exactly once per minute, with seconds/milliseconds = 0 }) Bangle.on('second', function(time) { // time is a Date object // fires exactly once per second, with milliseconds = 0 })
At least for buzzing every hour or redrawing clocks this should be sufficient to get rid of manually setting timeouts/intervals.
No idea if this would have a serious impact on performance/battery life though (especially for the V1, where clocks tend to clear their timeouts when the LCD is off)
-
the issue with a 'core' library is stuff always gets added to it
Good point,
Settings
it is then.enforce
settings.json
so justrequire('Settings').get('app', 'option.to.get', 'default')
might be betterYou're right, I think I mostly avoided it because I couldn't think of a nice way to ask for global settings from
settings.json
(passing in an empty first argument seems error-prone). But we can pass inBangle
(the object) and check for that. (unless that would lead to some issue like huge RAM usage I didn't think of?) -
I was thinking about adding simple
Settings
library, just something like
require('Settings').get('app.settings.json', 'option.to.get', 'default');
and
require('Settings').set('app.settings.json', 'option.to.set', 'value');
Probably wouldn't be much work to implement, but we could get rid of (almost?) all of the defaults-handling boilerplate in apps.
- Does this seem like a good idea, or would it add too much overhead for apps? (I think it would be ok, as they are already loading+parsing a settings file anyway)
- Having a separate library just for two functions feels a bit cluttery, maybe a "Core/Standard/Basic/Bikeshed" library with
getSetting
/setSetting
would be better? (I can't really think of similar functions right now, but going through all apps to change it later would be a shame.)
- Does this seem like a good idea, or would it add too much overhead for apps? (I think it would be ok, as they are already loading+parsing a settings file anyway)
-
-
flashing a zip via the Web IDE? How exactly did you do this
I downloaded a ZIP to my PC, then uploaded it into the browser. I got it to work using F12 by setting a breakpoint in the
stepDownload
function and manually settingdata.binary_url = ''
in the console. (it wasundefined
)I imagine the Layout error you hit was because of the bootloader.
Yeah, it was late and I was tired, so it was probably just me forgetting to upload the bootloader.
messing with Storage while out-of-memory probably somehow managed to erase all storage, no idea if it's reproducible
from what you describe it may be even this case https://github.com/espruino/Espruino/issues/2075
otherwise there is issue https://github.com/espruino/Espruino/issues/2009I doubt it was the watchdog, as the watch didn't reboot by itself.
Basically the watch was showing a "Memory" error, I tried long-pressing BTN3 which gave some error I forgot, and holding BTN1+2 got me stuck at the boot screen.
As for the memory error: I was testing an app which logs all incoming Gadgetbridge messages, and strongly suspect that caused it: it reads the full log into memory every time a new message arrives, and I got a few large ones that day. -
Today was also kind of a long/busy day, but I figured I'd post now while I remember it best:
- I managed to soft-brick my Bangle v1. I strongly suspect it has to to with my "great" idea to log all GB messages, which probably resulted in a combination of out-of-memory errors and
Storage
calls happening at almost the same time. - When I got home, the web IDE didn't list any files left in storage, so I figured I'd reset my watch
- "Install default apps" didn't work, because
https://banglejs.com/apps/defaultapps_banglejs.json
doesn't exist - Manually reinstalled apps, including my beloved
barclock
- Ran into some errors caused by
Layout
(a bit fuzzy what went wrong exactly... probably missing polyfills from me forgetting to install the bootloader.) Tried to update to cutting edge firmware by downloading the zip, ran into an error because of
function stepDownload(data) { if (window && window.location && window.location.protocol=="https:" && data.binary_url.substr(0,5)=="http:") // Uncaught TypeError: Cannot read properties of undefined (reading 'substr') data.binary_url = "https:"+data.binary_url.substr(5); data.flashFn(data); }
managed to flash the cutting edge firmware, still errors
uploading the latest bootloader fixed it (I think I probably forgot to upload it, and just tried to
load()
the clock from the web IDE, getting those errors because it was missing polyfills)
tl;dr:
- messing with
Storage
while out-of-memory probably somehow managed to erase all storage, no idea if it's reproducible - "Install default apps" is broken
- Flashing a local zip file is broken
- I managed to soft-brick my Bangle v1. I strongly suspect it has to to with my "great" idea to log all GB messages, which probably resulted in a combination of out-of-memory errors and
-
just remove qmOptions/etc from settings and instead store it in the Quiet mode app?
That would probably clean up things a bit.
So the idea is:Current situation:
- global
quiet
setting: apps check this so they know whether tobuzz
- global
qmOptions
setting: overrides options like brightness during quiet mode qmsched
app: changesquiet
setting at scheduled times, shows a widget
After moving things to
qmsched
:- keep global
quiet
setting: apps still check this. No longer needs it's own submenu. qmsched
app changesquiet
setting at scheduled times, shows the widgetqmsched
app also handles overriding options like brightness
- global
-
Oh right, that's the reason this stuff is built into all apps: it's the only way to know if it buzzes for an alarm or only for a notification.
We might get away with something likeBangle.forceBuzz()
for alarm apps? Someone might want to definitely disable all vibration though...
SuppressingsetLCDPower
from apps might work, because turning on for interaction is done by the firmware. But then you end up needing a "disable setLCDPower" setting to schedule it :-(I don't use an alarm app, and if a notification arrives I twist my watch to look at it anyway, so just scheduling
vibration = on/off
and removingsetLCDPower
from notifications would be fine with me...(The schedule app also works fine for me: "Off" at 8:30 and "Alarms" at 21:30.)
-
-
-
Maybe it would be an idea to create (yet another...) battery widget, which can (only) be customized before uploading?
Even if you do enable the kitchen sink, it would still save on reading the settings file. -
Something like that would be very nice!
Some thoughts:- Does it have to be a function? Could maybe just be
Bangle.APP
, as we already haveBangle.WIDGETS
? - When would it be allowed to change? I'm thinking only when calling
Bangle.loadWidgets()
. x,y,w,h
looks nice, but if something is called*Rect
I would expectx1,y1,x2,y2
, likeg.fillRect()
.Also:
x,y,w,h
feels neater, but will make apps calculate a lot ofx+w-1
, whereasx2
wouldn't have the off-by-one problems, from the above example:var dim = Bangle.getAppRect(); g.clearRect(dim.x, dim.y, dim.w, dim.h); // wrong g.clearRect(dim.x, dim.y, dim.w, dim.h + dim.y); // also wrong :-( g.clearRect(dim.x, dim.y, dim.x + dim.w - 1, dim.h + dim.y -1 ); // correct // vs g.clearRect(dim.x1, dim.y1, dim.x2, dim.y2);
Same goes for
var app = Bangle.getAppRect(); g.setFontAlign(1, 1); // right,bottom g.drawString('bottom right', app.x+app.w-1, app.y+app.h-1); // vs g.drawString('bottom right', app.x2, app.y2);
- Does it have to be a function? Could maybe just be
-
-
-
-
Add
layout.rerender
- so you setmodified:true
on any item that has changed, and it then automatically updates the layout for those and redraws anything that changed.I guess that sounds ideal, but what if changing some text means the item changes size, so adjacent (non-modified) elements would have to move?
Make it so you specify the layout with the maximum amount of text you expect in any particular field
That might be a bit tricky with Vector fonts, as it depends on the actual characters.
I'd really like to seefitWidth
/fitHeight
being pulled across, maybe even implicit:{type:"txt", font:"10%", label:"Vector:10%, automatic width" }, {type:"txt", width:"120", label:"Vector, fitted to be 120px width" }, {type:"txt", font:"10%", width:"120", label:"Vector:10%, cropped/padded to 120px" },
maybe
.render
should automatically clear the area regardless ofbgCol
Or maybe make
bgCol
default tog.theme.bg
when omitted, and you can set it explicitly tonull
/false
to prevent clearing?Another wishlist item: specify
width
andheight
in percentages (of whole screen).{type:"txt", width:"50%", label:"Vector, fitted to 120px on Bangle.js 1" },
-
Gave it a spin, and it works pretty nice. Definitely a huge improvement over fiddling with pixels by hand.
One minor annoyance I ran into:
The smoothest way to simply update a bunch of labels with minimal flicker seems to be settingfillx: true
andbgCol: g.theme.bg
for every element and then dolayout.update();layout.render()
, but that clutters up the layout object.
(It annoyed me enough that I wrote some code to add those properties afterwards)
But maybe once it's baked into the firmware it will be fast enough that we can just dolayout.clear();layout.update();layout.render()
without too much flicker? -
This looks pretty neat, hopefully I'll have some time to play with it this weekend.
Would it be bloaty to add something like this (untested):
Layout.prototype.setLabel = function(id, label) { var l = this._l; if (l[id].label !== label) { this.clear(id); l[id].label = label; render(id); } }
(or even add it to
txt
/btn
elements, so you could just dolayout.date.setLabel('New label')
)Just because I expect otherwise the
compare-clear-update-render
code will probably show up in pretty much all apps anyway. -
I think the documentation is lagging behind a bit, but the polyfill from the bootloader should clarify some things.
"clock" is not a callback, it is the mode. For "clock" mode it simply loads the launcher when BTN2 is pressed, so there is no need to pass a callback.
Yeah, I've had some error mentioning
appListStr
pop up every now and then.But retrying/refreshing fixed it every time, so I didn't look into it.
(and I usually use my
localhost
loader, and figured that might cause it)