Skip to content

Messages: tags — compose, display, filter, trending and autocomplete #32

Closed

Description

@Adron

Summary

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.

Activity

  1. Adron commented on Sep 16, 2026

    @Adron
    MemberAuthor

    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.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Table stakesarea:messagesArea: messagesparityWeb/API feature-parity work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions