Commit Graph

700 Commits

Author SHA1 Message Date
Julien Calixte
0b3411626c feat(utils): add uniqueFilename helper with -2 collision suffix 2026-05-25 21:17:42 +02:00
Julien Calixte
01bb4b8c70 refactor(github): extract putRaw and add uploadBinaryFile 2026-05-25 21:17:38 +02:00
Julien Calixte
8a8509a0f3 feat(notes): surface GitHub auth-expired state on freshness badge
Show a cloud-lock badge with a re-sign-in tooltip when the freshness
check resolves to unauthorized, and toast on badge click so the user
gets explicit feedback instead of a silent retry-loop.
2026-05-17 21:10:26 +02:00
Julien Calixte
151a4d9137 fix(github): auto-retry GitHub calls on 401 and expose unauthorized state
fetchLatestSha and queryFileContent were silently catching every error
(including expired-token 401s) and returning null, so the freshness
badge could stay on "offline" with no UI hint that re-auth was needed.
Wrap both calls in runWithAuthRetry to recover from refreshable tokens
transparently, and switch fetchLatestSha to a tagged result so the
freshness hook can distinguish auth failure from network failure.
2026-05-17 21:10:20 +02:00
Julien Calixte
c412c75cfd feat(auth): add force option and runWithAuthRetry helper
GitHub refresh tokens are single-use, so concurrent refreshes race and
the loser ends up with a revoked token — dedupe in-flight calls.
2026-05-17 21:10:13 +02:00
Julien Calixte
e39ac32e43 feat(public-notes): place user pill in header instead of tabs row
Moves the user identity element out of the tabs bar (where it was
absolutely positioned over the tabs) into a proper header row next to
the home button, and switches it from SignInAtproto to the shared
UserPill so the same atproto-first identity shows everywhere.
2026-05-17 14:15:22 +02:00
Julien Calixte
a7ea2ce9cf refactor(profile): adopt UserPill and ProfileModal in home and repos
Replaces the duplicated profile-chip button and profile_modal dialog in
WelcomeWorld and RepoList with the shared components, and removes the
now-orphaned profile-chip, hw-modal, hw-ms-label, hw-btn-ghost, and
hw-rule styles. As a side effect the displayed identity now prefers the
ATProto handle over the GitHub username.
2026-05-17 14:15:18 +02:00
Julien Calixte
1bf09a6629 feat(profile): add shared UserPill and ProfileModal components
UserPill renders an avatar + display name button, preferring the ATProto
handle over the GitHub username, and emits @click so each view decides
what to open. ProfileModal extracts the previously duplicated
profile_modal dialog with self-contained DaisyUI-token styling.
2026-05-17 14:15:13 +02:00
Julien Calixte
7a2ccc1bd1 fix(github): silence contents endpoint deprecation warnings
Use RFC 6570 reserved expansion ({+path}) so slashes stay literal in
the request URL, and pin the contents call to API version 2026-03-10
to clear the Sunset: 2028-03-10 header on the deprecated 2022-11-28
version. The only breaking change in 2026-03-10 (submodule type in
directory listings) doesn't affect us — fetchLatestSha is per-file
and the array branch already short-circuits.
2026-05-17 00:34:03 +02:00
Julien Calixte
e11609990d fix(repo): derive starred list from saved favorites
Starred section used to intersect favorites with the paginated GitHub
repo list, so favorites past the first page only appeared after the user
scrolled. Derive RepoBase directly from PouchDB favorites and exclude
them from "all repos" by both id and name.
2026-05-17 00:24:47 +02:00
Julien Calixte
e121cc2d05 fix(repo): dedupe favorite repos by name
Stale FavoriteRepo docs with old GitHub IDs (e.g. from deleted or
recreated repos) surfaced as duplicates once the prefix scan started
returning every doc.
2026-05-17 00:24:43 +02:00
Julien Calixte
f9e1495fc3 fix(repo): load all favorites without filtering by loaded repos
Previously favorites were only fetched for repos already loaded via
useRepos, hiding favorites whose repo metadata hadn't been resolved
yet.
2026-05-17 00:17:34 +02:00
Julien Calixte
eeca9d071f chore(analytics): point openpanel to stats apoena endpoint 2026-05-17 00:17:31 +02:00
Julien Calixte
e5dcdac65a feat(offline): record structured failures during note caching
Expose a failures list alongside the existing failedNotes counter so each
failure carries kind/path/sha/message. Also catches throws from
buildNoteDocs and bulkUpdate that previously aborted the whole loop.
2026-05-17 00:07:20 +02:00
Julien Calixte
2994839ee5 feat(offline): track structured failure details during caching
Replace the failure counter with a list of typed failures (fetch,
build, save, readme, unknown) carrying path, sha, message, and
affected doc ids so callers can surface diagnostics instead of just
a count.
2026-05-17 00:07:13 +02:00
Julien Calixte
dd576ced90 style(repo): strip border and shadow from brand mark in nav 2026-05-17 00:07:09 +02:00
Julien Calixte
0a2445a06d fix(repo): paginate repo list alphabetically server-side
Switch from /search/repositories (best-match order) to /user/repos
with sort=full_name so infinite scroll appends in A–Z order instead
of injecting new pages into earlier letters.
2026-05-16 23:59:04 +02:00
Julien Calixte
f3ed5e063f perf(offline): parallelise note caching with batched writes
Fetch blobs with a concurrency of 8 instead of one at a time, batch
PouchDB writes via bulkUpdate, filter already-cached files up front,
and run the README fetch in parallel with the worker loop.
2026-05-16 23:48:06 +02:00
Julien Calixte
2002ac670a feat(data): expose bulkUpdate on PouchDB wrapper
Wraps PouchDB.bulkDocs so callers can flush many docs in one worker
round trip, avoiding the read-before-write that data.update does per
document.
2026-05-16 23:47:59 +02:00
Julien Calixte
0ad747b69f fix(offline): pre-cache home README under its synthetic key
The home page reads README via getCachedMainReadme, which uses
Note-{owner}-{repo}-README, not the blob SHA. Cache-all only wrote
SHA-keyed entries, so the homepage README was empty offline.
2026-05-16 23:31:58 +02:00
Julien Calixte
c5236b2587 fix(offline): don't abort cache loop on a single fetch failure
A single null from queryFileContent silently exited cacheAllNotes,
leaving every later note uncached while the success toast still fired.
Skip the failing file, count failures, and surface them via errorMessage.
2026-05-16 23:31:42 +02:00
Julien Calixte
fc4ed188d7 feat(repo): add Octokit request timeouts and retry UI
Before, every GitHub call awaited indefinitely with no AbortSignal,
so a "lie-fi" connection (technically online, effectively dead) left
FluxNote stuck on the skeleton loader and the freshness badge spinning
forever. Inject an 8s AbortSignal.timeout via octokit.hook.before
(20s override on the recursive tree fetch), classify failures in the
userRepo store as auth vs network, and surface a "Couldn't reach
GitHub" retry button when no cached content is available.
2026-05-16 23:28:11 +02:00
Julien Calixte
de7ac8d096 fix(freshness): hold checking state for 400ms minimum
Cached GitHub responses resolved so fast that the spinner state was
overwritten before Vue could render it, so clicking the badge from
"Not checked" looked like nothing happened.
2026-05-16 18:38:59 +02:00
Julien Calixte
0ef339d42e fix(markdown): scope SVG download buttons to rendered diagrams
Only target SVGs inside .tikz / .mermaid containers so action-bar
icons (edit, save, freshness badge) no longer get download buttons.
2026-05-16 12:57:16 +02:00
Julien Calixte
0e70d808ce fix(markdown): raise PNG export scale to 3× 2026-05-16 12:31:18 +02:00
Julien Calixte
952417621e fix(markdown): embed used @font-face rules in exported SVGs
The exported SVG carries font-family="cmr7"/"cmsy7"/… attributes but
no @font-face, so standalone viewers fall back to system fonts. That
scatters TikZ glyphs (precomputed x positions assume Computer Modern
metrics) and turns cmsy7 minus signs into ¡ (custom symbol encoding).
Inline only the rules for font-families the SVG actually uses, and
await document.fonts.ready before rasterizing to PNG.
2026-05-16 12:29:10 +02:00
Julien Calixte
9d1b6552cb feat(markdown): add hover download buttons on rendered SVGs
Attach SVG and PNG (×2) download buttons to every rendered SVG (TikZ,
Mermaid, …) once post-render finishes. Exports always use the original
colors with a white background baked in, regardless of theme.
2026-05-16 12:17:04 +02:00
Julien Calixte
f3708b2f9d fix(markdown): invert TikZ SVGs on dark themes for readability 2026-05-16 11:47:31 +02:00
Julien Calixte
572a05962c fix(markdown): load TikZ font stylesheet to keep text aligned
The obsidian-tikzjax bundle emits SVG referencing Computer Modern font
families like cmbx7 but ships the @font-face declarations in a separate
styles.css. Without it the browser substitutes a default font whose
glyph widths don't match TeX's, leaving visible gaps between each
kerned text run. Lazy-load the stylesheet alongside the engine on
first TikZ render so cache hits and misses both see correct fonts.
2026-05-15 16:25:55 +02:00
Julien Calixte
33285d723a refactor(markdown): extract post-render effects into composable
Four components duplicated the watch -> nextTick -> listenToClick -> runTikz
shape. Collapse to useMarkdownPostRender, which also accepts optional flags
for Mermaid, Shikiji and image hydration so StackedNote no longer needs its
own inline conditional chain.
2026-05-15 15:48:12 +02:00
Julien Calixte
813f16655c Merge branch 'main' of ssh://git.apoena.dev:22222/remanso-space/remanso 2026-05-15 15:40:21 +02:00
Julien Calixte
bf19e982fe feat(markdown): render TikZ fenced blocks to SVG
Adds a markdown-it extractor for ```tikz blocks that emits a sanitized
placeholder, plus a runTikz() that lazy-loads the obsidian-tikzjax 0.5.2
bundle from jsdelivr on first encounter, sanitizes the produced SVG with
DOMPurify, and caches it in PouchDB keyed by sha256(source) so repeat
views are instant and offline-capable.
2026-05-15 15:38:48 +02:00
Julien Calixte
248dea6ade style(repos): use tabler lock icon for private repos 2026-05-14 16:18:11 +02:00
Julien Calixte
4fd72226ff refactor(repos): redesign RepoList in editorial style
Align the repo manager with WelcomeWorld and PublicNoteView: editorial
top nav, serif hero, pastel favorite tiles, A-Z grouped list, skeleton
and credential-error states, and a name filter.
2026-05-14 16:13:41 +02:00
Julien Calixte
816c3687d8 fix(auth): clear stale credential error after github re-auth
The 401 flag and cached repo list were module-level and only reset
after a 20-min stale window, so re-authenticating left the
"credentials are invalid or expired" message pinned on. Watch the
access token: reset state and refetch on change. Also await
saveCredentials before redirecting so refs are settled.
2026-05-14 13:04:44 +02:00
Julien Calixte
f2f2a3114b style: no more underline for header tag 2026-05-14 01:22:46 +02:00
Julien Calixte
2f71566083 style(modal): keep conflict modal actions stacked on all sizes 2026-05-14 01:10:40 +02:00
Julien Calixte
80ae544a28 style(notes): drop hover cursor on rotated stacked-note header 2026-05-14 01:10:38 +02:00
Julien Calixte
9e07204430 design: change light theme to light 2026-05-13 18:38:54 +02:00
Julien Calixte
aad07184fd fix(freshness): surface silent failures when pulling latest
queryFileContent threw on octokit errors (stale SHA 404, expired token,
network blip) and the rejection bubbled up unhandled through pullLatest
and onBadgeClick, leaving the badge stuck on "Outdated" with no log or
toast. Wrap the octokit call, log on failure, clear the cached SHA so
the next click re-resolves it, and show an error toast.

Also fix a dead `if (!user || !repo) { null }` that did nothing.
2026-05-06 22:02:50 +02:00
Julien Calixte
76829afba2 design: change light theme to caramellatte 2026-05-06 20:37:55 +02:00
Julien Calixte
05f59a568d design: change light theme to lemonade 2026-05-06 20:31:57 +02:00
Julien Calixte
559bfccd08 design: change dark theme to dracula 2026-05-06 20:26:01 +02:00
Julien Calixte
f8ae4351d6 design: change light theme to cupcake 2026-05-06 20:25:13 +02:00
Julien Calixte
30f200df30 fix(flux-note): stop showing sign-in prompt while readme is loading
Cache miss wrote null into store.readme before getMainReadme finished,
collapsing isLoading and surfacing the not-accessible UI mid-fetch.
Also branch that UI on auth state so signed-in users aren't told to
sign in when access fails.
2026-05-06 09:54:25 +02:00
Julien Calixte
fd7d06ce69 design: change light theme to retro 2026-05-05 16:11:45 +02:00
Julien Calixte
5a9c0a3704 lint 2026-05-04 23:54:26 +02:00
Julien Calixte
e425be5c96 refactor(freshness): drop time-based stale-known status
The 2-minute timer + tick ref decayed verified to stale-known and rendered
a clock icon, but the user can always click the badge to re-check. Removing
the timer simplifies the hook and the badge has one fewer visual state.
2026-05-04 23:53:48 +02:00
Julien Calixte
84803c45dd refactor(scroll): clean up debug overlay and pass anchor by param
Removes the temporary on-screen scroll diagnosis panel and the global
window.__scrollAtClick stash. The anchor scrollTop is now captured
synchronously at addStackedNote entry and threaded through
scrollToFocusedNote and scrollToNoteElement to scrollToElement, so no
state survives across calls — nothing to reset on repo or page change.
2026-05-04 23:02:12 +02:00
Julien Calixte
a526a9f6af fix(scroll): snap to click-time scrollTop before smooth scroll
Capture mainApp.scrollTop synchronously when addStackedNote runs and
snap the scroll back to that value before scrollIntoView fires, so
the smooth scroll begins from where the user actually tapped rather
than from a position drifted by momentum or async work.
2026-05-04 19:57:00 +02:00