Add links-mode embed thumbnails, item metadata, and media filters

This commit is contained in:
Fisto
2026-09-16 11:44:09 +02:00
parent 1fe204b91e
commit 973b9cff92
23 changed files with 863 additions and 82 deletions
+11 -6
View File
@@ -124,11 +124,15 @@ box live in Chat, not Call, and the connection stats are not chips yet.
- **Media** and **Bot** are scope buttons beside Guild and DM. They open a full-window view below
the header and the call strip (the shell is covered; only the header, and the call strip when it
is visible, stay on screen). Mobile is out of scope for the media feature.
- Media lists scraped items with kind chips (All, Images, GIFs, Videos, Audio), a source filter
(any, attachments, stickers, embeds), a source-channel filter built from the scrape list, a
channel picker with **Start links** / **Start download**, and the active scrapes with **Stop**.
Images and GIFs render from the cached preview when one exists, then the local file, then the
Discord CDN URL; videos and audio are link cards.
- Media lists scraped items with kind chips (All, Images, GIFs, Videos, Audio) and filters for
source (any, attachments, stickers, embeds), source channel, poster, aspect ratio, resolution,
and a posted-date range (from/to). **New scrape…** opens a popup with **Server** and **Group
chat** tabs: servers expand into their text channels, each channel (and each group chat) has
**Links** and **Download** buttons, and group chats always use the puppet. **History** lists
each scrape with start time, duration, pages, messages, media counts, bytes, files, and previews.
The scrape strip shows live progress with a pulse and **Stop**. Images and GIFs render from the
cached preview when one exists, then the local file, then the CDN URL; videos and audio are link
cards with the poster and posted time in the tooltip.
- Bot shows the slopbot connection state and the scrape queue.
- The views are self-contained: `poc/public/media.js` and `media.css`, over the `/api/media/*`
routes in the table below. See [media.md](media.md).
@@ -252,11 +256,12 @@ replaceable.
| POST | `/api/audio/stop` | none | Stop speech and clear the queue |
| POST | `/api/audio/capture` | `start` | Start or stop capture |
| GET | `/api/transcript` | `limit?`, `sessionId?` | Sessions and captured segments |
| GET | `/api/media` | `kind?`, `source?`, `channelId?`, `limit?`, `offset?` | Media items across every scrape, newest first. `source` is `attachment`, `sticker`, or `embed`; `channelId` filters by source channel. `localUrl`/`thumbUrl` when a file or preview exists |
| GET | `/api/media` | `kind?`, `source?`, `channelId?`, `authorId?`, `aspect?`, `resolution?`, `after?`, `before?`, `limit?`, `offset?` | Media items across every scrape, newest first. `source` is `attachment`, `sticker`, or `embed`; `aspect` and `resolution` are the preset keys; `after`/`before` are ISO times on `posted_at`. Items carry `authorName`, `postedAt`, `width`, `height`, `aspectRatio`; `localUrl`/`thumbUrl` when a file or preview exists |
| GET | `/api/media/:scrapeId/:itemId/file` | none | The downloaded file, content-typed from its extension |
| GET | `/api/media/:scrapeId/:itemId/thumb` | none | The cached WebP preview |
| GET | `/api/media/scrapes` | none | Every scrape with state and counters |
| GET | `/api/media/status` | none | Slopbot connection state and the scrape list |
| GET | `/api/media/authors` | none | Distinct posters across every scrape, with counts |
| GET | `/api/media/storage` | none | Usage against the limit, per-kind sizes, `nearLimit`; marks old scrapes when over |
| POST | `/api/media/scrape` | `channelId`, `guildId?`, `mode?`, `backend?`, `confirm?` | Start a media scrape. `backend` is `auto` (default), `slopbot`, or `puppet`. Near the limit: `409` with code `MEDIA_LIMIT` unless `confirm: true` |
| POST | `/api/media/scrape/stop` | `id` | Stop a media scrape |