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.
Why it wasn't done in #94
Two different shapes:
- The feed row renders
message.linkMetadata?.links → [LinkMetadataItem] (nested metadata object)
refreshMessageMetadata returns [MessageLinkPreview] (flat image / title)
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
Acceptance criteria
Files: Views/ComposeView.swift, Services/AppDataStore.swift, Models/Message.swift.
Split out of #91 (see PR #94), which wired
POST /api/messages/{id}/metadataafter publishing butstopped 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.
Why it wasn't done in #94
Two different shapes:
message.linkMetadata?.links→[LinkMetadataItem](nestedmetadataobject)refreshMessageMetadatareturns[MessageLinkPreview](flatimage/title)Folding one into the other needs a conversion plus a new
AppDataStoremutation to update analready-inserted message in place. That was outside "wire the existing call", so it was called out
rather than smuggled in.
Build this
[MessageLinkPreview]to[LinkMetadataItem]— pure and unit-testable, notinline in a view.
AppDataStoremutation that replaces thelinkMetadataof one already-inserted message by id.ComposeViewapplies the refresh response through it, still fire-and-forget: a failure mustleave the row exactly as it is, with no error surfaced.
Acceptance criteria
store mutation targeting the right message.
Files:
Views/ComposeView.swift,Services/AppDataStore.swift,Models/Message.swift.