Merge pull request #19533 from ramonlsouza/remove-audiocaptions-collection
Refactor: remove audio-captions collection
This commit is contained in:
commit
4df0cf81c5
@ -1,9 +0,0 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
|
||||
const AudioCaptions = new Mongo.Collection('audio-captions');
|
||||
|
||||
if (Meteor.isServer) {
|
||||
AudioCaptions.createIndexAsync({ meetingId: 1 });
|
||||
}
|
||||
|
||||
export default AudioCaptions;
|
@ -1,4 +0,0 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import handleTranscriptUpdated from '/imports/api/audio-captions/server/handlers/transcriptUpdated';
|
||||
|
||||
RedisPubSub.on('TranscriptUpdatedEvtMsg', handleTranscriptUpdated);
|
@ -1,12 +0,0 @@
|
||||
import setTranscript from '/imports/api/audio-captions/server/modifiers/setTranscript';
|
||||
|
||||
export default async function transcriptUpdated({ header, body }) {
|
||||
const { meetingId } = header;
|
||||
|
||||
const {
|
||||
transcriptId,
|
||||
transcript,
|
||||
} = body;
|
||||
|
||||
await setTranscript(meetingId, transcriptId, transcript);
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
import './eventHandlers';
|
||||
import './publishers';
|
@ -1,26 +0,0 @@
|
||||
import AudioCaptions from '/imports/api/audio-captions';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default async function clearAudioCaptions(meetingId) {
|
||||
if (meetingId) {
|
||||
try {
|
||||
const numberAffected = await AudioCaptions.removeAsync({ meetingId });
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info(`Cleared AudioCaptions (${meetingId})`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Error on clearing audio captions (${meetingId}). ${err}`);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const numberAffected = await AudioCaptions.removeAsync({});
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.info('Cleared AudioCaptions (all)');
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Error on clearing audio captions (all). ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import { check } from 'meteor/check';
|
||||
import AudioCaptions from '/imports/api/audio-captions';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default async function setTranscript(meetingId, transcriptId, transcript) {
|
||||
try {
|
||||
check(meetingId, String);
|
||||
check(transcriptId, String);
|
||||
check(transcript, String);
|
||||
|
||||
const selector = { meetingId };
|
||||
|
||||
const modifier = {
|
||||
$set: {
|
||||
transcriptId,
|
||||
transcript,
|
||||
},
|
||||
};
|
||||
|
||||
const numberAffected = await AudioCaptions.upsertAsync(selector, modifier);
|
||||
|
||||
if (numberAffected) {
|
||||
Logger.debug(`Set transcriptId=${transcriptId} transcript=${transcript} meeting=${meetingId}`);
|
||||
} else {
|
||||
Logger.debug(`Upserted transcriptId=${transcriptId} transcript=${transcript} meeting=${meetingId}`);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(`Setting audio captions transcript to the collection: ${err}`);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import AudioCaptions from '/imports/api/audio-captions';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import AuthTokenValidation, { ValidationStates } from '/imports/api/auth-token-validation';
|
||||
|
||||
async function audioCaptions() {
|
||||
const tokenValidation = await AuthTokenValidation
|
||||
.findOneAsync({ connectionId: this.connection.id });
|
||||
|
||||
if (!tokenValidation || tokenValidation.validationStatus !== ValidationStates.VALIDATED) {
|
||||
Logger.warn(`Publishing AudioCaptions was requested by unauth connection ${this.connection.id}`);
|
||||
return AudioCaptions.find({ meetingId: '' });
|
||||
}
|
||||
|
||||
const { meetingId, userId } = tokenValidation;
|
||||
Logger.debug('Publishing AudioCaptions', { meetingId, requestedBy: userId });
|
||||
|
||||
return AudioCaptions.find({ meetingId });
|
||||
}
|
||||
|
||||
function publish(...args) {
|
||||
const boundAudioCaptions = audioCaptions.bind(this);
|
||||
return boundAudioCaptions(...args);
|
||||
}
|
||||
|
||||
Meteor.publish('audio-captions', publish);
|
@ -13,7 +13,6 @@ import clearVoiceUsers from '/imports/api/voice-users/server/modifiers/clearVoic
|
||||
import clearUserInfo from '/imports/api/users-infos/server/modifiers/clearUserInfo';
|
||||
import clearScreenshare from '/imports/api/screenshare/server/modifiers/clearScreenshare';
|
||||
import clearTimer from '/imports/api/timer/server/modifiers/clearTimer';
|
||||
import clearAudioCaptions from '/imports/api/audio-captions/server/modifiers/clearAudioCaptions';
|
||||
import clearMeetingTimeRemaining from '/imports/api/meetings/server/modifiers/clearMeetingTimeRemaining';
|
||||
import clearLocalSettings from '/imports/api/local-settings/server/modifiers/clearLocalSettings';
|
||||
import clearRecordMeeting from './clearRecordMeeting';
|
||||
@ -42,7 +41,6 @@ export default async function meetingHasEnded(meetingId) {
|
||||
clearVoiceUsers(meetingId),
|
||||
clearUserInfo(meetingId),
|
||||
clearTimer(meetingId),
|
||||
clearAudioCaptions(meetingId),
|
||||
clearLocalSettings(meetingId),
|
||||
clearMeetingTimeRemaining(meetingId),
|
||||
clearRecordMeeting(meetingId),
|
||||
|
@ -4,7 +4,7 @@ import deviceInfo from '/imports/utils/deviceInfo';
|
||||
import { ActionsBarItemType, ActionsBarPosition } from 'bigbluebutton-html-plugin-sdk/dist/cjs/extensible-areas/actions-bar-item/enums';
|
||||
import Styled from './styles';
|
||||
import ActionsDropdown from './actions-dropdown/container';
|
||||
import AudioCaptionsButtonContainer from '/imports/ui/components/audio/captions/button/container';
|
||||
import AudioCaptionsButtonContainer from '/imports/ui/components/audio/audio-graphql/audio-captions/button/component';
|
||||
import CaptionsReaderMenuContainer from '/imports/ui/components/captions/reader-menu/container';
|
||||
import ScreenshareButtonContainer from '/imports/ui/components/actions-bar/screenshare/container';
|
||||
import ReactionsButtonContainer from './reactions-button/container';
|
||||
|
@ -3,7 +3,7 @@ import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
import Users from '/imports/api/users';
|
||||
import Meetings, { LayoutMeetings } from '/imports/api/meetings';
|
||||
import AudioCaptionsLiveContainer from '/imports/ui/components/audio/captions/live/container';
|
||||
import AudioCaptionsLiveContainer from '/imports/ui/components/audio/audio-graphql/audio-captions/live/component';
|
||||
import AudioCaptionsService from '/imports/ui/components/audio/captions/service';
|
||||
import { notify } from '/imports/ui/services/notification';
|
||||
import CaptionsContainer from '/imports/ui/components/captions/live/container';
|
||||
|
@ -1,259 +0,0 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import Service from '/imports/ui/components/audio/captions/service';
|
||||
import SpeechService from '/imports/ui/components/audio/captions/speech/service';
|
||||
import ButtonEmoji from '/imports/ui/components/common/button/button-emoji/ButtonEmoji';
|
||||
import BBBMenu from '/imports/ui/components/common/menu/component';
|
||||
import Styled from './styles';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { SET_SPEECH_LOCALE } from '/imports/ui/core/graphql/mutations/userMutations';
|
||||
|
||||
const intlMessages = defineMessages({
|
||||
start: {
|
||||
id: 'app.audio.captions.button.start',
|
||||
description: 'Start audio captions',
|
||||
},
|
||||
stop: {
|
||||
id: 'app.audio.captions.button.stop',
|
||||
description: 'Stop audio captions',
|
||||
},
|
||||
transcriptionSettings: {
|
||||
id: 'app.audio.captions.button.transcriptionSettings',
|
||||
description: 'Audio captions settings modal',
|
||||
},
|
||||
transcription: {
|
||||
id: 'app.audio.captions.button.transcription',
|
||||
description: 'Audio speech transcription label',
|
||||
},
|
||||
transcriptionOn: {
|
||||
id: 'app.switch.onLabel',
|
||||
},
|
||||
transcriptionOff: {
|
||||
id: 'app.switch.offLabel',
|
||||
},
|
||||
language: {
|
||||
id: 'app.audio.captions.button.language',
|
||||
description: 'Audio speech recognition language label',
|
||||
},
|
||||
'de-DE': {
|
||||
id: 'app.audio.captions.select.de-DE',
|
||||
description: 'Audio speech recognition german language',
|
||||
},
|
||||
'en-US': {
|
||||
id: 'app.audio.captions.select.en-US',
|
||||
description: 'Audio speech recognition english language',
|
||||
},
|
||||
'es-ES': {
|
||||
id: 'app.audio.captions.select.es-ES',
|
||||
description: 'Audio speech recognition spanish language',
|
||||
},
|
||||
'fr-FR': {
|
||||
id: 'app.audio.captions.select.fr-FR',
|
||||
description: 'Audio speech recognition french language',
|
||||
},
|
||||
'hi-ID': {
|
||||
id: 'app.audio.captions.select.hi-ID',
|
||||
description: 'Audio speech recognition indian language',
|
||||
},
|
||||
'it-IT': {
|
||||
id: 'app.audio.captions.select.it-IT',
|
||||
description: 'Audio speech recognition italian language',
|
||||
},
|
||||
'ja-JP': {
|
||||
id: 'app.audio.captions.select.ja-JP',
|
||||
description: 'Audio speech recognition japanese language',
|
||||
},
|
||||
'pt-BR': {
|
||||
id: 'app.audio.captions.select.pt-BR',
|
||||
description: 'Audio speech recognition portuguese language',
|
||||
},
|
||||
'ru-RU': {
|
||||
id: 'app.audio.captions.select.ru-RU',
|
||||
description: 'Audio speech recognition russian language',
|
||||
},
|
||||
'zh-CN': {
|
||||
id: 'app.audio.captions.select.zh-CN',
|
||||
description: 'Audio speech recognition chinese language',
|
||||
},
|
||||
});
|
||||
|
||||
const DEFAULT_LOCALE = 'en-US';
|
||||
const DISABLED = '';
|
||||
|
||||
const CaptionsButton = ({
|
||||
intl,
|
||||
active,
|
||||
isRTL,
|
||||
enabled,
|
||||
currentSpeechLocale,
|
||||
availableVoices,
|
||||
isSupported,
|
||||
isVoiceUser,
|
||||
}) => {
|
||||
const isTranscriptionDisabled = () => (
|
||||
currentSpeechLocale === DISABLED
|
||||
);
|
||||
|
||||
const [setSpeechLocale] = useMutation(SET_SPEECH_LOCALE);
|
||||
|
||||
const setUserSpeechLocale = (speechLocale, provider) => {
|
||||
setSpeechLocale({
|
||||
variables: {
|
||||
locale: speechLocale,
|
||||
provider,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const fallbackLocale = availableVoices.includes(navigator.language)
|
||||
? navigator.language : DEFAULT_LOCALE;
|
||||
|
||||
const getSelectedLocaleValue = (isTranscriptionDisabled() ? fallbackLocale : currentSpeechLocale);
|
||||
|
||||
const selectedLocale = useRef(getSelectedLocaleValue);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTranscriptionDisabled()) selectedLocale.current = getSelectedLocaleValue;
|
||||
}, [currentSpeechLocale]);
|
||||
|
||||
if (!enabled) return null;
|
||||
|
||||
const shouldRenderChevron = isSupported && isVoiceUser;
|
||||
|
||||
const getAvailableLocales = () => {
|
||||
let indexToInsertSeparator = -1;
|
||||
const availableVoicesObjectToMenu = availableVoices.map((availableVoice, index) => {
|
||||
if (availableVoice === availableVoices[0]) {
|
||||
indexToInsertSeparator = index;
|
||||
}
|
||||
return (
|
||||
{
|
||||
icon: '',
|
||||
label: intl.formatMessage(intlMessages[availableVoice]),
|
||||
key: availableVoice,
|
||||
iconRight: selectedLocale.current === availableVoice ? 'check' : null,
|
||||
customStyles: (selectedLocale.current === availableVoice) && Styled.SelectedLabel,
|
||||
disabled: isTranscriptionDisabled(),
|
||||
onClick: () => {
|
||||
selectedLocale.current = availableVoice;
|
||||
SpeechService.setSpeechLocale(selectedLocale.current, setUserSpeechLocale);
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
if (indexToInsertSeparator >= 0) {
|
||||
availableVoicesObjectToMenu.splice(indexToInsertSeparator, 0, {
|
||||
key: 'separator-01',
|
||||
isSeparator: true,
|
||||
});
|
||||
}
|
||||
return [
|
||||
...availableVoicesObjectToMenu,
|
||||
];
|
||||
};
|
||||
|
||||
const toggleTranscription = () => {
|
||||
SpeechService.setSpeechLocale(
|
||||
isTranscriptionDisabled() ? selectedLocale.current : DISABLED, setUserSpeechLocale,
|
||||
);
|
||||
};
|
||||
|
||||
const getAvailableLocalesList = () => (
|
||||
[{
|
||||
key: 'availableLocalesList',
|
||||
label: intl.formatMessage(intlMessages.language),
|
||||
customStyles: Styled.TitleLabel,
|
||||
disabled: true,
|
||||
},
|
||||
...getAvailableLocales(),
|
||||
{
|
||||
key: 'divider',
|
||||
label: intl.formatMessage(intlMessages.transcription),
|
||||
customStyles: Styled.TitleLabel,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: 'separator-02',
|
||||
isSeparator: true,
|
||||
},
|
||||
{
|
||||
key: 'transcriptionStatus',
|
||||
label: intl.formatMessage(
|
||||
isTranscriptionDisabled()
|
||||
? intlMessages.transcriptionOn
|
||||
: intlMessages.transcriptionOff,
|
||||
),
|
||||
customStyles: isTranscriptionDisabled()
|
||||
? Styled.EnableTrascription : Styled.DisableTrascription,
|
||||
disabled: false,
|
||||
onClick: toggleTranscription,
|
||||
}]
|
||||
);
|
||||
|
||||
const onToggleClick = (e) => {
|
||||
e.stopPropagation();
|
||||
Service.setAudioCaptions(!active);
|
||||
};
|
||||
|
||||
const startStopCaptionsButton = (
|
||||
<Styled.ClosedCaptionToggleButton
|
||||
icon={active ? 'closed_caption' : 'closed_caption_stop'}
|
||||
label={intl.formatMessage(active ? intlMessages.stop : intlMessages.start)}
|
||||
color={active ? 'primary' : 'default'}
|
||||
ghost={!active}
|
||||
hideLabel
|
||||
circle
|
||||
size="lg"
|
||||
onClick={onToggleClick}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
shouldRenderChevron
|
||||
? (
|
||||
<Styled.SpanButtonWrapper>
|
||||
<BBBMenu
|
||||
trigger={(
|
||||
<>
|
||||
{ startStopCaptionsButton }
|
||||
<ButtonEmoji
|
||||
emoji="device_list_selector"
|
||||
hideLabel
|
||||
label={intl.formatMessage(intlMessages.transcriptionSettings)}
|
||||
tabIndex={0}
|
||||
rotate
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
actions={getAvailableLocalesList()}
|
||||
opts={{
|
||||
id: 'default-dropdown-menu',
|
||||
keepMounted: true,
|
||||
transitionDuration: 0,
|
||||
elevation: 3,
|
||||
getcontentanchorel: null,
|
||||
fullwidth: 'true',
|
||||
anchorOrigin: { vertical: 'top', horizontal: isRTL ? 'right' : 'left' },
|
||||
transformOrigin: { vertical: 'bottom', horizontal: isRTL ? 'right' : 'left' },
|
||||
}}
|
||||
/>
|
||||
</Styled.SpanButtonWrapper>
|
||||
) : startStopCaptionsButton
|
||||
);
|
||||
};
|
||||
|
||||
CaptionsButton.propTypes = {
|
||||
intl: PropTypes.shape({
|
||||
formatMessage: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
active: PropTypes.bool.isRequired,
|
||||
isRTL: PropTypes.bool.isRequired,
|
||||
enabled: PropTypes.bool.isRequired,
|
||||
currentSpeechLocale: PropTypes.string.isRequired,
|
||||
availableVoices: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
isSupported: PropTypes.bool.isRequired,
|
||||
isVoiceUser: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(CaptionsButton);
|
@ -1,28 +0,0 @@
|
||||
import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Service from '/imports/ui/components/audio/captions/service';
|
||||
import Button from './component';
|
||||
import SpeechService from '/imports/ui/components/audio/captions/speech/service';
|
||||
import AudioService from '/imports/ui/components/audio/service';
|
||||
import AudioCaptionsButtonContainer from '../../audio-graphql/audio-captions/button/component';
|
||||
|
||||
const Container = (props) => <Button {...props} />;
|
||||
|
||||
withTracker(() => {
|
||||
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
|
||||
const availableVoices = SpeechService.getSpeechVoices();
|
||||
const currentSpeechLocale = SpeechService.getSpeechLocale();
|
||||
const isSupported = availableVoices.length > 0;
|
||||
const isVoiceUser = AudioService.isVoiceUser();
|
||||
return {
|
||||
isRTL,
|
||||
enabled: Service.hasAudioCaptions(),
|
||||
active: Service.getAudioCaptions(),
|
||||
currentSpeechLocale,
|
||||
availableVoices,
|
||||
isSupported,
|
||||
isVoiceUser,
|
||||
};
|
||||
})(Container);
|
||||
|
||||
export default AudioCaptionsButtonContainer;
|
@ -1,61 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
import Button from '/imports/ui/components/common/button/component';
|
||||
import Toggle from '/imports/ui/components/common/switch/component';
|
||||
import {
|
||||
colorWhite,
|
||||
colorPrimary,
|
||||
colorOffWhite,
|
||||
colorDangerDark,
|
||||
colorSuccess,
|
||||
} from '/imports/ui/stylesheets/styled-components/palette';
|
||||
|
||||
const ClosedCaptionToggleButton = styled(Button)`
|
||||
${({ ghost }) => ghost && `
|
||||
span {
|
||||
box-shadow: none;
|
||||
background-color: transparent !important;
|
||||
border-color: ${colorWhite} !important;
|
||||
}
|
||||
i {
|
||||
margin-top: .4rem;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const SpanButtonWrapper = styled.span`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const TranscriptionToggle = styled(Toggle)`
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-left: 1em;
|
||||
`;
|
||||
|
||||
const TitleLabel = {
|
||||
fontWeight: 'bold',
|
||||
opacity: 1,
|
||||
};
|
||||
|
||||
const EnableTrascription = {
|
||||
color: colorSuccess,
|
||||
};
|
||||
|
||||
const DisableTrascription = {
|
||||
color: colorDangerDark,
|
||||
};
|
||||
|
||||
const SelectedLabel = {
|
||||
color: colorPrimary,
|
||||
backgroundColor: colorOffWhite,
|
||||
};
|
||||
|
||||
export default {
|
||||
ClosedCaptionToggleButton,
|
||||
SpanButtonWrapper,
|
||||
TranscriptionToggle,
|
||||
TitleLabel,
|
||||
EnableTrascription,
|
||||
DisableTrascription,
|
||||
SelectedLabel,
|
||||
};
|
@ -1,104 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import UserContainer from './user/container';
|
||||
|
||||
const CAPTIONS_CONFIG = Meteor.settings.public.captions;
|
||||
|
||||
class LiveCaptions extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { clear: true };
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { clear } = this.state;
|
||||
|
||||
if (clear) {
|
||||
const { transcript } = this.props;
|
||||
if (prevProps.transcript !== transcript) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState({ clear: false });
|
||||
}
|
||||
} else {
|
||||
this.resetTimer();
|
||||
this.timer = setTimeout(() => this.setState({ clear: true }), CAPTIONS_CONFIG.time);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.resetTimer();
|
||||
}
|
||||
|
||||
resetTimer() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
transcript,
|
||||
transcriptId,
|
||||
} = this.props;
|
||||
|
||||
const { clear } = this.state;
|
||||
|
||||
const hasContent = transcript.length > 0 && !clear;
|
||||
|
||||
const wrapperStyles = {
|
||||
display: 'flex',
|
||||
};
|
||||
|
||||
const captionStyles = {
|
||||
whiteSpace: 'pre-line',
|
||||
wordWrap: 'break-word',
|
||||
fontFamily: 'Verdana, Arial, Helvetica, sans-serif',
|
||||
fontSize: '1.5rem',
|
||||
background: '#000000a0',
|
||||
color: 'white',
|
||||
padding: hasContent ? '.5rem' : undefined,
|
||||
};
|
||||
|
||||
const visuallyHidden = {
|
||||
position: 'absolute',
|
||||
overflow: 'hidden',
|
||||
clip: 'rect(0 0 0 0)',
|
||||
height: '1px',
|
||||
width: '1px',
|
||||
margin: '-1px',
|
||||
padding: '0',
|
||||
border: '0',
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={wrapperStyles}>
|
||||
{clear ? null : (
|
||||
<UserContainer
|
||||
background="#000000a0"
|
||||
transcriptId={transcriptId}
|
||||
/>
|
||||
)}
|
||||
<div style={captionStyles}>
|
||||
{clear ? '' : transcript}
|
||||
</div>
|
||||
<div
|
||||
style={visuallyHidden}
|
||||
aria-atomic
|
||||
aria-live="polite"
|
||||
>
|
||||
{clear ? '' : transcript}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LiveCaptions.propTypes = {
|
||||
transcript: PropTypes.string.isRequired,
|
||||
transcriptId: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default LiveCaptions;
|
@ -1,21 +0,0 @@
|
||||
import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Service from '/imports/ui/components/audio/captions/service';
|
||||
import LiveCaptions from './component';
|
||||
import AudioCaptionsLiveContainer from '../../audio-graphql/audio-captions/live/component';
|
||||
|
||||
const Container = (props) => <LiveCaptions {...props} />;
|
||||
|
||||
withTracker(() => {
|
||||
const {
|
||||
transcriptId,
|
||||
transcript,
|
||||
} = Service.getAudioCaptionsData();
|
||||
|
||||
return {
|
||||
transcript,
|
||||
transcriptId,
|
||||
};
|
||||
})(Container);
|
||||
|
||||
export default AudioCaptionsLiveContainer;
|
@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import UserAvatar from '/imports/ui/components/user-avatar/component';
|
||||
|
||||
const User = ({
|
||||
avatar,
|
||||
background,
|
||||
color,
|
||||
moderator,
|
||||
name,
|
||||
}) => (
|
||||
<div
|
||||
style={{
|
||||
background,
|
||||
minHeight: '3.25rem',
|
||||
padding: '.5rem',
|
||||
textTransform: 'capitalize',
|
||||
width: '3.25rem',
|
||||
}}
|
||||
>
|
||||
<UserAvatar
|
||||
avatar={avatar}
|
||||
color={color}
|
||||
moderator={moderator}
|
||||
>
|
||||
{name.slice(0, 2)}
|
||||
</UserAvatar>
|
||||
</div>
|
||||
);
|
||||
|
||||
User.propTypes = {
|
||||
avatar: PropTypes.string.isRequired,
|
||||
background: PropTypes.string.isRequired,
|
||||
color: PropTypes.string.isRequired,
|
||||
moderator: PropTypes.bool.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default User;
|
@ -1,44 +0,0 @@
|
||||
import React from 'react';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import Users from '/imports/api/users';
|
||||
import User from './component';
|
||||
|
||||
const MODERATOR = Meteor.settings.public.user.role_moderator;
|
||||
|
||||
const Container = (props) => <User {...props} />;
|
||||
|
||||
const getUser = (userId) => {
|
||||
const user = Users.findOne(
|
||||
{ userId },
|
||||
{
|
||||
fields: {
|
||||
avatar: 1,
|
||||
color: 1,
|
||||
role: 1,
|
||||
name: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (user) {
|
||||
return {
|
||||
avatar: user.avatar,
|
||||
color: user.color,
|
||||
moderator: user.role === MODERATOR,
|
||||
name: user.name,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
avatar: '',
|
||||
color: '',
|
||||
moderator: false,
|
||||
name: '',
|
||||
};
|
||||
};
|
||||
|
||||
export default withTracker(({ transcriptId }) => {
|
||||
const userId = transcriptId.split('-')[0];
|
||||
|
||||
return getUser(userId);
|
||||
})(Container);
|
@ -1,38 +1,8 @@
|
||||
import AudioCaptions from '/imports/api/audio-captions';
|
||||
import Auth from '/imports/ui/services/auth';
|
||||
|
||||
const getAudioCaptionsData = () => {
|
||||
const audioCaptions = AudioCaptions.findOne({ meetingId: Auth.meetingID });
|
||||
|
||||
if (audioCaptions) {
|
||||
return {
|
||||
transcriptId: audioCaptions.transcriptId,
|
||||
transcript: audioCaptions.transcript,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
transcriptId: '',
|
||||
transcript: '',
|
||||
};
|
||||
};
|
||||
|
||||
const getAudioCaptions = () => Session.get('audioCaptions') || false;
|
||||
|
||||
const setAudioCaptions = (value) => Session.set('audioCaptions', value);
|
||||
|
||||
const hasAudioCaptions = () => {
|
||||
const audioCaptions = AudioCaptions.findOne(
|
||||
{ meetingId: Auth.meetingID },
|
||||
{ fields: {} },
|
||||
);
|
||||
|
||||
return !!audioCaptions;
|
||||
};
|
||||
|
||||
export default {
|
||||
getAudioCaptionsData,
|
||||
getAudioCaptions,
|
||||
setAudioCaptions,
|
||||
hasAudioCaptions,
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ import { SMALL_VIEWPORT_BREAKPOINT } from '../../layout/enums';
|
||||
import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
|
||||
import { USER_LEAVE_MEETING } from '/imports/ui/core/graphql/mutations/userMutations';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import useMeeting from '/imports/ui/core/hooks/useMeeting';
|
||||
|
||||
const { isIphone } = deviceInfo;
|
||||
const { isSafari, isValidSafariVersion } = browserInfo;
|
||||
@ -30,11 +31,22 @@ const OptionsDropdownContainer = (props) => {
|
||||
];
|
||||
}
|
||||
|
||||
const {
|
||||
data: currentMeeting,
|
||||
} = useMeeting((m) => {
|
||||
return {
|
||||
componentsFlags: m.componentsFlags,
|
||||
};
|
||||
});
|
||||
|
||||
const componentsFlags = currentMeeting?.componentsFlags;
|
||||
const audioCaptionsEnabled = componentsFlags?.hasCaption;
|
||||
|
||||
const [userLeaveMeeting] = useMutation(USER_LEAVE_MEETING);
|
||||
|
||||
return (
|
||||
<OptionsDropdown {...{
|
||||
isMobile, isRTL, optionsDropdownItems, userLeaveMeeting, ...props,
|
||||
isMobile, isRTL, optionsDropdownItems, userLeaveMeeting, audioCaptionsEnabled, ...props,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -44,7 +56,6 @@ export default withTracker((props) => {
|
||||
const handleToggleFullscreen = () => FullscreenService.toggleFullScreen();
|
||||
return {
|
||||
amIModerator: props.amIModerator,
|
||||
audioCaptionsEnabled: audioCaptionsService.hasAudioCaptions(),
|
||||
audioCaptionsActive: audioCaptionsService.getAudioCaptions(),
|
||||
audioCaptionsSet: (value) => audioCaptionsService.setAudioCaptions(value),
|
||||
isMobile: deviceInfo.isMobile,
|
||||
|
@ -31,7 +31,6 @@ const SUBSCRIPTIONS = [
|
||||
'pads-sessions',
|
||||
'pads-updates',
|
||||
'notifications',
|
||||
'audio-captions',
|
||||
'layout-meetings',
|
||||
'user-reaction',
|
||||
'timer',
|
||||
|
@ -21,7 +21,6 @@ import '/imports/api/users-infos/server';
|
||||
import '/imports/api/users-persistent-data/server';
|
||||
import '/imports/api/connection-status/server';
|
||||
import '/imports/api/timer/server';
|
||||
import '/imports/api/audio-captions/server';
|
||||
import '/imports/api/pads/server';
|
||||
import '/imports/api/local-settings/server';
|
||||
import '/imports/api/voice-call-states/server';
|
||||
|
Loading…
Reference in New Issue
Block a user