[RN] Add color scheme support - Components
This commit is contained in:
parent
2941f5dde4
commit
e094b6516a
|
@ -9,10 +9,12 @@ import {
|
|||
CustomSubmitDialog,
|
||||
FIELD_UNDERLINE,
|
||||
PLACEHOLDER_COLOR,
|
||||
_abstractMapStateToProps,
|
||||
inputDialog as inputDialogStyle
|
||||
} from '../../base/dialog';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { JitsiConnectionErrors } from '../../base/lib-jitsi-meet';
|
||||
import { StyleType } from '../../base/styles';
|
||||
|
||||
import { authenticateAndUpgradeRole, cancelLogin } from '../actions';
|
||||
import styles from './styles';
|
||||
|
@ -38,6 +40,11 @@ type Props = {
|
|||
*/
|
||||
_connecting: boolean,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the base/dialog feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The error which occurred during login/authentication.
|
||||
*/
|
||||
|
@ -134,6 +141,7 @@ class LoginDialog extends Component<Props, State> {
|
|||
render() {
|
||||
const {
|
||||
_connecting: connecting,
|
||||
_dialogStyles,
|
||||
_error: error,
|
||||
_progress: progress,
|
||||
t
|
||||
|
@ -186,7 +194,7 @@ class LoginDialog extends Component<Props, State> {
|
|||
onChangeText = { this._onUsernameChange }
|
||||
placeholder = { 'user@domain.com' }
|
||||
placeholderTextColor = { PLACEHOLDER_COLOR }
|
||||
style = { inputDialogStyle.field }
|
||||
style = { _dialogStyles.field }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
value = { this.state.username } />
|
||||
<TextInput
|
||||
|
@ -195,7 +203,7 @@ class LoginDialog extends Component<Props, State> {
|
|||
placeholderTextColor = { PLACEHOLDER_COLOR }
|
||||
secureTextEntry = { true }
|
||||
style = { [
|
||||
inputDialogStyle.field,
|
||||
_dialogStyles.field,
|
||||
inputDialogStyle.bottomField
|
||||
] }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
|
@ -289,6 +297,7 @@ class LoginDialog extends Component<Props, State> {
|
|||
* _conference: JitsiConference,
|
||||
* _configHosts: Object,
|
||||
* _connecting: boolean,
|
||||
* _dialogStyles: StyleType,
|
||||
* _error: Object,
|
||||
* _progress: number
|
||||
* }}
|
||||
|
@ -307,6 +316,7 @@ function _mapStateToProps(state) {
|
|||
} = state['features/base/connection'];
|
||||
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_conference: authRequired,
|
||||
_configHosts: configHosts,
|
||||
_connecting: Boolean(connecting) || Boolean(thenableWithCancel),
|
||||
|
|
|
@ -1,6 +1,35 @@
|
|||
// @flow
|
||||
|
||||
import { ColorPalette, getRGBAFormat } from '../styles';
|
||||
|
||||
/**
|
||||
* The default color scheme of the application.
|
||||
*/
|
||||
export default {};
|
||||
export default {
|
||||
'BottomSheet': {
|
||||
background: ColorPalette.blackBlue,
|
||||
icon: ColorPalette.white,
|
||||
label: ColorPalette.white
|
||||
},
|
||||
'Dialog': {
|
||||
background: ColorPalette.blackBlue,
|
||||
border: getRGBAFormat(ColorPalette.white, 0.2),
|
||||
icon: ColorPalette.white,
|
||||
text: ColorPalette.white
|
||||
},
|
||||
'LargeVideo': {
|
||||
background: ColorPalette.black
|
||||
},
|
||||
'Thumbnail': {
|
||||
activeParticipantHighlight: ColorPalette.blue,
|
||||
activeParticipantTint: ColorPalette.black,
|
||||
background: ColorPalette.black
|
||||
},
|
||||
'Toolbox': {
|
||||
button: getRGBAFormat(ColorPalette.white, 0.7),
|
||||
buttonToggled: getRGBAFormat(ColorPalette.buttonUnderlay, 0.7),
|
||||
buttonToggledBorder:
|
||||
getRGBAFormat(ColorPalette.buttonUnderlay, 0.7),
|
||||
hangup: ColorPalette.red
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from 'react-native';
|
||||
|
||||
import { Icon } from '../../../font-icons';
|
||||
import { StyleType } from '../../../styles';
|
||||
|
||||
import AbstractDialog, {
|
||||
type Props as AbstractProps,
|
||||
|
@ -18,6 +19,11 @@ import { brandedDialog as styles } from './styles';
|
|||
export type Props = {
|
||||
...AbstractProps,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
t: Function
|
||||
}
|
||||
|
||||
|
@ -43,7 +49,7 @@ class BaseDialog<P: Props, S: State> extends AbstractDialog<P, S> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { style } = this.props;
|
||||
const { _dialogStyles, style } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
|
@ -55,7 +61,7 @@ class BaseDialog<P: Props, S: State> extends AbstractDialog<P, S> {
|
|||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { [
|
||||
styles.dialog,
|
||||
_dialogStyles.dialog,
|
||||
this.props.style
|
||||
] }>
|
||||
<TouchableOpacity
|
||||
|
@ -63,7 +69,7 @@ class BaseDialog<P: Props, S: State> extends AbstractDialog<P, S> {
|
|||
style = { styles.closeWrapper }>
|
||||
<Icon
|
||||
name = 'close'
|
||||
style = { styles.closeStyle } />
|
||||
style = { _dialogStyles.closeStyle } />
|
||||
</TouchableOpacity>
|
||||
{ this._renderContent() }
|
||||
</View>
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
import React from 'react';
|
||||
import { View, Text, TouchableOpacity } from 'react-native';
|
||||
|
||||
import { StyleType } from '../../../styles';
|
||||
|
||||
import BaseDialog, { type Props as BaseProps } from './BaseDialog';
|
||||
import {
|
||||
brandedDialog
|
||||
|
@ -11,6 +13,11 @@ import {
|
|||
type Props = {
|
||||
...BaseProps,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
t: Function
|
||||
}
|
||||
|
||||
|
@ -46,7 +53,7 @@ class BaseSubmitDialog<P: Props, S: *> extends BaseDialog<P, S> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderContent() {
|
||||
const { t } = this.props;
|
||||
const { _dialogStyles, t } = this.props;
|
||||
const additionalButtons = this._renderAdditionalButtons();
|
||||
|
||||
return (
|
||||
|
@ -65,7 +72,7 @@ class BaseSubmitDialog<P: Props, S: *> extends BaseDialog<P, S> {
|
|||
? null : brandedDialog.buttonFarLeft,
|
||||
brandedDialog.buttonFarRight
|
||||
] }>
|
||||
<Text style = { brandedDialog.text }>
|
||||
<Text style = { _dialogStyles.text }>
|
||||
{ t(this._getSubmitButtonKey()) }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
import React, { Component, type Node } from 'react';
|
||||
import { TouchableWithoutFeedback, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../color-scheme';
|
||||
import { Modal } from '../../../react';
|
||||
import { StyleType } from '../../../styles';
|
||||
|
||||
import { bottomSheetStyles as styles } from './styles';
|
||||
|
||||
|
@ -12,6 +15,11 @@ import { bottomSheetStyles as styles } from './styles';
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* The children to be displayed within this component.
|
||||
*/
|
||||
|
@ -28,7 +36,7 @@ type Props = {
|
|||
* A component emulating Android's BottomSheet. For all intents and purposes,
|
||||
* this component has been designed to work and behave as a {@code Dialog}.
|
||||
*/
|
||||
export default class BottomSheet extends Component<Props> {
|
||||
class BottomSheet extends Component<Props> {
|
||||
/**
|
||||
* Initializes a new {@code BottomSheet} instance.
|
||||
*
|
||||
|
@ -47,6 +55,8 @@ export default class BottomSheet extends Component<Props> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _styles } = this.props;
|
||||
|
||||
return [
|
||||
<View
|
||||
key = 'overlay'
|
||||
|
@ -60,7 +70,7 @@ export default class BottomSheet extends Component<Props> {
|
|||
onPress = { this._onCancel } >
|
||||
<View style = { styles.backdrop } />
|
||||
</TouchableWithoutFeedback>
|
||||
<View style = { styles.sheet }>
|
||||
<View style = { _styles.sheet }>
|
||||
{ this.props.children }
|
||||
</View>
|
||||
</View>
|
||||
|
@ -82,3 +92,19 @@ export default class BottomSheet extends Component<Props> {
|
|||
onCancel && onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _styles: StyleType
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_styles: ColorSchemeRegistry.get(state, 'BottomSheet')
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(BottomSheet);
|
||||
|
|
|
@ -5,6 +5,9 @@ import { Text, TouchableOpacity } from 'react-native';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { StyleType } from '../../../styles';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../functions';
|
||||
|
||||
import { type Props as BaseProps } from './BaseDialog';
|
||||
import BaseSubmitDialog from './BaseSubmitDialog';
|
||||
|
@ -13,6 +16,11 @@ import { brandedDialog } from './styles';
|
|||
type Props = {
|
||||
...BaseProps,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* Untranslated i18n key of the content to be displayed.
|
||||
*
|
||||
|
@ -49,7 +57,7 @@ class ConfirmDialog extends BaseSubmitDialog<Props, *> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderAdditionalButtons() {
|
||||
const { t } = this.props;
|
||||
const { _dialogStyles, t } = this.props;
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
|
@ -57,9 +65,9 @@ class ConfirmDialog extends BaseSubmitDialog<Props, *> {
|
|||
style = { [
|
||||
brandedDialog.button,
|
||||
brandedDialog.buttonFarLeft,
|
||||
brandedDialog.buttonSeparator
|
||||
_dialogStyles.buttonSeparator
|
||||
] }>
|
||||
<Text style = { brandedDialog.text }>
|
||||
<Text style = { _dialogStyles.text }>
|
||||
{ t('dialog.confirmNo') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
@ -72,14 +80,14 @@ class ConfirmDialog extends BaseSubmitDialog<Props, *> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderSubmittable() {
|
||||
const { contentKey, t } = this.props;
|
||||
const { _dialogStyles, contentKey, t } = this.props;
|
||||
const content
|
||||
= typeof contentKey === 'string'
|
||||
? t(contentKey)
|
||||
: this._renderHTML(t(contentKey.key, contentKey.params));
|
||||
|
||||
return (
|
||||
<Text style = { brandedDialog.text }>
|
||||
<Text style = { _dialogStyles.text }>
|
||||
{ content }
|
||||
</Text>
|
||||
);
|
||||
|
@ -88,4 +96,4 @@ class ConfirmDialog extends BaseSubmitDialog<Props, *> {
|
|||
_renderHTML: string => Object | string
|
||||
}
|
||||
|
||||
export default translate(connect()(ConfirmDialog));
|
||||
export default translate(connect(_abstractMapStateToProps)(ConfirmDialog));
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../functions';
|
||||
|
||||
import BaseDialog, { type Props } from './BaseDialog';
|
||||
|
||||
/**
|
||||
|
@ -19,4 +21,4 @@ class CustomDialog extends BaseDialog<Props, *> {
|
|||
}
|
||||
}
|
||||
|
||||
export default connect()(CustomDialog);
|
||||
export default connect(_abstractMapStateToProps)(CustomDialog);
|
||||
|
|
|
@ -4,6 +4,8 @@ import { connect } from 'react-redux';
|
|||
|
||||
import { translate } from '../../../i18n';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../functions';
|
||||
|
||||
import { type Props as BaseProps } from './BaseDialog';
|
||||
import BaseSubmitDialog from './BaseSubmitDialog';
|
||||
|
||||
|
@ -27,4 +29,5 @@ class CustomSubmitDialog extends BaseSubmitDialog<Props, *> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(connect()(CustomSubmitDialog));
|
||||
export default translate(
|
||||
connect(_abstractMapStateToProps)(CustomSubmitDialog));
|
||||
|
|
|
@ -5,6 +5,9 @@ import { View, Text, TextInput, TouchableOpacity } from 'react-native';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { translate } from '../../../i18n';
|
||||
import { StyleType } from '../../../styles';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../functions';
|
||||
|
||||
import { type State as AbstractState } from '../AbstractDialog';
|
||||
|
||||
|
@ -18,6 +21,11 @@ import {
|
|||
type Props = {
|
||||
...BaseProps,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The untranslated i18n key for the field label on the dialog.
|
||||
*/
|
||||
|
@ -63,7 +71,7 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
_renderContent() {
|
||||
const { okDisabled, t } = this.props;
|
||||
const { _dialogStyles, okDisabled, t } = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
|
@ -72,12 +80,12 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
brandedDialog.mainWrapper,
|
||||
styles.fieldWrapper
|
||||
] }>
|
||||
<Text style = { styles.fieldLabel }>
|
||||
<Text style = { _dialogStyles.fieldLabel }>
|
||||
{ t(this.props.contentKey) }
|
||||
</Text>
|
||||
<TextInput
|
||||
onChangeText = { this._onChangeText }
|
||||
style = { styles.field }
|
||||
style = { _dialogStyles.field }
|
||||
underlineColorAndroid = { FIELD_UNDERLINE }
|
||||
value = { this.state.fieldValue }
|
||||
{ ...this.props.textInputProps } />
|
||||
|
@ -91,7 +99,7 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
brandedDialog.buttonFarLeft,
|
||||
brandedDialog.buttonFarRight
|
||||
] }>
|
||||
<Text style = { brandedDialog.text }>
|
||||
<Text style = { _dialogStyles.text }>
|
||||
{ t('dialog.Ok') }
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
@ -130,4 +138,4 @@ class InputDialog extends BaseDialog<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(connect()(InputDialog));
|
||||
export default translate(connect(_abstractMapStateToProps)(InputDialog));
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../../color-scheme';
|
||||
import { BoxModel, ColorPalette, createStyleSheet } from '../../../styles';
|
||||
|
||||
import { PREFERRED_DIALOG_SIZE } from '../../constants';
|
||||
|
||||
const BORDER_RADIUS = 5;
|
||||
const DIALOG_BORDER_COLOR = 'rgba(255, 255, 255, 0.2)';
|
||||
|
||||
export const FIELD_UNDERLINE = ColorPalette.transparent;
|
||||
|
||||
|
@ -22,47 +22,6 @@ export const MD_ITEM_MARGIN_PADDING = 16;
|
|||
|
||||
export const PLACEHOLDER_COLOR = ColorPalette.lightGrey;
|
||||
|
||||
/**
|
||||
* Default styles for the items of a {@code BottomSheet}-based menu.
|
||||
*
|
||||
* These have been implemented as per the Material Design guidelines:
|
||||
* {@link https://material.io/guidelines/components/bottom-sheets.html}.
|
||||
*/
|
||||
const bottomSheetItemStyles = createStyleSheet({
|
||||
/**
|
||||
* Container style for a generic item rendered in the menu.
|
||||
*/
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
height: MD_ITEM_HEIGHT
|
||||
},
|
||||
|
||||
/**
|
||||
* Style for the {@code Icon} element in a generic item of the menu.
|
||||
*/
|
||||
iconStyle: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* Style for the label in a generic item rendered in the menu.
|
||||
*/
|
||||
labelStyle: {
|
||||
color: ColorPalette.white,
|
||||
flexShrink: 1,
|
||||
fontSize: MD_FONT_SIZE,
|
||||
marginLeft: 32,
|
||||
opacity: 0.90
|
||||
}
|
||||
});
|
||||
|
||||
export const bottomSheetItemStylesCombined = {
|
||||
...bottomSheetItemStyles,
|
||||
underlayColor: ColorPalette.overflowMenuItemUnderlay
|
||||
};
|
||||
|
||||
/**
|
||||
* The React {@code Component} styles of {@code BottomSheet}. These have
|
||||
* been implemented as per the Material Design guidelines:
|
||||
|
@ -94,16 +53,6 @@ export const bottomSheetStyles = createStyleSheet({
|
|||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: 'rgba(127, 127, 127, 0.6)'
|
||||
},
|
||||
|
||||
/**
|
||||
* Bottom sheet's base style.
|
||||
*/
|
||||
sheet: {
|
||||
backgroundColor: 'rgb(0, 3, 6)',
|
||||
flex: 1,
|
||||
paddingHorizontal: MD_ITEM_MARGIN_PADDING,
|
||||
paddingVertical: 8
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -131,38 +80,17 @@ export const brandedDialog = createStyleSheet({
|
|||
borderBottomRightRadius: BORDER_RADIUS
|
||||
},
|
||||
|
||||
buttonSeparator: {
|
||||
borderRightColor: DIALOG_BORDER_COLOR,
|
||||
borderRightWidth: 1
|
||||
},
|
||||
|
||||
buttonWrapper: {
|
||||
alignItems: 'stretch',
|
||||
borderRadius: BORDER_RADIUS,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
|
||||
closeStyle: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: MD_FONT_SIZE
|
||||
},
|
||||
|
||||
closeWrapper: {
|
||||
alignSelf: 'flex-end',
|
||||
padding: BoxModel.padding
|
||||
},
|
||||
|
||||
dialog: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: 'rgb(0, 3, 6)',
|
||||
borderColor: DIALOG_BORDER_COLOR,
|
||||
borderRadius: BORDER_RADIUS,
|
||||
borderWidth: 1,
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
maxWidth: PREFERRED_DIALOG_SIZE
|
||||
},
|
||||
|
||||
mainWrapper: {
|
||||
alignSelf: 'stretch',
|
||||
padding: BoxModel.padding * 2,
|
||||
|
@ -179,56 +107,135 @@ export const brandedDialog = createStyleSheet({
|
|||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
padding: 30
|
||||
},
|
||||
|
||||
text: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: MD_FONT_SIZE,
|
||||
textAlign: 'center'
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The React {@code Component} styles of {@code Dialog}.
|
||||
* Reusable (colored) style for text in any branded dialogs.
|
||||
*/
|
||||
export const dialog = createStyleSheet({
|
||||
/**
|
||||
* The style of the {@code Text} in a {@code Dialog} button.
|
||||
*/
|
||||
buttonText: {
|
||||
color: ColorPalette.blue
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of the {@code Text} in a {@code Dialog} button which is
|
||||
* disabled.
|
||||
*/
|
||||
disabledButtonText: {
|
||||
color: ColorPalette.darkGrey
|
||||
}
|
||||
});
|
||||
const brandedDialogText = {
|
||||
color: schemeColor('text'),
|
||||
fontSize: MD_FONT_SIZE,
|
||||
textAlign: 'center'
|
||||
};
|
||||
|
||||
export const inputDialog = createStyleSheet({
|
||||
bottomField: {
|
||||
marginBottom: 0
|
||||
},
|
||||
|
||||
field: {
|
||||
...brandedDialog.text,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: DIALOG_BORDER_COLOR,
|
||||
margin: BoxModel.margin,
|
||||
textAlign: 'left'
|
||||
},
|
||||
|
||||
fieldLabel: {
|
||||
...brandedDialog.text,
|
||||
margin: BoxModel.margin,
|
||||
textAlign: 'left'
|
||||
},
|
||||
|
||||
fieldWrapper: {
|
||||
...brandedDialog.mainWrapper,
|
||||
paddingBottom: BoxModel.padding * 2
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Default styles for the items of a {@code BottomSheet}-based menu.
|
||||
*
|
||||
* These have been implemented as per the Material Design guidelines:
|
||||
* {@link https://material.io/guidelines/components/bottom-sheets.html}.
|
||||
*/
|
||||
ColorSchemeRegistry.register('BottomSheet', {
|
||||
/**
|
||||
* Style for the {@code Icon} element in a generic item of the menu.
|
||||
*/
|
||||
iconStyle: {
|
||||
color: schemeColor('icon'),
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* Style for the label in a generic item rendered in the menu.
|
||||
*/
|
||||
labelStyle: {
|
||||
color: schemeColor('label'),
|
||||
flexShrink: 1,
|
||||
fontSize: MD_FONT_SIZE,
|
||||
marginLeft: 32,
|
||||
opacity: 0.90
|
||||
},
|
||||
|
||||
/**
|
||||
* Bottom sheet's base style.
|
||||
*/
|
||||
sheet: {
|
||||
backgroundColor: schemeColor('background'),
|
||||
flex: 1,
|
||||
paddingHorizontal: MD_ITEM_MARGIN_PADDING,
|
||||
paddingVertical: 8
|
||||
},
|
||||
|
||||
/**
|
||||
* Container style for a generic item rendered in the menu.
|
||||
*/
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
height: MD_ITEM_HEIGHT
|
||||
},
|
||||
|
||||
/**
|
||||
* Additional style that is not directly used as a style object.
|
||||
*/
|
||||
underlayColor: ColorPalette.overflowMenuItemUnderlay
|
||||
});
|
||||
|
||||
/**
|
||||
* Color schemed styles for all the component based on the abstract dialog.
|
||||
*/
|
||||
ColorSchemeRegistry.register('Dialog', {
|
||||
/**
|
||||
* Separator line for the buttons in a dialog.
|
||||
*/
|
||||
buttonSeparator: {
|
||||
borderRightColor: schemeColor('border'),
|
||||
borderRightWidth: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the close icon on a dialog.
|
||||
*/
|
||||
closeStyle: {
|
||||
color: schemeColor('icon'),
|
||||
fontSize: MD_FONT_SIZE
|
||||
},
|
||||
|
||||
/**
|
||||
* Base style of the dialogs.
|
||||
*/
|
||||
dialog: {
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: schemeColor('background'),
|
||||
borderColor: schemeColor('border'),
|
||||
borderRadius: BORDER_RADIUS,
|
||||
borderWidth: 1,
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
maxWidth: PREFERRED_DIALOG_SIZE
|
||||
},
|
||||
|
||||
/**
|
||||
* Field on an input dialog.
|
||||
*/
|
||||
field: {
|
||||
...brandedDialogText,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: schemeColor('border'),
|
||||
margin: BoxModel.margin,
|
||||
textAlign: 'left'
|
||||
},
|
||||
|
||||
/**
|
||||
* Style for the field label on an input dialog.
|
||||
*/
|
||||
fieldLabel: {
|
||||
...brandedDialogText,
|
||||
margin: BoxModel.margin,
|
||||
textAlign: 'left'
|
||||
},
|
||||
|
||||
text: {
|
||||
...brandedDialogText
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* @flow */
|
||||
|
||||
import { ColorSchemeRegistry } from '../color-scheme';
|
||||
import { toState } from '../redux';
|
||||
|
||||
/**
|
||||
|
@ -15,3 +16,17 @@ import { toState } from '../redux';
|
|||
export function isDialogOpen(stateful: Function | Object, component: Object) {
|
||||
return toState(stateful)['features/base/dialog'].component === component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of any Dialog based component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _dialogStyles: StyleType
|
||||
* }}
|
||||
*/
|
||||
export function _abstractMapStateToProps(state: Object): Object {
|
||||
return {
|
||||
_dialogStyles: ColorSchemeRegistry.get(state, 'Dialog')
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
VideoTrack
|
||||
} from '../../media';
|
||||
import { Container, TintedView } from '../../react';
|
||||
import { StyleType } from '../../styles';
|
||||
import { TestHint } from '../../testing/components';
|
||||
import { getTrackByMediaTypeAndParticipant } from '../../tracks';
|
||||
|
||||
|
@ -97,6 +98,11 @@ type Props = {
|
|||
*/
|
||||
tintEnabled: boolean,
|
||||
|
||||
/**
|
||||
* The style of the tinting when applied.
|
||||
*/
|
||||
tintStyle: StyleType,
|
||||
|
||||
/**
|
||||
* The test hint id which can be used to locate the {@code ParticipantView}
|
||||
* on the jitsi-meet-torture side. If not provided, the
|
||||
|
@ -186,11 +192,12 @@ class ParticipantView extends Component<Props> {
|
|||
*/
|
||||
render() {
|
||||
const {
|
||||
onPress,
|
||||
_avatar: avatar,
|
||||
_connectionStatus: connectionStatus,
|
||||
_renderVideo: renderVideo,
|
||||
_videoTrack: videoTrack
|
||||
_videoTrack: videoTrack,
|
||||
onPress,
|
||||
tintStyle
|
||||
} = this.props;
|
||||
|
||||
const waitForVideoStarted = false;
|
||||
|
@ -199,9 +206,10 @@ class ParticipantView extends Component<Props> {
|
|||
const renderAvatar = Boolean(!renderVideo && avatar);
|
||||
|
||||
// If the connection has problems, we will "tint" the video / avatar.
|
||||
const connectionProblem
|
||||
= connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE;
|
||||
const useTint
|
||||
= connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE
|
||||
|| this.props.tintEnabled;
|
||||
= connectionProblem || this.props.tintEnabled;
|
||||
|
||||
const testHintId
|
||||
= this.props.testHintId
|
||||
|
@ -238,7 +246,9 @@ class ParticipantView extends Component<Props> {
|
|||
{ useTint
|
||||
|
||||
// If the connection has problems, tint the video / avatar.
|
||||
&& <TintedView /> }
|
||||
&& <TintedView
|
||||
style = {
|
||||
connectionProblem ? undefined : tintStyle } /> }
|
||||
|
||||
{ this.props.useConnectivityInfoLabel
|
||||
&& this._renderConnectionInfo(connectionStatus) }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
import { ColorPalette } from '../../../styles';
|
||||
import { TINTED_VIEW_DEFAULT } from './styles';
|
||||
|
||||
/**
|
||||
* Base style for the {@code TintedView} component.
|
||||
|
@ -24,16 +24,6 @@ type Props = {
|
|||
*/
|
||||
children?: React$Node,
|
||||
|
||||
/**
|
||||
* Color used as the background of the view. Defaults to
|
||||
*/
|
||||
color: string,
|
||||
|
||||
/**
|
||||
* Opacity for the
|
||||
*/
|
||||
opacity: number,
|
||||
|
||||
/**
|
||||
* Style to override the base style.
|
||||
*/
|
||||
|
@ -45,15 +35,6 @@ type Props = {
|
|||
* the given color and opacity.
|
||||
*/
|
||||
export default class TintedView extends Component<Props> {
|
||||
/**
|
||||
* Default values for the component's props.
|
||||
*/
|
||||
static defaultProps = {
|
||||
color: ColorPalette.appBackground,
|
||||
opacity: 0.8,
|
||||
style: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
|
@ -61,7 +42,7 @@ export default class TintedView extends Component<Props> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { children, color, opacity, style } = this.props;
|
||||
const { children, style } = this.props;
|
||||
|
||||
// XXX Don't tint the children, tint the background only.
|
||||
return (
|
||||
|
@ -72,11 +53,8 @@ export default class TintedView extends Component<Props> {
|
|||
pointerEvents = 'none'
|
||||
style = { [
|
||||
BASE_STYLE,
|
||||
style,
|
||||
{
|
||||
backgroundColor: color,
|
||||
opacity
|
||||
}
|
||||
TINTED_VIEW_DEFAULT,
|
||||
style
|
||||
] } />
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
|
|
|
@ -324,6 +324,11 @@ const SIDEBAR_STYLES = {
|
|||
}
|
||||
};
|
||||
|
||||
export const TINTED_VIEW_DEFAULT = {
|
||||
backgroundColor: ColorPalette.appBackground,
|
||||
opacity: 0.8
|
||||
};
|
||||
|
||||
/**
|
||||
* The styles of the generic React {@code Component}s implemented by the feature
|
||||
* base/react.
|
||||
|
|
|
@ -18,6 +18,7 @@ export const ColorPalette = {
|
|||
* the sake of consistency.
|
||||
*/
|
||||
black: BLACK,
|
||||
blackBlue: 'rgb(0, 3, 6)',
|
||||
blue: '#17A0DB',
|
||||
blueHighlight: '#1081b2',
|
||||
buttonUnderlay: '#495258',
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { openDialog } from '../../../base/dialog';
|
||||
import { Audio, MEDIA_TYPE } from '../../../base/media';
|
||||
import {
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
pinParticipant
|
||||
} from '../../../base/participants';
|
||||
import { Container } from '../../../base/react';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
|
||||
|
||||
import { RemoteVideoMenu } from '../../../remote-video-menu';
|
||||
|
@ -53,6 +55,11 @@ type Props = {
|
|||
*/
|
||||
_onShowRemoteVideoMenu: ?Function,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* The Redux representation of the participant's video track.
|
||||
*/
|
||||
|
@ -106,6 +113,7 @@ class Thumbnail extends Component<Props> {
|
|||
_largeVideo: largeVideo,
|
||||
_onClick,
|
||||
_onShowRemoteVideoMenu,
|
||||
_styles,
|
||||
_videoTrack: videoTrack,
|
||||
disablePin,
|
||||
disableTint,
|
||||
|
@ -135,7 +143,7 @@ class Thumbnail extends Component<Props> {
|
|||
style = { [
|
||||
styles.thumbnail,
|
||||
participant.pinned && !disablePin
|
||||
? styles.thumbnailPinned : null,
|
||||
? _styles.thumbnailPinned : null,
|
||||
this.props.styleOverrides || null
|
||||
] }
|
||||
touchFeedback = { false }>
|
||||
|
@ -148,7 +156,9 @@ class Thumbnail extends Component<Props> {
|
|||
<ParticipantView
|
||||
avatarSize = { AVATAR_SIZE }
|
||||
participantId = { participantId }
|
||||
style = { _styles.participantViewStyle }
|
||||
tintEnabled = { participantInLargeVideo && !disableTint }
|
||||
tintStyle = { _styles.activeThumbnailTint }
|
||||
zOrder = { 1 } />
|
||||
|
||||
{ participant.role === PARTICIPANT_ROLE.MODERATOR
|
||||
|
@ -219,6 +229,7 @@ function _mapDispatchToProps(dispatch: Function, ownProps): Object {
|
|||
* _audioTrack: Track,
|
||||
* _isModerator: boolean,
|
||||
* _largeVideo: Object,
|
||||
* _styles: StyleType,
|
||||
* _videoTrack: Track
|
||||
* }}
|
||||
*/
|
||||
|
@ -238,6 +249,7 @@ function _mapStateToProps(state, ownProps) {
|
|||
_audioTrack: audioTrack,
|
||||
_isModerator: isLocalParticipantModerator(state),
|
||||
_largeVideo: largeVideo,
|
||||
_styles: ColorSchemeRegistry.get(state, 'Thumbnail'),
|
||||
_videoTrack: videoTrack
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../base/color-scheme';
|
||||
import { ColorPalette } from '../../base/styles';
|
||||
import { FILMSTRIP_SIZE } from '../constants';
|
||||
|
||||
|
@ -134,19 +137,6 @@ export default {
|
|||
position: 'absolute'
|
||||
},
|
||||
|
||||
/**
|
||||
* Pinned video thumbnail style.
|
||||
*/
|
||||
thumbnailPinned: {
|
||||
borderColor: ColorPalette.blue,
|
||||
shadowColor: ColorPalette.black,
|
||||
shadowOffset: {
|
||||
height: 5,
|
||||
width: 5
|
||||
},
|
||||
shadowRadius: 5
|
||||
},
|
||||
|
||||
tileView: {
|
||||
alignSelf: 'center'
|
||||
},
|
||||
|
@ -160,3 +150,36 @@ export default {
|
|||
justifyContent: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Color schemed styles for the @{code Thumbnail} component.
|
||||
*/
|
||||
ColorSchemeRegistry.register('Thumbnail', {
|
||||
|
||||
/**
|
||||
* Tinting style of the on-stage participant thumbnail.
|
||||
*/
|
||||
activeThumbnailTint: {
|
||||
backgroundColor: schemeColor('activeParticipantTint')
|
||||
},
|
||||
|
||||
/**
|
||||
* Coloring if the thumbnail background.
|
||||
*/
|
||||
participantViewStyle: {
|
||||
backgroundColor: schemeColor('background')
|
||||
},
|
||||
|
||||
/**
|
||||
* Pinned video thumbnail style.
|
||||
*/
|
||||
thumbnailPinned: {
|
||||
borderColor: schemeColor('activeParticipantHighlight'),
|
||||
shadowColor: schemeColor('activeParticipantHighlight'),
|
||||
shadowOffset: {
|
||||
height: 5,
|
||||
width: 5
|
||||
},
|
||||
shadowRadius: 5
|
||||
}
|
||||
});
|
||||
|
|
|
@ -3,27 +3,34 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../base/color-scheme';
|
||||
import { ParticipantView } from '../../base/participants';
|
||||
import { DimensionsDetector } from '../../base/responsive-ui';
|
||||
import { StyleType } from '../../base/styles';
|
||||
|
||||
import styles, { AVATAR_SIZE } from './styles';
|
||||
import { AVATAR_SIZE } from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link LargeVideo}.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Callback to invoke when the {@code LargeVideo} is clicked/pressed.
|
||||
*/
|
||||
onClick: Function,
|
||||
|
||||
/**
|
||||
* The ID of the participant (to be) depicted by LargeVideo.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_participantId: string
|
||||
_participantId: string,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* Callback to invoke when the {@code LargeVideo} is clicked/pressed.
|
||||
*/
|
||||
onClick: Function,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -114,6 +121,7 @@ class LargeVideo extends Component<Props, State> {
|
|||
} = this.state;
|
||||
const {
|
||||
_participantId,
|
||||
_styles,
|
||||
onClick
|
||||
} = this.props;
|
||||
|
||||
|
@ -124,7 +132,7 @@ class LargeVideo extends Component<Props, State> {
|
|||
avatarSize = { avatarSize }
|
||||
onPress = { onClick }
|
||||
participantId = { _participantId }
|
||||
style = { styles.largeVideo }
|
||||
style = { _styles.largeVideo }
|
||||
testHintId = 'org.jitsi.meet.LargeVideo'
|
||||
useConnectivityInfoLabel = { useConnectivityInfoLabel }
|
||||
zOrder = { 0 }
|
||||
|
@ -140,12 +148,14 @@ class LargeVideo extends Component<Props, State> {
|
|||
* @param {Object} state - Redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _participantId: string
|
||||
* _participantId: string,
|
||||
* _styles: StyleType
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_participantId: state['features/large-video'].participantId
|
||||
_participantId: state['features/large-video'].participantId,
|
||||
_styles: ColorSchemeRegistry.get(state, 'LargeVideo')
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import { ColorPalette, createStyleSheet } from '../../base/styles';
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../base/color-scheme';
|
||||
|
||||
/**
|
||||
* Size for the Avatar.
|
||||
*/
|
||||
export const AVATAR_SIZE = 200;
|
||||
|
||||
export default createStyleSheet({
|
||||
/**
|
||||
* Color schemed styles for the @{LargeVideo} component.
|
||||
*/
|
||||
ColorSchemeRegistry.register('LargeVideo', {
|
||||
|
||||
/**
|
||||
* Large video container style.
|
||||
|
@ -15,7 +18,7 @@ export default createStyleSheet({
|
|||
largeVideo: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: ColorPalette.appBackground,
|
||||
backgroundColor: schemeColor('background'),
|
||||
flex: 1,
|
||||
justifyContent: 'center'
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ type State = {
|
|||
*
|
||||
* @extends Component
|
||||
*/
|
||||
export default class AbstractStreamKeyForm extends Component<Props, State> {
|
||||
export default class AbstractStreamKeyForm<P: Props>
|
||||
extends Component<P, State> {
|
||||
helpURL: string;
|
||||
_debouncedUpdateValidationErrorVisibility: Function;
|
||||
|
||||
|
@ -61,7 +62,7 @@ export default class AbstractStreamKeyForm extends Component<Props, State> {
|
|||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
constructor(props: P) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -88,7 +89,7 @@ export default class AbstractStreamKeyForm extends Component<Props, State> {
|
|||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
componentDidUpdate(prevProps: P) {
|
||||
if (this.props.value !== prevProps.value) {
|
||||
this._debouncedUpdateValidationErrorVisibility();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ import React, { Component } from 'react';
|
|||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../../../base/dialog';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { StyleType } from '../../../../base/styles';
|
||||
|
||||
import {
|
||||
GOOGLE_API_STATES,
|
||||
|
@ -23,6 +25,11 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Style of the dialogs feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The Redux dispatch Function.
|
||||
*/
|
||||
|
@ -102,7 +109,7 @@ class GoogleSigninForm extends Component<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
const { _dialogStyles, t } = this.props;
|
||||
const { googleAPIState, googleResponse } = this.props;
|
||||
const signedInUser = googleResponse
|
||||
&& googleResponse.user
|
||||
|
@ -121,7 +128,11 @@ class GoogleSigninForm extends Component<Props> {
|
|||
return (
|
||||
<View style = { styles.formWrapper }>
|
||||
<View style = { styles.helpText }>
|
||||
<Text style = { styles.text }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.text
|
||||
] }>
|
||||
{ userInfo }
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -225,6 +236,7 @@ function _mapStateToProps(state: Object) {
|
|||
const { googleAPIState, googleResponse } = state['features/google-api'];
|
||||
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
googleAPIState,
|
||||
googleResponse
|
||||
};
|
||||
|
|
|
@ -2,13 +2,24 @@
|
|||
|
||||
import React from 'react';
|
||||
import { Linking, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../../../base/dialog';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { StyleType } from '../../../../base/styles';
|
||||
|
||||
import AbstractStreamKeyForm, {
|
||||
type Props
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractStreamKeyForm';
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* Style of the dialogs feature.
|
||||
*/
|
||||
_dialogStyles: StyleType
|
||||
};
|
||||
|
||||
import styles, { PLACEHOLDER_COLOR } from './styles';
|
||||
|
||||
/**
|
||||
|
@ -16,7 +27,7 @@ import styles, { PLACEHOLDER_COLOR } from './styles';
|
|||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class StreamKeyForm extends AbstractStreamKeyForm {
|
||||
class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
||||
/**
|
||||
* Initializes a new {@code StreamKeyForm} instance.
|
||||
*
|
||||
|
@ -37,11 +48,16 @@ class StreamKeyForm extends AbstractStreamKeyForm {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { t } = this.props;
|
||||
const { _dialogStyles, t } = this.props;
|
||||
|
||||
return (
|
||||
<View style = { styles.formWrapper }>
|
||||
<Text style = { styles.streamKeyInputLabel }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.text,
|
||||
styles.streamKeyInputLabel
|
||||
] }>
|
||||
{
|
||||
t('dialog.streamKey')
|
||||
}
|
||||
|
@ -56,7 +72,11 @@ class StreamKeyForm extends AbstractStreamKeyForm {
|
|||
{
|
||||
this.state.showValidationError
|
||||
? <View style = { styles.formFooterItem }>
|
||||
<Text style = { styles.warningText }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.warningText
|
||||
] }>
|
||||
{ t('liveStreaming.invalidStreamKey') }
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -66,7 +86,11 @@ class StreamKeyForm extends AbstractStreamKeyForm {
|
|||
<TouchableOpacity
|
||||
onPress = { this._onOpenHelp }
|
||||
style = { styles.streamKeyHelp } >
|
||||
<Text style = { styles.text }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.text
|
||||
] }>
|
||||
{
|
||||
t('liveStreaming.streamIdHelp')
|
||||
}
|
||||
|
@ -98,4 +122,4 @@ class StreamKeyForm extends AbstractStreamKeyForm {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(StreamKeyForm);
|
||||
export default translate(connect(_abstractMapStateToProps)(StreamKeyForm));
|
||||
|
|
|
@ -8,8 +8,11 @@ import {
|
|||
TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { _abstractMapStateToProps } from '../../../../base/dialog';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { StyleType } from '../../../../base/styles';
|
||||
|
||||
import { YOUTUBE_LIVE_DASHBOARD_URL } from '../constants';
|
||||
|
||||
|
@ -17,6 +20,11 @@ import styles, { ACTIVE_OPACITY, TOUCHABLE_UNDERLAY } from './styles';
|
|||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Style of the dialogs feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The list of broadcasts the user can pick from.
|
||||
*/
|
||||
|
@ -74,7 +82,7 @@ class StreamKeyPicker extends Component<Props, State> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { broadcasts } = this.props;
|
||||
const { _dialogStyles, broadcasts } = this.props;
|
||||
|
||||
if (!broadcasts) {
|
||||
return null;
|
||||
|
@ -85,7 +93,11 @@ class StreamKeyPicker extends Component<Props, State> {
|
|||
<View style = { styles.formWrapper }>
|
||||
<TouchableOpacity
|
||||
onPress = { this._onOpenYoutubeDashboard }>
|
||||
<Text style = { styles.warningText }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.warningText
|
||||
] }>
|
||||
{ this.props.t(
|
||||
'liveStreaming.getStreamKeyManually') }
|
||||
</Text>
|
||||
|
@ -97,7 +109,11 @@ class StreamKeyPicker extends Component<Props, State> {
|
|||
return (
|
||||
<View style = { styles.formWrapper }>
|
||||
<View style = { styles.streamKeyPickerCta }>
|
||||
<Text style = { styles.text }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.text
|
||||
] }>
|
||||
{ this.props.t('liveStreaming.choose') }
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -113,7 +129,11 @@ class StreamKeyPicker extends Component<Props, State> {
|
|||
? styles.streamKeyPickerItemHighlight : null
|
||||
] }
|
||||
underlayColor = { TOUCHABLE_UNDERLAY }>
|
||||
<Text style = { styles.text }>
|
||||
<Text
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.text
|
||||
] }>
|
||||
{ broadcast.title }
|
||||
</Text>
|
||||
</TouchableHighlight>))
|
||||
|
@ -155,4 +175,5 @@ class StreamKeyPicker extends Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(StreamKeyPicker);
|
||||
export default translate(
|
||||
connect(_abstractMapStateToProps)(StreamKeyPicker));
|
||||
|
|
|
@ -99,8 +99,7 @@ export default createStyleSheet({
|
|||
* Label for the previous field.
|
||||
*/
|
||||
streamKeyInputLabel: {
|
||||
alignSelf: 'flex-start',
|
||||
color: ColorPalette.white
|
||||
alignSelf: 'flex-start'
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -146,7 +145,8 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
text: {
|
||||
color: ColorPalette.white
|
||||
fontSize: 14,
|
||||
textAlign: 'left'
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,7 +14,7 @@ import AbstractStreamKeyForm, {
|
|||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class StreamKeyForm extends AbstractStreamKeyForm {
|
||||
class StreamKeyForm extends AbstractStreamKeyForm<Props> {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code StreamKeyForm} instance.
|
||||
|
|
|
@ -7,7 +7,10 @@ import {
|
|||
createRecordingDialogEvent,
|
||||
sendAnalytics
|
||||
} from '../../../analytics';
|
||||
import { DialogContent } from '../../../base/dialog';
|
||||
import {
|
||||
DialogContent,
|
||||
_abstractMapStateToProps
|
||||
} from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import {
|
||||
Container,
|
||||
|
@ -15,6 +18,7 @@ import {
|
|||
Switch,
|
||||
Text
|
||||
} from '../../../base/react';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { authorizeDropbox, updateDropboxToken } from '../../../dropbox';
|
||||
|
||||
import styles from './styles';
|
||||
|
@ -22,6 +26,11 @@ import { getRecordingDurationEstimation } from '../../functions';
|
|||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Style of the dialogs feature.
|
||||
*/
|
||||
_dialogStyles: StyleType,
|
||||
|
||||
/**
|
||||
* The redux dispatch function.
|
||||
*/
|
||||
|
@ -99,7 +108,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
*/
|
||||
_renderNoIntegrationsContent() {
|
||||
return (
|
||||
<DialogContent style = { styles.noIntegrationContent }>
|
||||
<DialogContent style = { this.props._dialogStyles.text }>
|
||||
{ this.props.t('recording.startRecordingBody') }
|
||||
</DialogContent>
|
||||
);
|
||||
|
@ -112,7 +121,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
* @returns {React$Component}
|
||||
*/
|
||||
_renderIntegrationsContent() {
|
||||
const { isTokenValid, isValidating, t } = this.props;
|
||||
const { _dialogStyles, isTokenValid, isValidating, t } = this.props;
|
||||
|
||||
let content = null;
|
||||
|
||||
|
@ -135,7 +144,10 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
style = { styles.header }>
|
||||
<Text
|
||||
className = 'recording-title'
|
||||
style = { styles.title }>
|
||||
style = { [
|
||||
_dialogStyles.text,
|
||||
styles.title
|
||||
] }>
|
||||
{ t('recording.authDropboxText') }
|
||||
</Text>
|
||||
<Switch
|
||||
|
@ -248,4 +260,5 @@ class StartRecordingDialogContent extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(connect()(StartRecordingDialogContent));
|
||||
export default translate(
|
||||
connect(_abstractMapStateToProps)(StartRecordingDialogContent));
|
||||
|
|
|
@ -28,10 +28,6 @@ export default createStyleSheet({
|
|||
paddingBottom: _PADDING
|
||||
},
|
||||
|
||||
noIntegrationContent: {
|
||||
color: ColorPalette.white
|
||||
},
|
||||
|
||||
startRecordingText: {
|
||||
paddingBottom: _PADDING
|
||||
},
|
||||
|
@ -42,7 +38,6 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
title: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
|
|
|
@ -4,15 +4,16 @@ import React, { Component } from 'react';
|
|||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import {
|
||||
BottomSheet,
|
||||
bottomSheetItemStylesCombined
|
||||
BottomSheet
|
||||
} from '../../../base/dialog';
|
||||
import {
|
||||
Avatar,
|
||||
getAvatarURL,
|
||||
getParticipantDisplayName
|
||||
} from '../../../base/participants';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
|
||||
import { hideRemoteVideoMenu } from '../../actions';
|
||||
|
||||
|
@ -42,6 +43,11 @@ type Props = {
|
|||
*/
|
||||
_avatarURL: string,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the BottomSheet.
|
||||
*/
|
||||
_bottomSheetStyles: StyleType,
|
||||
|
||||
/**
|
||||
* Display name of the participant retreived from Redux.
|
||||
*/
|
||||
|
@ -73,7 +79,7 @@ class RemoteVideoMenu extends Component<Props> {
|
|||
afterClick: this._onCancel,
|
||||
showLabel: true,
|
||||
participantID: this.props.participant.id,
|
||||
styles: bottomSheetItemStylesCombined
|
||||
styles: this.props._bottomSheetStyles
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -113,6 +119,7 @@ class RemoteVideoMenu extends Component<Props> {
|
|||
* @private
|
||||
* @returns {{
|
||||
* _avatarURL: string,
|
||||
* _bottomSheetStyles: StyleType,
|
||||
* _participantDisplayName: string
|
||||
* }}
|
||||
*/
|
||||
|
@ -121,6 +128,8 @@ function _mapStateToProps(state, ownProps) {
|
|||
|
||||
return {
|
||||
_avatarURL: getAvatarURL(participant),
|
||||
_bottomSheetStyles:
|
||||
ColorSchemeRegistry.get(state, 'BottomSheet'),
|
||||
_participantDisplayName: getParticipantDisplayName(
|
||||
state, participant.id)
|
||||
};
|
||||
|
|
|
@ -4,11 +4,12 @@ import React, { Component } from 'react';
|
|||
import { Platform } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import {
|
||||
BottomSheet,
|
||||
bottomSheetItemStylesCombined,
|
||||
hideDialog
|
||||
} from '../../../base/dialog';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { InviteButton } from '../../../invite';
|
||||
import { AudioRouteButton } from '../../../mobile/audio-mode';
|
||||
import { LiveStreamButton, RecordButton } from '../../../recording';
|
||||
|
@ -26,10 +27,15 @@ declare var __DEV__;
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the dialog feature.
|
||||
*/
|
||||
_bottomSheetStyles: StyleType,
|
||||
|
||||
/**
|
||||
* Used for hiding the dialog when the selection was completed.
|
||||
*/
|
||||
dispatch: Function,
|
||||
dispatch: Function
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -68,7 +74,7 @@ class OverflowMenu extends Component<Props> {
|
|||
const buttonProps = {
|
||||
afterClick: this._onCancel,
|
||||
showLabel: true,
|
||||
styles: bottomSheetItemStylesCombined
|
||||
styles: this.props._bottomSheetStyles
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -106,6 +112,22 @@ class OverflowMenu extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
OverflowMenu_ = connect()(OverflowMenu);
|
||||
/**
|
||||
* Function that maps parts of Redux state tree into component props.
|
||||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _bottomSheetStyles: StyleType
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_bottomSheetStyles:
|
||||
ColorSchemeRegistry.get(state, 'BottomSheet')
|
||||
};
|
||||
}
|
||||
|
||||
OverflowMenu_ = connect(_mapStateToProps)(OverflowMenu);
|
||||
|
||||
export default OverflowMenu_;
|
||||
|
|
|
@ -5,21 +5,19 @@ import { View } from 'react-native';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { Container } from '../../../base/react';
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { ChatButton } from '../../../chat';
|
||||
|
||||
import { isToolboxVisible } from '../../functions';
|
||||
import { HANGUP_BUTTON_SIZE } from '../../constants';
|
||||
|
||||
import AudioMuteButton from '../AudioMuteButton';
|
||||
import HangupButton from '../HangupButton';
|
||||
import VideoMuteButton from '../VideoMuteButton';
|
||||
|
||||
import OverflowMenuButton from './OverflowMenuButton';
|
||||
import styles, {
|
||||
chatButtonOverride,
|
||||
hangupButtonStyles,
|
||||
toolbarButtonStyles,
|
||||
toolbarToggledButtonStyles
|
||||
} from './styles';
|
||||
import styles from './styles';
|
||||
import VideoMuteButton from '../VideoMuteButton';
|
||||
|
||||
/**
|
||||
* The number of buttons other than {@link HangupButton} to render in
|
||||
|
@ -43,6 +41,11 @@ const _BUTTON_SIZE_FACTOR = 0.85;
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the toolbox is visible.
|
||||
*/
|
||||
|
@ -111,6 +114,7 @@ class Toolbox extends Component<Props, State> {
|
|||
* @returns {number}
|
||||
*/
|
||||
_calculateButtonSize() {
|
||||
const { _styles } = this.props;
|
||||
const { width } = this.state;
|
||||
|
||||
if (width <= 0) {
|
||||
|
@ -118,8 +122,8 @@ class Toolbox extends Component<Props, State> {
|
|||
return width;
|
||||
}
|
||||
|
||||
const hangupButtonSize = styles.hangupButton.width;
|
||||
const { style } = toolbarButtonStyles;
|
||||
const hangupButtonSize = HANGUP_BUTTON_SIZE;
|
||||
const { style } = _styles.buttonStyles;
|
||||
let buttonSize
|
||||
= (width
|
||||
|
||||
|
@ -155,12 +159,14 @@ class Toolbox extends Component<Props, State> {
|
|||
* @returns {Object | Array}
|
||||
*/
|
||||
_getChatButtonToggledStyle(baseStyle) {
|
||||
const { _styles } = this.props;
|
||||
|
||||
if (Array.isArray(baseStyle.style)) {
|
||||
return {
|
||||
...baseStyle,
|
||||
style: [
|
||||
...baseStyle.style,
|
||||
chatButtonOverride.toggled
|
||||
_styles.chatButtonOverride.toggled
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -169,7 +175,7 @@ class Toolbox extends Component<Props, State> {
|
|||
...baseStyle,
|
||||
style: [
|
||||
baseStyle.style,
|
||||
chatButtonOverride.toggled
|
||||
_styles.chatButtonOverride.toggled
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -196,9 +202,9 @@ class Toolbox extends Component<Props, State> {
|
|||
* @returns {React$Node}
|
||||
*/
|
||||
_renderToolbar() {
|
||||
const { _styles } = this.props;
|
||||
const buttonSize = this._calculateButtonSize();
|
||||
let buttonStyles = toolbarButtonStyles;
|
||||
let toggledButtonStyles = toolbarToggledButtonStyles;
|
||||
let { buttonStyles, toggledButtonStyles } = _styles;
|
||||
|
||||
if (buttonSize > 0) {
|
||||
const extraButtonStyle = {
|
||||
|
@ -241,7 +247,8 @@ class Toolbox extends Component<Props, State> {
|
|||
<AudioMuteButton
|
||||
styles = { buttonStyles }
|
||||
toggledStyles = { toggledButtonStyles } />
|
||||
<HangupButton styles = { hangupButtonStyles } />
|
||||
<HangupButton
|
||||
styles = { _styles.hangupButtonStyles } />
|
||||
<VideoMuteButton
|
||||
styles = { buttonStyles }
|
||||
toggledStyles = { toggledButtonStyles } />
|
||||
|
@ -261,11 +268,13 @@ class Toolbox extends Component<Props, State> {
|
|||
* {@code Toolbox} props.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _styles: StyleType,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state: Object): Object {
|
||||
return {
|
||||
_styles: ColorSchemeRegistry.get(state, 'Toolbox'),
|
||||
_visible: isToolboxVisible(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
||||
import { BoxModel, ColorPalette, createStyleSheet } from '../../../base/styles';
|
||||
|
||||
import { HANGUP_BUTTON_SIZE } from '../../constants';
|
||||
|
@ -9,7 +11,7 @@ import { HANGUP_BUTTON_SIZE } from '../../constants';
|
|||
* The style of toolbar buttons.
|
||||
*/
|
||||
const toolbarButton = {
|
||||
backgroundColor: ColorPalette.white,
|
||||
backgroundColor: schemeColor('button'),
|
||||
borderRadius: 20,
|
||||
borderWidth: 0,
|
||||
flex: 0,
|
||||
|
@ -20,7 +22,6 @@ const toolbarButton = {
|
|||
// XXX We probably tested BoxModel.margin and discovered it to be too small
|
||||
// for our taste.
|
||||
marginHorizontal: 7,
|
||||
opacity: 0.7,
|
||||
width: 40
|
||||
};
|
||||
|
||||
|
@ -33,29 +34,26 @@ const toolbarButtonIcon = {
|
|||
fontSize: 22
|
||||
};
|
||||
|
||||
/**
|
||||
* The style of toolbar buttons which display white icons.
|
||||
*/
|
||||
const whiteToolbarButton = {
|
||||
...toolbarButton,
|
||||
backgroundColor: schemeColor('buttonToggled')
|
||||
};
|
||||
|
||||
/**
|
||||
* The icon style of toolbar buttons which display white icons.
|
||||
*/
|
||||
const whiteToolbarButtonIcon = {
|
||||
...toolbarButtonIcon,
|
||||
color: ColorPalette.white
|
||||
};
|
||||
|
||||
/**
|
||||
* The Toolbox and toolbar related styles.
|
||||
*/
|
||||
const styles = createStyleSheet({
|
||||
/**
|
||||
* The style of the toolbar button which hangs the current conference up.
|
||||
*/
|
||||
hangupButton: {
|
||||
...toolbarButton,
|
||||
backgroundColor: ColorPalette.red,
|
||||
borderRadius: 30,
|
||||
height: HANGUP_BUTTON_SIZE,
|
||||
width: HANGUP_BUTTON_SIZE
|
||||
},
|
||||
|
||||
/**
|
||||
* The icon style of toolbar buttons which hangs the current conference up.
|
||||
*/
|
||||
hangupButtonIcon: {
|
||||
...toolbarButtonIcon,
|
||||
color: ColorPalette.white,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of the toolbar.
|
||||
|
@ -69,74 +67,60 @@ const styles = createStyleSheet({
|
|||
paddingHorizontal: BoxModel.margin
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of toolbar buttons.
|
||||
*/
|
||||
toolbarButton,
|
||||
|
||||
/**
|
||||
* The icon style of the toolbar buttons.
|
||||
*/
|
||||
toolbarButtonIcon,
|
||||
|
||||
/**
|
||||
* The style of the root/top-level {@link Container} of {@link Toolbox}.
|
||||
*/
|
||||
toolbox: {
|
||||
flexDirection: 'column',
|
||||
flexGrow: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of toolbar buttons which display white icons.
|
||||
*/
|
||||
whiteToolbarButton: {
|
||||
...toolbarButton,
|
||||
backgroundColor: ColorPalette.buttonUnderlay
|
||||
},
|
||||
|
||||
/**
|
||||
* The icon style of toolbar buttons which display white icons.
|
||||
*/
|
||||
whiteToolbarButtonIcon: {
|
||||
...toolbarButtonIcon,
|
||||
color: ColorPalette.white
|
||||
}
|
||||
});
|
||||
|
||||
export default styles;
|
||||
|
||||
/**
|
||||
* Styles for the hangup button.
|
||||
* Color schemed styles for the @{Toolbox} component.
|
||||
*/
|
||||
export const hangupButtonStyles = {
|
||||
iconStyle: styles.whiteToolbarButtonIcon,
|
||||
style: styles.hangupButton,
|
||||
underlayColor: ColorPalette.buttonUnderlay
|
||||
};
|
||||
ColorSchemeRegistry.register('Toolbox', {
|
||||
/**
|
||||
* Styles for buttons in the toolbar.
|
||||
*/
|
||||
buttonStyles: {
|
||||
iconStyle: toolbarButtonIcon,
|
||||
style: toolbarButton
|
||||
},
|
||||
|
||||
/**
|
||||
* Styles for buttons in the toolbar.
|
||||
*/
|
||||
export const toolbarButtonStyles = {
|
||||
iconStyle: styles.toolbarButtonIcon,
|
||||
style: styles.toolbarButton
|
||||
};
|
||||
/**
|
||||
* Overrides to the standard styles that we apply to the chat button, as
|
||||
* that behaves slightly differently to other buttons.
|
||||
*/
|
||||
chatButtonOverride: {
|
||||
toggled: {
|
||||
backgroundColor: ColorPalette.blue
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Styles for toggled buttons in the toolbar.
|
||||
*/
|
||||
export const toolbarToggledButtonStyles = {
|
||||
iconStyle: styles.whiteToolbarButtonIcon,
|
||||
style: styles.whiteToolbarButton
|
||||
};
|
||||
hangupButtonStyles: {
|
||||
iconStyle: whiteToolbarButtonIcon,
|
||||
style: {
|
||||
...toolbarButton,
|
||||
backgroundColor: schemeColor('hangup'),
|
||||
borderRadius: HANGUP_BUTTON_SIZE / 2,
|
||||
height: HANGUP_BUTTON_SIZE,
|
||||
width: HANGUP_BUTTON_SIZE
|
||||
},
|
||||
underlayColor: ColorPalette.buttonUnderlay
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides to the standard styles that we apply to the chat button, as that
|
||||
* behaves slightly differently to other buttons.
|
||||
*/
|
||||
export const chatButtonOverride = createStyleSheet({
|
||||
toggled: {
|
||||
backgroundColor: ColorPalette.blue
|
||||
/**
|
||||
* Styles for toggled buttons in the toolbar.
|
||||
*/
|
||||
toggledButtonStyles: {
|
||||
iconStyle: whiteToolbarButtonIcon,
|
||||
style: {
|
||||
...whiteToolbarButton,
|
||||
borderColor: schemeColor('buttonToggledBorder'),
|
||||
borderWidth: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue