[RN] Add color scheme support to header
This commit is contained in:
parent
20c1b1cfae
commit
55a971c0fd
|
@ -17,6 +17,13 @@ export default {
|
|||
icon: ColorPalette.white,
|
||||
text: ColorPalette.white
|
||||
},
|
||||
'Header': {
|
||||
background: ColorPalette.blue,
|
||||
icon: ColorPalette.white,
|
||||
statusBar: ColorPalette.blueHighlight,
|
||||
statusBarContent: ColorPalette.white,
|
||||
text: ColorPalette.white
|
||||
},
|
||||
'LargeVideo': {
|
||||
background: ColorPalette.black
|
||||
},
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import { TouchableOpacity } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../color-scheme';
|
||||
import { Icon } from '../../../font-icons';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link BackButton}
|
||||
*/
|
||||
|
@ -20,13 +20,18 @@ type Props = {
|
|||
/**
|
||||
* An external style object passed to the component.
|
||||
*/
|
||||
style?: Object
|
||||
style?: Object,
|
||||
|
||||
/**
|
||||
* The color schemed style of the Header component.
|
||||
*/
|
||||
_headerStyles: Object
|
||||
};
|
||||
|
||||
/**
|
||||
* A component rendering a back button.
|
||||
*/
|
||||
export default class BackButton extends Component<Props> {
|
||||
class BackButton extends Component<Props> {
|
||||
/**
|
||||
* Implements React's {@link Component#render()}, renders the button.
|
||||
*
|
||||
|
@ -41,10 +46,26 @@ export default class BackButton extends Component<Props> {
|
|||
<Icon
|
||||
name = { 'arrow_back' }
|
||||
style = { [
|
||||
styles.headerButtonIcon,
|
||||
this.props._headerStyles.headerButtonIcon,
|
||||
this.props.style
|
||||
] } />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(BackButton);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, TouchableOpacity } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../color-scheme';
|
||||
import { translate } from '../../../i18n';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link ForwardButton}
|
||||
*/
|
||||
|
@ -35,7 +35,12 @@ type Props = {
|
|||
/**
|
||||
* The function to be used to translate i18n labels.
|
||||
*/
|
||||
t: Function
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The color schemed style of the Header component.
|
||||
*/
|
||||
_headerStyles: Object
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -49,6 +54,8 @@ class ForwardButton extends Component<Props> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _headerStyles } = this.props;
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
accessibilityLabel = { 'Forward' }
|
||||
|
@ -56,8 +63,8 @@ class ForwardButton extends Component<Props> {
|
|||
onPress = { this.props.onPress } >
|
||||
<Text
|
||||
style = { [
|
||||
styles.headerButtonText,
|
||||
this.props.disabled && styles.disabledButtonText,
|
||||
_headerStyles.headerButtonText,
|
||||
this.props.disabled && _headerStyles.disabledButtonText,
|
||||
this.props.style
|
||||
] }>
|
||||
{ this.props.t(this.props.labelKey) }
|
||||
|
@ -67,4 +74,18 @@ class ForwardButton extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(ForwardButton);
|
||||
/**
|
||||
* Maps part of the Redux state to the props of the component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(ForwardButton));
|
||||
|
|
|
@ -2,14 +2,24 @@
|
|||
|
||||
import React, { Component, type Node } from 'react';
|
||||
import { Platform, SafeAreaView, StatusBar, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import styles, { HEADER_PADDING, STATUSBAR_COLOR } from './styles';
|
||||
import { ColorSchemeRegistry } from '../../../color-scheme';
|
||||
import { isDarkColor } from '../../../styles';
|
||||
|
||||
import { HEADER_PADDING } from './headerstyles';
|
||||
|
||||
/**
|
||||
* Compatibility header padding size for iOS 10 (and older) devices.
|
||||
*/
|
||||
const IOS10_PADDING = 20;
|
||||
|
||||
/**
|
||||
* Constanst for the (currently) supported statusbar colors.
|
||||
*/
|
||||
const STATUSBAR_DARK = 'dark-content';
|
||||
const STATUSBAR_LIGHT = 'light-content';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link Header}
|
||||
*/
|
||||
|
@ -23,43 +33,18 @@ type Props = {
|
|||
/**
|
||||
* The component's external style
|
||||
*/
|
||||
style: Object
|
||||
style: Object,
|
||||
|
||||
/**
|
||||
* The color schemed style of the component.
|
||||
*/
|
||||
_styles: Object
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic screen header component.
|
||||
*/
|
||||
export default class Header extends Component<Props> {
|
||||
|
||||
/**
|
||||
* The style of button-like React {@code Component}s rendered in
|
||||
* {@code Header}.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
static get buttonStyle(): Object {
|
||||
return styles.headerButtonIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* The style of a React {@code Component} rendering a {@code Header} as its
|
||||
* child.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
static get pageStyle(): Object {
|
||||
return styles.page;
|
||||
}
|
||||
|
||||
/**
|
||||
* The style of text rendered in {@code Header}.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
static get textStyle(): Object {
|
||||
return styles.headerText;
|
||||
}
|
||||
|
||||
class Header extends Component<Props> {
|
||||
/**
|
||||
* Initializes a new {@code Header} instance.
|
||||
*
|
||||
|
@ -78,20 +63,22 @@ export default class Header extends Component<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { _styles } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
style = { [
|
||||
styles.headerOverlay,
|
||||
_styles.headerOverlay,
|
||||
this._getIOS10CompatiblePadding()
|
||||
] } >
|
||||
<StatusBar
|
||||
backgroundColor = { STATUSBAR_COLOR }
|
||||
barStyle = 'light-content'
|
||||
backgroundColor = { _styles.statusBar }
|
||||
barStyle = { this._getStatusBarContentColor() }
|
||||
translucent = { false } />
|
||||
<SafeAreaView>
|
||||
<View
|
||||
style = { [
|
||||
styles.screenHeader,
|
||||
_styles.screenHeader,
|
||||
this.props.style
|
||||
] }>
|
||||
{
|
||||
|
@ -128,4 +115,54 @@ export default class Header extends Component<Props> {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the color of the statusbar content (light or dark) based on
|
||||
* certain criterias.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getStatusBarContentColor() {
|
||||
const { _styles } = this.props;
|
||||
const { statusBarContent } = _styles;
|
||||
|
||||
if (statusBarContent) {
|
||||
// We have the possibility to define the statusbar color in the
|
||||
// color scheme feature, but since mobile devices (at the moment)
|
||||
// only support two colors (light and dark) we need to normalize
|
||||
// the value.
|
||||
|
||||
if (isDarkColor(statusBarContent)) {
|
||||
return STATUSBAR_DARK;
|
||||
}
|
||||
|
||||
return STATUSBAR_LIGHT;
|
||||
}
|
||||
|
||||
// The statusbar color is not defined, so we need to base our choice
|
||||
// on the header colors
|
||||
const { statusBar, screenHeader } = _styles;
|
||||
|
||||
if (isDarkColor(statusBar || screenHeader.backgroundColor)) {
|
||||
return STATUSBAR_LIGHT;
|
||||
}
|
||||
|
||||
return STATUSBAR_DARK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of the component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _styles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_styles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(Header);
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../color-scheme';
|
||||
import { translate } from '../../../i18n';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link HeaderLabel}
|
||||
*/
|
||||
|
@ -20,7 +20,12 @@ type Props = {
|
|||
/**
|
||||
* The i18n translate function.
|
||||
*/
|
||||
t: Function
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The color schemed style of the Header component.
|
||||
*/
|
||||
_headerStyles: Object
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -34,13 +39,15 @@ class HeaderLabel extends Component<Props> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _headerStyles } = this.props;
|
||||
|
||||
return (
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.headerTextWrapper }>
|
||||
style = { _headerStyles.headerTextWrapper }>
|
||||
<Text
|
||||
style = { [
|
||||
styles.headerText
|
||||
_headerStyles.headerText
|
||||
] }>
|
||||
{ this.props.t(this.props.labelKey) }
|
||||
</Text>
|
||||
|
@ -49,4 +56,18 @@ class HeaderLabel extends Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
export default translate(HeaderLabel);
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(HeaderLabel));
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// @flex
|
||||
|
||||
import { StyleSheet } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../../color-scheme';
|
||||
import { BoxModel } from '../../../styles';
|
||||
|
||||
const HEADER_HEIGHT = 48;
|
||||
|
||||
export const HEADER_PADDING = BoxModel.padding / 2;
|
||||
|
||||
ColorSchemeRegistry.register('Header', {
|
||||
|
||||
/**
|
||||
* Style of a disabled button in the header (e.g. Next).
|
||||
*/
|
||||
disabledButtonText: {
|
||||
opacity: 0.6
|
||||
},
|
||||
|
||||
/**
|
||||
* Platform specific header button (e.g. back, menu, etc).
|
||||
*/
|
||||
headerButtonIcon: {
|
||||
alignSelf: 'center',
|
||||
color: schemeColor('icon'),
|
||||
fontSize: 22,
|
||||
marginRight: 12,
|
||||
padding: 8
|
||||
},
|
||||
|
||||
headerButtonText: {
|
||||
color: schemeColor('text'),
|
||||
fontSize: 20
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the header overlay to cover the unsafe areas.
|
||||
*/
|
||||
headerOverlay: {
|
||||
backgroundColor: schemeColor('background')
|
||||
},
|
||||
|
||||
/**
|
||||
* Generic style for a label placed in the header.
|
||||
*/
|
||||
headerText: {
|
||||
color: schemeColor('text'),
|
||||
fontSize: 18
|
||||
},
|
||||
|
||||
headerTextWrapper: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* The top-level element of a page.
|
||||
*/
|
||||
page: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
alignItems: 'stretch',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
|
||||
/**
|
||||
* Base style of Header.
|
||||
*/
|
||||
screenHeader: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: schemeColor('background'),
|
||||
flexDirection: 'row',
|
||||
height: HEADER_HEIGHT,
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: BoxModel.padding,
|
||||
paddingVertical: HEADER_PADDING
|
||||
},
|
||||
|
||||
statusBar: schemeColor('statusBar'),
|
||||
|
||||
statusBarContent: schemeColor('statusBarContent')
|
||||
});
|
|
@ -5,88 +5,13 @@ import { StyleSheet } from 'react-native';
|
|||
import { BoxModel, ColorPalette, createStyleSheet } from '../../../styles';
|
||||
|
||||
const AVATAR_OPACITY = 0.4;
|
||||
const HEADER_COLOR = ColorPalette.blue;
|
||||
|
||||
const HEADER_HEIGHT = 48;
|
||||
const OVERLAY_FONT_COLOR = 'rgba(255, 255, 255, 0.6)';
|
||||
const SECONDARY_ACTION_BUTTON_SIZE = 30;
|
||||
|
||||
export const AVATAR_SIZE = 65;
|
||||
export const HEADER_PADDING = BoxModel.padding / 2;
|
||||
export const STATUSBAR_COLOR = ColorPalette.blueHighlight;
|
||||
export const SIDEBAR_WIDTH = 250;
|
||||
export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
|
||||
|
||||
const HEADER_STYLES = {
|
||||
|
||||
disabledButtonText: {
|
||||
opacity: 0.6
|
||||
},
|
||||
|
||||
/**
|
||||
* Platform specific header button (e.g. back, menu, etc).
|
||||
*/
|
||||
headerButtonIcon: {
|
||||
alignSelf: 'center',
|
||||
color: ColorPalette.white,
|
||||
fontSize: 22,
|
||||
marginRight: 12,
|
||||
padding: 8
|
||||
},
|
||||
|
||||
headerButtonText: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 20
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the header overlay to cover the unsafe areas.
|
||||
*/
|
||||
headerOverlay: {
|
||||
backgroundColor: HEADER_COLOR
|
||||
},
|
||||
|
||||
/**
|
||||
* Generic style for a label placed in the header.
|
||||
*/
|
||||
headerText: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 18
|
||||
},
|
||||
|
||||
headerTextWrapper: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* The top-level element of a page.
|
||||
*/
|
||||
page: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
alignItems: 'stretch',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
|
||||
/**
|
||||
* Base style of Header.
|
||||
*/
|
||||
screenHeader: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: HEADER_COLOR,
|
||||
flexDirection: 'row',
|
||||
height: HEADER_HEIGHT,
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: BoxModel.padding,
|
||||
paddingVertical: HEADER_PADDING
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Style classes of the PagedList-based components.
|
||||
*/
|
||||
|
@ -355,7 +280,6 @@ export const TINTED_VIEW_DEFAULT = {
|
|||
* base/react.
|
||||
*/
|
||||
export default createStyleSheet({
|
||||
...HEADER_STYLES,
|
||||
...PAGED_LIST_STYLES,
|
||||
...SECTION_LIST_STYLES,
|
||||
...SIDEBAR_STYLES
|
||||
|
|
|
@ -23,6 +23,12 @@ const HEX_SHORT_COLOR_FORMAT
|
|||
*/
|
||||
const RGB_COLOR_FORMAT = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/i;
|
||||
|
||||
/**
|
||||
* RegExp pattern for RGBA color format.
|
||||
*/
|
||||
const RGBA_COLOR_FORMAT
|
||||
= /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*([0-9.]+)\)$/i;
|
||||
|
||||
/**
|
||||
* The list of the well-known style properties which may not be numbers on Web
|
||||
* but must be numbers on React Native.
|
||||
|
@ -136,6 +142,23 @@ export function getRGBAFormat(color: string, alpha: number): string {
|
|||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if a color is light or dark based on the ITU-R BT.709 and W3C
|
||||
* recommendations.
|
||||
*
|
||||
* NOTE: Please see https://www.w3.org/TR/WCAG20/#relativeluminancedef.
|
||||
*
|
||||
* @param {string} color - The color in rgb, rgba or hex format.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isDarkColor(color: string): boolean {
|
||||
const rgb = _getRGBObjectFormat(color);
|
||||
|
||||
return ((_getColorLuminance(rgb.r) * 0.2126)
|
||||
+ (_getColorLuminance(rgb.g) * 0.7152)
|
||||
+ (_getColorLuminance(rgb.b) * 0.0722)) <= 0.179;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an [0..1] alpha value into HEX.
|
||||
*
|
||||
|
@ -147,6 +170,67 @@ function _getAlphaInHex(alpha: number): string {
|
|||
.padStart(2, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculated the color luminance component for an individual color channel.
|
||||
*
|
||||
* NOTE: Please see https://www.w3.org/TR/WCAG20/#relativeluminancedef.
|
||||
*
|
||||
* @param {number} c - The color which we need the individual luminance
|
||||
* for.
|
||||
* @returns {number}
|
||||
*/
|
||||
function _getColorLuminance(c: number): number {
|
||||
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color string into an object containing the RGB values as numbers.
|
||||
*
|
||||
* NOTE: Object properties are not alpha-sorted for sanity.
|
||||
*
|
||||
* @param {string} color - The color to convert.
|
||||
* @returns {{
|
||||
* r: number,
|
||||
* g: number,
|
||||
* b: number
|
||||
* }}
|
||||
*/
|
||||
function _getRGBObjectFormat(color: string): {r: number, g: number, b: number} {
|
||||
let match = color.match(HEX_LONG_COLOR_FORMAT);
|
||||
|
||||
if (match) {
|
||||
return {
|
||||
r: parseInt(match[1], 16) / 255.0,
|
||||
g: parseInt(match[2], 16) / 255.0,
|
||||
b: parseInt(match[3], 16) / 255.0
|
||||
};
|
||||
}
|
||||
|
||||
match = color.match(HEX_SHORT_COLOR_FORMAT);
|
||||
if (match) {
|
||||
return {
|
||||
r: parseInt(`${match[1]}${match[1]}`, 16) / 255.0,
|
||||
g: parseInt(`${match[2]}${match[2]}`, 16) / 255.0,
|
||||
b: parseInt(`${match[3]}${match[3]}`, 16) / 255.0
|
||||
};
|
||||
}
|
||||
|
||||
match = color.match(RGB_COLOR_FORMAT) || color.match(RGBA_COLOR_FORMAT);
|
||||
if (match) {
|
||||
return {
|
||||
r: parseInt(match[1], 10) / 255.0,
|
||||
g: parseInt(match[2], 10) / 255.0,
|
||||
b: parseInt(match[3], 10) / 255.0
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Shims style properties to work correctly on native. Allows us to minimize the
|
||||
* number of style declarations that need to be set or overridden for specific
|
||||
|
|
|
@ -9,7 +9,7 @@ import { updateSettings } from '../../base/settings';
|
|||
* The type of the React {@code Component} props of
|
||||
* {@link AbstractSettingsView}.
|
||||
*/
|
||||
type Props = {
|
||||
export type Props = {
|
||||
|
||||
/**
|
||||
* The default URL for when there is no custom URL set in the settings.
|
||||
|
@ -47,15 +47,15 @@ type Props = {
|
|||
*
|
||||
* @abstract
|
||||
*/
|
||||
export class AbstractSettingsView extends Component<Props> {
|
||||
export class AbstractSettingsView<P: Props> extends Component<P> {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractSettingsView} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* @param {P} props - The React {@code Component} props to initialize
|
||||
* the component.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
constructor(props: P) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
|
|
|
@ -11,12 +11,14 @@ import {
|
|||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { BackButton, Header, Modal } from '../../../base/react';
|
||||
|
||||
import {
|
||||
AbstractSettingsView,
|
||||
_mapStateToProps
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractSettingsView';
|
||||
import { setSettingsViewVisible } from '../../actions';
|
||||
import FormRow from './FormRow';
|
||||
|
@ -25,12 +27,20 @@ import { normalizeUserInputURL } from '../../functions';
|
|||
import styles from './styles';
|
||||
import { HeaderLabel } from '../../../base/react/components/native';
|
||||
|
||||
type Props = AbstractProps & {
|
||||
|
||||
/**
|
||||
* Color schemed style of the header component.
|
||||
*/
|
||||
_headerStyles: Object
|
||||
}
|
||||
|
||||
/**
|
||||
* The native container rendering the app settings page.
|
||||
*
|
||||
* @extends AbstractSettingsView
|
||||
*/
|
||||
class SettingsView extends AbstractSettingsView {
|
||||
class SettingsView extends AbstractSettingsView<Props> {
|
||||
_urlField: Object;
|
||||
|
||||
/**
|
||||
|
@ -60,7 +70,7 @@ class SettingsView extends AbstractSettingsView {
|
|||
onRequestClose = { this._onRequestClose }
|
||||
presentationStyle = 'overFullScreen'
|
||||
visible = { this.props._visible }>
|
||||
<View style = { Header.pageStyle }>
|
||||
<View style = { this.props._headerStyles.page }>
|
||||
{ this._renderHeader() }
|
||||
{ this._renderBody() }
|
||||
</View>
|
||||
|
@ -239,4 +249,19 @@ class SettingsView extends AbstractSettingsView {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(SettingsView));
|
||||
|
|
|
@ -4,8 +4,9 @@ import React, { Component } from 'react';
|
|||
import { Switch, TouchableWithoutFeedback, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../base/color-scheme';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Header, Text } from '../../base/react';
|
||||
import { Text } from '../../base/react';
|
||||
import { updateSettings } from '../../base/settings';
|
||||
|
||||
import styles, { SWITCH_THUMB_COLOR, SWITCH_UNDER_COLOR } from './styles';
|
||||
|
@ -25,6 +26,11 @@ type Props = {
|
|||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Color schemed style of the header component.
|
||||
*/
|
||||
_headerStyles: Object,
|
||||
|
||||
/**
|
||||
* The current settings from redux.
|
||||
*/
|
||||
|
@ -55,15 +61,14 @@ class VideoSwitch extends Component<Props> {
|
|||
* @inheritdoc
|
||||
*/
|
||||
render() {
|
||||
const { t, _settings } = this.props;
|
||||
const { textStyle } = Header;
|
||||
const { t, _headerStyles, _settings } = this.props;
|
||||
|
||||
return (
|
||||
<View style = { styles.audioVideoSwitchContainer }>
|
||||
<TouchableWithoutFeedback
|
||||
onPress = { this._onStartAudioOnlyFalse }>
|
||||
<View style = { styles.switchLabel }>
|
||||
<Text style = { textStyle }>
|
||||
<Text style = { _headerStyles.headerText }>
|
||||
{ t('welcomepage.audioVideoSwitch.video') }
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -77,7 +82,7 @@ class VideoSwitch extends Component<Props> {
|
|||
<TouchableWithoutFeedback
|
||||
onPress = { this._onStartAudioOnlyTrue }>
|
||||
<View style = { styles.switchLabel }>
|
||||
<Text style = { textStyle }>
|
||||
<Text style = { _headerStyles.headerText }>
|
||||
{ t('welcomepage.audioVideoSwitch.audio') }
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -132,6 +137,7 @@ class VideoSwitch extends Component<Props> {
|
|||
*/
|
||||
export function _mapStateToProps(state: Object) {
|
||||
return {
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header'),
|
||||
_settings: state['features/base/settings']
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../base/color-scheme';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Icon } from '../../base/font-icons';
|
||||
import { MEDIA_TYPE } from '../../base/media';
|
||||
|
@ -21,7 +22,10 @@ import {
|
|||
} from '../../base/tracks';
|
||||
import { SettingsView } from '../../settings';
|
||||
|
||||
import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
|
||||
import {
|
||||
AbstractWelcomePage,
|
||||
_mapStateToProps as _abstractMapStateToProps
|
||||
} from './AbstractWelcomePage';
|
||||
import { setSideBarVisible } from '../actions';
|
||||
import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
|
||||
import styles, { PLACEHOLDER_TEXT_COLOR } from './styles';
|
||||
|
@ -90,18 +94,17 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { buttonStyle, pageStyle } = Header;
|
||||
const roomnameAccLabel = 'welcomepage.accessibilityLabel.roomname';
|
||||
const { t } = this.props;
|
||||
const { _headerStyles, t } = this.props;
|
||||
|
||||
return (
|
||||
<LocalVideoTrackUnderlay style = { styles.welcomePage }>
|
||||
<View style = { pageStyle }>
|
||||
<View style = { _headerStyles.page }>
|
||||
<Header style = { styles.header }>
|
||||
<TouchableOpacity onPress = { this._onShowSideBar } >
|
||||
<Icon
|
||||
name = 'menu'
|
||||
style = { buttonStyle } />
|
||||
style = { _headerStyles.headerButtonIcon } />
|
||||
</TouchableOpacity>
|
||||
<VideoSwitch />
|
||||
</Header>
|
||||
|
@ -269,4 +272,19 @@ class WelcomePage extends AbstractWelcomePage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux state to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _headerStyles: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
..._abstractMapStateToProps(state),
|
||||
_headerStyles: ColorSchemeRegistry.get(state, 'Header')
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(WelcomePage));
|
||||
|
|
Loading…
Reference in New Issue