You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
W8: Fold the refreshed link metadata into the just-posted feed row #96
Split out of #91 (see PR #94), which wired POST /api/messages/{id}/metadata after publishing but
stopped short of using its response.
Where it stands
After #94, posting a message with a link fires the metadata refresh. The preview appears on the next feed fetch — not on the row that was just inserted locally. That matches the web, so this is
a polish item, not a bug.
Folding one into the other needs a conversion plus a new AppDataStore mutation to update an
already-inserted message in place. That was outside "wire the existing call", so it was called out
rather than smuggled in.
Build this
A conversion from [MessageLinkPreview] to [LinkMetadataItem] — pure and unit-testable, not
inline in a view.
An AppDataStore mutation that replaces the linkMetadata of one already-inserted message by id.
ComposeView applies the refresh response through it, still fire-and-forget: a failure must
leave the row exactly as it is, with no error surfaced.
Implemented in #103 (stacked on #94). Closing here — further work tracks in the PR.
Read before merging: the conversion is correct but the pipeline is inert
The two shapes convert cleanly, so #103 does what this issue asked. But nothing user-visible
changes yet, because of two problems on either side of it — neither introduced by #103, both
verified independently:
refreshMessageMetadata decodes a shape the route never sends — filed as Bug: refreshMessageMetadata decodes a response shape the route never sends — always returns [] #104. It expects {"metadata":{"links":[…]}}; app/api/messages/[id]/metadata/route.ts:105 returns serialize({ links }) — top-level, with full LinkMetadataItem entries. Against the live API the
decode yields [] every time. The existing test passes only because its fixture was written to
the assumed shape.
#103 is still worth landing: the conversion and the store mutation are exactly what both fixes will
consume, and they are tested. But the chain only becomes visible once #104 and #105 land.
Note this does not invalidate #94 — that PR fires the POST and ignores the response, and the POST
still makes the server fetch and persist the metadata, so "preview appears on the next feed fetch"
works today.
Activity
Adron commentedon Sep 16, 2026
Implemented in #103 (stacked on #94). Closing here — further work tracks in the PR.
Read before merging: the conversion is correct but the pipeline is inert
The two shapes convert cleanly, so #103 does what this issue asked. But nothing user-visible
changes yet, because of two problems on either side of it — neither introduced by #103, both
verified independently:
refreshMessageMetadatadecodes a shape the route never sends — filed as Bug: refreshMessageMetadata decodes a response shape the route never sends — always returns [] #104. It expects{"metadata":{"links":[…]}};app/api/messages/[id]/metadata/route.ts:105returnsserialize({ links })— top-level, with fullLinkMetadataItementries. Against the live API thedecode yields
[]every time. The existing test passes only because its fixture was written tothe assumed shape.
FeedViewcannot see an in-place row update — filed as Bug: FeedView cannot see in-place row updates — merges only unseen ids, keyed on count #105. It mirrorsstore.feedMessagesinto a private
@Stateand merges only unseen ids, keyed on.count(FeedView.swift:385).Replacing a row's
linkMetadatachanges content, not count.#103 is still worth landing: the conversion and the store mutation are exactly what both fixes will
consume, and they are tested. But the chain only becomes visible once #104 and #105 land.
Note this does not invalidate #94 — that PR fires the POST and ignores the response, and the POST
still makes the server fetch and persist the metadata, so "preview appears on the next feed fetch"
works today.