media-renderer

Shared media renderer

src/components/common_stack_components/media/ · (UI-компонент) — єдина точка відображення image, video, audio, voice та звичайних файлів у card, inline і fullscreen-контекстах.

Суть

Shared media renderer уніфікує вигляд, loading/error states, playback, fullscreen-навігацію та поведінку звичайних файлів. Feature отримує дані, перевіряє права і перетворює власну модель на AppMediaItem; renderer не виконує бізнес-запитів, upload, moderation або видалення.

Публічні точки інтеграції:

  • MediaRenderer — показує один нормалізований media item;
  • MediaPreview — fullscreen-галерея над переданою колекцією;
  • getFileType — визначає media kind із declared type, MIME type, filename або URL;
  • createLocalMediaPreviewUrl — готує preview для локального файла до upload.

Use cases

Renderer використовують для вкладень повідомлень, листів, тікетів і коментарів, media libraries і pickers, документів та досягнень у картках, аватарів TU і fullscreen-перегляду колекцій.

Нові feature не повинні створювати власні image/video/audio/file viewers, якщо потрібна поведінка вже підтримується shared renderer.

Межі відповідальності

Shared rendererFeature-споживач
Вибір renderer за media kind.Отримання, кешування та оновлення даних.
Card, inline і fullscreen presentation.Мапінг backend-моделі в AppMediaItem.
Loading, unavailable і decode-ready states.Вибір original та preview URL потрібної якості.
Playback, seek, mute і час.Склад, порядок і фільтрація fullscreen-колекції.
Навігація та закриття fullscreen.Перевірка прав і фактичне видалення.
File open/download.Upload, moderation, selection та feature overlays.

Контракт AppMediaItem

ПолеОбов’язковістьЗначення
idтакСтабільний string ID у межах колекції.
kindтакimage, video, audio, voice або file.
srcтакOriginal image, actual video/audio/voice або URL файла.
previewSrcніПолегшене image preview або video poster.
name / filenameніНазва вкладення; використовується для alt/title і file card.
mimeTypeніДодаткова підказка для визначення типу.
sizeніРозмір у байтах; показується для file в inline і fullscreen.
urlніLegacy fallback для file; нові адаптери використовують src.

id має залишатися однаковим у card і fullscreen-колекції, інакше initialId не відкриє потрібний елемент.

Визначення типу

getFileType використовує доступні підказки в такому порядку:

  1. явний declared type: photo/image, video, voice, audio;
  2. MIME prefix;
  3. розширення filename або URL;
  4. невідомий формат стає file.

Declared type voice навмисно відрізняється від audio, щоб voice message мав власне представлення.

Варіанти відображення

VariantПризначенняПоведінка
cardGrid, picker, компактний attachment list.Показує полегшене preview без preload важкого media stream; клік може делегувати відкриття fullscreen.
inlineMedia всередині сторінки з локальним playback.Video/audio/voice відтворюються на місці; image/video використовують задану геометрію.
fullscreenОдин активний item у MediaPreview.Показує original/playable source, розширені controls і file action.

Image та video підтримують preset або комбінацію size/aspect ratio/fit. Зовнішній grid, gap, selection, badges і moderation controls залишаються відповідальністю feature.

Original і preview URL

Якщо джерело дає кілька рівнів якості:

URLВикористання
previewUrlМале card preview.
mediumUrlВеликий inline preview або video poster.
urlOriginal image, playable media або файл.

Адаптер передає original у src, а потрібний полегшений рівень — у previewSrc. Fullscreen використовує src.

Для image renderer може один раз перейти з недоступного previewSrc на src. У великих grid feature має уникати масового fallback на originals, якщо це створює надмірне мережеве навантаження.

Поведінка за типом

Image

Card та inline резервують media slot до завершення декодування. Під час завантаження показується loader; після помилки обох доступних джерел — unavailable state. Fullscreen показує original у межах viewport.

Video

Card використовує poster і не завантажує actual video для playback. Inline та fullscreen мають спільні play, mute і seek controls. За відсутності poster показується video placeholder.

Audio і voice

Card не preload-ить stream. Inline і fullscreen мають play, seek, current time та duration. Зміна item скидає playback state.

File

File card показує filename та extension. Inline і fullscreen додатково показують розмір, якщо він відомий.

Одна file action завжди запускає завантаження з початковим filename. PDF, TXT/MD і code-файли додатково відкриваються в новій вкладці для браузерного перегляду. Word, document, spreadsheet, presentation, archive та невідомі формати лише завантажуються.

Якщо file host дозволяє frontend-запит, renderer використовує тимчасовий локальний URL. Якщо запит заблоковано CORS або завершується помилкою, застосовується початковий URL.

Fullscreen preview

MediaPreview рендериться поверх сторінки та отримує готовий масив дозволених items. Feature передає initialId або initialIndex, щоб відкрити натиснутий елемент.

Керування:

  • Escape, close button або клік по overlay закривають preview;
  • ArrowLeft / ArrowRight і кнопки навігації переходять між items;
  • counter показує позицію у переданій колекції;
  • delete action з’являється тільки коли feature передала onDelete;
  • під час async delete повторна дія блокується;
  • якщо колекція спорожніла, preview закривається.

Renderer не підтверджує видалення і не визначає permissions — це робить feature.

Локальні файли до upload

createLocalMediaPreviewUrl готує browser preview:

  • image отримує зменшене локальне preview;
  • video отримує image frame;
  • для audio, voice і file helper не створює окремого visual preview.

Feature окремо створює основний локальний source для draft. Вона володіє всіма створеними URL і повинна звільнити їх після видалення draft, завершення upload або демонтування форми.

Loading та error states

  • visual media не показується до готовності preview/original;
  • video poster не перекриває вже готове video;
  • audio/voice/file мають власний unavailable state;
  • media error завершує loading state;
  • global loader застосовує feature лише для бізнес-операцій, які блокують цілий сценарій.

Правила інтеграції

  1. Нормалізувати backend record у стабільний AppMediaItem.
  2. Передати playable/original/download URL у src.
  3. Передати card або inline preview у previewSrc.
  4. Вибрати variant за поведінкою, а не лише за розміром.
  5. Для fullscreen зберігати selected ID/index і передавати всю дозволену колекцію.
  6. Тримати permissions, upload, delete confirmation, selection і filters у feature.
  7. Для локальних файлів очищати створені browser URL.

Поточні інтеграції

  • E-mail media;
  • Hiring Media Gallery;
  • hiring workspace і картка кандидата;
  • tickets;
  • Golden workspace v2 message/mail/e-mail attachments і media pickers;
  • operator card documents, passport scans, comments і achievements;
  • operator TU views.

Legacy media implementations ще існують. Їх можна мігрувати лише після звірки data contract, permissions і поточного user flow.

Зв’язки