11import { FileAudioIcon , PauseIcon , PlayIcon } from "lucide-react" ;
2- import { type ReactNode , useEffect , useRef , useState } from "react" ;
3- import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb" ;
4- import { getAttachmentUrl } from "@/utils/attachment" ;
2+ import { useEffect , useRef , useState } from "react" ;
53import { formatFileSize , getFileTypeLabel } from "@/utils/format" ;
6- import { formatAudioTime , getAttachmentMetadata } from "./attachmentViewHelpers" ;
4+ import { formatAudioTime } from "./attachmentViewHelpers" ;
75
86const AUDIO_PLAYBACK_RATES = [ 1 , 1.5 , 2 ] as const ;
97
@@ -47,30 +45,22 @@ const AudioProgressBar = ({ filename, currentTime, duration, progressPercent, on
4745) ;
4846
4947interface AudioAttachmentItemProps {
50- attachment ?: Attachment ;
51- filename ?: string ;
52- displayName ?: string ;
53- sourceUrl ?: string ;
54- mimeType ?: string ;
48+ filename : string ;
49+ sourceUrl : string ;
50+ mimeType : string ;
5551 size ?: number ;
56- actionSlot ?: ReactNode ;
52+ title ?: string ;
5753}
5854
59- const AudioAttachmentItem = ( { attachment, filename, displayName, sourceUrl, mimeType, size, actionSlot } : AudioAttachmentItemProps ) => {
60- const resolvedFilename = attachment ?. filename ?? filename ?? "audio" ;
61- const resolvedDisplayName = displayName ?? resolvedFilename ;
62- const resolvedSourceUrl = attachment ? getAttachmentUrl ( attachment ) : ( sourceUrl ?? "" ) ;
55+ const AudioAttachmentItem = ( { filename, sourceUrl, mimeType, size, title } : AudioAttachmentItemProps ) => {
6356 const audioRef = useRef < HTMLAudioElement > ( null ) ;
6457 const [ isPlaying , setIsPlaying ] = useState ( false ) ;
6558 const [ currentTime , setCurrentTime ] = useState ( 0 ) ;
6659 const [ duration , setDuration ] = useState ( 0 ) ;
6760 const [ playbackRate , setPlaybackRate ] = useState < ( typeof AUDIO_PLAYBACK_RATES ) [ number ] > ( 1 ) ;
68- const { fileTypeLabel, fileSizeLabel } = attachment
69- ? getAttachmentMetadata ( attachment )
70- : {
71- fileTypeLabel : getFileTypeLabel ( mimeType ?? "" ) ,
72- fileSizeLabel : size ? formatFileSize ( size ) : undefined ,
73- } ;
61+ const displayTitle = title ?? filename ;
62+ const fileTypeLabel = getFileTypeLabel ( mimeType ) ;
63+ const fileSizeLabel = size ? formatFileSize ( size ) : undefined ;
7464 const progressPercent = duration > 0 ? ( currentTime / duration ) * 100 : 0 ;
7565
7666 useEffect ( ( ) => {
@@ -131,8 +121,8 @@ const AudioAttachmentItem = ({ attachment, filename, displayName, sourceUrl, mim
131121
132122 < div className = "flex min-w-0 flex-1 items-start justify-between gap-3" >
133123 < div className = "min-w-0 flex-1" >
134- < div className = "truncate text-sm font-medium leading-5 text-foreground" title = { resolvedFilename } >
135- { resolvedDisplayName }
124+ < div className = "truncate text-sm font-medium leading-5 text-foreground" title = { filename } >
125+ { displayTitle }
136126 </ div >
137127 < div className = "flex flex-wrap items-center gap-x-1.5 gap-y-0.5 text-xs leading-4 text-muted-foreground" >
138128 < span > { fileTypeLabel } </ span >
@@ -146,20 +136,19 @@ const AudioAttachmentItem = ({ attachment, filename, displayName, sourceUrl, mim
146136 </ div >
147137
148138 < div className = "mt-0.5 flex shrink-0 items-center gap-1" >
149- { actionSlot }
150139 < button
151140 type = "button"
152141 onClick = { handlePlaybackRateChange }
153142 className = "inline-flex h-6 items-center justify-center px-1 text-[11px] font-medium text-muted-foreground transition-colors hover:text-foreground"
154- aria-label = { `Playback speed ${ playbackRate } x for ${ resolvedDisplayName } ` }
143+ aria-label = { `Playback speed ${ playbackRate } x for ${ displayTitle } ` }
155144 >
156145 { playbackRate } x
157146 </ button >
158147 < button
159148 type = "button"
160149 onClick = { togglePlayback }
161150 className = "inline-flex size-6.5 items-center justify-center rounded-md border border-border/45 bg-background/85 text-foreground transition-colors hover:bg-muted/45"
162- aria-label = { isPlaying ? `Pause ${ resolvedDisplayName } ` : `Play ${ resolvedDisplayName } ` }
151+ aria-label = { isPlaying ? `Pause ${ displayTitle } ` : `Play ${ displayTitle } ` }
163152 >
164153 { isPlaying ? < PauseIcon className = "size-3" /> : < PlayIcon className = "size-3 translate-x-[0.5px]" /> }
165154 </ button >
@@ -168,7 +157,7 @@ const AudioAttachmentItem = ({ attachment, filename, displayName, sourceUrl, mim
168157 </ div >
169158
170159 < AudioProgressBar
171- filename = { resolvedFilename }
160+ filename = { filename }
172161 currentTime = { currentTime }
173162 duration = { duration }
174163 progressPercent = { progressPercent }
@@ -177,7 +166,7 @@ const AudioAttachmentItem = ({ attachment, filename, displayName, sourceUrl, mim
177166
178167 < audio
179168 ref = { audioRef }
180- src = { resolvedSourceUrl }
169+ src = { sourceUrl }
181170 preload = "metadata"
182171 className = "hidden"
183172 onLoadedMetadata = { ( e ) => handleDuration ( e . currentTarget . duration ) }
0 commit comments