feat(lobby/prejoin/native): style updates (#12615)

feat(lobby/prejoin/native): style updates (#12615)
mobile-22.7 jitsi-meet_8111
Calinteodor 3 years ago committed by GitHub
parent 691e92b7ec
commit 48a6472b3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      lang/main.json
  2. 2
      react/features/conference/components/native/Conference.js
  3. 104
      react/features/lobby/components/native/KnockingParticipantList.js
  4. 96
      react/features/lobby/components/native/LobbyScreen.js
  5. 216
      react/features/lobby/components/native/styles.js
  6. 1
      react/features/old-client-notification/functions.ts
  7. 1
      react/features/participants-pane/components/breakout-rooms/components/native/BreakoutRoomParticipantItem.js
  8. 29
      react/features/participants-pane/components/native/LobbyParticipantItem.js
  9. 4
      react/features/participants-pane/components/native/LobbyParticipantList.js
  10. 5
      react/features/participants-pane/components/native/MeetingParticipantItem.js
  11. 12
      react/features/participants-pane/components/native/ParticipantItem.js
  12. 28
      react/features/participants-pane/components/native/styles.js
  13. 50
      react/features/prejoin/components/native/Prejoin.tsx
  14. 9
      react/features/prejoin/components/native/styles.js

@ -563,7 +563,6 @@
"lobby": { "lobby": {
"admit": "Admit", "admit": "Admit",
"admitAll": "Admit all", "admitAll": "Admit all",
"allow": "Allow",
"backToKnockModeButton": "Ask to join", "backToKnockModeButton": "Ask to join",
"chat": "Chat", "chat": "Chat",
"dialogTitle": "Lobby mode", "dialogTitle": "Lobby mode",

@ -462,7 +462,7 @@ class Conference extends AbstractConference<Props, State> {
{/* eslint-disable-next-line react/jsx-no-bind */} {/* eslint-disable-next-line react/jsx-no-bind */}
<AlwaysOnLabels createOnPress = { this._createOnPress } /> <AlwaysOnLabels createOnPress = { this._createOnPress } />
</View> </View>
{this._renderNotificationsContainer()} { this._renderNotificationsContainer() }
<KnockingParticipantList /> <KnockingParticipantList />
</SafeAreaView> </SafeAreaView>

@ -1,21 +1,22 @@
// @flow
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { View } from 'react-native';
import { Avatar } from '../../../base/avatar'; import { translate } from '../../../base/i18n/functions';
import { translate } from '../../../base/i18n'; import { isLocalParticipantModerator } from '../../../base/participants/functions';
import { isLocalParticipantModerator } from '../../../base/participants';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { handleLobbyChatInitialized } from '../../../chat/actions.any'; import Button from '../../../base/ui/components/native/Button';
import { BUTTON_TYPES } from '../../../base/ui/constants.native';
import { handleLobbyChatInitialized } from '../../../chat/actions.native';
import { navigate } from '../../../mobile/navigation/components/conference/ConferenceNavigationContainerRef'; import { navigate } from '../../../mobile/navigation/components/conference/ConferenceNavigationContainerRef';
import { screen } from '../../../mobile/navigation/routes'; import { screen } from '../../../mobile/navigation/routes';
import { setKnockingParticipantApproval } from '../../actions'; import ParticipantItem
import { HIDDEN_EMAILS } from '../../constants'; from '../../../participants-pane/components/native/ParticipantItem';
import { setKnockingParticipantApproval } from '../../actions.native';
import { getKnockingParticipants, getLobbyEnabled, showLobbyChatButton } from '../../functions'; import { getKnockingParticipants, getLobbyEnabled, showLobbyChatButton } from '../../functions';
import styles from './styles'; import styles from './styles';
/** /**
* Props type of the component. * Props type of the component.
*/ */
@ -44,12 +45,7 @@ export type Props = {
/** /**
* The Redux Dispatch function. * The Redux Dispatch function.
*/ */
dispatch: Function, dispatch: Function
/**
* Function to be used to translate i18n labels.
*/
t: Function
}; };
/** /**
@ -74,68 +70,47 @@ class KnockingParticipantList extends PureComponent<Props> {
* @inheritdoc * @inheritdoc
*/ */
render() { render() {
const { _participants, _visible, _showChatButton, t } = this.props; const { _participants, _visible, _showChatButton } = this.props;
if (!_visible) { if (!_visible) {
return null; return null;
} }
return ( return (
<ScrollView <>
style = { styles.knockingParticipantList }>
{ _participants.map(p => ( { _participants.map(p => (
<View <View
key = { p.id } key = { p.id }
style = { styles.knockingParticipantListEntry }> style = { styles.knockingParticipantListEntry }>
<Avatar <ParticipantItem
displayName = { p.name } displayName = { p.name }
size = { 48 } isKnockingParticipant = { true }
url = { p.loadableAvatarUrl } /> key = { p.id }
<View style = { styles.knockingParticipantListDetails }> participantID = { p.id }>
<Text style = { styles.knockingParticipantListText }> <Button
{ p.name } labelKey = { 'lobby.admit' }
</Text> onClick = { this._onRespondToParticipant(p.id, true) }
{ p.email && !HIDDEN_EMAILS.includes(p.email) && ( style = { styles.lobbyButtonAdmit }
<Text style = { styles.knockingParticipantListText }> type = { BUTTON_TYPES.PRIMARY } />
{ p.email } {
</Text> _showChatButton(p)
) } ? (
</View> <Button
<TouchableOpacity labelKey = { 'lobby.chat' }
onPress = { this._onRespondToParticipant(p.id, true) } onClick = { this._onInitializeLobbyChat(p.id) }
style = { [ style = { styles.lobbyButtonChat }
styles.knockingParticipantListButton, type = { BUTTON_TYPES.SECONDARY } />
styles.knockingParticipantListPrimaryButton ) : null
] }> }
<Text style = { styles.knockingParticipantListText }> <Button
{ t('lobby.allow') } labelKey = { 'lobby.reject' }
</Text> onClick = { this._onRespondToParticipant(p.id, false) }
</TouchableOpacity> style = { styles.lobbyButtonReject }
<TouchableOpacity type = { BUTTON_TYPES.DESTRUCTIVE } />
onPress = { this._onRespondToParticipant(p.id, false) } </ParticipantItem>
style = { [
styles.knockingParticipantListButton,
styles.knockingParticipantListSecondaryButton
] }>
<Text style = { styles.knockingParticipantListText }>
{ t('lobby.reject') }
</Text>
</TouchableOpacity>
{_showChatButton(p) ? (
<TouchableOpacity
onPress = { this._onInitializeLobbyChat(p.id) }
style = { [
styles.knockingParticipantListButton,
styles.knockingParticipantListSecondaryButton
] }>
<Text style = { styles.knockingParticipantListText }>
{ t('lobby.chat') }
</Text>
</TouchableOpacity>
) : null}
</View> </View>
)) } )) }
</ScrollView> </>
); );
} }
@ -168,6 +143,7 @@ class KnockingParticipantList extends PureComponent<Props> {
if (this.props._isPollsDisabled) { if (this.props._isPollsDisabled) {
return navigate(screen.conference.chat); return navigate(screen.conference.chat);
} }
navigate(screen.conference.chatandpolls.main); navigate(screen.conference.chatandpolls.main);
}; };
} }

@ -16,6 +16,7 @@ import { LargeVideo } from '../../../large-video/components';
import { navigate } import { navigate }
from '../../../mobile/navigation/components/lobby/LobbyNavigationContainerRef'; from '../../../mobile/navigation/components/lobby/LobbyNavigationContainerRef';
import { screen } from '../../../mobile/navigation/routes'; import { screen } from '../../../mobile/navigation/routes';
import { preJoinStyles } from '../../../prejoin/components/native/styles';
import AudioMuteButton from '../../../toolbox/components/AudioMuteButton'; import AudioMuteButton from '../../../toolbox/components/AudioMuteButton';
import VideoMuteButton from '../../../toolbox/components/VideoMuteButton'; import VideoMuteButton from '../../../toolbox/components/VideoMuteButton';
import AbstractLobbyScreen, { import AbstractLobbyScreen, {
@ -48,32 +49,39 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
* @inheritdoc * @inheritdoc
*/ */
render() { render() {
const { _aspectRatio } = this.props; const { _aspectRatio, _roomName } = this.props;
let contentWrapperStyles; let contentWrapperStyles;
let contentContainerStyles; let contentContainerStyles;
let largeVideoContainerStyles; let largeVideoContainerStyles;
if (_aspectRatio === ASPECT_RATIO_NARROW) { if (_aspectRatio === ASPECT_RATIO_NARROW) {
contentWrapperStyles = styles.contentWrapper; contentWrapperStyles = preJoinStyles.contentWrapper;
largeVideoContainerStyles = styles.largeVideoContainer; largeVideoContainerStyles = preJoinStyles.largeVideoContainer;
contentContainerStyles = styles.contentContainer; contentContainerStyles = styles.contentContainer;
} else { } else {
contentWrapperStyles = styles.contentWrapperWide; contentWrapperStyles = preJoinStyles.contentWrapperWide;
largeVideoContainerStyles = styles.largeVideoContainerWide; largeVideoContainerStyles = preJoinStyles.largeVideoContainerWide;
contentContainerStyles = styles.contentContainerWide; contentContainerStyles = preJoinStyles.contentContainerWide;
} }
return ( return (
<JitsiScreen <JitsiScreen
safeAreaInsets = { [ 'left' ] } safeAreaInsets = { [ 'right' ] }
style = { contentWrapperStyles }> style = { contentWrapperStyles }>
<BrandingImageBackground /> <BrandingImageBackground />
<View style = { largeVideoContainerStyles }> <View style = { largeVideoContainerStyles }>
<View style = { preJoinStyles.displayRoomNameBackdrop }>
<Text
numberOfLines = { 1 }
style = { preJoinStyles.preJoinRoomName }>
{ _roomName }
</Text>
</View>
<LargeVideo /> <LargeVideo />
</View> </View>
<View style = { contentContainerStyles }> <View style = { contentContainerStyles }>
{ this._renderContent() }
{ this._renderToolbarButtons() } { this._renderToolbarButtons() }
{ this._renderContent() }
</View> </View>
</JitsiScreen> </JitsiScreen>
); );
@ -122,15 +130,10 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
*/ */
_renderJoining() { _renderJoining() {
return ( return (
<View> <View style = { styles.lobbyWaitingFragmentContainer }>
<Text style = { styles.lobbyTitle }> <Text style = { styles.lobbyTitle }>
{ this.props.t('lobby.joiningTitle') } { this.props.t('lobby.joiningTitle') }
</Text> </Text>
<Text
numberOfLines = { 1 }
style = { styles.lobbyRoomName }>
{ this.props._roomName }
</Text>
<LoadingIndicator <LoadingIndicator
color = { BaseTheme.palette.icon01 } color = { BaseTheme.palette.icon01 }
style = { styles.loadingIndicator } /> style = { styles.loadingIndicator } />
@ -153,7 +156,7 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
return ( return (
<Input <Input
customStyles = {{ input: styles.customInput }} customStyles = {{ input: preJoinStyles.customInput }}
onChange = { this._onChangeDisplayName } onChange = { this._onChangeDisplayName }
placeholder = { t('lobby.nameField') } placeholder = { t('lobby.nameField') }
value = { displayName } /> value = { displayName } />
@ -178,19 +181,15 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
const { _passwordJoinFailed, t } = this.props; const { _passwordJoinFailed, t } = this.props;
return ( return (
<View style = { styles.formWrapper }> <Input
<Input autoCapitalize = 'none'
autoCapitalize = 'none' autoCompleteType = 'off'
autoCompleteType = 'off' customStyles = {{ input: styles.customInput }}
customStyles = {{ input: styles.customInput }} error = { _passwordJoinFailed }
onChange = { this._onChangePassword } onChange = { this._onChangePassword }
placeholder = { t('lobby.passwordField') } placeholder = { t('lobby.passwordField') }
secureTextEntry = { true } secureTextEntry = { true }
value = { this.state.password } /> value = { this.state.password } />
{ _passwordJoinFailed && <Text style = { styles.fieldError }>
{ t('lobby.invalidPassword') }
</Text> }
</View>
); );
} }
@ -201,20 +200,20 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
*/ */
_renderPasswordJoinButtons() { _renderPasswordJoinButtons() {
return ( return (
<View style = { styles.passwordJoinButtonsWrapper }> <View style = { styles.passwordJoinButtons }>
<Button
accessibilityLabel = 'lobby.backToKnockModeButton'
labelKey = 'lobby.backToKnockModeButton'
onClick = { this._onSwitchToKnockMode }
style = { styles.lobbyButton }
type = { BUTTON_TYPES.PRIMARY } />
<Button <Button
accessibilityLabel = 'lobby.passwordJoinButton' accessibilityLabel = 'lobby.passwordJoinButton'
disabled = { !this.state.password } disabled = { !this.state.password }
labelKey = 'lobby.passwordJoinButton' labelKey = { 'lobby.passwordJoinButton' }
onClick = { this._onJoinWithPassword } onClick = { this._onJoinWithPassword }
style = { styles.lobbyButton } style = { preJoinStyles.joinButton }
type = { BUTTON_TYPES.PRIMARY } /> type = { BUTTON_TYPES.PRIMARY } />
<Button
accessibilityLabel = 'lobby.backToKnockModeButton'
labelKey = 'lobby.backToKnockModeButton'
onClick = { this._onSwitchToKnockMode }
style = { preJoinStyles.joinButton }
type = { BUTTON_TYPES.TERTIARY } />
</View> </View>
); );
} }
@ -225,21 +224,12 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
* @inheritdoc * @inheritdoc
*/ */
_renderToolbarButtons() { _renderToolbarButtons() {
const { _aspectRatio } = this.props;
let toolboxContainerStyles;
if (_aspectRatio === ASPECT_RATIO_NARROW) {
toolboxContainerStyles = styles.toolboxContainer;
} else {
toolboxContainerStyles = styles.toolboxContainerWide;
}
return ( return (
<View style = { toolboxContainerStyles }> <View style = { preJoinStyles.toolboxContainer }>
<AudioMuteButton <AudioMuteButton
styles = { styles.buttonStylesBorderless } /> styles = { preJoinStyles.buttonStylesBorderless } />
<VideoMuteButton <VideoMuteButton
styles = { styles.buttonStylesBorderless } /> styles = { preJoinStyles.buttonStylesBorderless } />
</View> </View>
); );
} }
@ -254,14 +244,14 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
const { displayName } = this.state; const { displayName } = this.state;
return ( return (
<View style = { styles.standardButtonWrapper }> <View style = { styles.formWrapper }>
{ {
_knocking && _isLobbyChatActive _knocking && _isLobbyChatActive
&& <Button && <Button
accessibilityLabel = 'toolbar.openChat' accessibilityLabel = 'toolbar.openChat'
labelKey = 'toolbar.openChat' labelKey = 'toolbar.openChat'
onClick = { this._onNavigateToLobbyChat } onClick = { this._onNavigateToLobbyChat }
style = { styles.openChatButton } style = { preJoinStyles.joinButton }
type = { BUTTON_TYPES.PRIMARY } /> type = { BUTTON_TYPES.PRIMARY } />
} }
{ {
@ -271,7 +261,7 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
disabled = { !displayName } disabled = { !displayName }
labelKey = 'lobby.knockButton' labelKey = 'lobby.knockButton'
onClick = { this._onAskToJoin } onClick = { this._onAskToJoin }
style = { styles.lobbyButton } style = { preJoinStyles.joinButton }
type = { BUTTON_TYPES.PRIMARY } /> type = { BUTTON_TYPES.PRIMARY } />
} }
{ {
@ -280,7 +270,7 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
accessibilityLabel = 'lobby.enterPasswordButton' accessibilityLabel = 'lobby.enterPasswordButton'
labelKey = 'lobby.enterPasswordButton' labelKey = 'lobby.enterPasswordButton'
onClick = { this._onSwitchToPasswordMode } onClick = { this._onSwitchToPasswordMode }
style = { styles.enterPasswordButton } style = { preJoinStyles.joinButton }
type = { BUTTON_TYPES.PRIMARY } /> type = { BUTTON_TYPES.PRIMARY } />
} }
</View> </View>

@ -1,32 +1,8 @@
// @flow
import BaseTheme from '../../../base/ui/components/BaseTheme.native'; import BaseTheme from '../../../base/ui/components/BaseTheme.native';
const SECONDARY_COLOR = BaseTheme.palette.border04;
const lobbyText = {
...BaseTheme.typography.heading5,
color: BaseTheme.palette.text01,
textAlign: 'center'
};
export default { export default {
buttonStylesBorderless: {
iconStyle: {
color: BaseTheme.palette.icon01,
fontSize: 24
},
style: {
flexDirection: 'row',
justifyContent: 'center',
marginHorizontal: BaseTheme.spacing[3],
height: 24,
width: 24
},
underlayColor: 'transparent'
},
lobbyChatWrapper: { lobbyChatWrapper: {
backgroundColor: BaseTheme.palette.ui01, backgroundColor: BaseTheme.palette.ui01,
alignItems: 'stretch', alignItems: 'stretch',
@ -35,118 +11,32 @@ export default {
height: '100%' height: '100%'
}, },
lobbyChatHeader: { passwordJoinButtons: {
flexDirection: 'row', top: 40
padding: 20
},
lobbyChatTitle: {
color: BaseTheme.palette.text01,
fontSize: 20,
fontWeight: 'bold',
flexShrink: 1
},
lobbyChatCloseButton: {
fontSize: 24,
marginLeft: BaseTheme.spacing[3],
marginTop: BaseTheme.spacing[1],
color: BaseTheme.palette.icon01
},
contentWrapper: {
flex: 1
},
contentWrapperWide: {
flex: 1,
flexDirection: 'row'
},
largeVideoContainer: {
minHeight: '50%'
},
largeVideoContainerWide: {
height: '100%',
marginRight: 'auto',
position: 'absolute',
width: '50%'
}, },
contentContainer: { contentContainer: {
alignSelf: 'center',
display: 'flex',
justifyContent: 'center',
minHeight: '50%',
paddingHorizontal: BaseTheme.spacing[3],
width: 400
},
contentContainerWide: {
alignItems: 'center',
height: '100%',
justifyContent: 'center',
left: '50%',
paddingHorizontal: BaseTheme.spacing[3],
position: 'absolute',
width: '50%'
},
toolboxContainer: {
alignItems: 'center', alignItems: 'center',
backgroundColor: BaseTheme.palette.uiBackground,
bottom: 0,
display: 'flex', display: 'flex',
flexDirection: 'row', height: 388,
justifyContent: 'center', justifyContent: 'center',
marginTop: BaseTheme.spacing[3] position: 'absolute',
}, width: '100%',
zIndex: 1
toolboxContainerWide: {
flexDirection: 'row',
justifyContent: 'center',
marginTop: BaseTheme.spacing[3]
},
displayNameText: {
fontWeight: 'bold',
marginVertical: 10
},
editButton: {
alignSelf: 'flex-end',
paddingHorizontal: 10
},
editIcon: {
color: 'black',
fontSize: 16
}, },
formWrapper: { formWrapper: {
alignSelf: 'stretch', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center'
marginTop: 38
}, },
customInput: { customInput: {
marginHorizontal: BaseTheme.spacing[3], position: 'relative',
textAlign: 'center' textAlign: 'center',
}, top: BaseTheme.spacing[6],
width: 352
fieldError: {
color: BaseTheme.palette.warning03,
marginLeft: BaseTheme.spacing[3],
fontSize: 16
},
fieldLabel: {
...BaseTheme.typography.heading6,
color: BaseTheme.palette.text01,
textAlign: 'center'
},
standardButtonWrapper: {
alignSelf: 'stretch'
}, },
joiningMessage: { joiningMessage: {
@ -155,84 +45,58 @@ export default {
textAlign: 'center' textAlign: 'center'
}, },
passwordJoinButtonsWrapper: {
alignItems: 'stretch',
alignSelf: 'stretch',
marginHorizontal: BaseTheme.spacing[3]
},
loadingIndicator: { loadingIndicator: {
marginBottom: BaseTheme.spacing[3] marginBottom: BaseTheme.spacing[3]
}, },
participantBox: {
alignItems: 'center',
alignSelf: 'stretch',
borderColor: SECONDARY_COLOR,
borderRadius: 4,
borderWidth: 1,
marginVertical: 18,
paddingVertical: 12
},
lobbyButton: {
marginTop: BaseTheme.spacing[3]
},
openChatButton: {
marginHorizontal: BaseTheme.spacing[3],
marginTop: BaseTheme.spacing[3]
},
enterPasswordButton: {
marginHorizontal: BaseTheme.spacing[3],
marginTop: BaseTheme.spacing[3]
},
// KnockingParticipantList // KnockingParticipantList
knockingParticipantList: { knockingParticipantList: {
alignSelf: 'stretch', backgroundColor: BaseTheme.palette.ui01
backgroundColor: 'rgba(22, 38, 55, 0.8)',
flexDirection: 'column'
}, },
knockingParticipantListButton: {
borderRadius: 4,
marginHorizontal: 3,
paddingHorizontal: 10,
paddingVertical: 5
},
knockingParticipantListDetails: { knockingParticipantListDetails: {
flex: 1, flex: 1,
marginLeft: 10 marginLeft: BaseTheme.spacing[2]
}, },
knockingParticipantListEntry: { knockingParticipantListEntry: {
alignItems: 'center', alignItems: 'center',
flexDirection: 'row', backgroundColor: BaseTheme.palette.ui01,
padding: 10 flexDirection: 'row'
},
knockingParticipantListText: {
color: 'white'
}, },
knockingParticipantListPrimaryButton: { lobbyButtonAdmit: {
backgroundColor: 'rgb(3, 118, 218)' position: 'absolute',
right: 184,
top: 6
}, },
knockingParticipantListSecondaryButton: { lobbyButtonChat: {
backgroundColor: 'transparent' position: 'absolute',
right: 104,
top: 6
}, },
knockingParticipantListText: { lobbyButtonReject: {
color: 'white' position: 'absolute',
right: 16,
top: 6
}, },
lobbyTitle: { lobbyTitle: {
...lobbyText ...BaseTheme.typography.heading5,
color: BaseTheme.palette.text01,
marginBottom: BaseTheme.spacing[3],
textAlign: 'center'
}, },
lobbyRoomName: { lobbyWaitingFragmentContainer: {
...lobbyText, height: 260
marginBottom: BaseTheme.spacing[2]
} }
}; };

@ -10,6 +10,7 @@ export function isOldJitsiMeetElectronApp() {
return false; return false;
} }
// @ts-ignore
const match = navigator.userAgent.match(/(JitsiMeet)\s*\/\s*((\d+)\.[^\s]*)/); const match = navigator.userAgent.match(/(JitsiMeet)\s*\/\s*((\d+)\.[^\s]*)/);
if (!Array.isArray(match) || match.length < 3) { if (!Array.isArray(match) || match.length < 3) {

@ -33,7 +33,6 @@ const BreakoutRoomParticipantItem = ({ item, room }: Props) => {
return ( return (
<ParticipantItem <ParticipantItem
displayName = { item.displayName || defaultRemoteDisplayName } displayName = { item.displayName || defaultRemoteDisplayName }
isKnockingParticipant = { false }
isModerator = { isParticipantModerator(item) } isModerator = { isParticipantModerator(item) }
key = { item.jid } key = { item.jid }
onPress = { onPress } onPress = { onPress }

@ -1,18 +1,14 @@
// @flow
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { hasRaisedHand } from '../../../base/participants';
import Button from '../../../base/ui/components/native/Button'; import Button from '../../../base/ui/components/native/Button';
import { BUTTON_TYPES } from '../../../base/ui/constants.native'; import { BUTTON_TYPES } from '../../../base/ui/constants.native';
import { approveKnockingParticipant } from '../../../lobby/actions.native'; import { setKnockingParticipantApproval } from '../../../lobby/actions.native';
import { showContextMenuReject } from '../../actions.native';
import { MEDIA_STATE } from '../../constants';
import ParticipantItem from './ParticipantItem'; import ParticipantItem from './ParticipantItem';
import styles from './styles'; import styles from './styles';
type Props = { type Props = {
/** /**
@ -23,25 +19,26 @@ type Props = {
export const LobbyParticipantItem = ({ participant: p }: Props) => { export const LobbyParticipantItem = ({ participant: p }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const admit = useCallback(() => dispatch(approveKnockingParticipant(p.id), [ dispatch ])); const admit = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, true), [ dispatch ]));
const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ])); const reject = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, false), [ dispatch ]));
return ( return (
<ParticipantItem <ParticipantItem
audioMediaState = { MEDIA_STATE.NONE }
displayName = { p.name } displayName = { p.name }
isKnockingParticipant = { true } isKnockingParticipant = { true }
local = { p.local } key = { p.id }
onPress = { openContextMenuReject } participantID = { p.id } >
participant = { p } <Button
participantID = { p.id } accessibilityLabel = 'lobby.reject'
raisedHand = { hasRaisedHand(p) } labelKey = 'lobby.reject'
videoMediaState = { MEDIA_STATE.NONE }> onClick = { reject }
style = { styles.lobbyButtonReject }
type = { BUTTON_TYPES.DESTRUCTIVE } />
<Button <Button
accessibilityLabel = 'lobby.admit' accessibilityLabel = 'lobby.admit'
labelKey = 'lobby.admit' labelKey = 'lobby.admit'
onClick = { admit } onClick = { admit }
style = { styles.participantActionsButtonAdmit } style = { styles.lobbyButtonAdmit }
type = { BUTTON_TYPES.PRIMARY } /> type = { BUTTON_TYPES.PRIMARY } />
</ParticipantItem> </ParticipantItem>
); );

@ -32,8 +32,8 @@ const LobbyParticipantList = () => {
const title = ( const title = (
<View style = { styles.lobbyListDetails } > <View style = { styles.lobbyListDetails } >
<Text style = { styles.lobbyListDescription }> <Text style = { styles.lobbyListDescription }>
{t('participantsPane.headings.waitingLobby', { t('participantsPane.headings.waitingLobby',
{ count: participants.length })} { count: participants.length }) }
</Text> </Text>
{ {
participants.length > 1 && ( participants.length > 1 && (

@ -1,5 +1,3 @@
// @flow
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n';
@ -152,7 +150,6 @@ class MeetingParticipantItem extends PureComponent<Props> {
audioMediaState = { _audioMediaState } audioMediaState = { _audioMediaState }
disableModeratorIndicator = { _disableModeratorIndicator } disableModeratorIndicator = { _disableModeratorIndicator }
displayName = { _displayName } displayName = { _displayName }
isKnockingParticipant = { false }
isModerator = { _isModerator } isModerator = { _isModerator }
local = { _local } local = { _local }
onPress = { this._onPress } onPress = { this._onPress }
@ -202,5 +199,3 @@ function mapStateToProps(state, ownProps): Object {
export default translate(connect(mapStateToProps)(MeetingParticipantItem)); export default translate(connect(mapStateToProps)(MeetingParticipantItem));

@ -77,7 +77,7 @@ function ParticipantItem({
children, children,
displayName, displayName,
disableModeratorIndicator, disableModeratorIndicator,
isKnockingParticipant, isKnockingParticipant = false,
isModerator, isModerator,
local, local,
onPress, onPress,
@ -109,11 +109,11 @@ function ParticipantItem({
numberOfLines = { 1 } numberOfLines = { 1 }
style = { styles.participantName }> style = { styles.participantName }>
{ displayName } { displayName }
{local && ` (${t('chat.you')})` } { local && ` (${t('chat.you')})` }
</Text> </Text>
</View> </View>
{isModerator && !disableModeratorIndicator { isModerator && !disableModeratorIndicator
&& <Text style = { styles.moderatorLabel }>{t('videothumbnail.moderator')}</Text> && <Text style = { styles.moderatorLabel }>{ t('videothumbnail.moderator') }</Text>
} }
</View> </View>
{ {
@ -121,8 +121,8 @@ function ParticipantItem({
&& <> && <>
{ raisedHand && <RaisedHandIndicator /> } { raisedHand && <RaisedHandIndicator /> }
<View style = { styles.participantStatesContainer }> <View style = { styles.participantStatesContainer }>
<View style = { styles.participantStateVideo }>{VideoStateIcons[videoMediaState]}</View> <View style = { styles.participantStateVideo }>{ VideoStateIcons[videoMediaState] }</View>
<View>{AudioStateIcons[audioMediaState]}</View> <View>{ AudioStateIcons[audioMediaState] }</View>
</View> </View>
</> </>
} }

@ -56,6 +56,12 @@ const contextMenuItem = {
export default { export default {
participantActionsButtonAdmit: { participantActionsButtonAdmit: {
marginRight: BaseTheme.spacing[3],
position: 'absolute',
right: 88
},
participantActionsButtonReject: {
marginRight: BaseTheme.spacing[3], marginRight: BaseTheme.spacing[3],
position: 'absolute', position: 'absolute',
right: 0 right: 0
@ -69,8 +75,6 @@ export default {
participantContainer: { participantContainer: {
alignItems: 'center', alignItems: 'center',
borderBottomColor: BaseTheme.palette.field01Hover,
borderBottomWidth: 2,
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
height: BaseTheme.spacing[9], height: BaseTheme.spacing[9],
@ -81,6 +85,8 @@ export default {
participantContent: { participantContent: {
alignItems: 'center', alignItems: 'center',
borderBottomColor: BaseTheme.palette.field01Hover,
borderBottomWidth: 2.4,
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
height: '100%', height: '100%',
@ -145,7 +151,17 @@ export default {
}, },
lobbyListContent: { lobbyListContent: {
height: '16%' height: '24%'
},
lobbyButtonAdmit: {
position: 'absolute',
right: 16
},
lobbyButtonReject: {
position: 'absolute',
right: 104
}, },
lobbyListDescription: { lobbyListDescription: {
@ -170,11 +186,11 @@ export default {
}, },
meetingListContainer: { meetingListContainer: {
height: '58%' height: '56%'
}, },
meetingListFullContainer: { meetingListFullContainer: {
height: '82%' height: '80%'
}, },
meetingListDescription: { meetingListDescription: {
@ -183,7 +199,7 @@ export default {
}, },
collapsibleRoomContainer: { collapsibleRoomContainer: {
height: '30%' height: '32%'
}, },
participantsPaneContainer: { participantsPaneContainer: {

@ -10,8 +10,7 @@ import {
StyleProp, StyleProp,
Text, Text,
TextStyle, TextStyle,
View, View
ViewStyle
} from 'react-native'; } from 'react-native';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
@ -45,8 +44,9 @@ import AudioMuteButton from '../../../toolbox/components/AudioMuteButton';
import VideoMuteButton from '../../../toolbox/components/VideoMuteButton'; import VideoMuteButton from '../../../toolbox/components/VideoMuteButton';
import { isDisplayNameRequired } from '../../functions'; import { isDisplayNameRequired } from '../../functions';
import { IPrejoinProps } from '../../types'; import { IPrejoinProps } from '../../types';
// @ts-ignore // @ts-ignore
import styles from '../styles'; import { preJoinStyles as styles } from './styles';
const Prejoin: React.FC<IPrejoinProps> = ({ navigation }: IPrejoinProps) => { const Prejoin: React.FC<IPrejoinProps> = ({ navigation }: IPrejoinProps) => {
@ -166,29 +166,27 @@ const Prejoin: React.FC<IPrejoinProps> = ({ navigation }: IPrejoinProps) => {
// @ts-ignore // @ts-ignore
styles = { styles.buttonStylesBorderless } /> styles = { styles.buttonStylesBorderless } />
</View> </View>
<View style = { styles.formWrapper as StyleProp<ViewStyle> }> <Input
<Input // @ts-ignore
// @ts-ignore customStyles = {{ input: styles.customInput }}
customStyles = {{ input: styles.customInput }} onChange = { onChangeDisplayName }
onChange = { onChangeDisplayName } placeholder = { t('dialog.enterDisplayName') }
placeholder = { t('dialog.enterDisplayName') } value = { displayName } />
value = { displayName } /> <Button
<Button accessibilityLabel = 'prejoin.joinMeeting'
accessibilityLabel = 'prejoin.joinMeeting' disabled = { joinButtonDisabled }
disabled = { joinButtonDisabled } labelKey = 'prejoin.joinMeeting'
labelKey = 'prejoin.joinMeeting' // @ts-ignore
// @ts-ignore onClick = { !isJoining && onJoin }
onClick = { !isJoining && onJoin } style = { styles.joinButton }
style = { styles.joinButton } type = { PRIMARY } />
type = { PRIMARY } /> <Button
<Button accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode'
accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode' disabled = { joinButtonDisabled }
disabled = { joinButtonDisabled } labelKey = 'prejoin.joinMeetingInLowBandwidthMode'
labelKey = 'prejoin.joinMeetingInLowBandwidthMode' onClick = { onJoinLowBandwidth }
onClick = { onJoinLowBandwidth } style = { styles.joinButton }
style = { styles.joinButton } type = { TERTIARY } />
type = { TERTIARY } />
</View>
</View> </View>
</JitsiScreen> </JitsiScreen>
); );

@ -1,7 +1,7 @@
import BaseTheme from '../../base/ui/components/BaseTheme.native'; import BaseTheme from '../../../base/ui/components/BaseTheme.native';
export default { export const preJoinStyles = {
joinButton: { joinButton: {
marginTop: BaseTheme.spacing[3], marginTop: BaseTheme.spacing[3],
@ -78,11 +78,6 @@ export default {
width: 148 width: 148
}, },
formWrapper: {
alignItems: 'center',
justifyContent: 'center'
},
customInput: { customInput: {
textAlign: 'center', textAlign: 'center',
width: 352 width: 352
Loading…
Cancel
Save