2022-04-13 09:51:07 +08:00
|
|
|
import React, { useState, useEffect, useRef } from 'react';
|
2022-04-05 05:09:35 +08:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2022-04-21 04:49:11 +08:00
|
|
|
import Styled from './styles';
|
2024-05-29 21:26:11 +08:00
|
|
|
import { getSettingsSingletonInstance } from '/imports/ui/services/settings';
|
2022-04-05 05:09:35 +08:00
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
intl: PropTypes.shape({
|
|
|
|
formatMessage: PropTypes.func.isRequired,
|
|
|
|
}).isRequired,
|
2022-04-13 09:51:07 +08:00
|
|
|
stream: PropTypes.shape({
|
|
|
|
active: PropTypes.bool,
|
|
|
|
id: PropTypes.string,
|
|
|
|
}),
|
2022-04-12 04:18:43 +08:00
|
|
|
initialHearingState: PropTypes.bool,
|
2024-06-05 19:26:27 +08:00
|
|
|
playEchoStream: PropTypes.func.isRequired,
|
|
|
|
deattachEchoStream: PropTypes.func.isRequired,
|
|
|
|
shouldUseRTCLoopback: PropTypes.func.isRequired,
|
|
|
|
createAudioRTCLoopback: PropTypes.func.isRequired,
|
2024-09-06 07:53:33 +08:00
|
|
|
outputDeviceId: PropTypes.string,
|
|
|
|
setAudioSink: PropTypes.func.isRequired,
|
2022-04-05 05:09:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const intlMessages = defineMessages({
|
2022-07-13 21:59:49 +08:00
|
|
|
stopAudioFeedbackLabel: {
|
|
|
|
id: 'app.audio.stopAudioFeedback',
|
|
|
|
description: 'Stop audio feedback button label',
|
2022-04-05 05:09:35 +08:00
|
|
|
},
|
2024-08-09 07:52:50 +08:00
|
|
|
startAudioFeedback: {
|
|
|
|
id: 'app.audio.startAudioFeedback',
|
|
|
|
description: 'Start audio feedback button label',
|
2022-04-21 04:49:11 +08:00
|
|
|
},
|
2022-04-05 05:09:35 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const LocalEcho = ({
|
|
|
|
intl,
|
2024-06-11 21:05:08 +08:00
|
|
|
stream = null,
|
|
|
|
initialHearingState = false,
|
2024-06-05 19:26:27 +08:00
|
|
|
playEchoStream,
|
|
|
|
deattachEchoStream,
|
|
|
|
shouldUseRTCLoopback,
|
|
|
|
createAudioRTCLoopback,
|
2024-09-06 07:53:33 +08:00
|
|
|
outputDeviceId,
|
|
|
|
setAudioSink,
|
2022-04-05 05:09:35 +08:00
|
|
|
}) => {
|
2022-04-13 09:51:07 +08:00
|
|
|
const loopbackAgent = useRef(null);
|
2022-04-12 04:18:43 +08:00
|
|
|
const [hearing, setHearing] = useState(initialHearingState);
|
2024-05-29 21:26:11 +08:00
|
|
|
const Settings = getSettingsSingletonInstance();
|
2022-04-05 05:09:35 +08:00
|
|
|
const { animations } = Settings.application;
|
2024-08-09 07:52:50 +08:00
|
|
|
const icon = hearing ? 'no_audio' : 'listen';
|
|
|
|
const label = hearing ? intlMessages.stopAudioFeedbackLabel : intlMessages.startAudioFeedback;
|
2022-04-05 05:09:35 +08:00
|
|
|
|
2022-04-13 09:51:07 +08:00
|
|
|
const applyHearingState = (_stream) => {
|
2022-04-05 05:09:35 +08:00
|
|
|
if (hearing) {
|
2024-06-05 19:26:27 +08:00
|
|
|
playEchoStream(_stream, loopbackAgent.current);
|
2022-04-05 05:09:35 +08:00
|
|
|
} else {
|
2024-06-05 19:26:27 +08:00
|
|
|
deattachEchoStream();
|
2022-04-05 05:09:35 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-04-13 09:51:07 +08:00
|
|
|
const cleanup = () => {
|
|
|
|
if (loopbackAgent.current) loopbackAgent.current.stop();
|
2024-06-05 19:26:27 +08:00
|
|
|
deattachEchoStream();
|
2022-04-13 09:51:07 +08:00
|
|
|
};
|
|
|
|
|
2022-04-05 05:09:35 +08:00
|
|
|
useEffect(() => {
|
2024-06-05 19:26:27 +08:00
|
|
|
if (shouldUseRTCLoopback()) {
|
|
|
|
loopbackAgent.current = createAudioRTCLoopback();
|
2022-04-13 09:51:07 +08:00
|
|
|
}
|
|
|
|
return cleanup;
|
|
|
|
}, []);
|
2022-04-05 05:09:35 +08:00
|
|
|
|
|
|
|
useEffect(() => {
|
2022-04-13 09:51:07 +08:00
|
|
|
applyHearingState(stream);
|
2022-04-05 05:09:35 +08:00
|
|
|
}, [stream, hearing]);
|
|
|
|
|
2024-09-06 07:53:33 +08:00
|
|
|
useEffect(() => {
|
|
|
|
if (outputDeviceId) setAudioSink(outputDeviceId);
|
|
|
|
}, [outputDeviceId]);
|
|
|
|
|
2022-04-05 05:09:35 +08:00
|
|
|
return (
|
2022-04-21 04:49:11 +08:00
|
|
|
<Styled.LocalEchoTestButton
|
2022-07-02 04:55:32 +08:00
|
|
|
data-test={hearing ? 'stopHearingButton' : 'testSpeakerButton'}
|
2022-04-05 05:09:35 +08:00
|
|
|
label={intl.formatMessage(label)}
|
|
|
|
icon={icon}
|
2022-04-21 04:49:11 +08:00
|
|
|
size="md"
|
2022-04-05 05:09:35 +08:00
|
|
|
color="primary"
|
|
|
|
onClick={() => setHearing(!hearing)}
|
|
|
|
animations={animations}
|
|
|
|
/>
|
|
|
|
);
|
2022-04-13 09:51:07 +08:00
|
|
|
};
|
2022-04-05 05:09:35 +08:00
|
|
|
|
|
|
|
LocalEcho.propTypes = propTypes;
|
|
|
|
|
|
|
|
export default injectIntl(React.memo(LocalEcho));
|