feat(base/native): button abstractions (#11795)
* feat(base): created Button.tsx and IconButton.tsx
This commit is contained in:
parent
a685f096a0
commit
d42e18c7bb
|
@ -1,44 +0,0 @@
|
||||||
/* @flow */
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { Text, TouchableOpacity } from 'react-native';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Elements to display within the component.
|
|
||||||
*/
|
|
||||||
children: React$Node | Object,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler called when the user presses the button.
|
|
||||||
*/
|
|
||||||
onValueChange: Function,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The component's external style.
|
|
||||||
*/
|
|
||||||
style: Object
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a button.
|
|
||||||
*/
|
|
||||||
export default class ButtonImpl extends Component<Props> {
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}, renders the button.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress = { this.props.onValueChange } >
|
|
||||||
<Text style = { this.props.style }>
|
|
||||||
{ this.props.children }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Button as NativePaperButton } from 'react-native-paper';
|
||||||
|
|
||||||
|
import BaseTheme from '../../../ui/components/BaseTheme.native';
|
||||||
|
import styles from './styles';
|
||||||
|
import { BUTTON_MODES, BUTTON_TYPES } from '../../constants';
|
||||||
|
import { ButtonProps } from '../../types';
|
||||||
|
|
||||||
|
|
||||||
|
const Button: React.FC<ButtonProps> = ({
|
||||||
|
accessibilityLabel,
|
||||||
|
color: buttonColor,
|
||||||
|
disabled,
|
||||||
|
icon,
|
||||||
|
label,
|
||||||
|
labelStyle,
|
||||||
|
onPress,
|
||||||
|
style,
|
||||||
|
type
|
||||||
|
}: ButtonProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { CONTAINED, TEXT } = BUTTON_MODES;
|
||||||
|
const { DESTRUCTIVE, PRIMARY, SECONDARY, TERTIARY } = BUTTON_TYPES;
|
||||||
|
|
||||||
|
let buttonLabelStyles;
|
||||||
|
let buttonStyles;
|
||||||
|
let color;
|
||||||
|
let mode;
|
||||||
|
|
||||||
|
if (type === PRIMARY) {
|
||||||
|
buttonLabelStyles = styles.buttonLabelPrimary;
|
||||||
|
color = BaseTheme.palette.action01;
|
||||||
|
mode = CONTAINED
|
||||||
|
} else if (type === SECONDARY) {
|
||||||
|
buttonLabelStyles = styles.buttonLabelSecondary;
|
||||||
|
color = BaseTheme.palette.action02;
|
||||||
|
mode = CONTAINED
|
||||||
|
} else if (type === DESTRUCTIVE) {
|
||||||
|
color = BaseTheme.palette.actionDanger;
|
||||||
|
buttonLabelStyles = styles.buttonLabelDestructive;
|
||||||
|
mode = CONTAINED
|
||||||
|
} else if ( type === TERTIARY) {
|
||||||
|
buttonLabelStyles = styles.buttonLabelTertiary
|
||||||
|
mode = TEXT
|
||||||
|
} else {
|
||||||
|
color = buttonColor;
|
||||||
|
buttonLabelStyles = styles.buttonLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled) {
|
||||||
|
buttonLabelStyles = styles.buttonLabelDisabled;
|
||||||
|
buttonStyles = styles.buttonDisabled;
|
||||||
|
} else {
|
||||||
|
buttonStyles = styles.button;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NativePaperButton
|
||||||
|
accessibilityLabel = { t(accessibilityLabel) }
|
||||||
|
children = { t(label) }
|
||||||
|
color = { color }
|
||||||
|
disabled = { disabled }
|
||||||
|
icon = { icon }
|
||||||
|
labelStyle = { [
|
||||||
|
buttonLabelStyles,
|
||||||
|
labelStyle
|
||||||
|
] }
|
||||||
|
mode = { mode }
|
||||||
|
onPress = { onPress }
|
||||||
|
style = { [
|
||||||
|
buttonStyles,
|
||||||
|
style
|
||||||
|
] } />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Button;
|
|
@ -0,0 +1,64 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { TouchableRipple } from 'react-native-paper';
|
||||||
|
|
||||||
|
import { Icon } from '../../../icons';
|
||||||
|
import BaseTheme from '../../../ui/components/BaseTheme.native';
|
||||||
|
import styles from './styles';
|
||||||
|
import { BUTTON_TYPES } from '../../constants';
|
||||||
|
import { IconButtonProps } from '../../types';
|
||||||
|
|
||||||
|
|
||||||
|
const IconButton: React.FC<IconButtonProps> = ({
|
||||||
|
accessibilityLabel,
|
||||||
|
color: iconColor,
|
||||||
|
disabled,
|
||||||
|
onPress,
|
||||||
|
size,
|
||||||
|
src,
|
||||||
|
style,
|
||||||
|
tapColor,
|
||||||
|
type
|
||||||
|
}: IconButtonProps) => {
|
||||||
|
const { PRIMARY, SECONDARY, TERTIARY } = BUTTON_TYPES;
|
||||||
|
|
||||||
|
let color;
|
||||||
|
let rippleColor;
|
||||||
|
let iconButtonContainerStyles;
|
||||||
|
|
||||||
|
if (type === PRIMARY) {
|
||||||
|
color = BaseTheme.palette.icon01;
|
||||||
|
iconButtonContainerStyles = styles.iconButtonContainerPrimary;
|
||||||
|
rippleColor = BaseTheme.palette.action01;
|
||||||
|
} else if (type === SECONDARY) {
|
||||||
|
color = BaseTheme.palette.icon02;
|
||||||
|
iconButtonContainerStyles = styles.iconButtonContainerSecondary;
|
||||||
|
rippleColor = BaseTheme.palette.action02;
|
||||||
|
} else if ( type === TERTIARY) {
|
||||||
|
color = BaseTheme.palette.icon01;
|
||||||
|
iconButtonContainerStyles = styles.iconButtonContainer;
|
||||||
|
rippleColor = BaseTheme.palette.action03;
|
||||||
|
} else {
|
||||||
|
color = iconColor;
|
||||||
|
rippleColor = tapColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableRipple
|
||||||
|
accessibilityLabel = { accessibilityLabel }
|
||||||
|
disabled = { disabled }
|
||||||
|
onPress = { onPress }
|
||||||
|
rippleColor = { rippleColor }
|
||||||
|
style = { [
|
||||||
|
iconButtonContainerStyles,
|
||||||
|
style
|
||||||
|
] }>
|
||||||
|
<Icon
|
||||||
|
color = { color }
|
||||||
|
size = { 20 || size }
|
||||||
|
src = { src } />
|
||||||
|
</TouchableRipple>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IconButton;
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
export { default as AvatarListItem } from './AvatarListItem';
|
export { default as AvatarListItem } from './AvatarListItem';
|
||||||
export { default as BaseIndicator } from './BaseIndicator';
|
export { default as BaseIndicator } from './BaseIndicator';
|
||||||
export { default as Button } from './Button';
|
|
||||||
export { default as Container } from './Container';
|
export { default as Container } from './Container';
|
||||||
export { default as Image } from './Image';
|
export { default as Image } from './Image';
|
||||||
export { default as Link } from './Link';
|
export { default as Link } from './Link';
|
||||||
|
|
|
@ -134,10 +134,83 @@ export const BASE_INDICATOR = {
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const button = {
|
||||||
|
borderRadius: BaseTheme.shape.borderRadius,
|
||||||
|
height: BaseTheme.spacing[6],
|
||||||
|
minWidth: 85
|
||||||
|
};
|
||||||
|
|
||||||
|
const buttonLabel = {
|
||||||
|
...BaseTheme.typography.bodyShortBold,
|
||||||
|
padding: 2,
|
||||||
|
textTransform: 'capitalize'
|
||||||
|
};
|
||||||
|
|
||||||
|
const iconButtonContainer = {
|
||||||
|
alignItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
borderRadius: BaseTheme.shape.borderRadius,
|
||||||
|
height: BaseTheme.spacing[6],
|
||||||
|
width: BaseTheme.spacing[6]
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The styles of the generic React {@code Component}s implemented by the feature
|
* The styles of the generic React {@code Component}s implemented by the feature
|
||||||
* base/react.
|
* base/react.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
...SECTION_LIST_STYLES
|
...SECTION_LIST_STYLES,
|
||||||
|
|
||||||
|
button: {
|
||||||
|
...button
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabel: {
|
||||||
|
...buttonLabel
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabelDisabled: {
|
||||||
|
...buttonLabel,
|
||||||
|
color: BaseTheme.palette.text03
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonDisabled: {
|
||||||
|
...button,
|
||||||
|
backgroundColor: BaseTheme.palette.actionDisabled
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabelPrimary: {
|
||||||
|
...buttonLabel,
|
||||||
|
color: BaseTheme.palette.text01
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabelSecondary: {
|
||||||
|
...buttonLabel,
|
||||||
|
color: BaseTheme.palette.text02
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabelDestructive: {
|
||||||
|
...buttonLabel,
|
||||||
|
color: BaseTheme.palette.text01
|
||||||
|
},
|
||||||
|
|
||||||
|
buttonLabelTertiary: {
|
||||||
|
...buttonLabel,
|
||||||
|
color: BaseTheme.palette.text01
|
||||||
|
},
|
||||||
|
|
||||||
|
iconButtonContainer: {
|
||||||
|
...iconButtonContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
iconButtonContainerPrimary: {
|
||||||
|
...iconButtonContainer,
|
||||||
|
backgroundColor: BaseTheme.palette.action01
|
||||||
|
},
|
||||||
|
|
||||||
|
iconButtonContainerSecondary: {
|
||||||
|
...iconButtonContainer,
|
||||||
|
backgroundColor: BaseTheme.palette.action02
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,3 +5,21 @@
|
||||||
* everything, such as modal-type of components, or dialogs.
|
* everything, such as modal-type of components, or dialogs.
|
||||||
*/
|
*/
|
||||||
export const OVERLAY_Z_INDEX = 1000;
|
export const OVERLAY_Z_INDEX = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of the buttons.
|
||||||
|
*/
|
||||||
|
export const BUTTON_TYPES = {
|
||||||
|
PRIMARY: 'primary',
|
||||||
|
SECONDARY: 'secondary',
|
||||||
|
TERTIARY: 'tertiary',
|
||||||
|
DESTRUCTIVE: 'destructive'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The modes of the buttons.
|
||||||
|
*/
|
||||||
|
export const BUTTON_MODES = {
|
||||||
|
CONTAINED: 'contained',
|
||||||
|
TEXT: 'text'
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
export interface ButtonProps {
|
||||||
|
accessibilityLabel?: string;
|
||||||
|
color?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
label?: string;
|
||||||
|
labelStyle?: Object|undefined;
|
||||||
|
onPress?: Function;
|
||||||
|
style?: Object|undefined;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IconButtonProps {
|
||||||
|
accessibilityLabel?: string;
|
||||||
|
color?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
onPress?: Function;
|
||||||
|
size?: number|string;
|
||||||
|
src?: Function;
|
||||||
|
style?: Object|undefined;
|
||||||
|
tapColor?: string;
|
||||||
|
type?: string;
|
||||||
|
}
|
|
@ -89,6 +89,8 @@ export const colorMap = {
|
||||||
// Status bar
|
// Status bar
|
||||||
status01Bar: 'primary11',
|
status01Bar: 'primary11',
|
||||||
|
|
||||||
|
actionDisabled: 'surface09',
|
||||||
|
|
||||||
// Hover state for primary buttons
|
// Hover state for primary buttons
|
||||||
action01Hover: 'primary06',
|
action01Hover: 'primary06',
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ export const colorMap = {
|
||||||
action01Disabled: 'primary02',
|
action01Disabled: 'primary02',
|
||||||
|
|
||||||
// Secondary buttons
|
// Secondary buttons
|
||||||
action02: 'surface04',
|
action02: 'surface10',
|
||||||
|
|
||||||
// Hover state for secondary buttons
|
// Hover state for secondary buttons
|
||||||
action02Hover: 'surface05',
|
action02Hover: 'surface05',
|
||||||
|
@ -156,7 +158,7 @@ export const colorMap = {
|
||||||
text01: 'surface11',
|
text01: 'surface11',
|
||||||
|
|
||||||
// Secondary text with medium contrast
|
// Secondary text with medium contrast
|
||||||
text02: 'surface09',
|
text02: 'surface01',
|
||||||
|
|
||||||
// Tertiary text with low contrast – placeholders, disabled actions, label for disabled buttons
|
// Tertiary text with low contrast – placeholders, disabled actions, label for disabled buttons
|
||||||
text03: 'surface07',
|
text03: 'surface07',
|
||||||
|
@ -180,7 +182,7 @@ export const colorMap = {
|
||||||
icon01: 'surface11',
|
icon01: 'surface11',
|
||||||
|
|
||||||
// Secondary color for input fields
|
// Secondary color for input fields
|
||||||
icon02: 'surface09',
|
icon02: 'surface01',
|
||||||
|
|
||||||
// Tertiary color for disabled actions
|
// Tertiary color for disabled actions
|
||||||
icon03: 'surface07',
|
icon03: 'surface07',
|
||||||
|
|
|
@ -35,11 +35,3 @@ export const SMALL_WIDTH_THRESHOLD = 580;
|
||||||
* Lobby message type.
|
* Lobby message type.
|
||||||
*/
|
*/
|
||||||
export const LOBBY_CHAT_MESSAGE = 'LOBBY_CHAT_MESSAGE';
|
export const LOBBY_CHAT_MESSAGE = 'LOBBY_CHAT_MESSAGE';
|
||||||
|
|
||||||
/**
|
|
||||||
* The modes of the buttons of the chat and polls tabs.
|
|
||||||
*/
|
|
||||||
export const BUTTON_MODES = {
|
|
||||||
CONTAINED: 'contained',
|
|
||||||
TEXT: 'text'
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Text, TouchableOpacity, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
import { getFeatureFlag, INVITE_ENABLED } from '../../../base/flags';
|
import { getFeatureFlag, INVITE_ENABLED } from '../../../base/flags';
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import { Icon, IconAddPeople } from '../../../base/icons';
|
import { Icon, IconAddPeople } from '../../../base/icons';
|
||||||
import { getParticipantCountWithFake } from '../../../base/participants';
|
import { getParticipantCountWithFake } from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||||
import { doInvitePeople } from '../../../invite/actions.native';
|
import { doInvitePeople } from '../../../invite/actions.native';
|
||||||
|
@ -57,6 +59,19 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
this._onPress = this._onPress.bind(this);
|
this._onPress = this._onPress.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the "add people" icon.
|
||||||
|
*
|
||||||
|
* @returns {ReactElement}
|
||||||
|
*/
|
||||||
|
_renderAddPeopleIcon() {
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
size = { 20 }
|
||||||
|
src = { IconAddPeople } />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements {@code PureComponent#render}.
|
* Implements {@code PureComponent#render}.
|
||||||
*
|
*
|
||||||
|
@ -80,17 +95,13 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
||||||
{ t('lonelyMeetingExperience.youAreAlone') }
|
{ t('lonelyMeetingExperience.youAreAlone') }
|
||||||
</Text>
|
</Text>
|
||||||
{ !_isInviteFunctionsDiabled && !_isInBreakoutRoom && (
|
{ !_isInviteFunctionsDiabled && !_isInBreakoutRoom && (
|
||||||
<TouchableOpacity
|
<Button
|
||||||
|
accessibilityLabel = 'lonelyMeetingExperience.button'
|
||||||
|
icon = { this._renderAddPeopleIcon }
|
||||||
|
label = 'lonelyMeetingExperience.button'
|
||||||
onPress = { this._onPress }
|
onPress = { this._onPress }
|
||||||
style = { styles.lonelyButton }>
|
style = { styles.lonelyButton }
|
||||||
<Icon
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
size = { 24 }
|
|
||||||
src = { IconAddPeople }
|
|
||||||
style = { styles.lonelyButtonComponents } />
|
|
||||||
<Text style = { styles.lonelyButtonComponents }>
|
|
||||||
{ t('lonelyMeetingExperience.button') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
) }
|
) }
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
import { withSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
@ -24,7 +23,6 @@ import styles from './styles';
|
||||||
*/
|
*/
|
||||||
const CarMode = (): JSX.Element => {
|
const CarMode = (): JSX.Element => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { t } = useTranslation();
|
|
||||||
const connecting = useSelector(isConnecting);
|
const connecting = useSelector(isConnecting);
|
||||||
const isSharing = useSelector(isLocalVideoTrackDesktop);
|
const isSharing = useSelector(isLocalVideoTrackDesktop);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { createToolbarEvent, sendAnalytics } from '../../../../analytics';
|
import { createToolbarEvent, sendAnalytics } from '../../../../analytics';
|
||||||
import { appNavigate } from '../../../../app/actions';
|
import { appNavigate } from '../../../../app/actions';
|
||||||
|
import Button from '../../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||||
|
|
||||||
import EndMeetingIcon from './EndMeetingIcon';
|
import EndMeetingIcon from './EndMeetingIcon';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -15,7 +15,6 @@ import styles from './styles';
|
||||||
* @returns {JSX.Element} - The end meeting button.
|
* @returns {JSX.Element} - The end meeting button.
|
||||||
*/
|
*/
|
||||||
const EndMeetingButton = () : JSX.Element => {
|
const EndMeetingButton = () : JSX.Element => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onSelect = useCallback(() => {
|
const onSelect = useCallback(() => {
|
||||||
|
@ -26,13 +25,12 @@ const EndMeetingButton = () : JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('carmode.actions.leaveMeeting') }
|
accessibilityLabel = 'carmode.actions.leaveMeeting'
|
||||||
children = { t('carmode.actions.leaveMeeting') }
|
|
||||||
icon = { EndMeetingIcon }
|
icon = { EndMeetingIcon }
|
||||||
labelStyle = { styles.endMeetingButtonLabel }
|
label = 'carmode.actions.leaveMeeting'
|
||||||
mode = 'contained'
|
|
||||||
onPress = { onSelect }
|
onPress = { onSelect }
|
||||||
style = { styles.endMeetingButton } />
|
style = { styles.endMeetingButton }
|
||||||
|
type = { BUTTON_TYPES.DESTRUCTIVE } />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { openSheet } from '../../../../base/dialog/actions';
|
import { openSheet } from '../../../../base/dialog/actions';
|
||||||
|
import Button from '../../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||||
import AudioRoutePickerDialog from '../../../../mobile/audio-mode/components/AudioRoutePickerDialog';
|
import AudioRoutePickerDialog from '../../../../mobile/audio-mode/components/AudioRoutePickerDialog';
|
||||||
|
|
||||||
import AudioIcon from './AudioIcon';
|
import AudioIcon from './AudioIcon';
|
||||||
|
@ -15,7 +15,6 @@ import styles from './styles';
|
||||||
* @returns {JSX.Element} - The sound device button.
|
* @returns {JSX.Element} - The sound device button.
|
||||||
*/
|
*/
|
||||||
const SelectSoundDevice = () : JSX.Element => {
|
const SelectSoundDevice = () : JSX.Element => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onSelect = useCallback(() =>
|
const onSelect = useCallback(() =>
|
||||||
|
@ -24,13 +23,12 @@ const SelectSoundDevice = () : JSX.Element => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('carmode.actions.selectSoundDevice') }
|
accessibilityLabel = 'carmode.actions.selectSoundDevice'
|
||||||
children = { t('carmode.actions.selectSoundDevice') }
|
|
||||||
icon = { AudioIcon }
|
icon = { AudioIcon }
|
||||||
labelStyle = { styles.soundDeviceButtonLabel }
|
label = 'carmode.actions.selectSoundDevice'
|
||||||
mode = 'contained'
|
|
||||||
onPress = { onSelect }
|
onPress = { onSelect }
|
||||||
style = { styles.soundDeviceButton } />
|
style = { styles.soundDeviceButton }
|
||||||
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,29 +5,6 @@ import BaseTheme from '../../../../base/ui/components/BaseTheme.native';
|
||||||
*/
|
*/
|
||||||
const MICROPHONE_SIZE = 180;
|
const MICROPHONE_SIZE = 180;
|
||||||
|
|
||||||
/**
|
|
||||||
* Base button style.
|
|
||||||
*/
|
|
||||||
const baseButton = {
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
marginTop: BaseTheme.spacing[3],
|
|
||||||
marginLeft: BaseTheme.spacing[10],
|
|
||||||
marginRight: BaseTheme.spacing[10],
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'space-around',
|
|
||||||
width: 300
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base label style.
|
|
||||||
*/
|
|
||||||
const baseLabel = {
|
|
||||||
display: 'flex',
|
|
||||||
fontSize: 16,
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The styles of the safe area view that contains the title bar.
|
* The styles of the safe area view that contains the title bar.
|
||||||
*/
|
*/
|
||||||
|
@ -47,7 +24,7 @@ export default {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
bottom: 0,
|
bottom: BaseTheme.spacing[8],
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
position: 'absolute'
|
position: 'absolute'
|
||||||
|
@ -106,10 +83,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
roomTimer: {
|
roomTimer: {
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
...BaseTheme.typography.bodyShortBold,
|
...BaseTheme.typography.bodyShortBold,
|
||||||
paddingHorizontal: 8,
|
color: BaseTheme.palette.text01,
|
||||||
paddingVertical: 6,
|
|
||||||
textAlign: 'center'
|
textAlign: 'center'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -129,25 +104,13 @@ export default {
|
||||||
color: BaseTheme.palette.text02
|
color: BaseTheme.palette.text02
|
||||||
},
|
},
|
||||||
|
|
||||||
soundDeviceButtonLabel: {
|
|
||||||
...baseLabel,
|
|
||||||
color: BaseTheme.palette.text06
|
|
||||||
},
|
|
||||||
|
|
||||||
soundDeviceButton: {
|
soundDeviceButton: {
|
||||||
...baseButton,
|
marginBottom: BaseTheme.spacing[3],
|
||||||
backgroundColor: BaseTheme.palette.section01
|
width: 240
|
||||||
},
|
},
|
||||||
|
|
||||||
endMeetingButton: {
|
endMeetingButton: {
|
||||||
...baseButton,
|
width: 240
|
||||||
backgroundColor: BaseTheme.palette.actionDanger,
|
|
||||||
marginBottom: 60
|
|
||||||
},
|
|
||||||
|
|
||||||
endMeetingButtonLabel: {
|
|
||||||
...baseLabel,
|
|
||||||
color: BaseTheme.palette.text01
|
|
||||||
},
|
},
|
||||||
|
|
||||||
headerLabels: {
|
headerLabels: {
|
||||||
|
@ -196,13 +159,14 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
titleBar: {
|
titleBar: {
|
||||||
alignSelf: 'center'
|
alignSelf: 'center',
|
||||||
|
marginTop: BaseTheme.spacing[1]
|
||||||
},
|
},
|
||||||
|
|
||||||
videoStoppedLabel: {
|
videoStoppedLabel: {
|
||||||
|
...BaseTheme.typography.bodyShortRegularLarge,
|
||||||
color: BaseTheme.palette.text01,
|
color: BaseTheme.palette.text01,
|
||||||
marginBottom: 32,
|
marginBottom: BaseTheme.spacing[3]
|
||||||
...BaseTheme.typography.bodyShortRegularLarge
|
|
||||||
},
|
},
|
||||||
|
|
||||||
connectionIndicatorIcon: {
|
connectionIndicatorIcon: {
|
||||||
|
|
|
@ -79,18 +79,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
lonelyButton: {
|
lonelyButton: {
|
||||||
alignItems: 'center',
|
borderRadius: BaseTheme.spacing[4]
|
||||||
backgroundColor: BaseTheme.palette.action01,
|
|
||||||
borderRadius: 24,
|
|
||||||
flexDirection: 'row',
|
|
||||||
height: BaseTheme.spacing[6],
|
|
||||||
justifyContent: 'space-around',
|
|
||||||
paddingHorizontal: 12
|
|
||||||
},
|
|
||||||
|
|
||||||
lonelyButtonComponents: {
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
marginHorizontal: 6
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lonelyMeetingContainer: {
|
lonelyMeetingContainer: {
|
||||||
|
@ -170,7 +159,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
roomTimerView: {
|
roomTimerView: {
|
||||||
backgroundColor: BaseTheme.palette.action02,
|
backgroundColor: BaseTheme.palette.ui03,
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
minWidth: 50
|
minWidth: 50
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text, View, TouchableOpacity, TextInput } from 'react-native';
|
import { Text, View, TextInput } from 'react-native';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||||
import { LoadingIndicator } from '../../../base/react';
|
import { LoadingIndicator } from '../../../base/react';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui';
|
import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui';
|
||||||
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
import BaseTheme from '../../../base/ui/components/BaseTheme';
|
||||||
|
@ -22,7 +24,6 @@ import AbstractLobbyScreen, {
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
|
||||||
type Props = AbstractProps & {
|
type Props = AbstractProps & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,31 +186,21 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
_renderPasswordJoinButtons() {
|
_renderPasswordJoinButtons() {
|
||||||
const { t } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style = { styles.passwordJoinButtonsWrapper }>
|
<View style = { styles.passwordJoinButtonsWrapper }>
|
||||||
<TouchableOpacity
|
<Button
|
||||||
|
accessibilityLabel = 'lobby.backToKnockModeButton'
|
||||||
|
label = 'lobby.backToKnockModeButton'
|
||||||
onPress = { this._onSwitchToKnockMode }
|
onPress = { this._onSwitchToKnockMode }
|
||||||
style = { [
|
style = { styles.lobbyButton }
|
||||||
styles.button,
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
styles.primaryButton
|
<Button
|
||||||
] }>
|
accessibilityLabel = 'lobby.passwordJoinButton'
|
||||||
<Text style = { styles.primaryButtonText }>
|
|
||||||
{ t('lobby.backToKnockModeButton') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
disabled = { !this.state.password }
|
disabled = { !this.state.password }
|
||||||
|
label = 'lobby.passwordJoinButton'
|
||||||
onPress = { this._onJoinWithPassword }
|
onPress = { this._onJoinWithPassword }
|
||||||
style = { [
|
style = { styles.lobbyButton }
|
||||||
styles.button,
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
styles.primaryButton
|
|
||||||
] }>
|
|
||||||
<Text style = { styles.primaryButtonText }>
|
|
||||||
{ t('lobby.passwordJoinButton') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -245,44 +236,39 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
_renderStandardButtons() {
|
_renderStandardButtons() {
|
||||||
const { _knocking, _renderPassword, _isLobbyChatActive, t } = this.props;
|
const { _knocking, _renderPassword, _isLobbyChatActive } = this.props;
|
||||||
const { displayName } = this.state;
|
const { displayName } = this.state;
|
||||||
const askToJoinButtonStyles
|
|
||||||
= displayName ? styles.primaryButton : styles.primaryButtonDisabled;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style = { styles.standardButtonWrapper }>
|
<View style = { styles.standardButtonWrapper }>
|
||||||
{ _knocking && _isLobbyChatActive && <TouchableOpacity
|
{
|
||||||
onPress = { this._onNavigateToLobbyChat }
|
_knocking && _isLobbyChatActive
|
||||||
style = { [
|
&& <Button
|
||||||
styles.button,
|
accessibilityLabel = 'toolbar.openChat'
|
||||||
styles.primaryButton
|
label = 'toolbar.openChat'
|
||||||
] }>
|
onPress = { this._onNavigateToLobbyChat }
|
||||||
<Text style = { styles.primaryButtonText }>
|
style = { styles.lobbyButton }
|
||||||
{ t('toolbar.openChat') }
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
</Text>
|
}
|
||||||
</TouchableOpacity>}
|
{
|
||||||
{ _knocking || <TouchableOpacity
|
_knocking
|
||||||
disabled = { !displayName }
|
|| <Button
|
||||||
onPress = { this._onAskToJoin }
|
accessibilityLabel = 'lobby.knockButton'
|
||||||
style = { [
|
disabled = { !displayName }
|
||||||
styles.button,
|
label = 'lobby.knockButton'
|
||||||
askToJoinButtonStyles
|
onPress = { this._onAskToJoin }
|
||||||
] }>
|
style = { styles.lobbyButton }
|
||||||
<Text style = { styles.primaryButtonText }>
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
{ t('lobby.knockButton') }
|
}
|
||||||
</Text>
|
{
|
||||||
</TouchableOpacity> }
|
_renderPassword
|
||||||
{ _renderPassword && <TouchableOpacity
|
&& <Button
|
||||||
onPress = { this._onSwitchToPasswordMode }
|
accessibilityLabel = 'lobby.enterPasswordButton'
|
||||||
style = { [
|
label = 'lobby.enterPasswordButton'
|
||||||
styles.button,
|
onPress = { this._onSwitchToPasswordMode }
|
||||||
styles.primaryButton
|
style = { styles.enterPasswordButton }
|
||||||
] }>
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
<Text style = { styles.primaryButtonText }>
|
}
|
||||||
{ t('lobby.enterPasswordButton') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity> }
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,6 @@ import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
button: {
|
|
||||||
alignItems: 'center',
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
padding: BaseTheme.spacing[2],
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
width: '100%'
|
|
||||||
},
|
|
||||||
|
|
||||||
buttonStylesBorderless: {
|
buttonStylesBorderless: {
|
||||||
iconStyle: {
|
iconStyle: {
|
||||||
|
@ -137,7 +130,7 @@ export default {
|
||||||
color: BaseTheme.palette.text06,
|
color: BaseTheme.palette.text06,
|
||||||
height: BaseTheme.spacing[7],
|
height: BaseTheme.spacing[7],
|
||||||
marginTop: BaseTheme.spacing[3],
|
marginTop: BaseTheme.spacing[3],
|
||||||
marginHorizontal: 12,
|
marginHorizontal: BaseTheme.spacing[3],
|
||||||
padding: BaseTheme.spacing[2],
|
padding: BaseTheme.spacing[2],
|
||||||
textAlign: 'center'
|
textAlign: 'center'
|
||||||
},
|
},
|
||||||
|
@ -155,8 +148,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
standardButtonWrapper: {
|
standardButtonWrapper: {
|
||||||
alignSelf: 'stretch',
|
alignSelf: 'stretch'
|
||||||
marginHorizontal: 12
|
|
||||||
},
|
},
|
||||||
|
|
||||||
joiningMessage: {
|
joiningMessage: {
|
||||||
|
@ -185,26 +177,13 @@ export default {
|
||||||
paddingVertical: 12
|
paddingVertical: 12
|
||||||
},
|
},
|
||||||
|
|
||||||
primaryButton: {
|
lobbyButton: {
|
||||||
backgroundColor: BaseTheme.palette.action01,
|
|
||||||
marginTop: BaseTheme.spacing[3]
|
marginTop: BaseTheme.spacing[3]
|
||||||
},
|
},
|
||||||
|
|
||||||
primaryButtonDisabled: {
|
enterPasswordButton: {
|
||||||
backgroundColor: BaseTheme.palette.action03Disabled,
|
marginHorizontal: BaseTheme.spacing[3],
|
||||||
marginTop: BaseTheme.spacing[3]
|
marginTop: BaseTheme.spacing[6]
|
||||||
},
|
|
||||||
|
|
||||||
primaryButtonText: {
|
|
||||||
...BaseTheme.typography.labelButtonLarge,
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
lineHeight: 30
|
|
||||||
},
|
|
||||||
|
|
||||||
primaryText: {
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
margin: 'auto',
|
|
||||||
textAlign: 'center'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// KnockingParticipantList
|
// KnockingParticipantList
|
||||||
|
|
|
@ -57,7 +57,7 @@ export const drawerScreenOptions = {
|
||||||
export const drawerContentOptions = {
|
export const drawerContentOptions = {
|
||||||
drawerActiveBackgroundColor: BaseTheme.palette.uiBackground,
|
drawerActiveBackgroundColor: BaseTheme.palette.uiBackground,
|
||||||
drawerActiveTintColor: BaseTheme.palette.screen01Header,
|
drawerActiveTintColor: BaseTheme.palette.screen01Header,
|
||||||
drawerInactiveTintColor: BaseTheme.palette.text02,
|
drawerInactiveTintColor: BaseTheme.palette.text01,
|
||||||
drawerLabelStyle: {
|
drawerLabelStyle: {
|
||||||
marginLeft: BaseTheme.spacing[2]
|
marginLeft: BaseTheme.spacing[2]
|
||||||
},
|
},
|
||||||
|
@ -75,7 +75,7 @@ export const welcomeScreenOptions = {
|
||||||
...drawerScreenOptions,
|
...drawerScreenOptions,
|
||||||
drawerIcon: ({ focused }) => (
|
drawerIcon: ({ focused }) => (
|
||||||
<Icon
|
<Icon
|
||||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||||
size = { 20 }
|
size = { 20 }
|
||||||
src = { IconHome } />
|
src = { IconHome } />
|
||||||
),
|
),
|
||||||
|
@ -94,7 +94,7 @@ export const settingsScreenOptions = {
|
||||||
...drawerScreenOptions,
|
...drawerScreenOptions,
|
||||||
drawerIcon: ({ focused }) => (
|
drawerIcon: ({ focused }) => (
|
||||||
<Icon
|
<Icon
|
||||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||||
size = { 20 }
|
size = { 20 }
|
||||||
src = { IconSettings } />
|
src = { IconSettings } />
|
||||||
),
|
),
|
||||||
|
@ -110,7 +110,7 @@ export const termsAndPrivacyScreenOptions = {
|
||||||
...drawerScreenOptions,
|
...drawerScreenOptions,
|
||||||
drawerIcon: ({ focused }) => (
|
drawerIcon: ({ focused }) => (
|
||||||
<Icon
|
<Icon
|
||||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||||
size = { 20 }
|
size = { 20 }
|
||||||
src = { IconInfo } />
|
src = { IconInfo } />
|
||||||
),
|
),
|
||||||
|
@ -126,7 +126,7 @@ export const helpScreenOptions = {
|
||||||
...drawerScreenOptions,
|
...drawerScreenOptions,
|
||||||
drawerIcon: ({ focused }) => (
|
drawerIcon: ({ focused }) => (
|
||||||
<Icon
|
<Icon
|
||||||
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon02 }
|
color = { focused ? BaseTheme.palette.screen01Header : BaseTheme.palette.icon01 }
|
||||||
size = { 20 }
|
size = { 20 }
|
||||||
src = { IconHelp } />
|
src = { IconHelp } />
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import Button from '../../../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../../../base/react/constants';
|
||||||
import { createBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
import { createBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
const AddBreakoutRoomButton = () => {
|
const AddBreakoutRoomButton = () => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onAdd = useCallback(() =>
|
const onAdd = useCallback(() =>
|
||||||
|
@ -19,12 +18,11 @@ const AddBreakoutRoomButton = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('breakoutRooms.actions.add') }
|
accessibilityLabel = 'breakoutRooms.actions.add'
|
||||||
children = { t('breakoutRooms.actions.add') }
|
label = 'breakoutRooms.actions.add'
|
||||||
labelStyle = { styles.addButtonLabel }
|
|
||||||
mode = 'contained'
|
|
||||||
onPress = { onAdd }
|
onPress = { onAdd }
|
||||||
style = { styles.addButton } />
|
style = { styles.addButton }
|
||||||
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import Button from '../../../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../../../base/react/constants';
|
||||||
import { autoAssignToBreakoutRooms } from '../../../../../breakout-rooms/actions';
|
import { autoAssignToBreakoutRooms } from '../../../../../breakout-rooms/actions';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
|
||||||
const AutoAssignButton = () => {
|
const AutoAssignButton = () => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onAutoAssign = useCallback(() => {
|
const onAutoAssign = useCallback(() => {
|
||||||
|
@ -19,12 +19,12 @@ const AutoAssignButton = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('breakoutRooms.actions.autoAssign') }
|
accessibilityLabel = 'breakoutRooms.actions.autoAssign'
|
||||||
children = { t('breakoutRooms.actions.autoAssign') }
|
label = 'breakoutRooms.actions.autoAssign'
|
||||||
labelStyle = { styles.autoAssignLabel }
|
labelStyle = { styles.autoAssignLabel }
|
||||||
mode = 'contained'
|
|
||||||
onPress = { onAutoAssign }
|
onPress = { onAutoAssign }
|
||||||
style = { styles.transparentButton } />
|
style = { styles.transparentButton }
|
||||||
|
type = { BUTTON_TYPES.TERTIARY } />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,10 @@ const baseLabel = {
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
addButtonLabel: {
|
|
||||||
...baseLabel,
|
|
||||||
color: BaseTheme.palette.text01
|
|
||||||
},
|
|
||||||
|
|
||||||
addButton: {
|
addButton: {
|
||||||
...baseButton,
|
marginTop: BaseTheme.spacing[3],
|
||||||
backgroundColor: BaseTheme.palette.ui03
|
marginLeft: BaseTheme.spacing[3],
|
||||||
|
marginRight: BaseTheme.spacing[3]
|
||||||
},
|
},
|
||||||
|
|
||||||
collapsibleRoom: {
|
collapsibleRoom: {
|
||||||
|
@ -71,7 +67,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
transparentButton: {
|
transparentButton: {
|
||||||
backgroundColor: 'transparent',
|
|
||||||
marginTop: BaseTheme.spacing[3]
|
marginTop: BaseTheme.spacing[3]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -81,7 +76,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
autoAssignLabel: {
|
autoAssignLabel: {
|
||||||
...baseLabel,
|
|
||||||
color: BaseTheme.palette.link01
|
color: BaseTheme.palette.link01
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
// @flow
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { Icon, IconHorizontalPoints } from '../../../base/icons';
|
|
||||||
|
|
||||||
const HorizontalDotsIcon = () => (<Icon
|
|
||||||
size = { 20 }
|
|
||||||
src = { IconHorizontalPoints } />);
|
|
||||||
|
|
||||||
export default HorizontalDotsIcon;
|
|
|
@ -1,11 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { hasRaisedHand } from '../../../base/participants';
|
import { hasRaisedHand } from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { approveKnockingParticipant } from '../../../lobby/actions.native';
|
import { approveKnockingParticipant } from '../../../lobby/actions.native';
|
||||||
import { showContextMenuReject } from '../../actions.native';
|
import { showContextMenuReject } from '../../actions.native';
|
||||||
import { MEDIA_STATE } from '../../constants';
|
import { MEDIA_STATE } from '../../constants';
|
||||||
|
@ -25,7 +25,6 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const admit = useCallback(() => dispatch(approveKnockingParticipant(p.id), [ dispatch ]));
|
const admit = useCallback(() => dispatch(approveKnockingParticipant(p.id), [ dispatch ]));
|
||||||
const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ]));
|
const openContextMenuReject = useCallback(() => dispatch(showContextMenuReject(p), [ dispatch ]));
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ParticipantItem
|
<ParticipantItem
|
||||||
|
@ -39,12 +38,11 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
|
||||||
raisedHand = { hasRaisedHand(p) }
|
raisedHand = { hasRaisedHand(p) }
|
||||||
videoMediaState = { MEDIA_STATE.NONE }>
|
videoMediaState = { MEDIA_STATE.NONE }>
|
||||||
<Button
|
<Button
|
||||||
children = { t('lobby.admit') }
|
accessibilityLabel = 'lobby.admit'
|
||||||
contentStyle = { styles.participantActionsButtonContent }
|
label = 'lobby.admit'
|
||||||
labelStyle = { styles.participantActionsButtonText }
|
|
||||||
mode = 'contained'
|
|
||||||
onPress = { admit }
|
onPress = { admit }
|
||||||
style = { styles.participantActionsButtonAdmit } />
|
style = { styles.participantActionsButtonAdmit }
|
||||||
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
</ParticipantItem>
|
</ParticipantItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ScrollView, Text, View } from 'react-native';
|
import { ScrollView, Text, View } from 'react-native';
|
||||||
import { Button, withTheme } from 'react-native-paper';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { admitMultiple } from '../../../lobby/actions.native';
|
import { admitMultiple } from '../../../lobby/actions.native';
|
||||||
import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions';
|
import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions';
|
||||||
|
|
||||||
|
@ -13,15 +14,8 @@ import CollapsibleList from './CollapsibleList';
|
||||||
import { LobbyParticipantItem } from './LobbyParticipantItem';
|
import { LobbyParticipantItem } from './LobbyParticipantItem';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
type Props = {
|
|
||||||
|
|
||||||
/**
|
const LobbyParticipantList = () => {
|
||||||
* Theme used for styles.
|
|
||||||
*/
|
|
||||||
theme: Object
|
|
||||||
};
|
|
||||||
|
|
||||||
const LobbyParticipantList = ({ theme }: Props) => {
|
|
||||||
const lobbyEnabled = useSelector(getLobbyEnabled);
|
const lobbyEnabled = useSelector(getLobbyEnabled);
|
||||||
const participants = useSelector(getKnockingParticipants);
|
const participants = useSelector(getKnockingParticipants);
|
||||||
|
|
||||||
|
@ -30,11 +24,11 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
||||||
dispatch(admitMultiple(participants)),
|
dispatch(admitMultiple(participants)),
|
||||||
[ dispatch, participants ]);
|
[ dispatch, participants ]);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { palette } = theme;
|
|
||||||
|
|
||||||
if (!lobbyEnabled || !participants.length) {
|
if (!lobbyEnabled || !participants.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = (
|
const title = (
|
||||||
<View style = { styles.lobbyListDetails } >
|
<View style = { styles.lobbyListDetails } >
|
||||||
<Text style = { styles.lobbyListDescription }>
|
<Text style = { styles.lobbyListDescription }>
|
||||||
|
@ -44,12 +38,11 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
||||||
{
|
{
|
||||||
participants.length > 1 && (
|
participants.length > 1 && (
|
||||||
<Button
|
<Button
|
||||||
color = { palette.action02 }
|
accessibilityLabel = 'lobby.admitAll'
|
||||||
labelStyle = { styles.admitAllParticipantsActionButtonLabel }
|
label = 'lobby.admitAll'
|
||||||
mode = 'text'
|
labelStyle = { styles.admitAllButtonLabel }
|
||||||
onPress = { admitAll }>
|
onPress = { admitAll }
|
||||||
{t('lobby.admitAll')}
|
type = { BUTTON_TYPES.TERTIARY } />
|
||||||
</Button>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
|
@ -78,4 +71,4 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTheme(LobbyParticipantList);
|
export default LobbyParticipantList;
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { FlatList } from 'react-native';
|
import { FlatList } from 'react-native';
|
||||||
import { Button, withTheme } from 'react-native-paper';
|
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import { Icon, IconInviteMore } from '../../../base/icons';
|
import { Icon, IconInviteMore } from '../../../base/icons';
|
||||||
import { getLocalParticipant, getParticipantCountWithFake, getRemoteParticipants } from '../../../base/participants';
|
import { getLocalParticipant, getParticipantCountWithFake, getRemoteParticipants } from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
|
import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
|
||||||
import { doInvitePeople } from '../../../invite/actions.native';
|
import { doInvitePeople } from '../../../invite/actions.native';
|
||||||
import { participantMatchesSearch, shouldRenderInviteButton } from '../../functions';
|
import { participantMatchesSearch, shouldRenderInviteButton } from '../../functions';
|
||||||
|
@ -83,12 +86,7 @@ type Props = {
|
||||||
/**
|
/**
|
||||||
* Translation function.
|
* Translation function.
|
||||||
*/
|
*/
|
||||||
t: Function,
|
t: Function
|
||||||
|
|
||||||
/**
|
|
||||||
* Theme used for styles.
|
|
||||||
*/
|
|
||||||
theme: Object
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,17 +228,17 @@ class MeetingParticipantList extends PureComponent<Props> {
|
||||||
{
|
{
|
||||||
_showInviteButton
|
_showInviteButton
|
||||||
&& <Button
|
&& <Button
|
||||||
children = { t('participantsPane.actions.invite') }
|
accessibilityLabel = 'participantsPane.actions.invite'
|
||||||
icon = { this._renderInviteMoreIcon }
|
icon = { this._renderInviteMoreIcon }
|
||||||
labelStyle = { styles.inviteLabel }
|
label = 'participantsPane.actions.invite'
|
||||||
mode = 'contained'
|
|
||||||
onPress = { this._onInvite }
|
onPress = { this._onInvite }
|
||||||
style = { styles.inviteButton } />
|
style = { styles.inviteButton }
|
||||||
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
}
|
}
|
||||||
<ClearableInput
|
<ClearableInput
|
||||||
onChange = { this._onSearchStringChange }
|
onChange = { this._onSearchStringChange }
|
||||||
placeholder = { t('participantsPane.search') }
|
placeholder = { t('participantsPane.search') }
|
||||||
selectionColor = { this.props.theme.palette.text01 } />
|
selectionColor = { BaseTheme.palette.text01 } />
|
||||||
<FlatList
|
<FlatList
|
||||||
bounces = { false }
|
bounces = { false }
|
||||||
data = { [ _localParticipant?.id, ..._sortedRemoteParticipants ] }
|
data = { [ _localParticipant?.id, ..._sortedRemoteParticipants ] }
|
||||||
|
@ -280,4 +278,4 @@ function _mapStateToProps(state): Object {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(withTheme(MeetingParticipantList)));
|
export default translate(connect(_mapStateToProps)(MeetingParticipantList));
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { openDialog, openSheet } from '../../../base/dialog';
|
import { openDialog, openSheet } from '../../../base/dialog';
|
||||||
|
import { IconHorizontalPoints } from '../../../base/icons';
|
||||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import IconButton from '../../../base/react/components/native/IconButton';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { equals } from '../../../base/redux';
|
import { equals } from '../../../base/redux';
|
||||||
import {
|
import {
|
||||||
getBreakoutRooms,
|
getBreakoutRooms,
|
||||||
|
@ -29,7 +31,6 @@ import {
|
||||||
import { CollapsibleRoom } from '../breakout-rooms/components/native/CollapsibleRoom';
|
import { CollapsibleRoom } from '../breakout-rooms/components/native/CollapsibleRoom';
|
||||||
|
|
||||||
import { ContextMenuMore } from './ContextMenuMore';
|
import { ContextMenuMore } from './ContextMenuMore';
|
||||||
import HorizontalDotsIcon from './HorizontalDotsIcon';
|
|
||||||
import LobbyParticipantList from './LobbyParticipantList';
|
import LobbyParticipantList from './LobbyParticipantList';
|
||||||
import MeetingParticipantList from './MeetingParticipantList';
|
import MeetingParticipantList from './MeetingParticipantList';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -46,8 +47,6 @@ const ParticipantsPane = () => {
|
||||||
const isLocalModerator = useSelector(isLocalParticipantModerator);
|
const isLocalModerator = useSelector(isLocalParticipantModerator);
|
||||||
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
|
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
|
||||||
[ dispatch ]);
|
[ dispatch ]);
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { conference } = useSelector(state => state['features/base/conference']);
|
const { conference } = useSelector(state => state['features/base/conference']);
|
||||||
const _isBreakoutRoomsSupported = conference?.getBreakoutRooms()?.isSupported();
|
const _isBreakoutRoomsSupported = conference?.getBreakoutRooms()?.isSupported();
|
||||||
const currentRoomId = useSelector(getCurrentRoomId);
|
const currentRoomId = useSelector(getCurrentRoomId);
|
||||||
|
@ -92,21 +91,19 @@ const ParticipantsPane = () => {
|
||||||
{
|
{
|
||||||
showMuteAll && (
|
showMuteAll && (
|
||||||
<Button
|
<Button
|
||||||
children = { t('participantsPane.actions.muteAll') }
|
accessibilityLabel = 'participantsPane.actions.muteAll'
|
||||||
labelStyle = { styles.muteAllLabel }
|
label = 'participantsPane.actions.muteAll'
|
||||||
mode = 'contained'
|
|
||||||
onPress = { muteAll }
|
onPress = { muteAll }
|
||||||
style = { styles.muteAllMoreButton } />
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
showMoreActions && (
|
showMoreActions && (
|
||||||
<Button
|
<IconButton
|
||||||
icon = { HorizontalDotsIcon }
|
|
||||||
labelStyle = { styles.moreIcon }
|
|
||||||
mode = 'contained'
|
|
||||||
onPress = { openMoreMenu }
|
onPress = { openMoreMenu }
|
||||||
style = { styles.moreButton } />
|
src = { IconHorizontalPoints }
|
||||||
|
style = { styles.moreButton }
|
||||||
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -35,39 +35,8 @@ const contextMenuItemText = {
|
||||||
* The style of the participants pane buttons.
|
* The style of the participants pane buttons.
|
||||||
*/
|
*/
|
||||||
export const button = {
|
export const button = {
|
||||||
backgroundColor: BaseTheme.palette.action02,
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'center',
|
|
||||||
minWidth: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Small buttons.
|
|
||||||
*/
|
|
||||||
const smallButton = {
|
|
||||||
...button,
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
width: BaseTheme.spacing[7]
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mute all button.
|
|
||||||
*/
|
|
||||||
const muteAllButton = {
|
|
||||||
...button,
|
|
||||||
marginLeft: 'auto'
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The style of the participants pane buttons description.
|
|
||||||
*/
|
|
||||||
const buttonContent = {
|
|
||||||
...BaseTheme.typography.labelButton,
|
|
||||||
alignContent: 'center',
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,34 +57,15 @@ const contextMenuItem = {
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
participantActionsButtonAdmit: {
|
participantActionsButtonAdmit: {
|
||||||
backgroundColor: BaseTheme.palette.action01,
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
flexDirection: 'row',
|
|
||||||
height: BaseTheme.spacing[6],
|
|
||||||
marginRight: BaseTheme.spacing[3],
|
marginRight: BaseTheme.spacing[3],
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: 0,
|
right: 0
|
||||||
zIndex: 1
|
|
||||||
},
|
},
|
||||||
|
|
||||||
participantActionsButtonContent: {
|
admitAllButtonLabel: {
|
||||||
alignItems: 'center',
|
|
||||||
display: 'flex',
|
|
||||||
height: BaseTheme.spacing[5],
|
|
||||||
top: BaseTheme.spacing[1]
|
|
||||||
},
|
|
||||||
|
|
||||||
participantActionsButtonText: {
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
},
|
|
||||||
|
|
||||||
admitAllParticipantsActionButtonLabel: {
|
|
||||||
...BaseTheme.typography.heading6,
|
|
||||||
color: BaseTheme.palette.link01,
|
color: BaseTheme.palette.link01,
|
||||||
textTransform: 'capitalize',
|
marginRight: BaseTheme.spacing[6],
|
||||||
marginRight: BaseTheme.spacing[5],
|
marginTop: 14
|
||||||
marginTop: BaseTheme.spacing[3]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
participantContainer: {
|
participantContainer: {
|
||||||
|
@ -263,49 +213,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
inviteButton: {
|
inviteButton: {
|
||||||
backgroundColor: BaseTheme.palette.action01,
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
marginLeft: BaseTheme.spacing[3],
|
marginLeft: BaseTheme.spacing[3],
|
||||||
marginRight: BaseTheme.spacing[3],
|
marginRight: BaseTheme.spacing[3],
|
||||||
marginVertical: BaseTheme.spacing[3]
|
marginVertical: BaseTheme.spacing[3]
|
||||||
},
|
},
|
||||||
|
|
||||||
inviteLabel: {
|
|
||||||
fontSize: 15,
|
|
||||||
lineHeight: 30,
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
},
|
|
||||||
|
|
||||||
moreButton: {
|
moreButton: {
|
||||||
...smallButton,
|
marginLeft: BaseTheme.spacing[2]
|
||||||
marginLeft: BaseTheme.spacing[3]
|
|
||||||
},
|
|
||||||
|
|
||||||
moreIcon: {
|
|
||||||
...buttonContent,
|
|
||||||
height: BaseTheme.spacing[5],
|
|
||||||
marginLeft: 'auto'
|
|
||||||
},
|
|
||||||
|
|
||||||
muteAllButton: {
|
|
||||||
...muteAllButton
|
|
||||||
},
|
|
||||||
|
|
||||||
muteAllMoreButton: {
|
|
||||||
...muteAllButton
|
|
||||||
},
|
|
||||||
|
|
||||||
muteAllLabel: {
|
|
||||||
...BaseTheme.typography.labelButtonLarge,
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
marginVertical: BaseTheme.spacing[0],
|
|
||||||
marginHorizontal: BaseTheme.spacing[0],
|
|
||||||
paddingTop: 12,
|
|
||||||
paddingBottom: 12,
|
|
||||||
textTransform: 'capitalize',
|
|
||||||
width: 94
|
|
||||||
},
|
},
|
||||||
|
|
||||||
contextMenuItem: {
|
contextMenuItem: {
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Switch, Text, View } from 'react-native';
|
import { Switch, Text, View } from 'react-native';
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { getLocalParticipant } from '../../../base/participants';
|
import { getLocalParticipant } from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
import { BUTTON_MODES } from '../../../chat/constants';
|
|
||||||
import { isSubmitAnswerDisabled } from '../../functions';
|
import { isSubmitAnswerDisabled } from '../../functions';
|
||||||
import AbstractPollAnswer from '../AbstractPollAnswer';
|
import AbstractPollAnswer from '../AbstractPollAnswer';
|
||||||
import type { AbstractProps } from '../AbstractPollAnswer';
|
import type { AbstractProps } from '../AbstractPollAnswer';
|
||||||
|
@ -27,6 +27,7 @@ const PollAnswer = (props: AbstractProps) => {
|
||||||
} = props;
|
} = props;
|
||||||
const { changingVote } = poll;
|
const { changingVote } = poll;
|
||||||
const localParticipant = useSelector(getLocalParticipant);
|
const localParticipant = useSelector(getLocalParticipant);
|
||||||
|
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -51,26 +52,18 @@ const PollAnswer = (props: AbstractProps) => {
|
||||||
</View>
|
</View>
|
||||||
<View style = { chatStyles.buttonRow }>
|
<View style = { chatStyles.buttonRow }>
|
||||||
<Button
|
<Button
|
||||||
color = { BaseTheme.palette.action02 }
|
accessibilityLabel = 'polls.answer.skip'
|
||||||
labelStyle = { chatStyles.pollButtonLabel }
|
label = 'polls.answer.skip'
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { changingVote ? skipChangeVote : skipAnswer }
|
onPress = { changingVote ? skipChangeVote : skipAnswer }
|
||||||
style = { chatStyles.pollCreateButton } >
|
style = { chatStyles.pollCreateButton }
|
||||||
{ t('polls.answer.skip') }
|
type = { SECONDARY } />
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
color = { BaseTheme.palette.action01 }
|
accessibilityLabel = 'polls.answer.submit'
|
||||||
disabled = { isSubmitAnswerDisabled(checkBoxStates) }
|
disabled = { isSubmitAnswerDisabled(checkBoxStates) }
|
||||||
labelStyle = {
|
label = 'polls.answer.submit'
|
||||||
isSubmitAnswerDisabled(checkBoxStates)
|
|
||||||
? chatStyles.pollSendDisabledLabel
|
|
||||||
: chatStyles.pollSendLabel
|
|
||||||
}
|
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { submitAnswer }
|
onPress = { submitAnswer }
|
||||||
style = { chatStyles.pollCreateButton } >
|
style = { chatStyles.pollCreateButton }
|
||||||
{ t('polls.answer.submit') }
|
type = { PRIMARY } />
|
||||||
</Button>
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { View, Text, TextInput, FlatList } from 'react-native';
|
import { View, Text, TextInput, FlatList } from 'react-native';
|
||||||
import { Button, Divider, TouchableRipple } from 'react-native-paper';
|
import { Divider, TouchableRipple } from 'react-native-paper';
|
||||||
|
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
import { BUTTON_MODES } from '../../../chat/constants';
|
|
||||||
import styles
|
import styles
|
||||||
from '../../../welcome/components/native/settings/components/styles';
|
from '../../../welcome/components/native/settings/components/styles';
|
||||||
import { ANSWERS_LIMIT, CHAR_LIMIT } from '../../constants';
|
import { ANSWERS_LIMIT, CHAR_LIMIT } from '../../constants';
|
||||||
|
@ -16,8 +17,6 @@ import { chatStyles, dialogStyles } from './styles';
|
||||||
|
|
||||||
|
|
||||||
const PollCreate = (props: AbstractProps) => {
|
const PollCreate = (props: AbstractProps) => {
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
addAnswer,
|
addAnswer,
|
||||||
answers,
|
answers,
|
||||||
|
@ -56,6 +55,7 @@ const PollCreate = (props: AbstractProps) => {
|
||||||
* about whether a newly created input field has been rendered yet or not.
|
* about whether a newly created input field has been rendered yet or not.
|
||||||
*/
|
*/
|
||||||
const [ lastFocus, requestFocus ] = useState(null);
|
const [ lastFocus, requestFocus ] = useState(null);
|
||||||
|
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (lastFocus === null) {
|
if (lastFocus === null) {
|
||||||
|
@ -156,47 +156,36 @@ const PollCreate = (props: AbstractProps) => {
|
||||||
renderItem = { renderListItem } />
|
renderItem = { renderListItem } />
|
||||||
<View style = { chatStyles.pollCreateButtonsContainer }>
|
<View style = { chatStyles.pollCreateButtonsContainer }>
|
||||||
<Button
|
<Button
|
||||||
color = { BaseTheme.palette.action02 }
|
accessibilityLabel = 'polls.create.addOption'
|
||||||
disabled = { answers.length >= ANSWERS_LIMIT }
|
disabled = { answers.length >= ANSWERS_LIMIT }
|
||||||
labelStyle = { chatStyles.pollButtonLabel }
|
label = 'polls.create.addOption'
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { () => {
|
onPress = { () => {
|
||||||
// adding and answer
|
// adding and answer
|
||||||
addAnswer();
|
addAnswer();
|
||||||
requestFocus(answers.length);
|
requestFocus(answers.length);
|
||||||
} }
|
} }
|
||||||
style = { chatStyles.pollCreateAddButton }>
|
style = { chatStyles.pollCreateAddButton }
|
||||||
{ t('polls.create.addOption') }
|
type = { SECONDARY } />
|
||||||
</Button>
|
|
||||||
<View
|
<View
|
||||||
style = { chatStyles.buttonRow }>
|
style = { chatStyles.buttonRow }>
|
||||||
<Button
|
<Button
|
||||||
color = { BaseTheme.palette.action02 }
|
accessibilityLabel = 'polls.create.cancel'
|
||||||
labelStyle = { chatStyles.pollButtonLabel }
|
label = 'polls.create.cancel'
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { () => setCreateMode(false) }
|
onPress = { () => setCreateMode(false) }
|
||||||
style = { chatStyles.pollCreateButton } >
|
style = { chatStyles.pollCreateButton }
|
||||||
{ t('polls.create.cancel') }
|
type = { SECONDARY } />
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
color = { BaseTheme.palette.action01 }
|
accessibilityLabel = 'polls.create.send'
|
||||||
disabled = { isSubmitDisabled }
|
disabled = { isSubmitDisabled }
|
||||||
labelStyle = {
|
label = 'polls.create.send'
|
||||||
isSubmitDisabled
|
|
||||||
? chatStyles.pollSendDisabledLabel
|
|
||||||
: chatStyles.pollSendLabel
|
|
||||||
}
|
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { onSubmit }
|
onPress = { onSubmit }
|
||||||
style = { chatStyles.pollCreateButton } >
|
style = { chatStyles.pollCreateButton }
|
||||||
{ t('polls.create.send') }
|
type = { PRIMARY } />
|
||||||
</Button>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { Button, useTheme } from 'react-native-paper';
|
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||||
import { BUTTON_MODES } from '../../../chat/constants';
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { getUnreadPollCount } from '../../functions';
|
import { getUnreadPollCount } from '../../functions';
|
||||||
import AbstractPollsPane from '../AbstractPollsPane';
|
import AbstractPollsPane from '../AbstractPollsPane';
|
||||||
import type { AbstractProps } from '../AbstractPollsPane';
|
import type { AbstractProps } from '../AbstractPollsPane';
|
||||||
|
@ -22,7 +22,6 @@ const PollsPane = (props: AbstractProps) => {
|
||||||
const isPollsScreenFocused = useIsFocused();
|
const isPollsScreenFocused = useIsFocused();
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const nbUnreadPolls = useSelector(getUnreadPollCount);
|
const nbUnreadPolls = useSelector(getUnreadPollCount);
|
||||||
const { palette } = useTheme();
|
|
||||||
|
|
||||||
const nrUnreadPolls = !isPollsScreenFocused && nbUnreadPolls > 0
|
const nrUnreadPolls = !isPollsScreenFocused && nbUnreadPolls > 0
|
||||||
? `(${nbUnreadPolls})`
|
? `(${nbUnreadPolls})`
|
||||||
|
@ -47,13 +46,11 @@ const PollsPane = (props: AbstractProps) => {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!createMode && <Button
|
!createMode && <Button
|
||||||
color = { palette.action01 }
|
accessibilityLabel = 'polls.create.create'
|
||||||
labelStyle = { chatStyles.pollButtonLabel }
|
label = 'polls.create.create'
|
||||||
mode = { BUTTON_MODES.CONTAINED }
|
|
||||||
onPress = { onCreate }
|
onPress = { onCreate }
|
||||||
style = { chatStyles.createPollButton } >
|
style = { chatStyles.createPollButton }
|
||||||
{t('polls.create.create')}
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
</Button>
|
|
||||||
}
|
}
|
||||||
</JitsiScreen>
|
</JitsiScreen>
|
||||||
);
|
);
|
||||||
|
|
|
@ -167,20 +167,9 @@ export const chatStyles = createStyleSheet({
|
||||||
|
|
||||||
pollCreateButton: {
|
pollCreateButton: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: 4,
|
|
||||||
marginHorizontal: BaseTheme.spacing[2]
|
marginHorizontal: BaseTheme.spacing[2]
|
||||||
},
|
},
|
||||||
|
|
||||||
pollSendLabel: {
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
},
|
|
||||||
|
|
||||||
pollSendDisabledLabel: {
|
|
||||||
color: BaseTheme.palette.text03,
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
},
|
|
||||||
|
|
||||||
buttonRow: {
|
buttonRow: {
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
},
|
||||||
|
@ -200,13 +189,8 @@ export const chatStyles = createStyleSheet({
|
||||||
marginLeft: BaseTheme.spacing[2]
|
marginLeft: BaseTheme.spacing[2]
|
||||||
},
|
},
|
||||||
|
|
||||||
pollButtonLabel: {
|
|
||||||
textTransform: 'capitalize'
|
|
||||||
},
|
|
||||||
|
|
||||||
pollCreateAddButton: {
|
pollCreateAddButton: {
|
||||||
margin: BaseTheme.spacing[2],
|
margin: BaseTheme.spacing[2]
|
||||||
padding: BaseTheme.spacing[1]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleText: {
|
toggleText: {
|
||||||
|
@ -215,7 +199,6 @@ export const chatStyles = createStyleSheet({
|
||||||
},
|
},
|
||||||
|
|
||||||
createPollButton: {
|
createPollButton: {
|
||||||
padding: 4,
|
|
||||||
marginHorizontal: BaseTheme.spacing[4],
|
marginHorizontal: BaseTheme.spacing[4],
|
||||||
marginVertical: '8%'
|
marginVertical: '8%'
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,9 +2,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
BackHandler,
|
BackHandler,
|
||||||
Text,
|
|
||||||
View,
|
View,
|
||||||
TouchableOpacity,
|
|
||||||
TextInput,
|
TextInput,
|
||||||
Platform
|
Platform
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
@ -17,6 +15,8 @@ import { IconClose } from '../../base/icons';
|
||||||
import JitsiScreen from '../../base/modal/components/JitsiScreen';
|
import JitsiScreen from '../../base/modal/components/JitsiScreen';
|
||||||
import { getLocalParticipant } from '../../base/participants';
|
import { getLocalParticipant } from '../../base/participants';
|
||||||
import { getFieldValue } from '../../base/react';
|
import { getFieldValue } from '../../base/react';
|
||||||
|
import Button from '../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../base/react/constants';
|
||||||
import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
|
import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
|
||||||
import { updateSettings } from '../../base/settings';
|
import { updateSettings } from '../../base/settings';
|
||||||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||||
|
@ -28,15 +28,11 @@ import { screen } from '../../mobile/navigation/routes';
|
||||||
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 { isDisplayNameRequired } from '../functions';
|
import { isDisplayNameRequired } from '../functions';
|
||||||
|
import { PrejoinProps } from '../types';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
|
||||||
navigation: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props) => {
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const aspectRatio = useSelector(
|
const aspectRatio = useSelector(
|
||||||
|
@ -88,9 +84,8 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const { PRIMARY, SECONDARY } = BUTTON_TYPES;
|
||||||
const joinButtonDisabled = !displayName && isDisplayNameMandatory;
|
const joinButtonDisabled = !displayName && isDisplayNameMandatory;
|
||||||
const joinButtonStyles = joinButtonDisabled
|
|
||||||
? styles.primaryButtonDisabled : styles.primaryButton;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
BackHandler.addEventListener('hardwareBackPress', goBack);
|
BackHandler.addEventListener('hardwareBackPress', goBack);
|
||||||
|
@ -122,6 +117,7 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
||||||
toolboxContainerStyles = styles.toolboxContainerWide;
|
toolboxContainerStyles = styles.toolboxContainerWide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JitsiScreen
|
<JitsiScreen
|
||||||
safeAreaInsets = { [ 'left' ] }
|
safeAreaInsets = { [ 'left' ] }
|
||||||
|
@ -138,27 +134,19 @@ const Prejoin: ({ navigation }: Props) => JSX.Element = ({ navigation }: Props)
|
||||||
placeholderTextColor = { BaseTheme.palette.text03 }
|
placeholderTextColor = { BaseTheme.palette.text03 }
|
||||||
style = { styles.field }
|
style = { styles.field }
|
||||||
value = { displayName } />
|
value = { displayName } />
|
||||||
<TouchableOpacity
|
<Button
|
||||||
|
accessibilityLabel = 'prejoin.joinMeeting'
|
||||||
disabled = { joinButtonDisabled }
|
disabled = { joinButtonDisabled }
|
||||||
|
label = 'prejoin.joinMeeting'
|
||||||
onPress = { onJoin }
|
onPress = { onJoin }
|
||||||
style = { [
|
style = { styles.prejoinButton }
|
||||||
styles.button,
|
type = { PRIMARY } />
|
||||||
joinButtonStyles
|
<Button
|
||||||
] }>
|
accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode'
|
||||||
<Text style = { styles.primaryButtonText }>
|
label = 'prejoin.joinMeetingInLowBandwidthMode'
|
||||||
{ t('prejoin.joinMeeting') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress = { onJoinLowBandwidth }
|
onPress = { onJoinLowBandwidth }
|
||||||
style = { [
|
style = { styles.prejoinButton }
|
||||||
styles.button,
|
type = { SECONDARY } />
|
||||||
styles.secondaryButton
|
|
||||||
] }>
|
|
||||||
<Text style = { styles.secondaryButtonText }>
|
|
||||||
{ t('prejoin.joinMeetingInLowBandwidthMode') }
|
|
||||||
</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
<View style = { toolboxContainerStyles }>
|
<View style = { toolboxContainerStyles }>
|
||||||
<AudioMuteButton
|
<AudioMuteButton
|
||||||
|
|
|
@ -1,47 +1,13 @@
|
||||||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||||
|
|
||||||
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
const SECONDARY_COLOR = BaseTheme.palette.border04;
|
||||||
const btn = {
|
|
||||||
marginTop: BaseTheme.spacing[4]
|
|
||||||
};
|
|
||||||
const btnText = {
|
|
||||||
...BaseTheme.typography.labelButtonLarge,
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
lineHeight: 30
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
button: {
|
prejoinButton: {
|
||||||
alignItems: 'center',
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
padding: BaseTheme.spacing[2],
|
|
||||||
height: BaseTheme.spacing[7]
|
|
||||||
},
|
|
||||||
|
|
||||||
primaryButton: {
|
|
||||||
...btn,
|
|
||||||
backgroundColor: BaseTheme.palette.action01
|
|
||||||
},
|
|
||||||
|
|
||||||
primaryButtonDisabled: {
|
|
||||||
backgroundColor: BaseTheme.palette.action03Disabled,
|
|
||||||
marginTop: BaseTheme.spacing[4]
|
marginTop: BaseTheme.spacing[4]
|
||||||
},
|
},
|
||||||
|
|
||||||
primaryButtonText: {
|
|
||||||
...btnText
|
|
||||||
},
|
|
||||||
|
|
||||||
secondaryButton: {
|
|
||||||
...btn,
|
|
||||||
backgroundColor: BaseTheme.palette.action02
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
secondaryButtonText: {
|
|
||||||
...btnText
|
|
||||||
},
|
|
||||||
|
|
||||||
buttonStylesBorderless: {
|
buttonStylesBorderless: {
|
||||||
iconStyle: {
|
iconStyle: {
|
||||||
color: BaseTheme.palette.icon01,
|
color: BaseTheme.palette.icon01,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
interface PrejoinProps {
|
||||||
|
navigation: Object;
|
||||||
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Text, TouchableHighlight, View } from 'react-native';
|
import { Text } from 'react-native-paper';
|
||||||
import { type Dispatch } from 'redux';
|
import { type Dispatch } from 'redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createToolbarEvent,
|
createToolbarEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
} from '../../../analytics';
|
} from '../../../analytics';
|
||||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
|
||||||
import { RAISE_HAND_ENABLED, getFeatureFlag } from '../../../base/flags';
|
import { RAISE_HAND_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
import {
|
import {
|
||||||
|
@ -16,10 +15,12 @@ import {
|
||||||
hasRaisedHand,
|
hasRaisedHand,
|
||||||
raiseHand
|
raiseHand
|
||||||
} from '../../../base/participants';
|
} from '../../../base/participants';
|
||||||
|
import Button from '../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../base/react/constants';
|
||||||
import { connect } from '../../../base/redux';
|
import { connect } from '../../../base/redux';
|
||||||
import { type AbstractButtonProps } from '../../../base/toolbox/components';
|
import { type AbstractButtonProps } from '../../../base/toolbox/components';
|
||||||
|
|
||||||
import { type ReactionStyles } from './ReactionButton';
|
import styles from './styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link RaiseHandButton}.
|
* The type of the React {@code Component} props of {@link RaiseHandButton}.
|
||||||
|
@ -54,12 +55,7 @@ type Props = AbstractButtonProps & {
|
||||||
/**
|
/**
|
||||||
* Used to close the overflow menu after raise hand is clicked.
|
* Used to close the overflow menu after raise hand is clicked.
|
||||||
*/
|
*/
|
||||||
onCancel: Function,
|
onCancel: Function
|
||||||
|
|
||||||
/**
|
|
||||||
* Styles for the button.
|
|
||||||
*/
|
|
||||||
_styles: ReactionStyles
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,6 +123,17 @@ class RaiseHandButton extends Component<Props, *> {
|
||||||
return t(_raisedHand ? this.toggledLabel : this.label);
|
return t(_raisedHand ? this.toggledLabel : this.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the "raise hand" emoji.
|
||||||
|
*
|
||||||
|
* @returns {ReactElement}
|
||||||
|
*/
|
||||||
|
_renderRaiseHandEmoji() {
|
||||||
|
return (
|
||||||
|
<Text>✋</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements React's {@link Component#render()}.
|
* Implements React's {@link Component#render()}.
|
||||||
*
|
*
|
||||||
|
@ -134,24 +141,20 @@ class RaiseHandButton extends Component<Props, *> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { _enabled, _styles, t } = this.props;
|
const { _enabled } = this.props;
|
||||||
|
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableHighlight
|
<Button
|
||||||
accessibilityLabel = { t(this.accessibilityLabel) }
|
accessibilityLabel = { this.accessibilityLabel }
|
||||||
accessibilityRole = 'button'
|
icon = { this._renderRaiseHandEmoji }
|
||||||
|
label = { this._getLabel() }
|
||||||
onPress = { this._onClick }
|
onPress = { this._onClick }
|
||||||
style = { _styles.style }
|
style = { styles.raiseHandButton }
|
||||||
underlayColor = { _styles.underlayColor }>
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
<View style = { _styles.container }>
|
|
||||||
<Text style = { _styles.emoji }>✋</Text>
|
|
||||||
<Text style = { _styles.text }>{this._getLabel()}</Text>
|
|
||||||
</View>
|
|
||||||
</TouchableHighlight>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,8 +173,7 @@ function _mapStateToProps(state): Object {
|
||||||
return {
|
return {
|
||||||
_enabled: enabled,
|
_enabled: enabled,
|
||||||
_localParticipant,
|
_localParticipant,
|
||||||
_raisedHand: hasRaisedHand(_localParticipant),
|
_raisedHand: hasRaisedHand(_localParticipant)
|
||||||
_styles: ColorSchemeRegistry.get(state, 'Toolbox').raiseHandButton
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,21 +49,25 @@ function ReactionMenu({
|
||||||
return (
|
return (
|
||||||
<View style = { overflowMenu ? _styles.overflowReactionMenu : _styles.reactionMenu }>
|
<View style = { overflowMenu ? _styles.overflowReactionMenu : _styles.reactionMenu }>
|
||||||
<View style = { _styles.reactionRow }>
|
<View style = { _styles.reactionRow }>
|
||||||
{Object.keys(REACTIONS).map(key => (
|
{
|
||||||
<ReactionButton
|
Object.keys(REACTIONS).map(key => (
|
||||||
key = { key }
|
<ReactionButton
|
||||||
reaction = { key }
|
key = { key }
|
||||||
styles = { _styles.reactionButton } />
|
reaction = { key }
|
||||||
))}
|
styles = { _styles.reactionButton } />
|
||||||
{gifEnabled && (
|
))
|
||||||
<ReactionButton
|
}
|
||||||
onClick = { openGifMenu }
|
{
|
||||||
styles = { _styles.reactionButton }>
|
gifEnabled && (
|
||||||
<Image
|
<ReactionButton
|
||||||
height = { 22 }
|
onClick = { openGifMenu }
|
||||||
source = { require('../../../../../images/GIPHY_icon.png') } />
|
styles = { _styles.reactionButton }>
|
||||||
</ReactionButton>
|
<Image
|
||||||
)}
|
height = { 22 }
|
||||||
|
source = { require('../../../../../images/GIPHY_icon.png') } />
|
||||||
|
</ReactionButton>
|
||||||
|
)
|
||||||
|
}
|
||||||
</View>
|
</View>
|
||||||
<RaiseHandButton onCancel = { onCancel } />
|
<RaiseHandButton onCancel = { onCancel } />
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The styles of the native components of the feature {@code reactions}.
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
raiseHandButton: {
|
||||||
|
marginVertical: BaseTheme.spacing[3],
|
||||||
|
width: 240
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,10 +1,11 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
import { Button } from 'react-native-paper';
|
|
||||||
import { useDispatch, batch } from 'react-redux';
|
import { useDispatch, batch } from 'react-redux';
|
||||||
|
|
||||||
import { BottomSheet, hideSheet } from '../../../../base/dialog';
|
import { BottomSheet, hideSheet } from '../../../../base/dialog';
|
||||||
|
import Button from '../../../../base/react/components/native/Button';
|
||||||
|
import { BUTTON_TYPES } from '../../../../base/react/constants';
|
||||||
import { highlightMeetingMoment } from '../../../actions.any';
|
import { highlightMeetingMoment } from '../../../actions.any';
|
||||||
import styles from '../styles.native';
|
import styles from '../styles.native';
|
||||||
|
|
||||||
|
@ -28,20 +29,16 @@ const HighlightDialog = () => {
|
||||||
</Text>
|
</Text>
|
||||||
<View style = { styles.highlightDialogButtonsContainer } >
|
<View style = { styles.highlightDialogButtonsContainer } >
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('dialog.Cancel') }
|
accessibilityLabel = 'dialog.Cancel'
|
||||||
children = { t('dialog.Cancel') }
|
label = 'dialog.Cancel'
|
||||||
labelStyle = { styles.highlightDialogCancelLabel }
|
|
||||||
mode = 'contained'
|
|
||||||
onPress = { closeDialog }
|
onPress = { closeDialog }
|
||||||
style = { styles.highlightDialogCancelButton } />
|
type = { BUTTON_TYPES.SECONDARY } />
|
||||||
<View style = { styles.highlightDialogButtonsSpace } />
|
<View style = { styles.highlightDialogButtonsSpace } />
|
||||||
<Button
|
<Button
|
||||||
accessibilityLabel = { t('recording.highlight') }
|
accessibilityLabel = 'recording.highlight'
|
||||||
children = { t('recording.highlight') }
|
label = 'recording.highlight'
|
||||||
labelStyle = { styles.highlightDialogHighlighLabel }
|
|
||||||
mode = 'contained'
|
|
||||||
onPress = { highlightMoment }
|
onPress = { highlightMoment }
|
||||||
style = { styles.highlightDialogHighlightButton } />
|
type = { BUTTON_TYPES.PRIMARY } />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</BottomSheet>
|
</BottomSheet>
|
||||||
|
|
|
@ -39,18 +39,6 @@ const title = {
|
||||||
paddingLeft: BoxModel.padding
|
paddingLeft: BoxModel.padding
|
||||||
};
|
};
|
||||||
|
|
||||||
const baseHighlightDialogButton = {
|
|
||||||
borderRadius: BaseTheme.shape.borderRadius,
|
|
||||||
height: BaseTheme.spacing[7],
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: 'space-around'
|
|
||||||
};
|
|
||||||
|
|
||||||
const baseHighlightDialogLabel = {
|
|
||||||
...BaseTheme.typography.bodyShortBoldLarge,
|
|
||||||
textTransform: 'none'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
/**
|
/**
|
||||||
* Container for the StartRecordingDialog screen.
|
* Container for the StartRecordingDialog screen.
|
||||||
|
@ -104,22 +92,6 @@ export default {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column-reverse'
|
flexDirection: 'column-reverse'
|
||||||
},
|
},
|
||||||
highlightDialogCancelButton: {
|
|
||||||
...baseHighlightDialogButton,
|
|
||||||
backgroundColor: BaseTheme.palette.section01
|
|
||||||
},
|
|
||||||
highlightDialogHighlightButton: {
|
|
||||||
...baseHighlightDialogButton,
|
|
||||||
backgroundColor: BaseTheme.palette.action01
|
|
||||||
},
|
|
||||||
highlightDialogCancelLabel: {
|
|
||||||
...baseHighlightDialogLabel,
|
|
||||||
color: BaseTheme.palette.field01
|
|
||||||
},
|
|
||||||
highlightDialogHighlighLabel: {
|
|
||||||
...baseHighlightDialogLabel,
|
|
||||||
color: BaseTheme.palette.text01
|
|
||||||
},
|
|
||||||
highlightDialogButtonsSpace: {
|
highlightDialogButtonsSpace: {
|
||||||
height: 16,
|
height: 16,
|
||||||
width: '100%'
|
width: '100%'
|
||||||
|
|
|
@ -161,8 +161,7 @@ ColorSchemeRegistry.register('Toolbox', {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
width: '100%',
|
width: '100%'
|
||||||
marginBottom: 16
|
|
||||||
},
|
},
|
||||||
|
|
||||||
reactionButton: {
|
reactionButton: {
|
||||||
|
@ -172,28 +171,6 @@ ColorSchemeRegistry.register('Toolbox', {
|
||||||
emoji: reactionEmoji
|
emoji: reactionEmoji
|
||||||
},
|
},
|
||||||
|
|
||||||
raiseHandButton: {
|
|
||||||
style: {
|
|
||||||
...reactionButton,
|
|
||||||
backgroundColor: BaseTheme.palette.ui13,
|
|
||||||
width: '100%',
|
|
||||||
borderRadius: 6
|
|
||||||
},
|
|
||||||
underlayColor: BaseTheme.palette.ui13,
|
|
||||||
emoji: reactionEmoji,
|
|
||||||
text: {
|
|
||||||
color: BaseTheme.palette.text01,
|
|
||||||
fontWeight: '600',
|
|
||||||
marginLeft: 8,
|
|
||||||
lineHeight: 24
|
|
||||||
},
|
|
||||||
container: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
emojiAnimation: {
|
emojiAnimation: {
|
||||||
color: BaseTheme.palette.icon01,
|
color: BaseTheme.palette.icon01,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default {
|
||||||
* Global {@code Text} color for the components.
|
* Global {@code Text} color for the components.
|
||||||
*/
|
*/
|
||||||
text: {
|
text: {
|
||||||
color: BaseTheme.palette.text02
|
color: BaseTheme.palette.text01
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue