Commit Graph
7 Commits
Author SHA1 Message Date
tomdebone 1c75d56134 fix(tauri-app): NavRail click → view switch via callback prop
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.
2026-07-06 22:59:29 +02:00
tomdebone a60b612f68 fix(pds): 413 body shape + register app.bsky.feed.like/repost
Three fixes for the integration test plan:

1. Layer order in tauri.conf.json: `body_limit_fallback` must
   wrap `upload_blob_body_limit` so the JSON override is in
   effect when the 413 fires. Swapped.

2. Type annotation on the `from_fn` middleware:
   `.layer::<_, std::convert::Infallible>(...)`. The function
   never errors, so the second type param is Infallible.

3. Register the standard `app.bsky.feed.like` and
   `app.bsky.feed.repost` lexicons so the like/repost
   endpoints (which create records of those collections) pass
   the lex validator. We only ship what the PDS actually lets
   users create server-side; anything else passes `validate: false`.

The 'unprocessable entity' style message and 'unknown lexicon'
errors that came up during manual testing are now gone.

Also dropped the stuck migration-2 row from `_sqlx_migrations`
on the dev DB so the new lex schemas apply.
2026-07-06 21:34:10 +02:00
tomdebone 9eda0c2449 tauri-app: 8c profile copy buttons
The profile view now has two clipboard actions:
  * 'copy did'  — copies the bare DID to the system clipboard
  * 'copy at-uri' — copies 'at://<did>/app.twi.post' as a shareable link

Both surface a toast confirmation via the existing
maarcadetweet:notification event, so the user gets a small
'copied: ...' toast for confirmation. Right-click on a toast
still dismisses without action.

The copyToClipboard helper is in App.svelte (not pushed to
client.ts) because it only uses the browser navigator API.
2026-07-06 21:26:24 +02:00
tomdebone 238823aae1 tauri-app: 8b click-through notifications
OS notification body already arrived as a 'maarcadetweet:notification'
DOM event (Phase 7b). The toast pill that surfaces the body is now
clickable: left-click navigates to the URL the notification was
about (at://<did>/<col>/<rkey> opens the thread, unknown URL
falls back to the home view); right-click dismisses without
navigating. tauri-plugin-notification v2.x does not expose a
reliable OS-level notification-click callback (it only shows the
notification), so the two-step pattern (OS click focuses the app
+ in-app toast click navigates) is the standard workaround.

lastNotificationUrl is now $state so the toast title updates
when a new notification arrives.
2026-07-06 18:59:53 +02:00
tomdebone b912132a05 tauri-app: 8a review fixes
- 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.
2026-07-06 18:53:09 +02:00
tomdebone 226cfdac5c tauri-app: switch to native title bar (fixes drag + clicks)
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).
2026-07-06 16:29:39 +02:00
tomdebone c586fd39c9 maarcadetweet: initial commit
AT Protocol PDS + AppView + Tauri Desktop Client, 160-char post limit.

- PDS (Rust + axum + sqlx)
  - Auth: createAccount, createSession, refreshSession
  - Records: createRecord, deleteRecord (race-safe via SELECT FOR UPDATE)
  - Feed: feed.like.create, feed.repost.create
  - Sync: getRepo, getBlocks, getLatestCommit, getRecord (with MST proof), listRepos
  - Identity: resolveHandle
  - MST: spec-conformant (at-mst crate, 27 tests)
  - Repo: signed commits, TID counter (monotonic, 4096 wrap safe)

- AppView (Rust + axum + sqlx)
  - Jetstream consumer (WebSocket, exponential backoff, 38k+ events indexed)
  - REST API: timeline/home (graph-aware), profile, search, post (with thread hydration)
  - Handle-sync worker (did:plc + did:web)
  - JSONB embed storage + thread columns (migration 0003)
  - Like/repost counter cache (migration 0004)

- Tauri 2 + Svelte 5 Desktop Client
  - System tray (Show/Compose/Quit menu)
  - OS notifications (tauri-plugin-notification)
  - Auto-update (tauri-plugin-updater, placeholder endpoint)
  - Window-state (tauri-plugin-window-state)
  - 160-char compose with live counter
  - Image/Link embed rendering
  - LocalStorage-persisted like state
  - Timeline with poll (prepend new posts)
  - Custom TitleBar (transparent, no decorations)
  - Orange/IBM Plex Mono maarcade design

Tests: 231 Rust + 9 vitest = 240 passed.
2026-07-05 20:01:31 +02:00