Skip to content

refactor: resolve images through one shared implementation - #84

Open
medialaneio wants to merge 6 commits into
mainfrom
refactor/one-image-resolver
Open

refactor: resolve images through one shared implementation#84
medialaneio wants to merge 6 commits into
mainfrom
refactor/one-image-resolver

Conversation

@medialaneio

Copy link
Copy Markdown
Contributor

Both apps carried near-identical copies of ipfsToHttp, resolveTokenImage and ipfsToHttpServer. The copies had already drifted: one passed any data: URI straight to an img src, the other only data:image/ ones.

The logic now lives in @medialane/ui (toDisplayUrl, toDisplayUrlOrNull, toAbsoluteImageUrl) with tests covering ipfs references, external images, data URIs, stored route paths and the empty case. Each app keeps its exported names as thin delegations that bind its own gateway, so the ~156 call sites are unchanged.

Verified: typecheck, full test suite and next build green in both apps against the published @medialane/ui@0.150.3, and the published artifact exercised directly from a clean registry install. Bundle sizes unchanged.

Not browser-verified — the resolvers are pure functions, but no rendering test covers them.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GoVwAvA8SPAa3TRKrtxJaN

medialaneio and others added 6 commits August 31, 2026 14:51
toDisplayUrl and toDisplayUrlOrNull replace the near-identical copies each
app carried, so an ipfs:// reference, a data URI, an external http image and
an unresolvable value all resolve one way across the platform.
toAbsoluteImageUrl carries the og:image invariant — an absolute URL a crawler
can fetch on its own — in one place, with the reasoning attached to it.
A non-image data URI was passed straight to an img src, which cannot render.
The placeholder is the honest result.
Two defects made a weak match outrank a strong one. Results were grouped, and
cmdk 1.1.1 reorders items within a group but not the groups themselves, so a
0.13-scoring item in the first group sat above a 0.89-scoring item in the
second. The first group also rendered at a larger size, reading as a top
result when it was only the group without a heading.

While a query is active the palette is now one flat list in score order, so
the best match is first. Groups return when the query is cleared, where they
are a browsing aid rather than noise.

A relevance floor drops subsequence coincidences: matching s-e-t-t-i-n-g-s
across 'sell...trade...listings' scores 0.13 against 0.89 for a real hit, and
nothing observed lands between the two bands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GoVwAvA8SPAa3TRKrtxJaN
profileIdentity derives an identity only from a claimed username or the
wallet address. Both are governed: a username is unique, charset-restricted,
checked against a reserved list and reviewed before approval, and an address
is the account itself. The name an account types is returned alongside as a
label that never stands in for the identity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GoVwAvA8SPAa3TRKrtxJaN
profileIdentity took displayName, the word that made a free-text label look
like the thing to display for an account.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GoVwAvA8SPAa3TRKrtxJaN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant