feat(deep-link): handle autonomi:// URLs to trigger downloads#164
Merged
Conversation
Clicking an autonomi://<public_address> link in a browser now launches/ focuses the app and opens the Download-by-address dialog prefilled with the address (the dialog is the confirm + filename step — we never download silently from a web-triggered action). - Add tauri-plugin-deep-link (scheme registered in tauri.conf.json) and, on Windows/Linux, tauri-plugin-single-instance with the deep-link feature so a link opened while the app is already running routes into the existing window instead of spawning a duplicate. - lib.rs: register single-instance first (Win/Linux), init deep-link, register_all() at runtime for dev, capture cold-start URLs into DeepLinkState (drained via take_pending_deep_links), and emit a "deep-link" event for warm opens. - Frontend: plugins/deep-link.client.ts validates the URL (parseAutonomiDeepLink / isValidPublicAddress), stashes the address on the files store, and routes to /files; the page opens DownloadDialog prefilled. Cold/warm overlap deduped with a 2s window. Public-only by design (private uploads' datamap isn't URL-shareable). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tested end-to-end on Windows; several fixes from that pass: - First-attempt prefill: when a link is opened cold, the Files page navigates in with the Download dialog already mounted open, so its prefill watcher (keyed on a false->true transition) never fired. Make it `immediate` and also watch `prefillAddress` so the fields populate on mount and refresh if a link arrives while the dialog is open. - Nuxt context: the `listen` callback runs outside the Nuxt instance context, so useFilesStore()/navigateTo() inside it were unreliable. Capture the store + router at plugin init and reuse them. - Warm-start reliability (Win/Linux): also parse the autonomi:// URL out of the single-instance argv and emit it, not only relying on the deep-link feature forwarding to on_open_url. - Filename: support autonomi://<addr>?name=<file>, prefilled into the dialog (validated by the existing filenameError check). Adds unit tests for parseAutonomiDeepLink / isValidPublicAddress. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…inputs These inputs had no placeholder color, so the placeholder rendered near full text brightness (looked like an entered value in dark mode). Apply the app-standard placeholder-autonomi-muted token plus a slight opacity reduction, matching the other inputs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Clicking an
autonomi://<public_address>link in a browser should launch/focus the desktop app and start downloading that file — the public address is already the shareable handle, so a clickable link is the natural next step. Public-only by design (a private upload's datamap isn't URL-shareable).What
autonomi://URL scheme and routes a clicked link into the existing Download by address flow: the dialog opens prefilled with the address, which doubles as the confirm + filename step (a web-triggered link never downloads silently).autonomi://<addr>?name=<file>, prefilled into the dialog (validated by the existingfilenameErrorcheck).How
tauri-plugin-deep-link(scheme declared intauri.conf.json) and, on Windows/Linux,tauri-plugin-single-instancewith thedeep-linkfeature so a link opened while the app is already running routes into the existing window instead of spawning a duplicate. macOS delivers to the running app viaon_open_url.src-tauri/src/lib.rs: register single-instance first (Win/Linux), init deep-link,register_all()at runtime for dev, capture cold-start URLs intoDeepLinkState(drained viatake_pending_deep_links), and emit adeep-linkevent for warm opens. On Win/Linux the single-instance callback also parses theautonomi://URL out of argv and emits it, so warm-start doesn't depend solely on feature forwarding.plugins/deep-link.client.ts): validates the URL (parseAutonomiDeepLink/isValidPublicAddress), stashes the address (+ optional name) on the files store, and routes to/files. The store + router are captured at plugin init because the event callback runs outside the Nuxt instance context.DownloadDialogapplies the prefill on mount (not just on open-transition) so it works on the very first cold launch, and refreshes if a link arrives while it's open.Testing
?name=, anddownload_publicfetches/decrypts/saves.nuxi typecheckclean,vitest37/37 (addsparseAutonomiDeepLink/isValidPublicAddressunit tests),cargo checkclean.tauri dev(the bare dev exe has no Vite server), so it needs an installed/bundled build — pending verification on macOS.Out of scope
🤖 Generated with Claude Code