init
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
2025-09-02 14:49:16 +08:00
commit 38ba663466
2885 changed files with 391107 additions and 0 deletions

View File

@@ -0,0 +1 @@
export { default as JoinMeetingDialog } from './native/JoinMeetingDialog';

View File

@@ -0,0 +1 @@
export { default as JoinMeetingDialog } from './web/JoinMeetingDialog';

View File

@@ -0,0 +1,40 @@
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { View, ViewStyle } from 'react-native';
import Dialog from 'react-native-dialog';
import { StandaloneRaiseHandButton as RaiseHandButton } from '../../../reactions/components/native/RaiseHandButton';
import styles from '../../components/native/styles';
/**
* Component that renders the join meeting dialog for visitors.
*
* @returns {JSX.Element}
*/
export default function JoinMeetingDialog() {
const { t } = useTranslation();
const [ visible, setVisible ] = useState(true);
const closeDialog = useCallback(() => {
setVisible(false);
}, []);
return (
<Dialog.Container
coverScreen = { false }
visible = { visible }>
<Dialog.Title>{ t('visitors.joinMeeting.title') }</Dialog.Title>
<Dialog.Description>
{ t('visitors.joinMeeting.description') }
<View style = { styles.raiseHandButton as ViewStyle }>
{/* @ts-ignore */}
<RaiseHandButton disableClick = { true } />
</View>
</Dialog.Description>
<Dialog.Description>{t('visitors.joinMeeting.wishToSpeak')}</Dialog.Description>
<Dialog.Button
label = { t('dialog.Ok') }
onPress = { closeDialog } />
</Dialog.Container>
);
}

View File

@@ -0,0 +1,38 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { IconUsers } from '../../../base/icons/svg';
import Label from '../../../base/label/components/native/Label';
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
import { getVisitorsCount, getVisitorsShortText } from '../../functions';
const styles = {
raisedHandsCountLabel: {
alignItems: 'center',
backgroundColor: BaseTheme.palette.warning02,
borderRadius: BaseTheme.shape.borderRadius,
flexDirection: 'row',
marginLeft: BaseTheme.spacing[0],
marginBottom: BaseTheme.spacing[0]
},
raisedHandsCountLabelText: {
color: BaseTheme.palette.uiBackground,
paddingLeft: BaseTheme.spacing[2]
}
};
const VisitorsCountLabel = () => {
const visitorsCount = useSelector(getVisitorsCount);
return visitorsCount > 0 ? (
<Label
icon = { IconUsers }
iconColor = { BaseTheme.palette.uiBackground }
style = { styles.raisedHandsCountLabel }
text = { `${getVisitorsShortText(visitorsCount)}` }
textStyle = { styles.raisedHandsCountLabelText } />
) : null;
};
export default VisitorsCountLabel;

View File

@@ -0,0 +1,43 @@
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { Text, View, ViewStyle } from 'react-native';
import { useDispatch } from 'react-redux';
import { hangup } from '../../../base/connection/actions.native';
import LoadingIndicator from '../../../base/react/components/native/LoadingIndicator';
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
import Button from '../../../base/ui/components/native/Button';
import { BUTTON_TYPES } from '../../../base/ui/constants.any';
import lobbyStyles from '../../../lobby/components/native/styles';
import styles from './styles';
/**
* The component that renders visitors queue UI.
*
* @returns {ReactElement}
*/
export default function VisitorsQueue() {
const { t } = useTranslation();
const dispatch = useDispatch();
const onHangupClick = useCallback(() => {
dispatch(hangup());
}, []);
return (
<View style = { styles.visitorsQueue as ViewStyle }>
<Text style = { styles.visitorsQueueTitle }>
{ t('visitors.waitingMessage') }
</Text>
<LoadingIndicator
color = { BaseTheme.palette.icon01 }
style = { lobbyStyles.loadingIndicator } />
<Button
accessibilityLabel = 'toolbar.accessibilityLabel.leaveConference'
labelKey = 'toolbar.accessibilityLabel.leaveConference'
onClick = { onHangupClick }
style = { styles.hangupButton }
type = { BUTTON_TYPES.DESTRUCTIVE } />
</View>
);
}

View File

@@ -0,0 +1,34 @@
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
/**
* The styles of the feature visitors.
*/
export default {
hangupButton: {
marginTop: BaseTheme.spacing[3],
width: 240
},
raiseHandButton: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%'
},
visitorsQueue: {
alignItems: 'center',
display: 'flex',
justifyContent: 'center',
height: '100%',
width: '100%',
},
visitorsQueueTitle: {
...BaseTheme.typography.heading5,
color: BaseTheme.palette.text01,
marginBottom: BaseTheme.spacing[3],
textAlign: 'center'
},
};

View File

