Skip to content

Commit

Permalink
Merge branch 'main' into feat-mgmt-client
Browse files Browse the repository at this point in the history
  • Loading branch information
N7Remus authored Nov 18, 2024
2 parents 3885427 + cdeeb71 commit e53eccc
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 67 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,8 @@ can be found here: [config.example.js](public/config/config.example.js).
| logo | If not null, it shows the logo loaded from the specified URL, otherwise it shows the title. | `"url"` | ``"images/logo.edumeet.svg"`` |
| title | The title to show if the logo is not specified. | `"string"` | ``"edumeet"`` |
| randomizeOnBlank | Enable or disable randomize room name when it is blank. | `"boolean"` | ``true`` |
| transcriptionEnabled | Enable or disable transcription. | `"boolean"` | ``true`` |
| imprintUrl | Show a link to an imprint in the edumeet UI, keep blank to not show a link | `"string"` | ``""`` |
| privacyUrl | Show a link to a privacy notice in the edumeet UI, keep blank to not show a link | `"string"` | ``""`` |

---
9 changes: 9 additions & 0 deletions public/config/config.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ var config = {
// otherwise, it will remain empty and users will have to enter a room name.
randomizeOnBlank: true,

// Enable or disable transcription.
transcriptionEnabled: true,

// Imprint. If you want to link your imprint, please provide a URL in this variable. If it is empty, no link will be shown.
imprintUrl: '',

// Privacy notice. If you want to link your privacy notices, please provide a URL in this variable. If it is empty, no link will be shown.
privacyUrl: '',

// Client theme. Take a look at mui theme documentation.
theme: {
palette: {
Expand Down
3 changes: 3 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ const App = (): JSX.Element => {
if (roomState ==='left') {
dispatch(roomActions.setState('new'));
navigate('/');
setTimeout(() => {
window.location.reload();
}, 0);
}
}, [ roomState ]);

Expand Down
28 changes: 0 additions & 28 deletions src/components/controlbuttons/ImpressumButton.tsx

This file was deleted.

43 changes: 30 additions & 13 deletions src/components/helpdialog/HelpDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Button } from '@mui/material';
import { Button, Box, Link, Typography } from '@mui/material';
import { Close } from '@mui/icons-material';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import { uiActions } from '../../store/slices/uiSlice';
import { closeLabel } from '../translated/translatedComponents';
import { closeLabel, imprintLabel, privacyLabel } from '../translated/translatedComponents';
import ShortcutKeys from './ShortcutKeys';
import GenericDialog from '../genericdialog/GenericDialog';
import ImpressumButton from '../controlbuttons/ImpressumButton';
import edumeetConfig from '../../utils/edumeetConfig';

const HelpDialog = (): JSX.Element => {
const dispatch = useAppDispatch();
Expand All @@ -17,24 +17,41 @@ const HelpDialog = (): JSX.Element => {
}));
};

const privacyUrl = edumeetConfig.privacyUrl ?? '';
const imprintUrl = edumeetConfig.imprintUrl ?? '';

return (
<GenericDialog
open={ helpOpen }
onClose={ handleCloseHelp }
maxWidth='xs'
content={ <><ShortcutKeys /><ImpressumButton /></> }
content={ <><ShortcutKeys /></> }
actions={
<Button
onClick={ handleCloseHelp }
startIcon={ <Close /> }
variant='contained'
size='small'
>
{ closeLabel() }
</Button>
<Box display="flex" alignItems="center" justifyContent="space-between" width="100%">
<Box display="flex" alignItems="left">
{imprintUrl.trim() !== '' && (
<Link href={imprintUrl} target="_blank" color="inherit" underline="none">
<Typography variant="body2">{ imprintLabel() }</Typography>
</Link>
)}
{privacyUrl.trim() !== '' && (
<Link href={privacyUrl} target="_blank" color="inherit" underline="none" style={{ marginLeft: '16px' }}>
<Typography variant="body2">{ privacyLabel() }</Typography>
</Link>
)}
</Box>
<Button
onClick={ handleCloseHelp }
startIcon={ <Close /> }
variant='contained'
size='small'
>
{ closeLabel() }
</Button>
</Box>
}
/>
);
};

