element-hq / element-hq/element-meta
Element X Android: add a Links tab to the room media gallery
- Dominant language
- No language data
- Stars
- 112
- Forks
- 25
- Avg merge
- 6h 6m
- Merged PRs (30d)
- 4
Description
## Use case
The room gallery has Media and Files, but links shared in a conversation aren't reachable
anywhere in the app. Since there's also no in-room message search yet
(element-hq/element-x-android#6557), a URL posted more than a bit of scrolling ago is
effectively lost — the only way back to it is scrolling the room by hand.
Two cases from rooms I use daily (family and friends, ~5 people each):
- Someone drops a recipe or an article link mid-conversation. A week later I want it again,
and the choice is scrolling past several hundred messages or asking them to re-send it.
- Planning a weekend away: a booking link, a poll, a map link, posted across a few days in
between normal chat. Collecting them means re-reading the whole thread on a phone.
WhatsApp and Telegram both surface links next to media in the chat info screen, so it's also
where people look first.
## Why this isn't just another gallery filter
The gallery is built on `CreateTimelineParams.MediaOnly`, which filters SDK-side. There is no
`LinksOnly` equivalent, and there can't be a server-side one: in an encrypted room the
homeserver cannot match on message bodies. So links can only come from scanning the unfiltered
timeline on the client.
## How I'd tackle it
I have this working on a fork against v26.08.4 and I'm happy to contribute it:
- a `RoomLinksDataSource` in `libraries/mediaviewer` that scans `JoinedRoom.liveTimeline`
instead of creating a timeline of its own, started lazily on first visit to the tab
- bounded seeding — page back a few times until a handful of links show up, or the start of the
room or a budget is reached, because cost scales with events scanned, not links found
- a `LinkItem` model kept separate from `MediaItem` (a link has neither a `MediaSource` nor a
`ContentValidationState`), a third `MediaGalleryMode`, and a list item view
- roughly 840 lines of production code plus unit tests, so I'd split it across three PRs
(extractor, model + data source, UI) rather than one.
## What I'd like your call on before opening a PR
Two consequences of the client-side scan are user-visible, and both are product decisions
rather than implementation details:
1. Coverage is the history that's loaded, not the whole room. The empty state says so, but it's
still weaker than the Media tab, where the filter is authoritative.
2. Opening the tab paginates the room's live timeline (bounded), i.e. it does work the room
screen wouldn't otherwise do at that moment.
If either is a non-starter, the alternative is a link-filtered timeline in matrix-rust-sdk and
doing this properly on all three platforms — more work, but full coverage and parity. I'd
rather know which direction you want than write more code against the wrong one.
Related: does a Links tab fit your plans for iOS and Web, given the parity expectation in
CONTRIBUTING.md? I can only do the Android side.
Contributor guide
No contributing guide indexed for this repository
Research direction
First read the proposed approach in this issue and CONTRIBUTING.md, then inspect libraries/mediaviewer and JoinedRoom.liveTimeline. Before implementation, get a decision on bounded client-side history coverage, timeline pagination, and iOS/Web parity. Done would mean an approved scope for the Android Links tab and its staged implementation with unit tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android
- Domain
- mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100