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-13 09:51:07 +08:00
|
|
|
import Service from '/imports/ui/components/audio/local-echo/service';
|
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,
|
2022-04-05 05:09:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const defaultProps = {
|
|
|
|
stream: null,
|
2022-04-12 04:18:43 +08:00
|
|
|
initialHearingState: false,
|
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
|
|
|
},
|
2022-04-21 04:49:11 +08:00
|
|
|
testSpeakerLabel: {
|
|
|
|
id: 'app.audio.audioSettings.testSpeakerLabel',
|
|
|
|
description: 'Label for the speaker test button',
|
|
|
|
},
|
2022-04-05 05:09:35 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const LocalEcho = ({
|
|
|
|
intl,
|
|
|
|
stream,
|
2022-04-12 04:18:43 +08:00
|
|
|
initialHearingState,
|
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;
|
2022-04-13 09:51:07 +08:00
|
|
|
const icon = hearing ? 'mute' : 'unmute';
|
2022-07-13 21:59:49 +08:00
|
|
|
const label = hearing ? intlMessages.stopAudioFeedbackLabel : intlMessages.testSpeakerLabel;
|
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) {
|
2022-04-13 09:51:07 +08:00
|
|
|
Service.playEchoStream(_stream, loopbackAgent.current);
|
2022-04-05 05:09:35 +08:00
|
|
|
} else {
|
2022-04-13 09:51:07 +08:00
|
|
|
Service.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();
|
|
|
|
Service.deattachEchoStream();
|
|
|
|
};
|
|
|
|
|
2022-04-05 05:09:35 +08:00
|
|
|
useEffect(() => {
|
2022-04-13 09:51:07 +08:00
|
|
|
if (Service.useRTCLoopback()) {
|
2022-04-19 04:05:26 +08:00
|
|
|
loopbackAgent.current = Service.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]);
|
|
|
|
|
|
|
|
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-07-11 20:27:54 +08:00
|
|
|
$hearing={hearing}
|
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;
|
|
|
|
LocalEcho.defaultProps = defaultProps;
|
|
|
|
|
|
|
|
export default injectIntl(React.memo(LocalEcho));
|