Fix settings screen layout on iOS and add soft back button
This commit is contained in:
parent
410dc132e1
commit
112c856850
|
@ -27,12 +27,12 @@
|
|||
.icon-arrow_back:before {
|
||||
content: "\e5c4";
|
||||
}
|
||||
.icon-navigate_before:before {
|
||||
content: "\e408";
|
||||
}
|
||||
.icon-event_note:before {
|
||||
content: "\e616";
|
||||
}
|
||||
.icon-navigate_before:before {
|
||||
content: "\e408";
|
||||
}
|
||||
.icon-public:before {
|
||||
content: "\e80b";
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import { HIDE_APP_SETTINGS, SHOW_APP_SETTINGS } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Redux-signals the request to open the app settings modal.
|
||||
*
|
||||
* @returns {{
|
||||
* type: SHOW_APP_SETTINGS
|
||||
* }}
|
||||
*/
|
||||
export function showAppSettings() {
|
||||
return {
|
||||
type: SHOW_APP_SETTINGS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux-signals the request to hide the app settings modal.
|
||||
*
|
||||
* @returns {{
|
||||
* type: HIDE_APP_SETTINGS
|
||||
* }}
|
||||
*/
|
||||
* Redux-signals the request to hide the app settings modal.
|
||||
*
|
||||
* @returns {{
|
||||
* type: HIDE_APP_SETTINGS
|
||||
* }}
|
||||
*/
|
||||
export function hideAppSettings() {
|
||||
return {
|
||||
type: HIDE_APP_SETTINGS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux-signals the request to open the app settings modal.
|
||||
*
|
||||
* @returns {{
|
||||
* type: SHOW_APP_SETTINGS
|
||||
* }}
|
||||
*/
|
||||
export function showAppSettings() {
|
||||
return {
|
||||
type: SHOW_APP_SETTINGS
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,43 +2,44 @@
|
|||
|
||||
import { Component } from 'react';
|
||||
|
||||
import { hideAppSettings } from '../actions';
|
||||
import { getProfile, updateProfile } from '../../base/profile';
|
||||
|
||||
import { hideAppSettings } from '../actions';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link AbstractAppSettings}
|
||||
*/
|
||||
* The type of the React {@code Component} props of {@link AbstractAppSettings}
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
_aspectRatio: Symbol,
|
||||
|
||||
/**
|
||||
* The default URL for when there is no custom URL set in the profile.
|
||||
*/
|
||||
_serverURL: string,
|
||||
|
||||
/**
|
||||
* The current profile object.
|
||||
*/
|
||||
* The current profile object.
|
||||
*/
|
||||
_profile: Object,
|
||||
|
||||
/**
|
||||
* The visibility prop of the settings modal.
|
||||
*/
|
||||
* The default URL for when there is no custom URL set in the profile.
|
||||
*/
|
||||
_serverURL: string,
|
||||
|
||||
/**
|
||||
* The visibility prop of the settings modal.
|
||||
*/
|
||||
_visible: boolean,
|
||||
|
||||
/**
|
||||
* Redux store dispatch function.
|
||||
*/
|
||||
* Redux store dispatch function.
|
||||
*/
|
||||
dispatch: Dispatch<*>
|
||||
};
|
||||
|
||||
/**
|
||||
* Base (abstract) class for container component rendering
|
||||
* the app settings page.
|
||||
* Base (abstract) class for container component rendering the app settings
|
||||
* page.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
|
@ -65,12 +66,12 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onChangeDisplayName: (string) => void;
|
||||
|
||||
/**
|
||||
* Handles the display name field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The value typed in the name field.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the display name field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The value typed in the name field.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChangeDisplayName(text) {
|
||||
this._updateProfile({
|
||||
displayName: text
|
||||
|
@ -80,12 +81,12 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onChangeEmail: (string) => void;
|
||||
|
||||
/**
|
||||
* Handles the email field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The value typed in the email field.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the email field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The value typed in the email field.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChangeEmail(text) {
|
||||
this._updateProfile({
|
||||
email: text
|
||||
|
@ -95,12 +96,12 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onChangeServerURL: (string) => void;
|
||||
|
||||
/**
|
||||
* Handles the server name field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The server URL typed in the server field.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the server name field value change.
|
||||
*
|
||||
* @protected
|
||||
* @param {string} text - The server URL typed in the server field.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChangeServerURL(text) {
|
||||
this._updateProfile({
|
||||
serverURL: text
|
||||
|
@ -110,10 +111,10 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onRequestClose: () => void;
|
||||
|
||||
/**
|
||||
* Handles the back button.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the back button.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_onRequestClose() {
|
||||
this.props.dispatch(hideAppSettings());
|
||||
}
|
||||
|
@ -121,13 +122,13 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onStartAudioMutedChange: (boolean) => void;
|
||||
|
||||
/**
|
||||
* Handles the start audio muted change event.
|
||||
*
|
||||
* @protected
|
||||
* @param {boolean} newValue - The new value for the
|
||||
* start audio muted option.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the start audio muted change event.
|
||||
*
|
||||
* @protected
|
||||
* @param {boolean} newValue - The new value for the
|
||||
* start audio muted option.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onStartAudioMutedChange(newValue) {
|
||||
this._updateProfile({
|
||||
startWithAudioMuted: newValue
|
||||
|
@ -137,13 +138,13 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_onStartVideoMutedChange: (boolean) => void;
|
||||
|
||||
/**
|
||||
* Handles the start video muted change event.
|
||||
*
|
||||
* @protected
|
||||
* @param {boolean} newValue - The new value for the
|
||||
* start video muted option.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Handles the start video muted change event.
|
||||
*
|
||||
* @protected
|
||||
* @param {boolean} newValue - The new value for the
|
||||
* start video muted option.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onStartVideoMutedChange(newValue) {
|
||||
this._updateProfile({
|
||||
startWithVideoMuted: newValue
|
||||
|
@ -153,12 +154,12 @@ export class AbstractAppSettings extends Component<Props> {
|
|||
_updateProfile: (Object) => void;
|
||||
|
||||
/**
|
||||
* Updates the persisted profile on any change.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} updateObject - The partial update object for the profile.
|
||||
* @returns {void}
|
||||
*/
|
||||
* Updates the persisted profile on any change.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} updateObject - The partial update object for the profile.
|
||||
* @returns {void}
|
||||
*/
|
||||
_updateProfile(updateObject: Object) {
|
||||
this.props.dispatch(updateProfile({
|
||||
...this.props._profile,
|
||||
|
@ -181,8 +182,8 @@ export function _mapStateToProps(state: Object) {
|
|||
|
||||
return {
|
||||
_aspectRatio: state['features/base/aspect-ratio'].aspectRatio,
|
||||
_serverURL,
|
||||
_profile,
|
||||
_serverURL,
|
||||
_visible: state['features/app-settings'].visible
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,24 +5,21 @@ import {
|
|||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
View } from 'react-native';
|
||||
View
|
||||
} from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import {
|
||||
_mapStateToProps,
|
||||
AbstractAppSettings
|
||||
} from './AbstractAppSettings';
|
||||
import BackButton from './BackButton';
|
||||
import FormRow from './FormRow';
|
||||
import FormSectionHeader from './FormSectionHeader';
|
||||
import styles, { HEADER_PADDING } from './styles';
|
||||
|
||||
import { getSafetyOffset } from '../functions.native';
|
||||
|
||||
import { ASPECT_RATIO_NARROW } from '../../base/aspect-ratio';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { isIPad } from '../../base/react';
|
||||
|
||||
import { _mapStateToProps, AbstractAppSettings } from './AbstractAppSettings';
|
||||
import BackButton from './BackButton';
|
||||
import FormRow from './FormRow';
|
||||
import FormSectionHeader from './FormSectionHeader';
|
||||
import { getSafetyOffset } from '../functions';
|
||||
import styles, { HEADER_PADDING } from './styles';
|
||||
|
||||
/**
|
||||
* The native container rendering the app settings page.
|
||||
*
|
||||
|
@ -30,10 +27,10 @@ import { isIPad } from '../../base/react';
|
|||
*/
|
||||
class AppSettings extends AbstractAppSettings {
|
||||
/**
|
||||
* Instantiates a new {@code AppSettings} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
* Instantiates a new {@code AppSettings} instance.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -49,8 +46,8 @@ class AppSettings extends AbstractAppSettings {
|
|||
render() {
|
||||
const { _profile, t } = this.props;
|
||||
|
||||
// FIXME: presentationStyle is added to workaround
|
||||
// orientation issue on iOS
|
||||
// FIXME: presentationStyle is added to workaround orientation issue on
|
||||
// iOS
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
@ -131,12 +128,12 @@ class AppSettings extends AbstractAppSettings {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculates header safety padding for mobile devices.
|
||||
* See comment in functions.js.
|
||||
*
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
* Calculates header safety padding for mobile devices. See comment in
|
||||
* functions.js.
|
||||
*
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getSafetyPadding() {
|
||||
if (isIPad() || this.props._aspectRatio === ASPECT_RATIO_NARROW) {
|
||||
const safeOffset = Math.max(getSafetyOffset(), HEADER_PADDING);
|
||||
|
|
|
@ -3,29 +3,29 @@
|
|||
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';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The icon glyph to be used on a specific platform.
|
||||
*/
|
||||
* 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}
|
||||
*/
|
||||
* The type of the React {@code Component} props of {@link BackButton}
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The action to be performed when the button is pressed.
|
||||
*/
|
||||
* The action to be performed when the button is pressed.
|
||||
*/
|
||||
onPress: Function,
|
||||
|
||||
/**
|
||||
* An external style object passed to the component.
|
||||
*/
|
||||
* An external style object passed to the component.
|
||||
*/
|
||||
style: Object
|
||||
};
|
||||
|
||||
|
|
|
@ -1,40 +1,38 @@
|
|||
/* @flow */
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Text,
|
||||
View } from 'react-native';
|
||||
import { Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
|
||||
|
||||
import { getSafetyOffset } from '../functions';
|
||||
|
||||
import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio';
|
||||
import { translate } from '../../base/i18n';
|
||||
|
||||
import { getSafetyOffset } from '../functions';
|
||||
import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link FormRow}
|
||||
*/
|
||||
* The type of the React {@code Component} props of {@link FormRow}
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
_aspectRatio: Symbol,
|
||||
|
||||
/**
|
||||
*/
|
||||
*
|
||||
*/
|
||||
children: Object,
|
||||
|
||||
/**
|
||||
* Prop to decide if a row separator is to be rendered.
|
||||
*/
|
||||
* Prop to decide if a row separator is to be rendered.
|
||||
*/
|
||||
fieldSeparator: boolean,
|
||||
|
||||
/**
|
||||
* The i18n key of the text label of the form field.
|
||||
*/
|
||||
* The i18n key of the text label of the form field.
|
||||
*/
|
||||
i18nLabel: string,
|
||||
|
||||
/**
|
||||
|
@ -44,8 +42,8 @@ type Props = {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements a React {@code Component} which renders a standardized row
|
||||
* on a form. The component should have exactly one child component.
|
||||
* Implements a React {@code Component} which renders a standardized row on a
|
||||
* form. The component should have exactly one child component.
|
||||
*/
|
||||
class FormRow extends Component<Props> {
|
||||
/**
|
||||
|
@ -96,17 +94,17 @@ class FormRow extends Component<Props> {
|
|||
_getDefaultFieldProps: (field: Component<*, *>) => Object;
|
||||
|
||||
/**
|
||||
* Assembles the default props to the field child component of
|
||||
* this form row.
|
||||
*
|
||||
* Currently tested/supported field types:
|
||||
* - TextInput
|
||||
* - Switch (needs no addition props ATM).
|
||||
*
|
||||
* @private
|
||||
* @param {Object} field - The field (child) component.
|
||||
* @returns {Object}
|
||||
*/
|
||||
* Assembles the default props to the field child component of this form
|
||||
* row.
|
||||
*
|
||||
* Currently tested/supported field types:
|
||||
* - TextInput
|
||||
* - Switch (needs no addition props ATM).
|
||||
*
|
||||
* @private
|
||||
* @param {Object} field - The field (child) component.
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getDefaultFieldProps(field: Object) {
|
||||
if (field && field.type) {
|
||||
switch (field.type.displayName) {
|
||||
|
@ -124,12 +122,12 @@ class FormRow extends Component<Props> {
|
|||
_getRowStyle: () => Array<Object>;
|
||||
|
||||
/**
|
||||
* Assembles the row style array based on the row's props.
|
||||
* For padding, see comment in functions.js.
|
||||
*
|
||||
* @private
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
* Assembles the row style array based on the row's props. For padding, see
|
||||
* comment in functions.js.
|
||||
*
|
||||
* @private
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
_getRowStyle() {
|
||||
const rowStyle = [
|
||||
styles.fieldContainer
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
/* @flow */
|
||||
// @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';
|
||||
|
||||
import { getSafetyOffset } from '../functions';
|
||||
import styles, { CONTAINER_PADDING } from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link FormSectionHeader}
|
||||
*/
|
||||
* The type of the React {@code Component} props of {@link FormSectionHeader}
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
* The current aspect ratio of the screen.
|
||||
*/
|
||||
_aspectRatio: Symbol,
|
||||
|
||||
/**
|
||||
* The i18n key of the text label of the section.
|
||||
*/
|
||||
* The i18n key of the text label of the section.
|
||||
*/
|
||||
i18nLabel: string,
|
||||
|
||||
/**
|
||||
* An external style object passed to the component.
|
||||
*/
|
||||
* An external style object passed to the component.
|
||||
*/
|
||||
style: Object,
|
||||
|
||||
/**
|
||||
|
@ -38,8 +37,8 @@ type Props = {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements a React {@code Component} which renders
|
||||
* a section header on a form. This calculates the available safe view as well.
|
||||
* 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> {
|
||||
/**
|
||||
|
@ -80,17 +79,16 @@ class FormSectionHeader extends Component<Props> {
|
|||
_getSafetyMargin: () => Object;
|
||||
|
||||
/**
|
||||
* Calculates the safety margin for this header.
|
||||
* See comment in functions.js.
|
||||
*
|
||||
* @private
|
||||
* @returns {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
|
||||
);
|
||||
const safeOffset
|
||||
= Math.max(getSafetyOffset() - CONTAINER_PADDING, 0);
|
||||
|
||||
return {
|
||||
marginLeft: safeOffset,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Platform } from 'react-native';
|
||||
|
||||
import {
|
||||
BoxModel,
|
||||
ColorPalette,
|
||||
|
@ -13,30 +14,29 @@ const TEXT_SIZE = 17;
|
|||
|
||||
/**
|
||||
* The styles of the React {@code Components} of the feature
|
||||
* {@code AppSettings}.
|
||||
* {@code app-settings}.
|
||||
*/
|
||||
export default createStyleSheet({
|
||||
|
||||
/**
|
||||
*The platform specific back button style.
|
||||
*/
|
||||
* The platform specific back button style.
|
||||
*/
|
||||
backIcon: {
|
||||
alignSelf: 'center',
|
||||
...Platform.select({
|
||||
ios: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 30
|
||||
},
|
||||
android: {
|
||||
fontSize: 24,
|
||||
padding: 8
|
||||
},
|
||||
ios: {
|
||||
fontSize: 30
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Standardized style for a field container {@code View}.
|
||||
*/
|
||||
* Standardized style for a field container {@code View}.
|
||||
*/
|
||||
fieldContainer: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
|
@ -44,25 +44,25 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Standard container for a {@code View} containing a field label.
|
||||
*/
|
||||
* Standard container for a {@code View} containing a field label.
|
||||
*/
|
||||
fieldLabelContainer: {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
|
||||
/**
|
||||
* Field container style for all but last row {@code View}.
|
||||
*/
|
||||
* Field container style for all but last row {@code View}.
|
||||
*/
|
||||
fieldSeparator: {
|
||||
borderBottomWidth: 1,
|
||||
borderColor: 'rgba(0, 0, 0, 0.1)'
|
||||
},
|
||||
|
||||
/**
|
||||
* Style for the {@code View} containing each
|
||||
* field values (the actual field).
|
||||
*/
|
||||
* Style for the {@code View} containing each
|
||||
* field values (the actual field).
|
||||
*/
|
||||
fieldValueContainer: {
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
|
@ -77,8 +77,8 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Page header {@code View}.
|
||||
*/
|
||||
* Page header {@code View}.
|
||||
*/
|
||||
headerContainer: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: HEADER_COLOR,
|
||||
|
@ -88,31 +88,31 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* The title {@code Text} of the header.
|
||||
*/
|
||||
* The title {@code Text} of the header.
|
||||
*/
|
||||
headerTitle: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 24
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the scrollview to be able to scroll the content.
|
||||
*/
|
||||
* Style of the ScrollView to be able to scroll the content.
|
||||
*/
|
||||
scrollView: {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The back button style on the settings screen.
|
||||
*/
|
||||
* The back button style on the settings screen.
|
||||
*/
|
||||
settingsBackButton: {
|
||||
color: ColorPalette.white,
|
||||
fontSize: 25
|
||||
},
|
||||
|
||||
/**
|
||||
* The top level container {@code View}.
|
||||
*/
|
||||
* The top level container {@code View}.
|
||||
*/
|
||||
settingsContainer: {
|
||||
backgroundColor: ColorPalette.white,
|
||||
flex: 1,
|
||||
|
@ -123,16 +123,16 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Global {@code Text} color for the page.
|
||||
*/
|
||||
* Global {@code Text} color for the page.
|
||||
*/
|
||||
text: {
|
||||
color: ColorPalette.black,
|
||||
fontSize: TEXT_SIZE
|
||||
},
|
||||
|
||||
/**
|
||||
* Standard text input field style.
|
||||
*/
|
||||
* Standard text input field style.
|
||||
*/
|
||||
textInputField: {
|
||||
flex: 1,
|
||||
fontSize: TEXT_SIZE,
|
||||
|
|
|
@ -6,23 +6,17 @@ 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}
|
||||
*/
|
||||
* 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.
|
||||
*/
|
||||
// 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;
|
||||
return isIPhoneX() ? IPHONEX_OFFSET : IPHONE_OFFSET;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* @flow */
|
||||
|
||||
import { hideAppSettings } from './actions';
|
||||
// @flow
|
||||
|
||||
import { SET_ROOM } from '../base/conference';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { hideAppSettings } from './actions';
|
||||
|
||||
/**
|
||||
* The Redux middleware to trigger settings screen show or hide
|
||||
* when necessary.
|
||||
|
@ -30,8 +30,8 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
* @private
|
||||
* @returns {Object} The new state.
|
||||
*/
|
||||
function _closeAppSettings(store, next, action) {
|
||||
store.dispatch(hideAppSettings());
|
||||
function _closeAppSettings({ dispatch }, next, action) {
|
||||
dispatch(hideAppSettings());
|
||||
|
||||
return next(action);
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ export class AbstractApp extends Component {
|
|||
* @returns {void}
|
||||
*/
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const currentProps = this.props;
|
||||
const { props } = this;
|
||||
|
||||
this.init.then(() => {
|
||||
// The consumer of this AbstractApp did not provide a redux store.
|
||||
|
@ -191,7 +191,7 @@ export class AbstractApp extends Component {
|
|||
// its own internal redux store. If the consumer did not
|
||||
// provide a redux store before, then this instance is
|
||||
// using its own internal redux store already.
|
||||
&& typeof currentProps.store !== 'undefined') {
|
||||
&& typeof props.store !== 'undefined') {
|
||||
this.setState({
|
||||
store: this._maybeCreateStore(nextProps)
|
||||
});
|
||||
|
@ -201,11 +201,11 @@ export class AbstractApp extends Component {
|
|||
let { url } = nextProps;
|
||||
|
||||
url = toURLString(url);
|
||||
if (toURLString(currentProps.url) !== url
|
||||
if (toURLString(props.url) !== url
|
||||
|
||||
// XXX Refer to the implementation of loadURLObject: in
|
||||
// ios/sdk/src/JitsiMeetView.m for further information.
|
||||
|| currentProps.timestamp !== nextProps.timestamp) {
|
||||
|| props.timestamp !== nextProps.timestamp) {
|
||||
this._openURL(url || this._getDefaultURL());
|
||||
}
|
||||
});
|
||||
|
@ -375,11 +375,10 @@ export class AbstractApp extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const profileServerURL = getProfile(
|
||||
this._getStore().getState()
|
||||
).serverURL;
|
||||
|
||||
return this.props.defaultURL || profileServerURL || DEFAULT_URL;
|
||||
return (
|
||||
this.props.defaultURL
|
||||
|| getProfile(this._getStore().getState()).serverURL
|
||||
|| DEFAULT_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -214,6 +214,7 @@ function _visitNode(node, callback) {
|
|||
if (console) {
|
||||
const loggerLevels = require('jitsi-meet-logger').levels;
|
||||
|
||||
console.disableYellowBox = true;
|
||||
Object.keys(loggerLevels).forEach(key => {
|
||||
const level = loggerLevels[key];
|
||||
const consoleLog = console[level];
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
/* @flow */
|
||||
import { PROFILE_UPDATED } from './actionTypes';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
// @flow
|
||||
|
||||
import {
|
||||
getLocalParticipant,
|
||||
participantUpdated
|
||||
} from '../participants';
|
||||
import { getLocalParticipant, participantUpdated } from '../participants';
|
||||
import { getProfile } from '../profile';
|
||||
import { toState } from '../redux';
|
||||
import { MiddlewareRegistry, toState } from '../redux';
|
||||
|
||||
import { PROFILE_UPDATED } from './actionTypes';
|
||||
|
||||
/**
|
||||
* A MiddleWare to update the local participant when the profile
|
||||
* is updated.
|
||||
* A middleWare to update the local participant when the profile is updated.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @returns {Function}
|
||||
|
@ -34,11 +30,17 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
* @returns {void}
|
||||
*/
|
||||
function _updateLocalParticipant(store) {
|
||||
const localParticipant = getLocalParticipant(toState(store));
|
||||
const profile = getProfile(toState(store));
|
||||
const state = toState(store);
|
||||
const localParticipant = getLocalParticipant(state);
|
||||
const profile = getProfile(state);
|
||||
|
||||
localParticipant.email = profile.email;
|
||||
localParticipant.name = profile.displayName;
|
||||
store.dispatch(participantUpdated({
|
||||
// Identify that the participant to update i.e. the local participant:
|
||||
id: localParticipant && localParticipant.id,
|
||||
local: true,
|
||||
|
||||
store.dispatch(participantUpdated(localParticipant));
|
||||
// Specify the updates to be applied to the identified participant:
|
||||
email: profile.email,
|
||||
name: profile.displayName
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -1,37 +1,35 @@
|
|||
// @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}
|
||||
*/
|
||||
* 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;
|
||||
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}
|
||||
*/
|
||||
* 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))
|
||||
);
|
||||
&& ((height === IPHONEX_HEIGHT && width === IPHONEX_WIDTH)
|
||||
|| (height === IPHONEX_WIDTH && width === IPHONEX_HEIGHT)));
|
||||
}
|
||||
|
|
|
@ -26,18 +26,18 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
});
|
||||
|
||||
/**
|
||||
* Stores the recently joined room into {@code window.localStorage}.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code SET_ROOM} which is being
|
||||
* dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
* Stores the recently joined room into {@code window.localStorage}.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code SET_ROOM} which is being
|
||||
* dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _storeJoinedRoom(store, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
|
@ -70,18 +70,18 @@ function _storeJoinedRoom(store, next, action) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Updates the conference length when left.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code CONFERENCE_WILL_LEAVE} which
|
||||
* is being dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
* Updates the conference length when left.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified action is being
|
||||
* dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified action to the specified store.
|
||||
* @param {Action} action - The redux action {@code CONFERENCE_WILL_LEAVE} which
|
||||
* is being dispatched in the specified store.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _updateConferenceDuration({ getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
|
|
|
@ -201,11 +201,11 @@ export class AbstractWelcomePage extends Component<*, *> {
|
|||
_onSettingsOpen: () => void;
|
||||
|
||||
/**
|
||||
* Sets the app settings modal visible.
|
||||
*
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
* Sets the app settings modal visible.
|
||||
*
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSettingsOpen() {
|
||||
this.props.dispatch(showAppSettings());
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Layout of the button container.
|
||||
*/
|
||||
* Layout of the button container.
|
||||
*/
|
||||
buttonRow: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
|
@ -54,8 +54,8 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Style of the join button.
|
||||
*/
|
||||
* Style of the join button.
|
||||
*/
|
||||
joinButton: {
|
||||
flex: 1
|
||||
},
|
||||
|
@ -126,16 +126,16 @@ export default createStyleSheet({
|
|||
},
|
||||
|
||||
/**
|
||||
* Style of the settings button.
|
||||
*/
|
||||
* Style of the settings button.
|
||||
*/
|
||||
settingsButton: {
|
||||
width: 65,
|
||||
marginRight: BoxModel.margin
|
||||
},
|
||||
|
||||
/**
|
||||
* Style of the settings icon on the settings button.
|
||||
*/
|
||||
* Style of the settings icon on the settings button.
|
||||
*/
|
||||
settingsIcon: {
|
||||
fontSize: 24,
|
||||
alignSelf: 'center'
|
||||
|
|
Loading…
Reference in New Issue