+const AudioProgressBar = ({ filename, currentTime, duration, progressPercent, onSeek, className }: AudioProgressBarProps) => (
+
+
onSeek(e.target.value)}
+ onChange={(e) => onSeek(Number(e.target.value))}
aria-label={`Seek ${filename}`}
- className="relative z-10 h-4 w-full cursor-pointer appearance-none bg-transparent outline-none disabled:cursor-default
+ className="relative z-10 h-3.5 w-full cursor-pointer appearance-none bg-transparent outline-none disabled:cursor-default
[&::-webkit-slider-runnable-track]:h-1 [&::-webkit-slider-runnable-track]:rounded-full
[&::-webkit-slider-runnable-track]:bg-transparent
- [&::-webkit-slider-thumb]:mt-[-3px] [&::-webkit-slider-thumb]:size-2 [&::-webkit-slider-thumb]:appearance-none
+ [&::-webkit-slider-thumb]:mt-[-2.5px] [&::-webkit-slider-thumb]:size-2 [&::-webkit-slider-thumb]:appearance-none
[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border [&::-webkit-slider-thumb]:border-border/50
[&::-webkit-slider-thumb]:bg-background/95
[&::-moz-range-track]:h-1 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent
@@ -38,9 +47,6 @@ const AudioProgressBar = ({ filename, currentTime, duration, progressPercent, on
disabled={duration === 0}
/>
-
- {formatAudioTime(currentTime)} / {duration > 0 ? formatAudioTime(duration) : "--:--"}
-
);
@@ -62,6 +68,9 @@ const AudioAttachmentItem = ({ filename, sourceUrl, mimeType, size, title }: Aud
const fileTypeLabel = getFileTypeLabel(mimeType);
const fileSizeLabel = size ? formatFileSize(size) : undefined;
const progressPercent = duration > 0 ? (currentTime / duration) * 100 : 0;
+ const currentTimeLabel = formatAudioTime(currentTime);
+ const durationLabel = getDurationLabel(duration);
+ const timeLabel = `${currentTimeLabel} / ${durationLabel}`;
useEffect(() => {
if (!audioRef.current) {
@@ -90,9 +99,8 @@ const AudioAttachmentItem = ({ filename, sourceUrl, mimeType, size, title }: Aud
audio.pause();
};
- const handleSeek = (value: string) => {
+ const handleSeek = (nextTime: number) => {
const audio = audioRef.current;
- const nextTime = Number(value);
if (!audio || Number.isNaN(nextTime)) {
return;
@@ -103,9 +111,7 @@ const AudioAttachmentItem = ({ filename, sourceUrl, mimeType, size, title }: Aud
};
const handlePlaybackRateChange = () => {
- const currentRateIndex = AUDIO_PLAYBACK_RATES.findIndex((rate) => rate === playbackRate);
- const nextRate = AUDIO_PLAYBACK_RATES[(currentRateIndex + 1) % AUDIO_PLAYBACK_RATES.length];
- setPlaybackRate(nextRate);
+ setPlaybackRate((currentRate) => getNextPlaybackRate(currentRate));
};
const handleDuration = (value: number) => {
@@ -113,56 +119,49 @@ const AudioAttachmentItem = ({ filename, sourceUrl, mimeType, size, title }: Aud
};
return (
-
-
-
-
-
-
-
-
-
- {displayTitle}
-
-
- {fileTypeLabel}
- {fileSizeLabel && (
- <>
- •
- {fileSizeLabel}
- >
- )}
-
+
+
+
+
+ {displayTitle}
-
-
-
-
+
+ {fileTypeLabel}
+ {fileSizeLabel ? ` · ${fileSizeLabel}` : ""}
+
+
-
+
+
+
+
{timeLabel}
+
+
+