feat(navigation) two actions screen header buttons ui updates

This commit is contained in:
Calin Chitu 2022-02-11 11:49:49 +02:00 committed by Calinteodor
parent 6ab46186e2
commit eb720d5ddc
10 changed files with 144 additions and 102 deletions

View File

@ -5,6 +5,7 @@ import BaseTheme from '../../../base/ui/components/BaseTheme.native';
export const INSECURE_ROOM_NAME_LABEL_COLOR = BaseTheme.palette.actionDanger;
const TITLE_BAR_BUTTON_SIZE = 24;
const HEADER_ACTION_BUTTON_SIZE = 17;
/**
@ -36,7 +37,7 @@ export default {
},
headerNavigationIcon: {
marginLeft: 12
marginLeft: 14
},
headerNavigationButton: {
@ -45,6 +46,19 @@ export default {
width: BaseTheme.spacing[6]
},
headerNavigationText: {
color: BaseTheme.palette.text01,
fontSize: HEADER_ACTION_BUTTON_SIZE,
marginHorizontal: BaseTheme.spacing[3]
},
headerNavigationTextBold: {
...BaseTheme.typography.labelButton,
color: BaseTheme.palette.text01,
fontSize: HEADER_ACTION_BUTTON_SIZE,
marginHorizontal: BaseTheme.spacing[3]
},
/**
* View that contains the indicators.
*/

View File

@ -72,8 +72,7 @@ class SharedDocument extends PureComponent<Props> {
headerLeft: () => (
<HeaderNavigationButton
onPress = { goBack }
src = { IconArrowBack }
style = { styles.headerArrowBack } />
src = { IconArrowBack } />
)
});
}

View File

