feat(client/android): copy a host's punktfunk:// link #79

Merged
enricobuehler merged 1 commits from worktree-android-copy-link into main 2026-08-06 19:32:35 +00:00
Owner

Android was the one app that could open a punktfunk:// link but never hand one out. So every Android link had to be typed by hand — and the host's stable record id, the part that keeps a link working after the box changes address or the client is reinstalled, isn't shown anywhere in the UI to type.

This came out of a user asking how to wire the Android app into Beacon Launcher. Nothing was actually missing for that — MainActivity is exported and handles ACTION_VIEW for the scheme, and launch= is wired end to end, so Beacon's custom-launch intent (am start -a android.intent.action.VIEW -d "punktfunk://connect/<host>?launch=steam:570") works today. What was missing was any way to get the URL off the device without hand-assembling it.

What changed

Copy link in both homes, which matters here specifically: a handheld with a controller attached is in the console home, so a touch-only action would have missed exactly the user who asked.

  • Touch grid — a new item in the host card's overflow menu
  • Console home — a new action in the host options dialog (Up on a tile), including on pinned tiles

The URL comes from DeepLinks.forHost(), the shared self-emitted form that was already sitting unused in the kit. So Android now emits what every other client emits: stable record id first, with host= and fp= alongside as the recovery path. A pinned card carries its own profile, matching Linux and Apple; a plain host card carries none and keeps honouring the host's binding, exactly like tapping it does.

Confirmation UX

Android 13+ draws its own clipboard preview, so we add nothing on top of it — stacking a second confirmation is the platform's own documented anti-pattern. Below 13 we say so ourselves: the notice banner in the touch grid, a toast in the console home, which renders neither banner.

Docs

profiles-and-links.md no longer says "the Android app has no copy action yet", and its pinned-card paragraph now reads "Linux, Apple and Android". Checked and correctly left alone: clients.md's generic pointer, and the support matrix's punktfunk:// column (already for Android — that column is about links working, which they always did; only emission was missing).

No release-notes entry: there's no v0.25.0.md on main, and those notes are prepared elsewhere — this needs picking up there.

Verification

:app:testDebugUnitTest (compiles app + kit) and :kit:testDebugUnitTest both green. :app:assembleDebug not run — it pulls in the full Rust NDK build and this is Kotlin-only, so compileDebugKotlin is the meaningful gate. The emitted URL itself is already covered by the cross-language vector tests, so the three emitters can't drift.

Not yet exercised on glass. Worth a tap on a real device, particularly the sub-Android-13 toast path.

Android was the one app that could **open** a `punktfunk://` link but never **hand one out**. So every Android link had to be typed by hand — and the host's stable record id, the part that keeps a link working after the box changes address or the client is reinstalled, isn't shown anywhere in the UI to type. This came out of a user asking how to wire the Android app into [Beacon Launcher](https://play.google.com/store/apps/details?id=com.radikal.gamelauncher). Nothing was actually missing for that — `MainActivity` is exported and handles `ACTION_VIEW` for the scheme, and `launch=` is wired end to end, so Beacon's custom-launch intent (`am start -a android.intent.action.VIEW -d "punktfunk://connect/<host>?launch=steam:570"`) works today. What was missing was any way to get the URL off the device without hand-assembling it. ## What changed **Copy link in both homes**, which matters here specifically: a handheld with a controller attached is in the console home, so a touch-only action would have missed exactly the user who asked. - Touch grid — a new item in the host card's overflow menu - Console home — a new action in the host options dialog (Up on a tile), including on pinned tiles The URL comes from `DeepLinks.forHost()`, the shared self-emitted form that was already sitting unused in the kit. So Android now emits what every other client emits: stable record id first, with `host=` and `fp=` alongside as the recovery path. A **pinned card carries its own profile**, matching Linux and Apple; a plain host card carries none and keeps honouring the host's binding, exactly like tapping it does. ## Confirmation UX Android 13+ draws its own clipboard preview, so we add nothing on top of it — stacking a second confirmation is the platform's own documented anti-pattern. Below 13 we say so ourselves: the notice banner in the touch grid, a toast in the console home, which renders neither banner. ## Docs `profiles-and-links.md` no longer says "the Android app has no copy action yet", and its pinned-card paragraph now reads "Linux, Apple and Android". Checked and correctly left alone: `clients.md`'s generic pointer, and the support matrix's `punktfunk://` column (already ✅ for Android — that column is about links *working*, which they always did; only emission was missing). No release-notes entry: there's no `v0.25.0.md` on `main`, and those notes are prepared elsewhere — this needs picking up there. ## Verification `:app:testDebugUnitTest` (compiles app + kit) and `:kit:testDebugUnitTest` both green. `:app:assembleDebug` not run — it pulls in the full Rust NDK build and this is Kotlin-only, so `compileDebugKotlin` is the meaningful gate. The emitted URL itself is already covered by the cross-language vector tests, so the three emitters can't drift. **Not yet exercised on glass.** Worth a tap on a real device, particularly the sub-Android-13 toast path.
enricobuehler added 1 commit 2026-08-06 19:25:25 +00:00
feat(client/android): copy a host's punktfunk:// link
ci / bun-nix (pull_request) Successful in 25s
ci / web (pull_request) Successful in 1m8s
ci / docs-site (pull_request) Successful in 1m16s
ci / rust-arm64 (pull_request) Successful in 1m41s
android / android (pull_request) Successful in 3m22s
ci / rust (pull_request) Failing after 7m33s
f33e442b43
Android was the one app that could open a punktfunk:// link but never hand
one out, so every Android link had to be typed by hand — and the host's
stable record id, which is the part that keeps a link working after the box
changes address, isn't shown anywhere in the UI to type.

Both homes now offer Copy link: the touch grid's card overflow menu, and the
controller home's host options (Up on a tile). A pinned card copies its own
profile with it, matching Linux and Apple; a host card copies none and so
keeps honouring the host's binding, exactly like tapping it does.

The URL is the shared self-emitted form (DeepLinks.forHost), already covered
by the cross-language vector tests, so the three emitters stay in step.

Android 13+ draws its own clipboard confirmation and we add nothing on top of
it; below that we say so ourselves, as a toast in the console home, which
renders neither banner.
enricobuehler merged commit 50fa228bab into main 2026-08-06 19:32:35 +00:00
enricobuehler deleted branch worktree-android-copy-link 2026-08-06 19:32:43 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#79