Notechondria
Version: 0.1.67 Build Date: 2026-04-23T00:00
What's Changed
Bug — note share / deep-link redirect failure
User-reported: opening a #/notes/<uuid> share URL in a fresh tab
didn't always land on the note. Three root causes bundled into one
fix:
-
Regex was over-strict. The fragment pattern in
editor_app/lib/app_shell.dartused^/?notes/<uuid>$— the trailing$anchor rejected any suffix, so#/notes/<uuid>/(trailing slash) and#/notes/<uuid>?ref=share(tracking query) both failed to match. Relaxed to drop the^and$anchors; the UUID shape is still strict enough that it won't false-match on unrelated fragments. -
OAuth callback stripped the fragment.
app_shell_oauth_mixin.dart::handleOAuthCallbackcleaned the URL withuri.removeFragment().replace(queryParameters: {})so a refresh wouldn't re-process the OAuth code. But that also dropped a#/notes/<uuid>that survived the OAuth round-trip — common on "click share link → redirected to login → sign in with Google" flows. Fix: keep the fragment, only clear the query. -
Private-note 403 surfaced as raw exception text.
_openNoteByUuidstuffed the backend's 403 string straight into_errorMessage. Now the editor detectspermission / forbidden / 403with no active session and substitutes a clear "This note is private. Sign in to view it" prompt so a cold share-link open actually tells the user what to do.
Regression test for the full cold-start deep-link path (with and
without session, with and without OAuth callback in the URL) is
tracked in docs/TODO.md — the editor smoke-test harness doesn't
have a web navigator shim yet.
Multi-device session manager — HTTP client methods (3 apps)
-
0.1.65 shipped the backend for multi-session auth
(
creators.Session,MultiSessionAuthentication, the two new endpointsGET /api/v1/auth/sessions/andDELETE /api/v1/auth/sessions/<id>/). 0.1.67 adds the HTTP client glue so the UI work can slot in without more plumbing:- Shared
AuthClientinterface gainslistSessions(token)andrevokeSession(token, sessionId). - All three per-app
HttpNotechondriaClientclasses (editor, planner, portal) implement them against/auth/sessions/and/auth/sessions/<id>/. - Per-app abstract
NotechondriaClientclasses dropped their redundantcheckSession/logoutdecls so the inheritedAuthClientis the single source of truth. (Both were already duplicated there from a pre-share refactor.)
- Shared
- Active Sessions card UI + multi-device warning banner remain deferred in TODO.md — both now unblocked by this round.
Splash — mobile cross-fade gap
-
On narrow (mobile) layouts the prev / active / next metabolite
skeletal formulas all disappeared briefly once per full rotation,
producing a visible blank moment. Root cause: the outer
if (activePos.dx > -30)guard insplash_painter.dart::paintskipped the ENTIRE crossfade block whenever the active cycle node drifted off the left edge — even though the previous and next formulas sit at different positions on the ring.paintFormulaAtalready does its own per-formula off-screen test, so the outer gate was redundant and harmful. Removed. Also dropped the now-deadactivePoslocal.
Files Changed
VERSION— bumped 0.1.66 → 0.1.67.frontend/editor_app/lib/app_shell.dart— relaxed_noteUuidPatternregex (drop^…$anchors).frontend/editor_app/lib/core/auth_flows.dart—_openNoteByUuidnow substitutes a "Sign in to view this note" message on 403/permission errors when there's no active session.frontend/editor_app/lib/core/client.dart— dropped redundantcheckSession/logoutduplicates (inherited from sharedAuthClientnow).frontend/editor_app/lib/core/http_client.dart— newlistSessionsandrevokeSessionimplementations.frontend/planner_app/lib/core/client.dart— dropped duplicate decls; addedlistSessions+revokeSessionimpls.frontend/portal_app/lib/core/client.dart— addedlistSessions+revokeSessionimpls.frontend/notechondria_shared/lib/src/app_shell/auth_client.dart— interface gainslistSessions(token)andrevokeSession(token, sessionId).frontend/notechondria_shared/lib/src/app_shell/app_shell_oauth_mixin.dart—handleOAuthCallbackpreserves the fragment when cleaning the URL after processing the OAuth?code=&state=.frontend/notechondria_shared/lib/src/components/splash_painter.dart— removed the outeractivePos.dx > -30gate and the unusedactivePoslocal.docs/TODO.md— closed the deep-link bug entry (replaced with a regression-test follow-up) and the start-up-animation cross-fade entry; updated the multi-device-session-manager entry to reflect the shipped HTTP methods.