1
0
Fork 0

feat(voiceover): add admin audio preview for voice submissions

This commit is contained in:
Jason Fraley 2026-09-09 18:54:58 -04:00
parent cbe88c141b
commit 1b552b3a6d
3 changed files with 76 additions and 0 deletions

View file

@ -11,6 +11,7 @@ import { default as default_2f2033acccb3be245f1a85f7b4271dac } from '@/component
import { default as default_4b88a624e9f0b376cffcc6814d459adb } from '@/components/admin/assignments/AssignmentMembersField' import { default as default_4b88a624e9f0b376cffcc6814d459adb } from '@/components/admin/assignments/AssignmentMembersField'
import { default as default_0edde40a6ccd30c893b1227360f69360 } from '@/components/static/TickDurationDescription' import { default as default_0edde40a6ccd30c893b1227360f69360 } from '@/components/static/TickDurationDescription'
import { default as default_2d468cc5cf0b647ffca3201592c20825 } from '@/components/static/WarningMessage' import { default as default_2d468cc5cf0b647ffca3201592c20825 } from '@/components/static/WarningMessage'
import { AudioPreviewField as AudioPreviewField_6bccef9bf4ea41ed573ab9f36fa579b2 } from '@/components/admin/voiceover/AudioPreviewField'
import { default as default_7fa52484aec46e988e9cfb5e86c0c759 } from '@/components/admin/narrative-flow/NarrativeFlowEditor' import { default as default_7fa52484aec46e988e9cfb5e86c0c759 } from '@/components/admin/narrative-flow/NarrativeFlowEditor'
import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
@ -58,6 +59,7 @@ export const importMap = {
"@/components/admin/assignments/AssignmentMembersField#default": default_4b88a624e9f0b376cffcc6814d459adb, "@/components/admin/assignments/AssignmentMembersField#default": default_4b88a624e9f0b376cffcc6814d459adb,
"@/components/static/TickDurationDescription#default": default_0edde40a6ccd30c893b1227360f69360, "@/components/static/TickDurationDescription#default": default_0edde40a6ccd30c893b1227360f69360,
"@/components/static/WarningMessage#default": default_2d468cc5cf0b647ffca3201592c20825, "@/components/static/WarningMessage#default": default_2d468cc5cf0b647ffca3201592c20825,
"@/components/admin/voiceover/AudioPreviewField#AudioPreviewField": AudioPreviewField_6bccef9bf4ea41ed573ab9f36fa579b2,
"@/components/admin/narrative-flow/NarrativeFlowEditor#default": default_7fa52484aec46e988e9cfb5e86c0c759, "@/components/admin/narrative-flow/NarrativeFlowEditor#default": default_7fa52484aec46e988e9cfb5e86c0c759,
"@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient": FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, "@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,

View file

@ -35,6 +35,16 @@ export const VoiceSubmissions: CollectionConfig = {
delete: ({ req }) => hasRoles(["developer"], req.user), delete: ({ req }) => hasRoles(["developer"], req.user),
}, },
fields: [ fields: [
{
name: "audioPreview",
type: "ui",
label: "Take audio",
admin: {
components: {
Field: "@/components/admin/voiceover/AudioPreviewField#AudioPreviewField",
},
},
},
{ {
name: "script", name: "script",
type: "relationship", type: "relationship",

View file

@ -0,0 +1,64 @@
"use client";
import { useDocumentInfo } from "@payloadcms/ui";
import React from "react";
type UploadDocData = {
filename?: string | null;
filesize?: number | null;
mimeType?: string | null;
url?: string | null;
};
const formatBytes = (bytes: number | null | undefined): string => {
if (!bytes || bytes <= 0) return "";
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};
/**
* Inline audio player for upload collections. Registered on voice-submissions as
* a `ui` field so reviewers can listen to a take directly in the admin panel.
* Reads the document's file URL from document info (no form state involved).
*/
export const AudioPreviewField = () => {
const { data } = useDocumentInfo();
const doc = (data ?? {}) as UploadDocData;
const url = doc.url ?? (doc.filename ? `/api/media/file/${doc.filename}` : "");
if (!url) {
return (
<p
style={{
color: "var(--theme-elevation-500)",
fontStyle: "italic",
}}
>
No audio file on this submission yet.
</p>
);
}
const meta = [doc.filename, doc.mimeType, formatBytes(doc.filesize)].filter(Boolean).join(" | ");
return (
<div>
<audio controls preload="metadata" src={url} style={{ width: "100%" }}>
Your browser does not support audio playback.
</audio>
<p
style={{
color: "var(--theme-elevation-500)",
fontSize: "12px",
marginTop: "4px",
wordBreak: "break-all",
}}
>
{meta}
</p>
</div>
);
};
export default AudioPreviewField;