@@ -0,0 +1,72 @@
import { noop } from 'lodash-es';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
import ToolboxButtonWithPopup from '../../../base/toolbox/components/web/ToolboxButtonWithPopup';
import Dialog from '../../../base/ui/components/web/Dialog';
import { RaiseHandButton } from '../../../reactions/components/web/RaiseHandButton';
const useStyles = makeStyles()(theme => {
return {
raiseHand: {
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
marginTop: theme.spacing(3),
marginBottom: theme.spacing(3),
pointerEvents: 'none'
},
raiseHandTooltip: {
border: '1px solid #444',
borderRadius: theme.shape.borderRadius,
paddingBottom: theme.spacing(1),
paddingTop: theme.spacing(1),
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2)
},
raiseHandButton: {
display: 'inline-block',
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
position: 'relative'
}
};
});
/**
* Component that renders the join meeting dialog for visitors.
*
* @returns {JSX.Element}
*/
export default function JoinMeetingDialog() {
const { t } = useTranslation();
const { classes } = useStyles();
return (
<Dialog
cancel = {{ hidden: true }}
ok = {{ translationKey: 'dialog.Ok' }}
titleKey = 'visitors.joinMeeting.title'>
<div className = 'join-meeting-dialog'>
<p>{t('visitors.joinMeeting.description')}</p>
<div className = { classes.raiseHand }>
<p className = { classes.raiseHandTooltip }>{t('visitors.joinMeeting.raiseHand')}</p>
<div className = { classes.raiseHandButton }>
<ToolboxButtonWithPopup
onPopoverClose = { noop }
onPopoverOpen = { noop }
popoverContent = { null }
visible = { false }>
{/* @ts-ignore */}
<RaiseHandButton
disableClick = { true }
raisedHand = { true } />
</ToolboxButtonWithPopup>
</div>
</div>
<p>{t('visitors.joinMeeting.wishToSpeak')}</p>
</div>
</Dialog>
);
}

View File

@@ -0,0 +1,37 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { IconUsers } from '../../../base/icons/svg';
import Label from '../../../base/label/components/web/Label';
import Tooltip from '../../../base/tooltip/components/Tooltip';
import { getVisitorsCount, getVisitorsShortText } from '../../functions';
const useStyles = makeStyles()(theme => {
return {
label: {
backgroundColor: theme.palette.warning02,
color: theme.palette.uiBackground
}
};
});
const VisitorsCountLabel = () => {
const { classes: styles, theme } = useStyles();
const visitorsCount = useSelector(getVisitorsCount);
const { t } = useTranslation();
return visitorsCount > 0 ? (<Tooltip
content = { t('visitors.labelTooltip', { count: visitorsCount }) }
position = { 'bottom' }>
<Label
className = { styles.label }
icon = { IconUsers }
iconColor = { theme.palette.icon04 }
id = 'visitorsCountLabel'
text = { `${getVisitorsShortText(visitorsCount)}` } />
</Tooltip>) : null;
};
export default VisitorsCountLabel;

View File

@@ -0,0 +1,107 @@
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { hangup } from '../../../base/connection/actions.web';
import Button from '../../../base/ui/components/web/Button';
import LoadingIndicator from '../../../base/ui/components/web/Spinner';
const useStyles = makeStyles()(theme => {
return {
container: {
height: '100%',
position: 'absolute',
inset: '0 0 0 0',
display: 'flex',
backgroundColor: theme.palette.ui01,
zIndex: 252,
'@media (max-width: 720px)': {
flexDirection: 'column-reverse'
}
},
content: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
flexShrink: 0,
boxSizing: 'border-box',
position: 'relative',
width: '100%',
height: '100%',
zIndex: 252,
'@media (max-width: 720px)': {
height: 'auto',
margin: '0 auto'
},
// mobile phone landscape
'@media (max-width: 420px)': {
padding: '16px 16px 0 16px',
width: '100%'
},
'@media (max-width: 400px)': {
padding: '16px'
}
},
contentControls: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
margin: 'auto',
width: '100%'
},
roomName: {
...theme.typography.heading5,
color: theme.palette.text01,
marginBottom: theme.spacing(4),
overflow: 'hidden',
textAlign: 'center',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
width: '100%'
},
spinner: {
margin: theme.spacing(4),
}
};
});
/**
* The component that renders visitors queue UI.
*
* @returns {ReactElement}
*/
export default function VisitorsQueue() {
const { classes } = useStyles();
const { t } = useTranslation();
const dispatch = useDispatch();
const onHangupClick = useCallback(() => {
dispatch(hangup());
}, []);
return (<div
className = { classes.container }
id = 'visitors-waiting-queue'>
<div className = { classes.content }>
<div className = { classes.contentControls }>
<span className = { classes.roomName }>
{ t('visitors.waitingMessage') }
</span>
<div className = { classes.spinner }>
<LoadingIndicator size = 'large' />
</div>
<Button
labelKey = 'toolbar.accessibilityLabel.leaveConference'
onClick = { onHangupClick }
testId = 'toolbar.accessibilityLabel.leaveConference'
type = 'destructive' />
</div>
</div>
</div>);
}