matrix-org / matrix-org/matrix-rust-sdk

Timeline focus for caller-supplied event IDs (generalize the pinned-events mechanism)

Open
#6,876 11 comments 0 reactions 1 assignee View on GitHub

@Hywan is already working on this.

Since Aug 14, 2026.

Dominant language
Rust
Stars
2.3k
Forks
500
Avg merge
1d 16h
Merged PRs (30d)
106

Description

## Use case

Our app has a posts feed that ranks thread roots by their latest reply. When a thread has recent replies but its root is outside the timeline window the client has loaded, I still want to show that root, with its aggregations applied (reactions, edits, redaction state) and kept up to date while it's on screen.

The SDK already has all the machinery for this, it's just only reachable for pinned events: the pinned-events cache loads each pinned id with `load_or_fetch_event_with_relations`, runs everything through timeline aggregation, and stays live. There's currently no way to point that pipeline at events of our own choosing.

## What can be done today

One `TimelineFocus::Event { thread_mode: ForceThread }` timeline per missing root, kept subscribed, plus some bounded forward pagination to pull in the relation tree. It works, and every piece is SDK machinery, but it's N timelines and a fair amount of orchestration for something the pinned-events cache already does generically.

I also just proposed exposing `load_or_fetch_event_with_relations` over FFI (#6875), which helps for one-shot cases, but it leaves aggregation to each client and has no live-update story.

## Proposal

A timeline focus that takes a caller-supplied list of event ids — something like `TimelineFocus::SpecificEvents { event_ids: Vec }` — reusing the pinned-events pipeline with the id list coming from the caller instead of `m.room.pinned_events`.

While scoping this I ran into a few design questions I'd rather not guess on:

- **Storage**: the pinned cache persists into a per-room pinned linked chunk and reloads from it on startup. Arbitrary id-sets probably shouldn't share that (two sets would fight over it) — our instinct is no persistence at all, in-memory like the event-focused cache.
- **Construction**: pinned is a per-room singleton in the cache registry; caller-supplied sets seem to fit the per-call construction style of `event_focused(...)` better.
- **Updates**: pinned reloads off the pin-state stream; caller ids have no stream. Recreating the timeline when the set changes would be fine for our use, but maybe a setter is preferable.

Happy to implement via a draft PR this if the direction sounds reasonable, just wanted to check the shape first.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.