The attachment list plays audio inline but downloads everything else
The portal shows files attached to sessions and deliverables through an AttachmentList component. Every file gets a download button. Audio files get a second button — Play. The distinction comes from two functions. The first, isAudio, checks whether the MIME type starts with audio/ or matches one of three specific types — audio/mpeg, audio/mp4, audio/m4a. That function controls whether the file row shows the Audio label next to the file size. The second function, isStreamableAudio, is stricter. It checks against a whitelist of six MIME types that browsers can decode natively — mpeg, mp3, mp4, m4a, aac, ogg. A WAV file is audio but not streamable in this context because browser support is inconsistent and the files are typically hundreds of megabytes. A streamable file gets the Play button. A non-streamable audio file gets Download only. When the client taps Play, the component fetches a signed R2 download URL from the file endpoint and sets it as the source of an HTML audio element that appears below the file list. The audio element uses autoPlay so playback begins immediately, controls so the client can scrub and adjust volume, and an onEnded callback that clears the URL and resets the playing state. Tapping Play on a file that is already playing stops it — the same button toggles between Play and Stop based on whether the playingId matches the file ID. Only one file plays at a time because there is one audio element and one URL in state. Starting a new file replaces the previous one. The signed URL expires after twenty-four hours but the audio element only needs it for the initial fetch — once the browser starts streaming, the connection stays open until playback completes or the user navigates away. One component, two MIME checks, one audio element, and every mastered track, rough mix, and session recording is playable without leaving the portal.
Comments coming soon
Sign in with TikTok to leave a comment. Coming soon.