Stop the content edit dialog rewriting types it cannot represent

Opening Edit on a YouTube item and pressing Save Changes — with nothing else touched — turned it
into an MP4.

The type dropdown offers six fixed options and is rendered unconditionally. For video/youtube no
option matched, so the browser selected the first one, video/mp4. The save handler then reads the
select's value and sends it because it differs from the stored type:

    const mimeType = overlay.querySelector('#editMimeType').value;   // 'video/mp4'
    if (mimeType !== contentItem.mime_type) updateData.mime_type = mimeType;

and the server stores what it is sent. mime_type is the renderer selector in every player, so the
item became an "MP4" whose source is a YouTube embed page: a dead slide on every screen in the
playlist. It could not be undone from the dialog either, because there is no video/youtube option to
set it back, and the YouTube-specific controls disappear once the type has changed.

The same applies to uploads the sniffer accepts but the list omits — the sniffer allows fifteen
types, the dropdown covers six — so .mov, .svg, .heic, .avif and .bmp were all rewritten the same
way.

The dialog now includes the item's actual type as a selected option whenever the fixed six cannot
express it, so opening and saving is a no-op and the type is never silently changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
This commit is contained in:
Claude 2026-07-30 21:09:59 -05:00
parent a3b668d32f
commit f66c941c1d

View file

@ -714,6 +714,15 @@ function showEditModal(contentItem, onSave) {
<option value="image/png" ${contentItem.mime_type === 'image/png' ? 'selected' : ''}>${t('content.mime.image_png')}</option>
<option value="image/gif" ${contentItem.mime_type === 'image/gif' ? 'selected' : ''}>${t('content.mime.image_gif')}</option>
<option value="image/webp" ${contentItem.mime_type === 'image/webp' ? 'selected' : ''}>${t('content.mime.image_webp')}</option>
${['video/mp4','video/webm','image/jpeg','image/png','image/gif','image/webp'].includes(contentItem.mime_type) ? '' : `
<!-- The item's ACTUAL type, for the cases the six choices above cannot express:
video/youtube, and uploads the sniffer accepts but this list omits (.mov, .svg,
.heic, .avif, .bmp). Without it no option matched, the browser selected the first
one - video/mp4 - and pressing Save with nothing else changed rewrote the item's
type. mime_type is the renderer selector in every player, so a YouTube item became
an "MP4" whose source is an embed page: a dead slide on every screen, and
unrecoverable here because there was no option to set it back. -->
<option value="${esc(contentItem.mime_type || '')}" selected>${esc(contentItem.mime_type || '')}</option>`}
</select>
</div>
<div class="form-group">