New App: Line Dash - A swipeable analog clock and stats dashboard #4272
Merged
Conversation
added 30 commits
June 27, 2026 12:28
The Vector font's space glyph is a full character wide, which made the gap between day and month look oversized. drawOverlayPill now accepts the big line as two parts drawn with a narrow fixed gap (6px); the RESET? popup keeps using the plain string form. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Vector font advance width includes trailing spacing after the last glyph, so values centered via setFontAlign sat about 2px left of the circle center (vertically they were already exact). Nudge the text right proportionally to the font size; verified against watch screenshots and emulator renders (offset now 0px for 09/14 on the barometer, clock and battery checked visually).
New swipeable screen showing air pressure on a 950-1050 hPa dial in 10 hPa steps, using the Bangle.js 2 pressure sensor. The sensor is only powered while the screen is shown (same pattern as the HRM, without the debounce since the barometer starts cheaply); readings redraw at most every 2 seconds, and a -- placeholder is shown until the first reading arrives. Toggleable via a Show Barometer setting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lay the pressure scale out like the battery fuel gauge (270-450 degrees, full 950-1050 hPa range always visible, labels on every second tick to avoid collisions). Add an optional centerSize gauge option so the four-digit hPa reading renders in the same font size as the two-digit battery value instead of being shrunk. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Revert the enlarged center circle; instead drawNumber accepts an array of two strings rendered as stacked lines, so 1014 shows as 10 over 14 in the standard-size circle. Sub-1000 readings stay on one line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
100 hPa now spread over 300 degrees instead of 180, so small pressure changes move the dial noticeably. Every 10 hPa tick gets a label since the wider spacing leaves room for four-digit values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The dial and its tick labels already give the hundreds, so the center circle only shows the last two digits (leading zero, full font size) with a small hPa label below - reusing drawNumber's label support. This replaces the stacked two-line rendering for four-digit values.
The last-two-digits value now truncates like the steps/distance decimals instead of rounding, so it matches the needle position. Swiping up or down on the barometer screen shows the exact reading (e.g. 1010.6 with an hPa label) in the same pill overlay style as the date on the clock face; the date overlay timeout was generalized into an info overlay shared by both screens.
10 subdivisions per 10 hPa interval instead of 5, matching the tick density of the steps/distance gauges; the 5 hPa mark gets the medium tick automatically.
Staying on the baro screen overnight kept the sensor polling every second and redrawing the gauge every 2s, draining the battery. The barometer now runs continuously only while the screen is shown AND the watch is unlocked; while locked, the once-a-minute redraw takes a single Bangle.getPressure() one-shot reading instead, so the display keeps updating without the standby cost. All power decisions go through one updateBaroPower() helper (screen change, lock/unlock, charging, startup).
New 'Sea level (hPa)' settings entry: the menu takes a one-shot raw reading when opened and the user dials in the value their weather report gives; the stored factor (QNH / raw) corrects altitude and sensor offset in one constant. Applied to every reading, so the dial, circle digits and exact-reading overlay all show sea-level pressure. Default factor 1 keeps the previous behavior.
Vertical swipes on the baro screen now cycle: exact sea-level reading -> altitude -> hidden. The altitude comes from the international barometric formula using the raw pressure and the sea-level value entered at calibration (default 1013.25), so the calibration doubles as the altimeter reference.
The continuous green-to-red gradient produced dithered in-between colors on the 3-bit display at almost every charge level. The dial now shows fixed fuel-gauge zones in native colors instead - green above 30%, yellow warning band down to 15%, red reserve below - and the needle and center circle take the color of the current zone.
Plugging in felt sluggish and briefly showed a locked state: the backlight was raised before the unlock, and the resulting lcdPower and lock events each repainted a screen the charge handler had just drawn (three full redraws instead of one). Unlock now happens before the backlight wake, the lock listener only repaints when the lock state on screen actually changed, and the lcdPower listener skips repainting a screen drawn less than 500ms ago.
Plugging in now only wakes the backlight, and only after the battery dashboard has been drawn, so the light reveals the finished screen. The watch stays locked; the lcdPower listener's freshness check keeps the wake from repainting the screen a second time.
The minute redraw loop could die after plugging in: the lock listener cleared the draw timeout and, since the repaint-skip optimization, did not always redraw (which is what re-armed it). And with the display counted as off, queueDraw/draw stopped entirely - but the transflective screen stays readable on the charger, so the gauge visibly froze. The lock and lcdPower listeners now re-arm the minute tick whenever they skip a repaint, and queueDraw/draw keep running while charging regardless of the LCD state.
Tap no longer advances to the next gauge: it now shows the info overlay of the current dashboard (date on the clock, exact pressure/altitude cycle on the barometer) and drives the trip reset confirmation on the distance screen. Vertical swipes are reserved for navigating sub-views (day/trip on the distance gauge); horizontal swipes keep cycling the dashboards.
Swipe up on the barometer switches to an altimeter dial (marked ALT), swipe down returns to the pressure dial. One full revolution covers 100m with ticks every 10m and subticks every meter; the center circle shows the hundreds of meters. Tap shows the exact altitude as a pill, replacing the old three-step overlay cycle on the pressure dial (each view now has its own single-value overlay). The active sub-view is persisted across app reloads like the trip view.
Put 0 at the 12 o'clock position of the altimeter dial instead of the 7 o'clock position the other gauges start at, so the needle behaves like an aircraft altimeter (25m points right, 50m down). The dial also wraps below zero, showing the end of the 90m segment left of the 0.
The unit on the labels already tells the altimeter apart from the pressure dial, matching how the distance gauge marks its ticks.
New 'Altitude Unit' setting switches the altimeter between meters and feet: same dial, one revolution per 100 units, with 2ft subticks in feet mode since 1ft is below the sensor resolution. The needle now follows an exponentially smoothed altitude so sensor noise (~0.5m) does not make it flutter on the fine dial; after a gap in readings (one-shot polling while locked) the value snaps instead of lagging. The tap overlay keeps showing the exact unsmoothed altitude.
Tap now shows the exact step count on the steps gauge and the exact distance of the current view (day total or trip) on the distance gauge, so every dashboard answers a tap with its precise value. The trip reset moves back to its original gesture (swipe up in the trip view, confirmed by another swipe up) and taps are ignored while the RESET? popup shows; vertical swipes dismiss a visible pill.
bobrippling
reviewed
Jul 15, 2026
bobrippling
left a comment
Collaborator
There was a problem hiding this comment.
Looks great - just one question
added 2 commits
July 15, 2026 18:53
apps.json had an accidentally committed generated copy instead of the upstream placeholder, and jimp (local screenshot tooling) had slipped into package.json/package-lock.json. None of this belongs in the PR.
The previous reset used current upstream, which includes upstream's own js-yaml bump and so still showed up in the PR diff.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR introduces Line Dash, a new clock face based on the beautiful Line Clock by deepDiverPaul. The original minimalist line aesthetic was expanded into a swipeable suite of interactive dashboard gauges.
Features of the new app:
The app is intentionally full-screen and does not display widgets. An attribution to the original author has been placed in the
LICENSEandREADME.mdfiles.