@ -5,11 +5,6 @@ import { ColorPalette } from '../../../base/styles';
export const INDICATOR_COLOR = ColorPalette.lightGrey;
export default {
headerArrowBack: {
marginLeft: 12
},
indicatorWrapper: {
alignItems: 'center',
backgroundColor: ColorPalette.white,

View File

@ -8,7 +8,7 @@ import {
TouchableOpacity,
View
} from 'react-native';
import { Text, TouchableRipple, withTheme } from 'react-native-paper';
import { withTheme } from 'react-native-paper';
import { AlertDialog, openDialog } from '../../../../base/dialog';
import { translate } from '../../../../base/i18n';
@ -26,6 +26,8 @@ import {
type Item
} from '../../../../base/react';
import { connect } from '../../../../base/redux';
import HeaderNavigationButton
from '../../../../mobile/navigation/components/HeaderNavigationButton';
import ClearableInput from '../../../../participants-pane/components/native/ClearableInput';
import { beginShareRoom } from '../../../../share-room';
import { INVITE_TYPES } from '../../../constants';
@ -139,18 +141,14 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
* @returns {void}
*/
componentDidMount() {
const { navigation, t, theme } = this.props;
const { palette } = theme;
const { navigation, t } = this.props;
navigation.setOptions({
headerRight: () => (
<TouchableRipple
<HeaderNavigationButton
disabled = { this._isAddDisabled() }
rippleColor = { palette.screen01Header } >
<Text style = { styles.headerSendInvite }>
{ t('inviteDialog.send') }
</Text>
</TouchableRipple>
label = { t('inviteDialog.send') }
twoActions = { true } />
)
});
}
@ -161,20 +159,16 @@ class AddPeopleDialog extends AbstractAddPeopleDialog<Props, State> {
* @inheritdoc
*/
componentDidUpdate(prevProps) {
const { navigation, t, theme } = this.props;
const { palette } = theme;
const { navigation, t } = this.props;
navigation.setOptions({
// eslint-disable-next-line react/no-multi-comp
headerRight: () => (
<TouchableRipple
<HeaderNavigationButton
disabled = { this._isAddDisabled() }
label = { t('inviteDialog.send') }
onPress = { this._onInvite }
rippleColor = { palette.screen01Header } >
<Text style = { styles.headerSendInvite }>
{ t('inviteDialog.send') }
</Text>
</TouchableRipple>
twoActions = { true } />
)
});

View File

@ -1,17 +1,19 @@
// @flow
import React, { Component } from 'react';
import { Linking, View } from 'react-native';
import { Linking, Platform, View } from 'react-native';
import { WebView } from 'react-native-webview';
import { type Dispatch } from 'redux';
import { openDialog } from '../../../../base/dialog';
import { translate } from '../../../../base/i18n';
import { IconClose } from '../../../../base/icons';
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
import { LoadingIndicator } from '../../../../base/react';
import { connect } from '../../../../base/redux';
import { renderArrowBackButton }
from '../../../../mobile/navigation/components/welcome/functions';
import HeaderNavigationButton
from '../../../../mobile/navigation/components/HeaderNavigationButton';
import { navigateRoot } from '../../../../mobile/navigation/rootNavigationContainerRef';
import { screen } from '../../../../mobile/navigation/routes';
import { getDialInfoPageURLForURIString } from '../../../functions';
@ -30,7 +32,12 @@ type Props = {
/**
* Default prop for navigating between screen components(React Navigation).
*/
route: Object
route: Object,
/**
* Translation function.
*/
t: Function
};
/**
@ -46,6 +53,7 @@ class DialInSummary extends Component<Props> {
constructor(props: Props) {
super(props);
this._onNavigateToRoot = this._onNavigateToRoot.bind(this);
this._onError = this._onError.bind(this);
this._onNavigate = this._onNavigate.bind(this);
this._renderLoading = this._renderLoading.bind(this);
@ -59,14 +67,24 @@ class DialInSummary extends Component<Props> {
* @returns {void}
*/
componentDidMount() {
const {
navigation
} = this.props;
const { navigation, t } = this.props;
navigation.setOptions({
headerLeft: () =>
renderArrowBackButton(() =>
navigation.navigate(screen.welcome.main))
headerLeft: () => {
if (Platform.OS === 'ios') {
return (
<HeaderNavigationButton
label = { t('dialog.close') }
onPress = { this._onNavigateToRoot } />
);
}
return (
<HeaderNavigationButton
onPress = { this._onNavigateToRoot }
src = { IconClose } />
);
}
});
}
@ -94,6 +112,17 @@ class DialInSummary extends Component<Props> {
);
}
_onNavigateToRoot: () => void;
/**
* Callback to handle navigation back to root.
*
* @returns {void}
*/
_onNavigateToRoot() {
navigateRoot(screen.root);
}
_onError: () => void;
/**

View File

@ -2,37 +2,76 @@
import React from 'react';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Text, TouchableRipple } from 'react-native-paper';
import { Icon } from '../../../base/icons';
import BaseTheme from '../../../base/ui/components/BaseTheme';
import styles from '../../../conference/components/native/styles';
type Props = {
/**
* Is the button disabled?
*/
disabled?: boolean,
/**
* Label of the button.
*/
label?: string,
/**
* Callback to invoke when the {@code HeaderNavigationButton} is clicked/pressed.
*/
onPress: Function,
onPress?: Function,
/**
* The ImageSource to be rendered as image.
*/
src: Object,
src?: Object,
/**
* The component's external style.
* Header has two actions.
*/
style?: Object
twoActions?: boolean
}
const HeaderNavigationButton = ({ onPress, src, style }: Props) => (
const HeaderNavigationButton
= ({
disabled,
label,
onPress,
src,
twoActions
}: Props) =>
(
<>
{
src ? (
<TouchableOpacity
onPress = { onPress }
style = { styles.headerNavigationButton }>
<Icon
size = { 20 }
src = { src }
style = { [ styles.headerNavigationIcon, style ] } />
style = { styles.headerNavigationIcon } />
</TouchableOpacity>
) : (
<TouchableRipple
disabled = { disabled }
onPress = { onPress }
rippleColor = { BaseTheme.palette.screen01Header }>
<Text
style = {
twoActions
? styles.headerNavigationTextBold
: styles.headerNavigationText
}>
{ label }
</Text>
</TouchableRipple>
)}
</>
);

View File

@ -4,7 +4,6 @@ import { TransitionPresets } from '@react-navigation/stack';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Platform } from 'react-native';
import { Text, TouchableRipple } from 'react-native-paper';
import {
Icon,
@ -20,14 +19,6 @@ import HeaderNavigationButton from './components/HeaderNavigationButton';
import { goBack } from './components/conference/ConferenceNavigationContainerRef';
/**
* Close button text color.
*/
export const closeTextColor = {
color: BaseTheme.palette.text01,
marginLeft: BaseTheme.spacing[3]
};
/**
* Navigation container theme.
*/
@ -211,13 +202,9 @@ export const presentationScreenOptions = {
if (Platform.OS === 'ios') {
return (
<TouchableRipple
onPress = { goBack }
rippleColor = { BaseTheme.palette.screen01Header }>
<Text style = { closeTextColor }>
{ t('dialog.close') }
</Text>
</TouchableRipple>
<HeaderNavigationButton
label = { t('dialog.close') }
onPress = { goBack } />
);
}
@ -226,7 +213,6 @@ export const presentationScreenOptions = {
onPress = { goBack }
src = { IconClose } />
);
},
headerStatusBarHeight: 0,
headerStyle: {

View File

@ -1,13 +1,13 @@
// @flow
import React from 'react';
import { Text, TouchableRipple } from 'react-native-paper';
import { translate } from '../../../../base/i18n';
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
import { connect } from '../../../../base/redux';
import BaseTheme from '../../../../base/ui/components/BaseTheme';
import { googleApi } from '../../../../google-api';
import HeaderNavigationButton
from '../../../../mobile/navigation/components/HeaderNavigationButton';
import { goBack }
from '../../../../mobile/navigation/components/conference/ConferenceNavigationContainerRef';
import { setLiveStreamKey } from '../../../actions';
@ -33,7 +33,7 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
super(props);
// Bind event handlers so they are only bound once per instance.
this._onOkPress = this._onOkPress.bind(this);
this._onStartPress = this._onStartPress.bind(this);
this._onStreamKeyChangeNative
= this._onStreamKeyChangeNative.bind(this);
this._onStreamKeyPick = this._onStreamKeyPick.bind(this);
@ -52,25 +52,22 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
navigation.setOptions({
headerRight: () => (
<TouchableRipple
onPress = { this._onOkPress }
rippleColor = { BaseTheme.palette.screen01Header } >
<Text style = { styles.startLiveStreamLabel }>
{ t('dialog.start') }
</Text>
</TouchableRipple>
<HeaderNavigationButton
label = { t('dialog.start') }
onPress = { this._onStartPress }
twoActions = { true } />
)
});
}
_onOkPress: () => void;
_onStartPress: () => void;
/**
* Starts live stream session and goes back to the previous screen.
*
* @returns {void}
*/
_onOkPress() {
_onStartPress() {
this._onSubmit() && goBack();
}

View File

@ -57,14 +57,6 @@ export default createStyleSheet({
marginBottom: BoxModel.margin
},
/**
* Label for the button that starts live stream.
*/
startLiveStreamLabel: {
color: BaseTheme.palette.text01,
marginRight: 12
},
/**
* Container for the live stream screen.
*/

View File

@ -1,12 +1,12 @@
// @flow
import React from 'react';
import { Text, TouchableRipple } from 'react-native-paper';
import { translate } from '../../../../base/i18n';
import JitsiScreen from '../../../../base/modal/components/JitsiScreen';
import { connect } from '../../../../base/redux';
import BaseTheme from '../../../../base/ui/components/BaseTheme';
import HeaderNavigationButton
from '../../../../mobile/navigation/components/HeaderNavigationButton';
import { goBack } from
'../../../../mobile/navigation/components/conference/ConferenceNavigationContainerRef';
import AbstractStartRecordingDialog, {
@ -32,7 +32,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog<Props> {
constructor(props: Props) {
super(props);
this._onOkPress = this._onOkPress.bind(this);
this._onStartPress = this._onStartPress.bind(this);
}
/**
@ -55,36 +55,33 @@ class StartRecordingDialog extends AbstractStartRecordingDialog<Props> {
isValidating
} = this.state;
// disable ok button id recording service is shown only, when
// disable start button id recording service is shown only, when
// validating dropbox token, if that is not enabled we either always
// show the ok button or if just dropbox is enabled ok is available
// show the start button or if just dropbox is enabled start is available
// when there is token
const isOkDisabled
const isStartDisabled
= _fileRecordingsServiceEnabled ? isValidating
: _isDropboxEnabled ? !isTokenValid : false;
navigation.setOptions({
headerRight: () => (
<TouchableRipple
disabled = { isOkDisabled }
onPress = { this._onOkPress }
rippleColor = { BaseTheme.palette.screen01Header } >
<Text style = { styles.startRecordingLabel }>
{ t('dialog.start') }
</Text>
</TouchableRipple>
<HeaderNavigationButton
disabled = { isStartDisabled }
label = { t('dialog.start') }
onPress = { this._onStartPress }
twoActions = { true } />
)
});
}
_onOkPress: () => void;
_onStartPress: () => void;
/**
* Starts recording session and goes back to the previous screen.
*
* @returns {void}
*/
_onOkPress() {
_onStartPress() {
this._onSubmit() && goBack();
}