export default HelpDialog;
export default HelpDialog;
9 changes: 9 additions & 0 deletions src/components/translated/translatedComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -805,4 +805,13 @@ export const managementExtraSettingsLabel = (): string => intl.formatMessage({
export const ruleSettingsLabel = (): string => intl.formatMessage({
id: 'label.managementRuleSettings',
defaultMessage: 'Rule settings'

export const imprintLabel = (): string => intl.formatMessage({
id: 'label.imprint',
defaultMessage: 'Imprint'
});

export const privacyLabel = (): string => intl.formatMessage({
id: 'label.privacy',
defaultMessage: 'Privacy'
});
46 changes: 46 additions & 0 deletions src/components/volume/MicVolume.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import LinearProgress from '@mui/material/LinearProgress';
import { useContext, useEffect, useState } from 'react';
import { ServiceContext } from '../../store/store';
import { VolumeWatcher } from '../../utils/volumeWatcher';
import hark from 'hark';

const MicVolume = (): JSX.Element => {
const { mediaService } = useContext(ServiceContext);
const [ volumeLevel, setVolume ] = useState<number>(0);

useEffect(() => {
let volumeWatcher: VolumeWatcher | undefined;

// Add hark for mic
if (mediaService.previewMicTrack) {
const harkStream = new MediaStream();

harkStream.addTrack(mediaService.previewMicTrack.clone());

const micHark = hark(harkStream, {
play: false,
interval: 100,
threshold: -60,
history: 100
});

volumeWatcher = new VolumeWatcher({ hark: micHark });
}

const onVolumeChange = ({ scaledVolume }: { scaledVolume: number }): void => {
setVolume(scaledVolume*10); // Range: 0-100
};

volumeWatcher?.on('volumeChange', onVolumeChange);

return () => {
volumeWatcher?.off('volumeChange', onVolumeChange);
};
}, [ mediaService.previewMicTrack ]);

return (
<LinearProgress color='success' variant="determinate" value={volumeLevel} />
);
};

export default MicVolume;
3 changes: 2 additions & 1 deletion src/services/mediaService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ProducerSource } from '../utils/types';
import { MediaSender } from '../utils/mediaSender';
import type { ClientMonitor } from '@observertc/client-monitor-js';
import { Logger } from '../utils/Logger';
import edumeetConfig from '../utils/edumeetConfig';

const logger = new Logger('MediaService');

Expand Down Expand Up @@ -665,7 +666,7 @@ export class MediaService extends EventEmitter {
get localCapabilities(): LocalCapabilities {
return {
canRecord: Boolean(MediaRecorder),
canTranscribe: Boolean(window.webkitSpeechRecognition),
canTranscribe: Boolean(window.webkitSpeechRecognition) && edumeetConfig.transcriptionEnabled,
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"label.fullscreen": "Vollbild",
"label.guest": null,
"label.high": "Hoch (HD)",
"label.imprint": "Impressum",
"label.italic": "kursiv",
"label.join": "Eintreten",
"label.joinBreakoutRoom": null,
Expand All @@ -77,6 +78,7 @@
"label.openSettings": null,
"label.participants": "Teilnehmer",
"label.password": "Passwort",
"label.privacy": "Datenschutz",
"label.promoteAllPeers": "Alle Teilnehmer reinlassen",
"label.recordingInProgress": "Aufnahme läuft...",
"label.removeBreakoutRoom": null,
Expand Down
10 changes: 7 additions & 3 deletions src/utils/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { TFLite } from '../services/effectsService';

export const defaultEdumeetConfig: EdumeetConfig = {
managementUrl: undefined,
impressumUrl: '/privacy/privacy.html',
p2penabled: false,
loginEnabled: false,
developmentPort: 8443,
Expand Down Expand Up @@ -78,6 +77,7 @@ export const defaultEdumeetConfig: EdumeetConfig = {
},
title: 'edumeet',
randomizeOnBlank: true,
transcriptionEnabled: true,
theme: {
background: 'linear-gradient(135deg, rgba(1,42,74,1) 0%, rgba(1,58,99,1) 50%, rgba(1,73,124,1) 100%)',
appBarColor: 'rgba(0, 0, 0, 0.4)',
Expand All @@ -91,12 +91,13 @@ export const defaultEdumeetConfig: EdumeetConfig = {
sideContentItemDarkColor: 'rgba(150, 150, 150, 0.4)',
sideContainerBackgroundColor: 'rgba(255, 255, 255, 0.7)',
},
reduxLoggingEnabled: false
reduxLoggingEnabled: false,
imprintUrl: '',
privacyUrl: ''
};

export interface EdumeetConfig {
managementUrl?: string;
impressumUrl: string;
p2penabled: boolean;
loginEnabled: boolean;
developmentPort: number;
Expand Down Expand Up @@ -129,8 +130,11 @@ export interface EdumeetConfig {
notificationSounds: Record<NotificationType, NotificationSound>;
title: string;
randomizeOnBlank: boolean;
transcriptionEnabled: boolean;
theme: ThemeOptions;
reduxLoggingEnabled: boolean;
imprintUrl: string;
privacyUrl: string;
}

export interface HTMLMediaElementWithSink extends HTMLMediaElement {
Expand Down
42 changes: 31 additions & 11 deletions src/views/join/Join.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect } from 'react';
import { Button } from '@mui/material';
import { Button, Box, Link, Typography } from '@mui/material';
import TextInputField from '../../components/textinputfield/TextInputField';
import { useAppDispatch, useAppSelector, useNotifier } from '../../store/hooks';
import { joinLabel, yourNameLabel } from '../../components/translated/translatedComponents';
import { joinLabel, yourNameLabel, imprintLabel, privacyLabel } from '../../components/translated/translatedComponents';
import { AccountCircle } from '@mui/icons-material';
import MediaPreview from '../../components/mediapreview/MediaPreview';
import AudioInputChooser from '../../components/devicechooser/AudioInputChooser';
Expand All @@ -18,7 +18,10 @@ import { meActions } from '../../store/slices/meSlice';
import AudioOutputChooser from '../../components/devicechooser/AudioOutputChooser';
import { canSelectAudioOutput } from '../../store/selectors';
import TestAudioOutputButton from '../../components/audiooutputtest/AudioOutputTest';
import edumeetConfig from '../../utils/edumeetConfig';
import ImpressumButton from '../../components/controlbuttons/ImpressumButton';

Check warning on line 22 in src/views/join/Join.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

'ImpressumButton' is defined but never used

Check failure on line 22 in src/views/join/Join.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

'ImpressumButton' is defined but never used
import MicVolume from '../../components/volume/MicVolume';


Check warning on line 25 in src/views/join/Join.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

More than 1 blank line not allowed
interface JoinProps {
roomId: string;
Expand Down Expand Up @@ -61,6 +64,9 @@ const Join = ({ roomId }: JoinProps): React.JSX.Element => {
}
}, []);

const privacyUrl = edumeetConfig.privacyUrl ?? '';
const imprintUrl = edumeetConfig.imprintUrl ?? '';

return (
<GenericDialog
title={ <PrecallTitle /> }
Expand All @@ -70,6 +76,7 @@ const Join = ({ roomId }: JoinProps): React.JSX.Element => {
<AudioInputChooser />
{ showAudioOutputChooser && <AudioOutputChooser /> }
<VideoInputChooser />
<MicVolume />
<TestAudioOutputButton />
<BlurSwitch />
<ChooserDiv>
Expand All @@ -85,15 +92,28 @@ const Join = ({ roomId }: JoinProps): React.JSX.Element => {
</>
}
actions={
<><ImpressumButton /><Button
onClick={handleJoin}
variant='contained'
disabled={!displayName || joinInProgress || mediaLoading}
size='small'
>
{joinLabel()}
</Button></>

<Box display="flex" alignItems="center" justifyContent="space-between" width="100%">
<Box display="flex" alignItems="left">
{imprintUrl.trim() !== '' && (
<Link href={imprintUrl} target="_blank" color="inherit" underline="none">
<Typography variant="body2">{ imprintLabel() }</Typography>
</Link>
)}
{privacyUrl.trim() !== '' && (
<Link href={privacyUrl} target="_blank" color="inherit" underline="none" style={{ marginLeft: '16px' }}>
<Typography variant="body2">{ privacyLabel() }</Typography>
</Link>
)}
</Box>
<Button
onClick={handleJoin}
variant='contained'
disabled={!displayName || joinInProgress || mediaLoading}
size='small'
>
{ joinLabel() }
</Button>
</Box>
}
/>
);
Expand Down
Loading

0 comments on commit e53eccc

Please sign in to comment.