Skip to content

Commit 3c60ceb

Browse files
Merge pull request #265 from TheAngryRaven/BETA
v2.9.0 - rebrand and native app prep
2 parents 1267441 + e00c53a commit 3c60ceb

132 files changed

Lines changed: 3870 additions & 648 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Deploy beta-proxy
2+
3+
# beta-proxy/ is the reverse-proxy Worker that serves beta.lapwingdata.com (it
4+
# forwards to the lapwing `beta` branch preview). It is a SEPARATE Worker from
5+
# the main app — Cloudflare's connected-repo CI builds the app but nothing
6+
# deploys this proxy. This workflow does:
7+
# • validate it on PRs that touch it (dry-run, no secrets — runs on forks too)
8+
# • deploy it on BETA pushes that change it, or on demand (workflow_dispatch)
9+
#
10+
# Required repo secrets for the deploy job:
11+
# • CLOUDFLARE_API_TOKEN — token with "Edit Cloudflare Workers" on the account
12+
# • CLOUDFLARE_ACCOUNT_ID — the account that owns the lapwingdata.com zone
13+
14+
on:
15+
push:
16+
branches: [BETA]
17+
paths:
18+
- "beta-proxy/**"
19+
- ".github/workflows/deploy-beta-proxy.yml"
20+
pull_request:
21+
paths:
22+
- "beta-proxy/**"
23+
- ".github/workflows/deploy-beta-proxy.yml"
24+
workflow_dispatch:
25+
26+
permissions:
27+
contents: read
28+
29+
# Pin the wrangler version used to both validate and deploy so runs are
30+
# reproducible (beta-proxy has no committed lockfile).
31+
env:
32+
WRANGLER_VERSION: "4.103.0"
33+
34+
# Never let two deploys of the same ref overlap; queue rather than cancel so an
35+
# in-flight deploy always finishes.
36+
concurrency:
37+
group: deploy-beta-proxy-${{ github.ref }}
38+
cancel-in-progress: false
39+
40+
jobs:
41+
# Bundle + config check for PRs. Needs no Cloudflare secrets, so it catches a
42+
# broken wrangler.toml before it can reach BETA (and works for fork PRs).
43+
validate:
44+
if: github.event_name == 'pull_request'
45+
name: Dry-run
46+
runs-on: ubuntu-latest
47+
defaults:
48+
run:
49+
working-directory: beta-proxy
50+
steps:
51+
- uses: actions/checkout@v4
52+
- run: npx --yes wrangler@${{ env.WRANGLER_VERSION }} deploy --dry-run --config ./wrangler.toml
53+
54+
deploy:
55+
if: github.event_name != 'pull_request'
56+
name: Deploy Worker
57+
runs-on: ubuntu-latest
58+
steps:
59+
- uses: actions/checkout@v4
60+
- uses: cloudflare/wrangler-action@v3
61+
with:
62+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
63+
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
64+
workingDirectory: beta-proxy
65+
wranglerVersion: ${{ env.WRANGLER_VERSION }}
66+
command: deploy --config ./wrangler.toml

.lovable/plan.md

