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
Messages: tags — compose, display, filter, trending and autocomplete #32
Tags are a first-class product feature with their own endpoints. Models/Message.cs already carries Tags, but nothing composes, renders, or filters on them.
Live verification (2026-09-15)
GET /api/tags/trending -> 200 {"tags":[{"tag":"Lego","count":2,"lastUsedAt":"..."}, ...]}
GET /api/tags/autocomplete?q=le -> 200 {"tags":[{"tag":"Lego","count":2},{"tag":"learning","count":1}]}
Both answer the bearer sync-token.
API
POST /api/messages accepts tags: string[].
GET /api/messages?tag=<tag> filters the feed by tag.
GET /api/tags/trending — most-used tags on public messages in a trailing window.
GET /api/tags/autocomplete?q= — case-insensitive literal prefix match.
Acceptance criteria
Services/InterlinedApiClient.Tags.cs with GetTrendingTagsAsync and AutocompleteTagsAsync.
Tag input in the composer with prefix autocomplete, sent as tags[].
Tag chips render on feed cards and are clickable → filter the feed via ?tag=.
A trending-tags panel (right rail fits the existing shell).
Pairs with the AI Suggest tags action — an accepted tag suggestion populates this input.
Implemented in #155 — work continues in the PR from here.
Services/InterlinedApiClient.Tags.cs covers both endpoints, tags ride along on POST /api/messages as tags: string[], chips on cards filter the feed via ?tag=, and there is a trending bar. The panel went inside FeedView rather than the shell's right rail, since MainWindow.xaml is in open PR #149.
Two things the live API pinned down: tags are not hashtag-shaped — orbit culture and life is short, o brave girl are real tags — so the compose input splits on commas only, never whitespace; and the count from trending is a different number from the count from autocomplete (trailing window vs all-time), so neither is a cache of the other. Autocomplete rejects an empty q with a 400, so a blank query short-circuits client-side. The compose write path is built and deliberately unexercised.
Activity
Adron commentedon Sep 16, 2026
Implemented in #155 — work continues in the PR from here.
Services/InterlinedApiClient.Tags.cscovers both endpoints, tags ride along onPOST /api/messagesastags: string[], chips on cards filter the feed via?tag=, and there is a trending bar. The panel went inside FeedView rather than the shell's right rail, sinceMainWindow.xamlis in open PR #149.Two things the live API pinned down: tags are not hashtag-shaped —
orbit cultureandlife is short, o brave girlare real tags — so the compose input splits on commas only, never whitespace; and thecountfrom trending is a different number from thecountfrom autocomplete (trailing window vs all-time), so neither is a cache of the other. Autocomplete rejects an emptyqwith a 400, so a blank query short-circuits client-side. The compose write path is built and deliberately unexercised.