Skip to content

feat(hosts): draw images in the Pocket face preview - #1445

Open
valentinfernandez1 wants to merge 8 commits into
mainfrom
feat/android-face-preview-images
Open

valentinfernandez1 wants to merge 8 commits into
mainfrom
feat/android-face-preview-images

Conversation

@valentinfernandez1

@valentinfernandez1 valentinfernandez1 commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

What

The Pocket face preview in the debug menu draws a face's images, on Android and iOS.

  • Bulletin images load through the same IPFS gateway real cards use.
  • Archive images load from the server that served the face. The path is read as a file name, the way a card reads it from the archive, so an image always comes from that server. A path that climbs above the root with .. draws as empty space.
  • Pressing Draw again fetches the face and its images fresh, so an edit to either shows right away.

On iOS, overlapping loads of the same image share one load. Kingfisher never finished the second of two overlapping loads of one address, so a face showing the same image twice kept a spinner in one of them. This also applies to real cards.

The dev loop guides for both apps cover images and an HTTPS tunnel for a physical phone.

Why

So developers can check a face's images while working on it, without publishing. Requested in paritytech/platform-bugs#98.

Testing

  • Android: a unit test for the uncached face fetch.
  • iOS: a test for how an image source becomes an address, and one for the shared image load. Full test suite passes.
  • Checked on the Android emulator and the iOS simulator against a local server. Archive images draw, including a path with .. inside the archive. A path above the root and a path naming another server do not reach anything outside the face's server. An edited image and an edited face show after pressing Draw.
  • Android was also checked through a Cloudflare HTTPS tunnel.

The debug face preview drew a face without its images, so checking an
image change on a Pocket face needed a deploy.

The preview loads Bulletin images through the IPFS gateway and archive
images from the server that served the face, at the path they have in the
published archive. An archive path that leaves that server or contains a
`..` segment draws as empty space. The `..` check runs on the path itself
because Android's URI drops a leading `..` that the JVM keeps.

Pressing Draw again fetches the face and its images fresh. The face fetch
skips the app's HTTP cache, which answered for edited faces, and the screen
redraws even when the face file did not change, so an edited image shows.

The Android dev loop guide covers images and an HTTPS tunnel for phones
without adb.
The face is fetched with OkHttp, so its images now resolve with OkHttp's
HttpUrl too. A face URL OkHttp accepts no longer fails java.net.URI's
stricter parser, and the result is the same in unit tests and on the
device.

Drop KDoc from impl-module code, which the Android guide keeps for api
modules.
A card reads an archive path as a file inside the archive. The preview
resolved it as a URL, so it refused `images/badges/../stamp.png`, which a
card draws, and normalised `\`, `%2e%2e` and `?query` into paths a card
does not have.

The preview now adds each path segment as a literal file name on the
face's server, so an address cannot leave that server. Only a path that
climbs above the root is refused, as the archive refuses it.

Bulletin images keep the image cache. A CID names content that never
changes, so only archive images skip the cache on each Draw.
@valentinfernandez1 valentinfernandez1 added the host-android Touches the Android host tree label Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request touches an app, which is not built by default. Add a label for each build you want:

  • Android build, android-device-build: attaches an APK that installs on an Android phone or an emulator.

Each starts as soon as it is added and follows the branch from then on.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Bundle size report

Compared with main at abfc1dd.

Raw Gzip Brotli
truapi-host 7.89 MiB 5.66 MiB 5.39 MiB
truapi-provider 4.03 MiB 1.27 MiB 960.1 KiB
truapi 6.30 MiB 891.5 KiB 730.0 KiB
Total 18.23 MiB 7.81 MiB 7.04 MiB

WebAssembly modules

Raw Gzip Brotli
truapi-host/wasm/web/truapi_server_bg.wasm 2.78 MiB 992.4 KiB 747.9 KiB
truapi-host/wasm/web/truapi_verifiable_bg.wasm 4.89 MiB 4.64 MiB 4.61 MiB
truapi-provider/truapi_provider_bg.wasm 3.99 MiB 1.26 MiB 952.4 KiB

No file changed size.

Commit: b85d056

Archive images skipped the memory cache entirely, so rotating the phone
or changing theme fetched them again, which is slow through a tunnel.
Their memory cache entry is now keyed by the draw, so each Draw still
fetches an edited image while a single draw reuses what it loaded.
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

CI Status: 24 required jobs green, 17 passed and 7 skipped by path filter.

All job results
job result
android-bindings skipped
bundle-size success
changes success
changeset-guard skipped
cli-package skipped
codegen success
e2e skipped
explorer success
headless-install success
host-android-bindings success
host-android-detekt success
host-wasm success
ios-bindings success
ios-swift skipped
licenses success
playground success
provider-android-bindings skipped
release-guard success
rust success
ts-client success
ts-debugger success
ts-host success
wasm-provider success
workflow-lint skipped

Signing credentials: failure as of 2026-10-15, a release may fail

Commit b85d056e · run log

…gain

The per-draw memory cache key started again at 1 each time the preview
opened, and the image cache is shared across the app. After leaving the
preview, editing an image and drawing again, the old image came back from
memory. Archive images skip the memory cache again, so every Draw asks the
dev server.

The new test doubles use mockk, as AGENTS.md asks for the Android host.
@valentinfernandez1
valentinfernandez1 marked this pull request as ready for review October 15, 2026 14:46
@valentinfernandez1
valentinfernandez1 requested a review from a team October 15, 2026 14:46
The debug face preview now draws a face's images. A Bulletin image loads from
the IPFS gateway the Pocket uses. An Archive image loads from the server the
face came from, with its path read as a file name under the root, as a card
reads it. A path that climbs above the root draws nothing, and a full address
or a query in the path stays a literal file name.

Pressing Draw again fetches the face and its archive images again, so edited
files show without restarting the app. The face fetch skips the HTTP cache,
and each draw gives the card a new identity.

Overlapping loads of the same image now share one load. Kingfisher's async
retrieve never returned for the second of two overlapping loads of one
address, so a face showing the same image twice kept a spinner in one cell.
This also affects real cards with a repeated image on a cold cache.

The dev loop doc covers images in the preview and drawing on a physical
iPhone through an HTTPS tunnel.
@github-actions github-actions Bot added the host-ios Touches the iOS host tree label Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request touches an app, which is not built by default. Add a label for each build you want:

  • iOS simulator build, ios-simulator-build: builds the iOS app, runs its tests and attaches a build for the iOS Simulator on a Mac.
  • iOS device build, ios-device-build: attaches a signed build that installs on a registered iPhone or iPad.

Each starts as soon as it is added and follows the branch from then on.

@valentinfernandez1 valentinfernandez1 changed the title feat(android): draw images in the Pocket face preview feat(hosts): draw images in the Pocket face preview Oct 15, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

host-android Touches the Android host tree host-ios Touches the iOS host tree

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant