Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 59 additions & 23 deletions src/components/AudioRecordingComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import micSVG from "../icons/mic.svg";
import pauseSVG from "../icons/pause.svg";
import resumeSVG from "../icons/play.svg";
import saveSVG from "../icons/save.svg";
import discardSVG from "../icons/stop.svg";
import discardSVG from "../icons/trash.svg";
import "../styles/audio-recorder.css";

const LiveAudioVisualizer = React.lazy(async () => {
Expand Down Expand Up @@ -66,6 +66,14 @@ const AudioRecorder: (props: Props) => ReactElement = ({
stopRecording();
};

const startAudioRecorder: React.MouseEventHandler<HTMLButtonElement> = (
event
) => {
startRecording();
const target = event.target as HTMLElement;
target?.focus();
};

const convertToDownloadFileExtension = async (
webmBlob: Blob
): Promise<Blob> => {
Expand Down Expand Up @@ -134,29 +142,40 @@ const AudioRecorder: (props: Props) => ReactElement = ({
}`}
data-testid="audio_recorder"
>
<img
src={isRecording ? saveSVG : micSVG}
<button
className={`audio-recorder-mic ${
classes?.AudioRecorderStartSaveClass ?? ""
}`}
onClick={isRecording ? () => stopAudioRecorder() : startRecording}
data-testid="ar_mic"
aria-label={isRecording ? "Save recording" : "Start recording"}
title={isRecording ? "Save recording" : "Start recording"}
/>
onClick={isRecording ? () => stopAudioRecorder() : startAudioRecorder}
>
<img
src={isRecording ? saveSVG : micSVG}
alt={isRecording ? "Save recording" : "Start recording"}
width={16}
height={16}
/>
</button>
<span
role="timer"
aria-atomic="true"
hidden={!isRecording}
aria-hidden={!isRecording ? "true" : "false"}
className={`audio-recorder-timer ${
!isRecording ? "display-none" : ""
} ${classes?.AudioRecorderTimerClass ?? ""}`}
classes?.AudioRecorderTimerClass ?? ""
}`}
data-testid="ar_timer"
>
{Math.floor(recordingTime / 60)}:
{String(recordingTime % 60).padStart(2, "0")}
</span>
{showVisualizer ? (
<span
className={`audio-recorder-visualizer ${
!isRecording ? "display-none" : ""
}`}
hidden={!isRecording}
aria-hidden={!isRecording ? "true" : "false"}
className="audio-recorder-visualizer"
>
{mediaRecorder && (
<Suspense fallback={<></>}>
Expand All @@ -176,32 +195,49 @@ const AudioRecorder: (props: Props) => ReactElement = ({
</span>
) : (
<span
hidden={!isRecording}
aria-hidden={!isRecording ? "true" : "false"}
className={`audio-recorder-status ${
!isRecording ? "display-none" : ""
} ${classes?.AudioRecorderStatusClass ?? ""}`}
classes?.AudioRecorderStatusClass ?? ""
}`}
>
<span className="audio-recorder-status-dot"></span>
Recording
</span>
)}
<img
src={isPaused ? resumeSVG : pauseSVG}
<button
hidden={!isRecording}
aria-hidden={!isRecording ? "true" : "false"}
tabIndex={!isRecording ? -1 : 0}
className={`audio-recorder-options ${
!isRecording ? "display-none" : ""
} ${classes?.AudioRecorderPauseResumeClass ?? ""}`}
classes?.AudioRecorderPauseResumeClass ?? ""
}`}
onClick={togglePauseResume}
aria-label={isPaused ? "Resume recording" : "Pause recording"}
title={isPaused ? "Resume recording" : "Pause recording"}
data-testid="ar_pause"
/>
<img
src={discardSVG}
data-testid={"ar_pause"}
>
<img
src={isPaused ? resumeSVG : pauseSVG}
alt={isPaused ? "Resume recording" : "Pause recording"}
width={16}
height={16}
/>
</button>
<button
hidden={!isRecording}
aria-hidden={!isRecording ? "true" : "false"}
tabIndex={!isRecording ? -1 : 0}
className={`audio-recorder-options ${
!isRecording ? "display-none" : ""
} ${classes?.AudioRecorderDiscardClass ?? ""}`}
classes?.AudioRecorderDiscardClass ?? ""
}`}
onClick={() => stopAudioRecorder(false)}
aria-label="Discard Recording"
title="Discard Recording"
data-testid="ar_cancel"
/>
>
<img src={discardSVG} width={16} height={16} alt="Discard Recording" />
</button>
</div>
);
};
Expand Down
3 changes: 3 additions & 0 deletions src/icons/trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 15 additions & 17 deletions src/styles/audio-recorder.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,23 @@
-webkit-tap-highlight-color: transparent;
}

.audio-recorder-mic {
.audio-recorder button {
box-sizing: content-box;
cursor: pointer;
height: 16px;
background: transparent;
border: none;
color: black;
cursor: pointer;
margin: 0;
padding: 12px;
}

.audio-recorder img {
aspect-ratio: 1/1;
display: block;
}

.audio-recorder .audio-recorder-mic {
border-radius: 20px;
border-radius: 50%;
}

.audio-recorder.recording .audio-recorder-mic {
Expand Down Expand Up @@ -57,24 +64,15 @@
margin-right: 5px;
}

.audio-recorder-options {
box-sizing: content-box;
height: 16px;
cursor: pointer;
padding: 12px 6px 12px 12px;
}
.audio-recorder-options ~ .audio-recorder-options {
padding: 12px 12px 12px 6px;
border-radius: 0 5px 5px 0;
}

.recording {
border-radius: 12px;
width: 300px;
padding-inline: 10px;
width: 320px;
width: min-content;
transition: all 0.2s ease-out;
}

.display-none {
.audio-recorder [hidden] {
display: none;
}

Expand Down