PhoenixKitWeb.Components.Core.MediaThumbnail (phoenix_kit v1.7.208)

Copy Markdown View Source

Provides a component for resolving and rendering media file thumbnail URLs.

Handles file type detection (image, video, PDF, document) and selects the appropriate thumbnail variant from the file's URL map.

Summary

Functions

Normalizes a raw saved-rotation value (metadata["rotation"]) to one of the four snapped angles.

Resolves the best thumbnail URL for a media file.

Tailwind class rotating a thumbnail to the image's saved orientation.

Resolves the best thumbnail URL for a media file.

Functions

normalized_rotation(deg)

@spec normalized_rotation(term()) :: 0 | 90 | 180 | 270

Normalizes a raw saved-rotation value (metadata["rotation"]) to one of the four snapped angles.

Mirrors MediaCanvasViewer's own normalization: only the four snapped angles Fresco emits count; anything else (nil, garbage, a legacy string) reads as unrotated (0).

resolve_url(file, size \\ :small)

@spec resolve_url(map(), :small | :card | :medium) :: String.t() | nil

Resolves the best thumbnail URL for a media file.

Returns nil when no suitable URL is available.

Examples

resolve_url(file)           # small thumbnail
resolve_url(file, :medium)  # medium preview

rotation_class(file, opts \\ [])

@spec rotation_class(
  map(),
  keyword()
) :: String.t() | nil

Tailwind class rotating a thumbnail to the image's saved orientation.

The orientation lives on the file row (metadata["rotation"], written by the viewer's persist_rotation bridge) and applies to the whole image, so every rendering of it — canvas and thumbnail — should honor it. Baked variants stay unrotated: rendering the saved angle with a CSS transform costs nothing, needs no re-encode, and keeps annotations (which live in the image's own coordinate space) aligned as they rotate along.

In a square box (aspect-square cards, w-10 h-10 list cells) a quarter turn needs nothing else: rotating a square leaves the same square, and because object-cover crops about the center — which rotation maps onto itself — cropping-then-rotating shows exactly what rotating-then-cropping would.

A non-square box needs the quarter turn to scale back up, or the covered image (now turned onto its side) would letterbox: pass box: and the scale rides along. Half turns never need it. The scale literal per box shape is hardcoded rather than computed — Tailwind only emits arbitrary values it can see in source, so an interpolated scale-[…] would silently render as no scale at all.

Nil-tolerant: unrotated, garbage, and maps carrying no :rotation at all return nil.

Options

  • :box — the thumbnail box's aspect: :square (default) or :landscape_4_3 (the stacks preview pile's w-32 h-24).

Examples

<img src={url} class={["w-full h-full object-cover", rotation_class(file)]} />

<img src={url} class={["w-full h-full object-cover",
                       rotation_class(file, box: :landscape_4_3)]} />

thumbnail_url(assigns)

Resolves the best thumbnail URL for a media file.

Size modes:

  • :small (default) — tiny cells (list rows, selectors): prefers the baked Etcher thumbnail, then the 150px thumbnail
  • :card — large grid/stack cards: prefers the baked Etcher thumbnail (400px), then the 300px small, then medium; only after those falls back to the light 150px thumbnail, keeping the full-res original (which would force a live vector overlay) as the last resort
  • :medium — for gallery/preview: prefers medium/thumbnail variants

Attributes

  • file - Media file map with file_type and urls fields (required)
  • size - Thumbnail size preference: :small, :card, or :medium (default: :small)

Examples

<.thumbnail_url file={file} :let={url}>
  <img src={url} />
</.thumbnail_url>

<.thumbnail_url file={file} size={:medium} :let={url}>
  <img src={url} />
</.thumbnail_url>

Attributes

  • file (:map) (required)
  • size (:atom) - Defaults to :small. Must be one of :small, :card, or :medium.

Slots

  • inner_block (required)