Two independent Svelte 5 effect-loop bugs that triggered the
same 'effect_update_depth_exceeded' guard:
1. PostCard.svelte: the embed-quote-fetch $effect and the
likedBox $effect.pre read a state variable (quotedLoading /
likedBox) and then synchronously wrote to it in the same
effect run. Svelte 5's effect tracker schedules
possible_effect_self_invalidation on the touched state, the
effect re-fires immediately, and the cycle trips the
'flush_count > 1000' guard. With ~30 PostCards mounting on
login the per-card loop compounds into the depth exceeded
error. Wrap the read+write blocks in untrack() so the
hydration flags don't contribute to the effect's dep set;
the outer 'post.embed.uri / post.did / post.rkey' reads
remain tracked so navigation between cards still triggers a
fresh hydrate.
2. App.svelte: the four $effect blocks (home-refresh,
home-poll, profile-refresh, search-debounce) lived and died
together. Even after splitting, Svelte 5 still flagged the
call chain into refreshTimeline / refreshProfile because
their sync prelude writes 'timelineLoading = true' /
'profileLoading = true' while the effect already tracks the
same downstream state via the proxy. Drive everything
imperatively through a single setView(v) function and move
the 5s poll into the session.subscribe callback, which fires
only on actual login/logout transitions. setView is the
single point that flips view AND triggers the right refresh
per destination — NavRail on_select, LoginScreen onLogin,
handleLogout, the 'back to timeline' button, and the tray
navigate-event bridge all route through it now.
Also: NavRail and StatusBar self-style their grid-area in
their own component styles ('grid-area: rail' / 'status') so
App.svelte doesn't need the fragile '$state.s-XXX > nav.rail'
cross-component selector that Svelte 5 was failing to match
in the Tauri webview, leaving rail buttons invisible to clicks.
The `bind:current={view}` pattern in NavRail did not propagate
clicks to the parent's $state. Svelte 5's $bindable on this
runtime is flakey and on this particular build (Tauri 2.11 +
svelte 5.x) the setter was never invoked when a button was
clicked, so the view state stayed 'home' no matter which rail
button the user pressed. The user reported 'search tut sich nix
genau auch bei compose etc.'
Replace with explicit callback prop:
let { view = 'home', on_select } = $props();
onclick={() => on_select?.(item.id)}
The parent then mutates its own `view` rune directly via the
arrow function — Svelte tracks this unconditionally regardless of
runtime-specific bindable semantics.
Includes a vitest regression test that mounts a real Svelte
component harness (jsdom) and asserts that click events on each
rail button flip the parent's `view` and update the .active
class — so any future regression is caught in CI rather than at
the Tauri app window.
- fetchBlob cache keyed by (did, cid), not just cid.
Security: future per-DID access control on getBlob would
otherwise leak the first responder's bytes to subsequent
viewers.
- EmbedImage: pass did to releaseBlob, release previous cid
on cid change (no leaked URLs).
- ComposeBox: releaseBlob called with both did and cid.
- pds-server: rename test
get_blob_after_upload_with_different_did ->
get_blob_returns_404_for_cross_did_cid_lookup. The
docstring was misleading — the test only verifies the
(did,cid) PK on the PDS row, not auth. The renamed name
matches what the test actually checks.
- vitest: update releaseBlob call sites to the new
(did, cid) signature.
The previous 'custom' title bar used tauri.conf.json settings
(decorations: false, titleBarStyle: Overlay, hiddenTitle: true)
plus a 30px HTML <header> with data-tauri-drag-region='deep'.
Two problems made the app unusable:
1. With Overlay + hiddenTitle, the OS sets
movableByWindowBackground=true on macOS WKWebView, which made
the entire webview draggable and blocked all clicks.
2. Tauri 2's WKWebView integration has a known issue
(tao#N) where the drag.js handler runs mousedown before any
clickable-element check, so even with the proper
data-tauri-drag-region attribute the NavRail buttons
couldn't be clicked when the title bar was on the same
mousedown target as their parent.
Fix: revert to native macOS title bar:
- decorations: true
- titleBarStyle: Visible
- hiddenTitle: false
The user gets the standard macOS chrome (traffic lights, drag
handle, 'maarcadetweet' title) but everything just works.
Custom title-bar work deferred until Tauri 3.0 (which fixes the
WKWebView + movableByWindowBackground interaction).
Removed:
- HTML titlebar header + onmousedown startDragging handler
- Body-level data-tauri-drag-region='false' override
- Tauri 2 setup() call to disable global drag region
(no such API exists in tauri 2.11.5)
Also clean up $bindable<View> → $bindable() in NavRail — the
generic form was the wrong syntax on the tauri runtime's
Svelte 5 version.
All 240 tests still pass (231 Rust + 9 vitest).