Lines changed: 0 additions & 78 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,131 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
> from git history and grouped by theme rather than exhaustive per-commit
1212
> detail.
1313
14+
## [2.9.0] - 2026-06-22
15+
16+
### Added
17+
- **Password strength rules + a realtime checker on sign-up.** The registration
18+
form now enforces stronger passwords (at least 8 characters, with a lowercase
19+
letter, an uppercase letter, a number, and a symbol) and shows a live strength
20+
meter with a per-rule checklist that updates as you type. The check is fully
21+
offline (`lib/passwordStrength.ts`).
22+
- **"Update available" check that doesn't rely on the service worker.** The app
23+
now also compares the running build against a build-emitted `version.json`
24+
fetched fresh from the server, so a stale tab reliably surfaces the "Update
25+
ready" prompt even when the service worker's own update detection stalls behind
26+
HTTP/CDN caching. The Refresh button hard-reboots onto the new build.
27+
- **Separate cloud + local storage bars in the profile.** When signed in, the
28+
profile now shows two storage meters — one for cloud quota and one for on-device
29+
(local) storage — instead of just the cloud one. The local bar carries an (i)
30+
bubble explaining that the device's real free space isn't visible to the app, so
31+
the bar is marked against an arbitrary 10 GB and can be safely ignored (local
32+
storage has no limit).
33+
- **Generic logger-connection layer.** Downloads now go through one
34+
`LoggerConnection` interface (`listLogs` / `downloadLog` / `disconnect`) in
35+
`src/lib/loggers/`, with `createFledglingConnection()` adapting the Web Bluetooth
36+
transport. This is the seam future loggers plug into — MyChron over the native
37+
(Tauri) shell, Alfano over BLE — without the download UI having to branch on
38+
transport. `DeviceContext` now tracks the connected `loggerKind`.
39+
- **Logger picker.** "Download from logger" now opens an image-based chooser of
40+
supported loggers instead of jumping straight to Bluetooth: **PerchWerks
41+
Fledgling** (DIY, Bluetooth), **AiM MyChron 5 / 5S / 2T** (Wi-Fi, native app
42+
required), and **Alfano 6 / 7** (Bluetooth, coming soon). The Fledgling runs the
43+
existing Bluetooth download flow; MyChron and Alfano open explanatory dialogs for
44+
now (MyChron's copy differs between the native app and the web). Placeholder
45+
artwork lives in `public/loggers/` for easy swap-out. New `logger` i18n namespace.
46+
- **Download from a MyChron over Wi-Fi (native app).** In the native (Tauri) app,
47+
the MyChron tile in the logger picker now runs a real download: it connects to the
48+
logger over Wi-Fi (on Android it prompts you to pick the MyChron in the system
49+
Wi-Fi dialog), lists the sessions on the device, and downloads + opens the one you
50+
choose — mirroring the existing Bluetooth flow. The web app is unchanged (browsers
51+
can't reach the logger's Wi-Fi) and still shows the explanatory dialog. Built on a
52+
new `createMychronConnection()` adapter behind the existing `LoggerConnection`
53+
interface; the native Tauri IPC (`@tauri-apps/api`) is lazy-loaded so it never
54+
enters the web bundle. A native-only **Settings → MyChron** field lets you set the
55+
Wi-Fi name prefix the system picker filters on, in case your logger broadcasts a
56+
different name.
57+
- **Safe-area padding on native / installed PWA.** Every full-screen surface now
58+
respects the device's safe-area insets (status bar / notch) via
59+
`env(safe-area-inset-*)` and `viewport-fit=cover`, so chrome no longer sits under
60+
the phone's status bar — the app shell + landing, the full-page routes
61+
(login/register/admin/legal), and the file-manager drawer (its garage/profile/
62+
device header). A no-op on browsers and desktops without a safe area.
63+
- **Privacy / Terms links on the sign-in page.** The login screen now links to the
64+
Privacy Policy and Terms of Service.
65+
- **"Back to app" returns you where you were.** The back button on the Privacy and
66+
Terms pages now steps back to the page you came from (e.g. the sign-in or register
67+
screen) instead of always jumping to the home screen.
68+
69+
### Changed
70+
- **Picker/landing polish.** Logger names shortened to "AiM MyChron 5+" and
71+
"Alfano 6+" (single-line, and future-proof for newer models); the account-
72+
deletion page picked up the shared sticky brand header; and the landing
73+
"Telemetry Data Viewer" tagline was removed for now.
74+
- **Open-source links moved into About.** The GitHub repository links left the
75+
landing page and now live in the About dialog under "Free & Open Source", above
76+
the feature list. The About feature list was also refreshed with the headline
77+
additions from the last month (7 languages, native Android app + MyChron Wi-Fi
78+
download, phone-as-logger GPS timing, optional cloud sync, AI driving coach).
79+
- **Logger picker polish.** Real product photos replace the placeholder art, and
80+
the picker is now mobile-friendly: compact horizontal cards on phones (instead of
81+
full-height ones that filled the screen), a height cap so it scrolls within the
82+
viewport, native safe-area padding, an explicit Close button on mobile, and a
83+
trademark/ownership note for the MyChron and Alfano brands.
84+
- **Sticky headers across the landing and auth/legal pages.** The landing banner
85+
is now pinned to the top of the screen, so the Login button is always reachable
86+
and content scrolls cleanly under the status bar on mobile. The login, register,
87+
privacy, and terms pages share one sticky, clickable brand header (`BrandHeader`)
88+
that returns you home — and the privacy/terms pages now carry the mobile
89+
safe-area padding the rest of the app has.
90+
- **Native build hides paid-plan UI.** On the native app (where paid plans aren't
91+
sold per Google Play policy), the registration page no longer shows the pricing
92+
cards at all — just the free sign-up form. (Profile billing buttons were already
93+
hidden on native.)
94+
- **"Download from logger" relabel.** The file-manager button previously labelled
95+
"Download from DovesDataLogger" is now "Download from logger" and opens the new
96+
logger picker.
97+
- **Logger picker is now eager.** The picker menu was split out of the lazy
98+
Bluetooth chunk into a lightweight host (`LoggerDownload`), so the home-screen
99+
"Download from logger" button opens the menu instantly instead of waiting on (and
100+
silently failing when) the BLE chunk stalls. The heavy BLE flow still loads lazily
101+
— only once the Fledgling is picked.
102+
- **Device tab is Fledgling-gated.** The drawer's Device tab (settings / tracks /
103+
firmware) now shows a "Fledgling only" notice when the connected logger isn't a
104+
Fledgling, groundwork for MyChron/Alfano connections that don't expose those
105+
surfaces.
106+
- **Landing page upload is now a 50/50 split.** The big drag-and-drop dropzone now
107+
shares the top of the home screen with an equal-billing "Download from logger"
108+
panel, since most users pull logs straight off a logger rather than dragging files
109+
in. The separate "Download from logger" tile was removed (its action moved into the
110+
split).
111+
- **Landing footer / link cleanup.** Privacy Policy and Terms of Service moved out of
112+
the mid-page link row: on the stable build they now flank the operated-by / version
113+
block in the footer (Privacy left, Terms right). Credits moved up next to the
114+
Browser Compatibility button.
115+
- **Leaner native landing page.** On the native (Android/Tauri) shell the landing
116+
page now hides the marketing hero, the feature roadmap, the GitHub repo links and
117+
the sponsor button — the user has already installed the app. The "Build your own
118+
logger" tile stays.
119+
- **Header logo returns to the home screen.** Tapping the LapWing logo (top-left)
120+
in an open session now closes the session and returns to the landing page.
121+
- **Purple theme + new logo.** The brand accent moved from teal to **purple**
122+
(`--primary` and its mirrors `--ring`/`--sidebar-primary`/`--sidebar-ring`, in
123+
both light and dark), and the gauge glyph in the app/page headers is replaced
124+
with the new **LapWing logo** (`web-logo.png`, via a shared `BrandLogo`
125+
component). Pairs with the refreshed app icons and favicon. Data-viz colors
126+
(speed/telemetry scales) are unchanged.
127+
128+
### Fixed
129+
- **External links opened inside the native app.** Links like "Build your own
130+
logger" now reliably open in the system browser on the native (Tauri) app
131+
instead of navigating the in-app WebView, by routing through Tauri's opener
132+
plugin when the shell hasn't wired the `__HTT_NATIVE__` bridge (`platform.ts`).
133+
- **Login rate limiter locked out valid sign-ins.** The limiter counted *every*
134+
sign-in attempt — successes included — as a failure on a pre-login check, so
135+
after five tries an IP was locked for an hour even with the correct password.
136+
It now only counts genuine failures, clears the counter on a successful login,
137+
and ages failures out over a 15-minute sliding window.
138+
14139
## [2.8.0] - 2026-06-20
15140

16141
### Added

0 commit comments

Comments
 (0)