mirror of https://github.com/jitsi/jitsi-meet
parent
b7f950f5f7
commit
410dc132e1
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,56 @@ |
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react'; |
||||
import { TouchableOpacity } from 'react-native'; |
||||
|
||||
import styles from './styles'; |
||||
|
||||
import { Icon } from '../../base/font-icons'; |
||||
import { Platform } from '../../base/react'; |
||||
|
||||
/** |
||||
* The icon glyph to be used on a specific platform. |
||||
*/ |
||||
const BACK_ICON = Platform.OS === 'android' ? 'arrow_back' : 'navigate_before'; |
||||
|
||||
/** |
||||
* The type of the React {@code Component} props of {@link BackButton} |
||||
*/ |
||||
type Props = { |
||||
|
||||
/** |
||||
* The action to be performed when the button is pressed. |
||||
*/ |
||||
onPress: Function, |
||||
|
||||
/** |
||||
* An external style object passed to the component. |
||||
*/ |
||||
style: Object |
||||
}; |
||||
|
||||
/** |
||||
* A component rendering a back button that looks native on both platforms. |
||||
*/ |
||||
export default class BackButton extends Component<Props> { |
||||
/** |
||||
* Implements React's {@link Component#render()}, renders the button. |
||||
* |
||||
* @inheritdoc |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
return ( |
||||
<TouchableOpacity |
||||
accessibilityLabel = { 'Back' } |
||||
onPress = { this.props.onPress }> |
||||
<Icon |
||||
name = { BACK_ICON } |
||||
style = { [ |
||||
styles.backIcon, |
||||
this.props.style |
||||
] } /> |
||||
</TouchableOpacity> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,119 @@ |
||||
/* @flow */ |
||||
|
||||
import React, { Component } from 'react'; |
||||
import { Text, View } from 'react-native'; |
||||
import { connect } from 'react-redux'; |
||||
|
||||
import styles, { CONTAINER_PADDING } from './styles'; |
||||
|
||||
import { getSafetyOffset } from '../functions'; |
||||
|
||||
import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio'; |
||||
import { translate } from '../../base/i18n'; |
||||
|
||||
/** |
||||
* The type of the React {@code Component} props of {@link FormSectionHeader} |
||||
*/ |
||||
type Props = { |
||||
|
||||
/** |
||||
* The current aspect ratio of the screen. |
||||
*/ |
||||
_aspectRatio: Symbol, |
||||
|
||||
/** |
||||
* The i18n key of the text label of the section. |
||||
*/ |
||||
i18nLabel: string, |
||||
|
||||
/** |
||||
* An external style object passed to the component. |
||||
*/ |
||||
style: Object, |
||||
|
||||
/** |
||||
* Invoked to obtain translated strings. |
||||
*/ |
||||
t: Function |
||||
} |
||||
|
||||
/** |
||||
* Implements a React {@code Component} which renders |
||||
* a section header on a form. This calculates the available safe view as well. |
||||
*/ |
||||
class FormSectionHeader extends Component<Props> { |
||||
/** |
||||
* Initializes a new {@code FormSectionHeader} instance. |
||||
* |
||||
* @param {Object} props - Component properties. |
||||
*/ |
||||
constructor(props) { |
||||
super(props); |
||||
|
||||
this._getSafetyMargin = this._getSafetyMargin.bind(this); |
||||
} |
||||
|
||||
/** |
||||
* Implements React's {@link Component#render()}. |
||||
* |
||||
* @inheritdoc |
||||
* @override |
||||
* @returns {ReactElement} |
||||
*/ |
||||
render() { |
||||
const { t } = this.props; |
||||
|
||||
return ( |
||||
<View |
||||
style = { [ |
||||
styles.formSectionTitle, |
||||
this.props.style, |
||||
this._getSafetyMargin() |
||||
] } > |
||||
<Text> |
||||
{ t(this.props.i18nLabel) } |
||||
</Text> |
||||
</View> |
||||
); |
||||
} |
||||
|
||||
_getSafetyMargin: () => Object; |
||||
|
||||
/** |
||||
* Calculates the safety margin for this header. |
||||
* See comment in functions.js. |
||||
* |
||||
* @private |
||||
* @returns {Object} |
||||
*/ |
||||
_getSafetyMargin() { |
||||
if (this.props._aspectRatio === ASPECT_RATIO_WIDE) { |
||||
const safeOffset = Math.max( |
||||
getSafetyOffset() - CONTAINER_PADDING, 0 |
||||
); |
||||
|
||||
return { |
||||
marginLeft: safeOffset, |
||||
marginRight: safeOffset |
||||
}; |
||||
} |
||||
|
||||
return undefined; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Maps (parts of) the redux state to the React {@code Component} props of |
||||
* {@code FormSectionHeader}. |
||||
* |
||||
* @param {Object} state - The redux state. |
||||
* @protected |
||||
* @returns {Object} |
||||
*/ |
||||
export function _mapStateToProps(state: Object) { |
||||
return { |
||||
_aspectRatio: state['features/base/aspect-ratio'].aspectRatio |
||||
}; |
||||
} |
||||
|
||||
export default translate(connect(_mapStateToProps)(FormSectionHeader)); |
@ -0,0 +1,28 @@ |
||||
// @flow
|
||||
|
||||
import { isIPhoneX, Platform } from '../base/react'; |
||||
|
||||
const IPHONE_OFFSET = 20; |
||||
const IPHONEX_OFFSET = 44; |
||||
|
||||
/** |
||||
* Determines the offset to be used for the device. |
||||
* This uses a custom implementation to minimize empty area around screen, |
||||
* especially on iPhone X. |
||||
* |
||||
* @returns {number} |
||||
*/ |
||||
export function getSafetyOffset() { |
||||
if (Platform.OS === 'android') { |
||||
/* Android doesn't need offset, except the Essential phone. Should be |
||||
* addressed later with a generic solution. |
||||
*/ |
||||
return 0; |
||||
} |
||||
|
||||
if (isIPhoneX()) { |
||||
return IPHONEX_OFFSET; |
||||
} |
||||
|
||||
return IPHONE_OFFSET; |
||||
} |
@ -1,5 +1,4 @@ |
||||
export * from './actions'; |
||||
export * from './components'; |
||||
export * from './functions'; |
||||
|
||||
import './reducer'; |
||||
|
@ -0,0 +1,37 @@ |
||||
/* @flow */ |
||||
|
||||
import { hideAppSettings } from './actions'; |
||||
|
||||
import { SET_ROOM } from '../base/conference'; |
||||
import { MiddlewareRegistry } from '../base/redux'; |
||||
|
||||
/** |
||||
* The Redux middleware to trigger settings screen show or hide |
||||
* when necessary. |
||||
* |
||||
* @param {Store} store - The Redux store. |
||||
* @returns {Function} |
||||
*/ |
||||
MiddlewareRegistry.register(store => next => action => { |
||||
switch (action.type) { |
||||
case SET_ROOM: |
||||
return _closeAppSettings(store, next, action); |
||||
} |
||||
|
||||
return next(action); |
||||
}); |
||||
|
||||
/** |
||||
* Hides the settings screen. |
||||
* |
||||
* @param {Store} store - The redux store. |
||||
* @param {Dispatch} next - The redux dispatch function. |
||||
* @param {Action} action - The redux action. |
||||
* @private |
||||
* @returns {Object} The new state. |
||||
*/ |
||||
function _closeAppSettings(store, next, action) { |
||||
store.dispatch(hideAppSettings()); |
||||
|
||||
return next(action); |
||||
} |
@ -0,0 +1,37 @@ |
||||
// @flow
|
||||
|
||||
import { Dimensions } from 'react-native'; |
||||
import Platform from './Platform'; |
||||
|
||||
const IPHONEX_HEIGHT = 812; |
||||
const IPHONEX_WIDTH = 375; |
||||
|
||||
/** |
||||
* Determines if the device is an iPad or not. |
||||
* |
||||
* @returns {boolean} |
||||
*/ |
||||
export function isIPad() { |
||||
const { height, width } = Dimensions.get('window'); |
||||
|
||||
return Platform.OS === 'ios' && ( |
||||
Math.max(height, width) |
||||
/ Math.min(height, width)) < 1.6; |
||||
} |
||||
|
||||
/** |
||||
* Determines if it's an iPhone X or not. |
||||
* |
||||
* @returns {boolean} |
||||
*/ |
||||
export function isIPhoneX() { |
||||
const { height, width } = Dimensions.get('window'); |
||||
|
||||
return ( |
||||
Platform.OS === 'ios' |
||||
&& ((height === IPHONEX_HEIGHT |
||||
&& width === IPHONEX_WIDTH) |
||||
|| (height === IPHONEX_WIDTH |
||||
&& width === IPHONEX_HEIGHT)) |
||||
); |
||||
} |
Loading…
Reference in new issue