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