Image, album, and video bubbles in the official-assets category now render the attachment filename as a bottom-left overlay so editors can identify the source asset at a glance. Shared AttachmentFilenameLabel component mirrors the AttachmentDownloadPill style, uses filenameWithExtension so MIME-only attachments still get a sensible label, and is pointer-events-none so it never blocks the bubble's tap target.
37 lines
2.9 KiB
Markdown
37 lines
2.9 KiB
Markdown
---
|
|
title: "官方物料 cards — bottom-left filename overlay"
|
|
type: quick-work
|
|
date: 2026-06-03
|
|
---
|
|
|
|
# 官方物料 cards — bottom-left filename overlay
|
|
|
|
## Task
|
|
In every content card classified as 官方物料 (`categorySlug === "official-assets"`), display the source filename at the bottom-left of the card — image filename for image bubbles, video filename for video bubbles.
|
|
|
|
## Data Source — Confirmed
|
|
- Endpoint: `/api/posts` (list, called by `src/components/messageStream/hooks/usePostStream.ts:89`) and `/api/posts/:id` (single, used by `MessageStream` deep-links).
|
|
- Field: `Post.attachments[*].filename` (`src/types/post.ts`).
|
|
- Category gate: `Post.categorySlug === "official-assets"` (also referenced in `src/lib/categorySvgSlug.ts:13`, `src/pages/Categories/index.tsx:23`, `src/pages/Home/index.tsx:33`).
|
|
- No additional API call is needed — `filename` already ships with the post payload.
|
|
|
|
## Changes
|
|
- `src/components/messageStream/AttachmentFilenameLabel.tsx` (new) — small dark pill overlay using `filenameWithExtension(att.filename, att.mime)`, positioned `absolute bottom-2 left-2`, with `pointer-events-none`, `max-w-[calc(100%-1rem)]`, `truncate`, and a `title` attribute so the full filename is available on hover. Style mirrors the `AttachmentDownloadPill` (`bg-black/80` + `ring-white/20` + `backdrop-blur-md`) for visual consistency.
|
|
- `src/components/messageStream/bubbles/SingleImageFrame.tsx` — accepts new `showFilename?: boolean` prop; when true, renders `AttachmentFilenameLabel` alongside the existing top-left download pill.
|
|
- `src/components/messageStream/bubbles/ImageBubble.tsx` — passes `showFilename={post.categorySlug === "official-assets"}`.
|
|
- `src/components/messageStream/bubbles/ImageWithTextBubble.tsx` — same gate, threaded through `SingleImageFrame`.
|
|
- `src/components/messageStream/bubbles/AlbumBubble.tsx` — when category matches, renders the filename label inside each visible tile (skipping the `+N` overflow tile so its overlay stays clean).
|
|
- `src/components/messageStream/bubbles/VideoBubble.tsx` — `VideoAttachmentCard` accepts `showFilename`, threaded into both the multi-video grid layout and the single-video layout. Skipped on the `+N` overflow tile.
|
|
|
|
## Verification
|
|
- `npx tsc --noEmit` — clean.
|
|
- `npm run format` then `npm run format:check` — clean.
|
|
- `npm test` — 49/49 passing.
|
|
- Visual confirmation pending on a posts feed that contains `official-assets` content.
|
|
|
|
## Notes
|
|
- Reuses existing `filenameWithExtension` util so attachments without an extension still get a sensible label from their MIME type.
|
|
- The label is `pointer-events-none` so it never blocks the bubble's own tap target (open lightbox / play video).
|
|
- Only single/album/video bubbles surface this. `FileDocBubble` already renders the filename inline, so no overlay is needed there.
|
|
- If a future requirement adds more "show filename" categories, switch `showFilename` from a boolean gate to a derived util (e.g. `shouldShowAttachmentFilename(post)`).
|