Linked-materials hover badge: show what the material is (type, size, PDF page count), not just how many #57
Labels
No labels
bug
discussion
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
edufeed/edufeed-app#57
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The request
On a resource card, when material is linked, a badge appears over the cover on hover: "📎 1 Materialien verlinkt". A user asked whether the hover could say a little more about what is behind the card — e.g. "a linked PDF with 12 pages", "an image", "a PowerPoint with 24 slides" — rather than only how many things there are.
(card: "Anders sein" heißt einmalig sein…, rpi-ekkw-ekhn.de).
Where this lives today
src/lib/components/educational/AMBResourceCard.svelte:388-395— the badge is already hover-only (opacity-0 … group-hover:opacity-100), so there is a place to put this; it just has nothing but a count in it.The count comes from
:74-78:Note it merges two different things: uploaded/attached files (
encoding:contentUrl) and external references (r). Those have very different metadata available, which shapes what is feasible below.What is already available — no new data needed
getAMBEncodings()(src/lib/helpers/educational/ambHelpers.js:330-351) already returns per attached file:mimeTypecomes fromencoding:encodingFormatandsizefromencoding:contentSize, both emitted at publish time (src/lib/helpers/publication/publicationTags.js:127-131).So "a linked PDF (2.4 MB)", "an image", "a PowerPoint" is achievable today from data already on the event. That is most of the user's request and it needs no format change, no migration, and no network call. Good first slice.
What is not available — the page/slide counts
AMB's
encoding:*has no page or slide count, so nothing on the event carries it. Options, roughly in cost order:PDFs are nearly free.
src/lib/server/pdfThumbnail.js:27already does:doc.numPagesis right there. The/api/pdf-thumbnailendpoint already fetches, renders and caches the file, andpdfThumbnailGate.jsalready implements the rights policy for when the app may touch it at all (open license, or an attested Blossom upload with a sha256). Returning a page count alongside the thumbnail — or from a sibling endpoint sharing the cache — reuses all of that. This is the cheap path and I would do it first.Slide counts are not. There is no PPTX handling anywhere in the app today. It would mean a new server-side dependency to unzip the OOXML and count
ppt/slides/slideN.xml, plus the same rights gate. Real work, and worth deciding whether it earns its keep versus just saying "a PowerPoint".Images could carry dimensions the same way, though nothing extracts them today either.
Three constraints worth knowing before scoping
rtags carry no type at all — just a URL. For external links the best available guess is the file extension, or an HTTPHEADforContent-Type(a network call per card, with the same rights and privacy questions as any outbound fetch). Deciding what an external link renders as is part of this issue, not an afterthought.Multi-file resources have a pairing problem.
getAMBEncodings()alignsencoding:contentUrl,encoding:encodingFormatandencoding:contentSizeby position across separate tag lists. The publish path notes this explicitly (publicationTags.js:122-124): "Single file by design — the positional getAMBEncodings pairing can't disambiguate mixed link/upload runs with heterogeneous optional fields." So if one of several files is missing a format or size, the indices shift and a later file gets labelled with an earlier file's type. A per-item hover list for multi-file resources needs that fixed — or needs to degrade to a summary when the tag counts do not line up.A long-tail question: what does the hover show for 5 linked items? A list will not fit in a badge. Probably "PDF · 12 pages, 2 images, 1 more" or similar — a design call, not just an engineering one.
Adjacent, small, and visible in the screenshot
The badge reads "1 Materialien verlinkt" — wrong plural. Same in English:
"{count} linked materials"renders "1 linked materials". Neithermessages/de.json:2742normessages/en.json:2742has a plural form, and there are currently zero ICU plural forms anywhere inmessages/de.json. Whoever touches this string should fix that at the same time; if this is the first plural in the project it is worth checking how the Paraglide setup wants them expressed.Suggested slicing
/api/pdf-thumbnailmachinery and its rights gate.rlinks — decide the policy, then implement.Steps 1 and 2 deliver most of what the user asked for.
User request relayed by @laoc_buzz in #edufeed-app. Code references are at
dev@09842a48.Slices 1 and 2 shipped in #75, merged to
devat65a16f1b.encoding:*), plural fixed:📎 PDF · 2,4 MB.📎 PDF · 12 Seiten · 2,4 MB. The thumbnail render writesnumPagesto a sidecar and/api/pdf-inforeads it, so a card whose cover already rendered costs no second fetch. Gated oncanDeriveThumbnail, attached files only (anrlink carries no attestation).Browser-verified by @TestOER at
88776df9against an instrumented file host: the one-fetch claim with a fresh cache dir and a fresh URL per trial, plus the no-cover-first control that proves the counter can see a fetch at all, plus the rights gate in both the refusing and the must-allow direction.Slices 3 and 4 are still open and need a product call (asked in the Buzz thread, unanswered):
rlinks — extension guess vs an HTTPHEADper card to a third party on every feed render. My recommendation: extension guess, no network call.Related: #76. The sidecar handoff is correct but currently rarely taken, because thumbnail rendering fails for every PDF with non-embedded standard fonts. Pre-existing, and it does not change the behaviour of this feature — only its cost.