[IMPROVE] Use UI Elements from react-navigation (#4314)

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Alex Junior 2022-07-06 10:23:02 -03:00 committed by GitHub
parent 2e8b7d7755
commit 1027b6c9e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 289 additions and 350 deletions

View File

@ -97,7 +97,7 @@ const ActionSheetContentWithInputAndSubmit = ({
const { hideActionSheet } = useActionSheet();
return (
<View style={sharedStyles.containerScrollView}>
<View style={sharedStyles.containerScrollView} testID='action-sheet-content-with-input-and-submit'>
<>
<View style={styles.titleContainer}>
{iconName ? <CustomIcon name={iconName} size={32} color={iconColor || colors.dangerColor} /> : null}

View File

@ -10,7 +10,7 @@ export const IconSet = createIconSetFromIcoMoon(icoMoonConfig, 'custom', 'custom
export type TIconsName = keyof typeof mappedIcons;
interface ICustomIcon extends TextProps {
export interface ICustomIcon extends TextProps {
name: TIconsName;
size: number;
color: string;

View File

@ -1,69 +0,0 @@
import React from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import { StyleSheet, View } from 'react-native';
import { themes } from '../../lib/constants';
import { themedHeader } from '../../lib/methods/helpers/navigation';
import { isIOS, isTablet } from '../../lib/methods/helpers';
import { useTheme } from '../../theme';
export const headerHeight = isIOS ? 50 : 56;
export const getHeaderHeight = (isLandscape: boolean): number => {
if (isIOS) {
if (isLandscape && !isTablet) {
return 32;
}
return 44;
}
return 56;
};
interface IHeaderTitlePosition {
insets: {
left: number;
right: number;
};
numIconsRight: number;
}
export const getHeaderTitlePosition = ({
insets,
numIconsRight
}: IHeaderTitlePosition): {
left: number;
right: number;
} => ({
left: insets.left,
right: insets.right + Math.max(45 * numIconsRight, 15)
});
const styles = StyleSheet.create({
container: {
height: headerHeight,
flexDirection: 'row',
justifyContent: 'center',
elevation: 4
}
});
interface IHeader {
headerLeft: () => React.ReactElement | null;
headerTitle: () => React.ReactElement;
headerRight: () => React.ReactElement | null;
}
const Header = ({ headerLeft, headerTitle, headerRight }: IHeader): React.ReactElement => {
const { theme } = useTheme();
return (
<SafeAreaView style={{ backgroundColor: themes[theme].headerBackground }} edges={['top', 'left', 'right']}>
<View style={[styles.container, { ...themedHeader(theme).headerStyle }]}>
{headerLeft ? headerLeft() : null}
{headerTitle ? headerTitle() : null}
{headerRight ? headerRight() : null}
</View>
</SafeAreaView>
);
};
export default Header;

View File

@ -3,12 +3,10 @@ import React from 'react';
import { isIOS } from '../../lib/methods/helpers';
import I18n from '../../i18n';
import Container from './HeaderButtonContainer';
import Item from './HeaderButtonItem';
import Item, { IHeaderButtonItem } from './HeaderButtonItem';
interface IHeaderButtonCommon {
interface IHeaderButtonCommon extends IHeaderButtonItem {
navigation?: any; // TODO: Evaluate proper type
onPress?: () => void;
testID?: string;
}
// Left
@ -28,20 +26,20 @@ export const CloseModal = React.memo(
)
);
export const CancelModal = React.memo(({ onPress, testID }: Partial<IHeaderButtonCommon>) => (
export const CancelModal = React.memo(({ onPress, testID, ...props }: IHeaderButtonCommon) => (
<Container left>
{isIOS ? (
<Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} />
<Item title={I18n.t('Cancel')} onPress={onPress} testID={testID} {...props} />
) : (
<Item iconName='close' onPress={onPress} testID={testID} />
<Item iconName='close' onPress={onPress} testID={testID} {...props} />
)}
</Container>
));
// Right
export const More = React.memo(({ onPress, testID }: Partial<IHeaderButtonCommon>) => (
export const More = React.memo(({ onPress, testID, ...props }: IHeaderButtonCommon) => (
<Container>
<Item iconName='kebab' onPress={onPress} testID={testID} />
<Item iconName='kebab' onPress={onPress} testID={testID} {...props} />
</Container>
));
@ -58,7 +56,7 @@ export const Preferences = React.memo(({ onPress, testID, ...props }: IHeaderBut
));
export const Legal = React.memo(
({ navigation, testID, onPress = () => navigation?.navigate('LegalView') }: IHeaderButtonCommon) => (
<More onPress={onPress} testID={testID} />
({ navigation, testID, onPress = () => navigation?.navigate('LegalView'), ...props }: IHeaderButtonCommon) => (
<More onPress={onPress} testID={testID} {...props} />
)
);

View File

@ -1,18 +1,18 @@
import React from 'react';
import { Platform, StyleSheet, Text } from 'react-native';
import Touchable from 'react-native-platform-touchable';
import { PlatformPressable } from '@react-navigation/elements';
import { CustomIcon, TIconsName } from '../CustomIcon';
import { CustomIcon, ICustomIcon, TIconsName } from '../CustomIcon';
import { useTheme } from '../../theme';
import { themes } from '../../lib/constants';
import sharedStyles from '../../views/Styles';
interface IHeaderButtonItem {
export interface IHeaderButtonItem extends Omit<ICustomIcon, 'name' | 'size' | 'color'> {
title?: string;
iconName?: TIconsName;
onPress?: <T>(arg: T) => void;
testID?: string;
badge?(): void;
color?: string;
}
export const BUTTON_HIT_SLOP = {
@ -24,7 +24,7 @@ export const BUTTON_HIT_SLOP = {
const styles = StyleSheet.create({
container: {
marginHorizontal: 6
padding: 6
},
title: {
...Platform.select({
@ -39,19 +39,21 @@ const styles = StyleSheet.create({
}
});
const Item = ({ title, iconName, onPress, testID, badge }: IHeaderButtonItem): React.ReactElement => {
const { theme } = useTheme();
const Item = ({ title, iconName, onPress, testID, badge, color, ...props }: IHeaderButtonItem): React.ReactElement => {
const { colors } = useTheme();
return (
<Touchable onPress={onPress} testID={testID} hitSlop={BUTTON_HIT_SLOP} style={styles.container}>
<PlatformPressable onPress={onPress} testID={testID} hitSlop={BUTTON_HIT_SLOP} style={styles.container}>
<>
{iconName ? (
<CustomIcon name={iconName} size={24} color={themes[theme].headerTintColor} />
<CustomIcon name={iconName} size={24} color={color || colors.headerTintColor} {...props} />
) : (
<Text style={[styles.title, { color: themes[theme].headerTintColor }]}>{title}</Text>
<Text style={[styles.title, { color: color || colors.headerTintColor }]} {...props}>
{title}
</Text>
)}
{badge ? badge() : null}
</>
</Touchable>
</PlatformPressable>
);
};

View File

@ -7,8 +7,8 @@ const styles = StyleSheet.create({
badgeContainer: {
padding: 2,
position: 'absolute',
right: -3,
top: -3,
right: 2,
top: 2,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center'

View File

@ -1,25 +1,33 @@
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions, react/prop-types, react/destructuring-assignment */
import React from 'react';
import { Dimensions, View } from 'react-native';
import { Dimensions, SafeAreaView } from 'react-native';
import { storiesOf } from '@storybook/react-native';
import { Provider } from 'react-redux';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Header, HeaderBackground } from '@react-navigation/elements';
import Header from '../Header';
import { longText } from '../../../storybook/utils';
import { ThemeContext } from '../../theme';
import { store } from '../../../storybook/stories';
import { colors } from '../../lib/constants';
import { colors, themes } from '../../lib/constants';
import RoomHeaderComponent from './RoomHeader';
const stories = storiesOf('RoomHeader', module).addDecorator(story => <Provider store={store}>{story()}</Provider>);
// TODO: refactor after react-navigation v6
const HeaderExample = ({ title }) => (
<Header headerTitle={() => <View style={{ flex: 1, paddingHorizontal: 12 }}>{title()}</View>} />
);
const stories = storiesOf('RoomHeader', module)
.addDecorator(story => <Provider store={store}>{story()}</Provider>)
.addDecorator(story => <SafeAreaProvider>{story()}</SafeAreaProvider>);
const { width, height } = Dimensions.get('window');
const HeaderExample = ({ title, theme = 'light' }) => (
<SafeAreaView>
<Header
title=''
headerTitle={title}
headerTitleAlign='left'
headerBackground={() => <HeaderBackground style={{ backgroundColor: themes[theme].headerBackground }} />}
/>
</SafeAreaView>
);
const RoomHeader = ({ ...props }) => (
<RoomHeaderComponent
width={width}
@ -28,6 +36,8 @@ const RoomHeader = ({ ...props }) => (
type='p'
testID={props.title}
onPress={() => alert('header pressed!')}
status={props.status}
usersTyping={props.usersTyping}
{...props}
/>
);
@ -84,7 +94,7 @@ stories.add('thread', () => (
const ThemeStory = ({ theme }) => (
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
<HeaderExample title={() => <RoomHeader subtitle='subtitle' />} />
<HeaderExample title={() => <RoomHeader subtitle='subtitle' />} theme={theme} />
</ThemeContext.Provider>
);

File diff suppressed because one or more lines are too long

View File

@ -64,7 +64,7 @@ export const colors = {
passcodeDotEmpty: '#CBCED1',
passcodeDotFull: '#6C727A',
previewBackground: '#1F2329',
previewTintColor: '#ffffff',
previewTintColor: '#f9f9f9',
backdropOpacity: 0.3,
attachmentLoadingOpacity: 0.7,
collapsibleQuoteBorder: '#CBCED1',
@ -116,7 +116,7 @@ export const colors = {
passcodeDotEmpty: '#CBCED1',
passcodeDotFull: '#6C727A',
previewBackground: '#030b1b',
previewTintColor: '#ffffff',
previewTintColor: '#f9f9f9',
backdropOpacity: 0.9,
attachmentLoadingOpacity: 0.3,
collapsibleQuoteBorder: '#CBCED1',
@ -168,7 +168,7 @@ export const colors = {
passcodeDotEmpty: '#CBCED1',
passcodeDotFull: '#6C727A',
previewBackground: '#000000',
previewTintColor: '#ffffff',
previewTintColor: '#f9f9f9',
backdropOpacity: 0.9,
attachmentLoadingOpacity: 0.3,
collapsibleQuoteBorder: '#CBCED1',

View File

@ -3,6 +3,7 @@ import { DarkTheme, DefaultTheme } from '@react-navigation/native';
import { themes } from '../../../constants';
import { TSupportedThemes } from '../../../../theme';
import { isIOS } from '../deviceInfo';
export * from './animations';
@ -26,6 +27,9 @@ export const drawerStyle = {
width: 320
};
// TODO: Remove it once we migrate dropdowns to action sheet
export const headerHeight = isIOS ? 50 : 56;
export const themedHeader = (theme: TSupportedThemes) => ({
headerStyle: {
...borderBottom(theme),

View File

@ -1,7 +1,7 @@
import React from 'react';
import { PermissionsAndroid, StyleSheet, View } from 'react-native';
import { connect } from 'react-redux';
import { StackNavigationProp } from '@react-navigation/stack';
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/native';
import CameraRoll from '@react-native-community/cameraroll';
import * as mime from 'react-native-mime-types';
@ -9,6 +9,7 @@ import RNFetchBlob from 'rn-fetch-blob';
import { Video } from 'expo-av';
import { sha256 } from 'js-sha256';
import { withSafeAreaInsets } from 'react-native-safe-area-context';
import { HeaderBackground, HeaderHeightContext } from '@react-navigation/elements';
import { LISTENER } from '../containers/Toast';
import EventEmitter from '../lib/methods/helpers/events';
@ -21,7 +22,6 @@ import * as HeaderButton from '../containers/HeaderButton';
import { isAndroid, formatAttachmentUrl } from '../lib/methods/helpers';
import { getUserSelector } from '../selectors/login';
import { withDimensions } from '../dimensions';
import { getHeaderHeight } from '../containers/Header';
import StatusBar from '../containers/StatusBar';
import { InsideStackParamList } from '../stacks/types';
import { IApplicationState, IUser, IAttachment } from '../definitions';
@ -86,18 +86,25 @@ class AttachmentView extends React.Component<IAttachmentViewProps, IAttachmentVi
} catch {
// Do nothing
}
const options = {
title,
headerLeft: () => <HeaderButton.CloseModal testID='close-attachment-view' navigation={navigation} />,
headerRight: () =>
Allow_Save_Media_to_Gallery ? <HeaderButton.Download testID='save-image' onPress={this.handleSave} /> : null,
headerBackground: () => <View style={{ flex: 1, backgroundColor: themes[theme].previewBackground }} />,
const options: StackNavigationOptions = {
title: title || '',
headerTitleAlign: 'center',
headerTitleStyle: { color: themes[theme].previewTintColor },
headerTintColor: themes[theme].previewTintColor,
headerTitleStyle: { color: themes[theme].previewTintColor, paddingHorizontal: 20 },
headerTitleContainerStyle: { marginHorizontal: -20 },
headerTitleAlign: 'center'
headerTitleContainerStyle: { flex: 1, maxWidth: undefined },
headerLeftContainerStyle: { flexGrow: undefined, flexBasis: undefined },
headerRightContainerStyle: { flexGrow: undefined, flexBasis: undefined },
headerLeft: () => (
<HeaderButton.CloseModal testID='close-attachment-view' navigation={navigation} color={themes[theme].previewTintColor} />
),
headerRight: () =>
Allow_Save_Media_to_Gallery ? (
<HeaderButton.Download testID='save-image' onPress={this.handleSave} color={themes[theme].previewTintColor} />
) : null,
headerBackground: () => (
<HeaderBackground style={{ backgroundColor: themes[theme].previewBackground, shadowOpacity: 0, elevation: 0 }} />
)
};
// @ts-ignore
navigation.setOptions(options);
};
@ -147,14 +154,17 @@ class AttachmentView extends React.Component<IAttachmentViewProps, IAttachmentVi
renderImage = (uri: string) => {
const { width, height, insets } = this.props;
const headerHeight = getHeaderHeight(width > height);
return (
<ImageViewer
uri={uri}
onLoadEnd={() => this.setState({ loading: false })}
width={width}
height={height - insets.top - insets.bottom - headerHeight}
/>
<HeaderHeightContext.Consumer>
{headerHeight => (
<ImageViewer
uri={uri}
onLoadEnd={() => this.setState({ loading: false })}
width={width}
height={height - insets.top - insets.bottom - (headerHeight || 0)}
/>
)}
</HeaderHeightContext.Consumer>
);
};

View File

@ -1,6 +1,5 @@
import React, { useEffect, useState, useCallback } from 'react';
import { FlatList } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { RouteProp } from '@react-navigation/native';
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements';
@ -12,7 +11,6 @@ import StatusBar from '../../containers/StatusBar';
import ActivityIndicator from '../../containers/ActivityIndicator';
import SearchHeader from '../../containers/SearchHeader';
import BackgroundContainer from '../../containers/BackgroundContainer';
import { getHeaderTitlePosition } from '../../containers/Header';
import { useTheme } from '../../theme';
import Navigation from '../../lib/navigation/appNavigation';
import { goRoom } from '../../lib/methods/helpers/goRoom';
@ -73,7 +71,6 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
const [loading, setLoading] = useState(true);
const [offset, setOffset] = useState(0);
const insets = useSafeAreaInsets();
const { theme } = useTheme();
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
const rooms = useAppSelector(state => state.room.rooms);
@ -248,9 +245,10 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
const getHeader = (): StackNavigationOptions => {
if (isSearching) {
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 });
return {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 0 },
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item
@ -263,35 +261,29 @@ const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListView
</HeaderButton.Container>
),
headerTitle: () => <SearchHeader onSearchChangeText={onChangeText} testID='team-channels-view-search-header' />,
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () => null
};
}
const options: StackNavigationOptions = {
headerTitleAlign: undefined,
headerTitle: I18n.t('Canned_Responses'),
headerTitleContainerStyle: { maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 1 },
headerLeft: () => (
<HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={themes[theme].headerTintColor} />
),
headerTitleAlign: 'center',
headerTitle: I18n.t('Canned_Responses'),
headerTitleContainerStyle: {
left: 0,
right: 0
}
headerRight: () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={() => setIsSearching(true)} />
</HeaderButton.Container>
)
};
if (isMasterDetail) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
}
options.headerRight = () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={() => setIsSearching(true)} />
</HeaderButton.Container>
);
return options;
};

View File

@ -1,11 +1,10 @@
import React, { useEffect, useLayoutEffect, useState } from 'react';
import { FlatList, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements';
import { RouteProp } from '@react-navigation/core';
import { IMessageFromServer } from '../../definitions';
import { IMessageFromServer, TThreadModel } from '../../definitions';
import { ChatsStackParamList } from '../../stacks/types';
import ActivityIndicator from '../../containers/ActivityIndicator';
import I18n from '../../i18n';
@ -16,10 +15,8 @@ import SafeAreaView from '../../containers/SafeAreaView';
import * as HeaderButton from '../../containers/HeaderButton';
import * as List from '../../containers/List';
import BackgroundContainer from '../../containers/BackgroundContainer';
import { getHeaderTitlePosition } from '../../containers/Header';
import { useTheme } from '../../theme';
import SearchHeader from '../../containers/SearchHeader';
import { TThreadModel } from '../../definitions/IThread';
import Item from './Item';
import { Services } from '../../lib/services';
import { useAppSelector } from '../../lib/hooks';
@ -53,7 +50,6 @@ const DiscussionsView = ({ navigation, route }: IDiscussionsViewProps): React.Re
const [searchTotal, setSearchTotal] = useState(0);
const { colors } = useTheme();
const insets = useSafeAreaInsets();
const load = async (text = '') => {
if (loading) {
@ -103,9 +99,10 @@ const DiscussionsView = ({ navigation, route }: IDiscussionsViewProps): React.Re
const setHeader = () => {
let options: Partial<StackNavigationOptions>;
if (isSearching) {
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 });
options = {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 0 },
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item iconName='close' onPress={onCancelSearchPress} />
@ -114,25 +111,18 @@ const DiscussionsView = ({ navigation, route }: IDiscussionsViewProps): React.Re
headerTitle: () => (
<SearchHeader onSearchChangeText={onSearchChangeText} testID='discussion-messages-view-search-header' />
),
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () => null
};
return options;
}
options = {
headerTitleAlign: 'center',
headerTitle: I18n.t('Discussions'),
headerRightContainerStyle: { flexGrow: 1 },
headerLeft: () => (
<HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={colors.headerTintColor} />
),
headerTitleAlign: 'center',
headerTitle: I18n.t('Discussions'),
headerTitleContainerStyle: {
left: 0,
right: 0
},
headerRight: () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={onSearchPress} />

View File

@ -63,7 +63,7 @@ export function DeleteAccountActionSheetContent(): React.ReactElement {
onCancel={hideActionSheet}
onSubmit={password => handleDeleteAccount(password)}
placeholder={i18n.t('Password')}
testID='room-info-edit-view-name'
testID='profile-view-delete-account-sheet'
iconName='warning'
confirmTitle={i18n.t('Delete_Account')}
confirmBackgroundColor={colors.dangerColor}

View File

@ -1,5 +1,5 @@
import React, { useCallback } from 'react';
import { StyleSheet } from 'react-native';
import { StyleSheet, Platform } from 'react-native';
import { StackNavigationProp } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements';
@ -7,11 +7,19 @@ import { themes } from '../../lib/constants';
import Avatar from '../../containers/Avatar';
import { ChatsStackParamList } from '../../stacks/types';
import { TSupportedThemes } from '../../theme';
import { isIOS } from '../../lib/methods/helpers';
const styles = StyleSheet.create({
container: {
...Platform.select({
ios: {
minWidth: 60
}
})
},
avatar: {
borderRadius: 10,
marginHorizontal: 16
marginHorizontal: 15
}
});
@ -59,9 +67,11 @@ const LeftButtons = ({
return (
<HeaderBackButton
label={label}
labelVisible={isIOS}
onPress={onPress}
tintColor={themes[theme].headerTintColor}
labelStyle={{ fontSize, marginLeft }}
style={styles.container}
/>
);
}

View File

@ -24,7 +24,7 @@ import RoomHeader from '../../containers/RoomHeader';
import StatusBar from '../../containers/StatusBar';
import ReactionsModal from '../../containers/ReactionsModal';
import { LISTENER } from '../../containers/Toast';
import { getBadgeColor, isBlocked, isTeamRoom, makeThreadName } from '../../lib/methods/helpers/room';
import { getBadgeColor, isBlocked, makeThreadName } from '../../lib/methods/helpers/room';
import { isReadOnly } from '../../lib/methods/helpers/isReadOnly';
import { showErrorAlert } from '../../lib/methods/helpers/info';
import { withTheme } from '../../theme';
@ -574,7 +574,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
let token: string | undefined;
let avatar: string | undefined;
let visitor: IVisitor | undefined;
let status: string | undefined;
let sourceType: IOmnichannelSource | undefined;
if ('id' in room) {
subtitle = room.topic;
@ -585,7 +584,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
({ id: userId, token } = user);
avatar = room.name;
visitor = room.visitor;
status = room.status;
}
if ('source' in room) {
@ -594,19 +592,18 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
visitor = room.visitor;
}
let numIconsRight = 2;
if (tmid || (status && joined)) {
numIconsRight = 1;
} else if (teamId && isTeamRoom({ teamId, joined })) {
numIconsRight = 3;
}
const omnichannelPermissions = { canForwardGuest, canReturnQueue, canPlaceLivechatOnHold };
const paddingRight = this.getPaddingLeft(numIconsRight, isMasterDetail);
navigation.setOptions({
headerShown: true,
headerTitleAlign: 'left',
headerTitleContainerStyle: { paddingRight },
headerTitleContainerStyle: {
flex: 1,
marginLeft: 0,
marginRight: 4,
maxWidth: undefined
},
headerRightContainerStyle: { flexGrow: undefined, flexBasis: undefined },
headerLeft: () => (
<LeftButtons
tmid={tmid}
@ -656,13 +653,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
});
};
getPaddingLeft = (numIcons: number, isMasterDetail: boolean) => {
if (numIcons === 3) {
return isMasterDetail ? 40 : 35;
}
return isMasterDetail ? 20 : 0;
};
goRoomActionsView = (screen?: keyof ModalStackParamList) => {
logEvent(events.ROOM_GO_RA);
const { room, member, joined, canForwardGuest, canReturnQueue, canViewCannedResponse, canPlaceLivechatOnHold } = this.state;

View File

@ -1,20 +1,18 @@
import React from 'react';
import { StyleSheet, Text, TextInputProps, TouchableOpacity, TouchableOpacityProps, View } from 'react-native';
import { TextInput } from '../../../containers/TextInput';
import I18n from '../../../i18n';
import sharedStyles from '../../Styles';
import { themes } from '../../../lib/constants';
import { CustomIcon } from '../../../containers/CustomIcon';
import { isIOS, isTablet } from '../../../lib/methods/helpers';
import { useOrientation } from '../../../dimensions';
import { useTheme } from '../../../theme';
import SearchHeader from '../../../containers/SearchHeader';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
marginLeft: isTablet ? 10 : 0
justifyContent: 'center'
},
button: {
flexDirection: 'row',
@ -56,26 +54,14 @@ const Header = React.memo(
onSearchChangeText,
onPress
}: IRoomHeader) => {
const { theme } = useTheme();
const titleColorStyle = { color: themes[theme].headerTitleColor };
const isLight = theme === 'light';
const { colors } = useTheme();
const { isLandscape } = useOrientation();
const scale = isIOS && isLandscape && !isTablet ? 0.8 : 1;
const titleFontSize = 16 * scale;
const subTitleFontSize = 14 * scale;
if (showSearchHeader) {
return (
<View style={styles.container}>
<TextInput
autoFocus
style={[styles.subtitle, isLight && titleColorStyle, { fontSize: titleFontSize }]}
placeholder='Search'
onChangeText={onSearchChangeText}
testID='rooms-list-view-search-input'
/>
</View>
);
return <SearchHeader onSearchChangeText={onSearchChangeText} testID='rooms-list-view-search-input' />;
}
let subtitle;
if (connecting) {
@ -91,12 +77,12 @@ const Header = React.memo(
<View style={styles.container}>
<TouchableOpacity onPress={onPress} testID='rooms-list-header-server-dropdown-button'>
<View style={styles.button}>
<Text style={[styles.title, titleColorStyle, { fontSize: titleFontSize }]} numberOfLines={1}>
<Text style={[styles.title, { fontSize: titleFontSize, color: colors.headerTitleColor }]} numberOfLines={1}>
{serverName}
</Text>
<CustomIcon
name='chevron-down'
color={themes[theme].headerTintColor}
color={colors.headerTintColor}
style={[showServerDropdown && styles.upsideDown]}
size={18}
/>
@ -104,7 +90,7 @@ const Header = React.memo(
{subtitle ? (
<Text
testID='rooms-list-header-server-subtitle'
style={[styles.subtitle, { color: themes[theme].auxiliaryText, fontSize: subTitleFontSize }]}
style={[styles.subtitle, { color: colors.auxiliaryText, fontSize: subTitleFontSize }]}
numberOfLines={1}>
{subtitle}
</Text>

View File

@ -3,7 +3,6 @@ import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { toggleServerDropdown, closeServerDropdown, setSearch } from '../../../actions/rooms';
import { TSupportedThemes, withTheme } from '../../../theme';
import EventEmitter from '../../../lib/methods/helpers/events';
import { KEY_COMMAND, handleCommandOpenServerDropdown, IKeyCommandEvent } from '../../../commands';
import { isTablet } from '../../../lib/methods/helpers';
@ -18,7 +17,6 @@ interface IRoomsListHeaderViewProps {
connecting: boolean;
connected: boolean;
isFetching: boolean;
theme: TSupportedThemes;
server: string;
dispatch: Dispatch;
}
@ -87,4 +85,4 @@ const mapStateToProps = (state: IApplicationState) => ({
server: state.server.server
});
export default connect(mapStateToProps)(withTheme(RoomsListHeaderView));
export default connect(mapStateToProps)(RoomsListHeaderView);

View File

@ -20,7 +20,7 @@ import { isTablet } from '../../lib/methods/helpers';
import { localAuthenticate } from '../../lib/methods/helpers/localAuthentication';
import { showConfirmationAlert } from '../../lib/methods/helpers/info';
import log, { events, logEvent } from '../../lib/methods/helpers/log';
import { headerHeight } from '../../containers/Header';
import { headerHeight } from '../../lib/methods/helpers/navigation';
import { goRoom } from '../../lib/methods/helpers/goRoom';
import UserPreferences from '../../lib/methods/userPreferences';
import { IApplicationState, IBaseScreen, RootEnum, TServerModel } from '../../definitions';

View File

@ -7,6 +7,7 @@ import { Q } from '@nozbe/watermelondb';
import { withSafeAreaInsets } from 'react-native-safe-area-context';
import { Subscription } from 'rxjs';
import { StackNavigationOptions } from '@react-navigation/stack';
import { Header } from '@react-navigation/elements';
import database from '../../lib/database';
import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../containers/RoomItem';
@ -21,6 +22,7 @@ import { serverInitAdd } from '../../actions/server';
import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation';
import { withTheme } from '../../theme';
import EventEmitter from '../../lib/methods/helpers/events';
import { themedHeader } from '../../lib/methods/helpers/navigation';
import {
KEY_COMMAND,
handleCommandAddNewServer,
@ -35,7 +37,6 @@ import {
import { getUserSelector } from '../../selectors/login';
import { goRoom } from '../../lib/methods/helpers/goRoom';
import SafeAreaView from '../../containers/SafeAreaView';
import Header, { getHeaderTitlePosition } from '../../containers/Header';
import { withDimensions } from '../../dimensions';
import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry';
import {
@ -415,55 +416,59 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
this.setState({ canCreateRoom }, () => this.setHeader());
};
getHeader = () => {
getHeader = (): StackNavigationOptions => {
const { searching, canCreateRoom } = this.state;
const { navigation, isMasterDetail, insets, theme } = this.props;
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: searching ? 0 : 3 });
return {
headerTitleAlign: 'left',
headerLeft: () =>
searching ? (
const { navigation, isMasterDetail } = this.props;
if (searching) {
return {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 0 },
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item iconName='close' onPress={this.cancelSearch} />
</HeaderButton.Container>
) : (
<HeaderButton.Drawer
navigation={navigation}
testID='rooms-list-view-sidebar'
onPress={
isMasterDetail
? () => navigation.navigate('ModalStackNavigator', { screen: 'SettingsView' })
: // @ts-ignore
() => navigation.toggleDrawer()
}
/>
),
headerTitle: () => <RoomsListHeaderView theme={theme} />,
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () =>
searching ? null : (
<HeaderButton.Container>
{canCreateRoom ? (
<HeaderButton.Item iconName='create' onPress={this.goToNewMessage} testID='rooms-list-view-create-channel' />
) : null}
<HeaderButton.Item iconName='search' onPress={this.initSearching} testID='rooms-list-view-search' />
<HeaderButton.Item iconName='directory' onPress={this.goDirectory} testID='rooms-list-view-directory' />
</HeaderButton.Container>
)
headerTitle: () => <RoomsListHeaderView />,
headerRight: () => null
};
}
return {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 4, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: undefined, flexBasis: undefined },
headerLeft: () => (
<HeaderButton.Drawer
navigation={navigation}
testID='rooms-list-view-sidebar'
onPress={
isMasterDetail
? () => navigation.navigate('ModalStackNavigator', { screen: 'SettingsView' })
: // @ts-ignore
() => navigation.toggleDrawer()
}
/>
),
headerTitle: () => <RoomsListHeaderView />,
headerRight: () => (
<HeaderButton.Container>
{canCreateRoom ? (
<HeaderButton.Item iconName='create' onPress={this.goToNewMessage} testID='rooms-list-view-create-channel' />
) : null}
<HeaderButton.Item iconName='search' onPress={this.initSearching} testID='rooms-list-view-search' />
<HeaderButton.Item iconName='directory' onPress={this.goDirectory} testID='rooms-list-view-directory' />
</HeaderButton.Container>
)
};
};
setHeader = () => {
const { navigation } = this.props;
const options = this.getHeader() as Partial<StackNavigationOptions>;
const options = this.getHeader();
navigation.setOptions(options);
};
// internalSetState = (...args: { chats: TSubscriptionModel; chatsUpdate: TSubscriptionModel; loading: boolean }[]) => {
internalSetState = (
state:
| ((
@ -923,14 +928,14 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
};
renderHeader = () => {
const { isMasterDetail } = this.props;
const { isMasterDetail, theme } = this.props;
if (!isMasterDetail) {
return null;
}
const options = this.getHeader();
return <Header {...options} />;
return <Header title='' {...themedHeader(theme)} {...options} />;
};
renderItem = ({ item }: { item: IRoomItem }) => {

View File

@ -3,11 +3,11 @@ import { Video } from 'expo-av';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ScrollView, StyleSheet, Text } from 'react-native';
import prettyBytes from 'pretty-bytes';
import { useHeaderHeight } from '@react-navigation/elements';
import { CustomIcon, TIconsName } from '../../containers/CustomIcon';
import { ImageViewer, types } from '../../containers/ImageViewer';
import { useDimensions, useOrientation } from '../../dimensions';
import { getHeaderHeight } from '../../containers/Header';
import { useDimensions } from '../../dimensions';
import sharedStyles from '../Styles';
import I18n from '../../i18n';
import { isAndroid } from '../../lib/methods/helpers';
@ -66,9 +66,8 @@ interface IPreview {
const Preview = React.memo(({ item, theme, isShareExtension, length }: IPreview) => {
const type = item?.mime;
const { width, height } = useDimensions();
const { isLandscape } = useOrientation();
const insets = useSafeAreaInsets();
const headerHeight = getHeaderHeight(isLandscape);
const headerHeight = useHeaderHeight();
const thumbsHeight = length > 1 ? THUMBS_HEIGHT : 0;
const calculatedHeight = height - insets.top - insets.bottom - MESSAGEBOX_HEIGHT - thumbsHeight - headerHeight;

View File

@ -106,13 +106,13 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
// if is share extension show default back button
if (!this.isShareExtension) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} color={themes[theme].previewTintColor} />;
}
if (!attachments.length && !readOnly) {
options.headerRight = () => (
<HeaderButton.Container>
<HeaderButton.Item title={I18n.t('Send')} onPress={this.send} />
<HeaderButton.Item title={I18n.t('Send')} onPress={this.send} color={themes[theme].previewTintColor} />
</HeaderButton.Container>
);
}

View File

@ -3,7 +3,6 @@ import { StackNavigationOptions } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements';
import React from 'react';
import { Alert, FlatList, Keyboard } from 'react-native';
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
import { connect } from 'react-redux';
import { deleteRoom } from '../actions/room';
@ -11,7 +10,6 @@ import { DisplayMode, themes } from '../lib/constants';
import { TActionSheetOptions, TActionSheetOptionsItem, withActionSheet } from '../containers/ActionSheet';
import ActivityIndicator from '../containers/ActivityIndicator';
import BackgroundContainer from '../containers/BackgroundContainer';
import { getHeaderTitlePosition } from '../containers/Header';
import * as HeaderButton from '../containers/HeaderButton';
import RoomHeader from '../containers/RoomHeader';
import SafeAreaView from '../containers/SafeAreaView';
@ -74,7 +72,6 @@ interface ITeamChannelsViewState {
}
interface ITeamChannelsViewProps extends IBaseScreen<ChatsStackParamList, 'TeamChannelsView'> {
insets: EdgeInsets;
useRealName: boolean;
width: number;
StoreLastMessage: boolean;
@ -190,18 +187,18 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
setHeader = () => {
const { isSearching, showCreate, data } = this.state;
const { navigation, isMasterDetail, insets, theme } = this.props;
const { navigation, isMasterDetail, theme } = this.props;
const { team } = this;
if (!team) {
return;
}
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 2 });
if (isSearching) {
const options: StackNavigationOptions = {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 0 },
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item iconName='close' onPress={this.onCancelSearchPress} />
@ -210,27 +207,33 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
headerTitle: () => (
<SearchHeader onSearchChangeText={this.onSearchChangeText} testID='team-channels-view-search-header' />
),
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () => null
};
return navigation.setOptions(options);
}
const options: StackNavigationOptions = {
headerShown: true,
headerTitleAlign: 'left',
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerTitleContainerStyle: { flex: 1, marginLeft: 0, marginRight: 4, maxWidth: undefined },
headerLeftContainerStyle: { minWidth: 60 },
headerRightContainerStyle: { flexGrow: undefined, flexBasis: undefined },
headerLeft: () => (
<HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={themes[theme].headerTintColor} />
),
headerTitle: () => (
<RoomHeader title={getRoomTitle(team)} subtitle={team.topic} type={team.t} onPress={this.goRoomActionsView} teamMain />
),
headerRight: () => (
<HeaderButton.Container>
{showCreate ? (
<HeaderButton.Item
iconName='create'
testID='team-channels-view-create'
onPress={() => navigation.navigate('AddChannelTeamView', { teamId: this.teamId, teamChannels: data })}
/>
) : null}
<HeaderButton.Item iconName='search' testID='team-channels-view-search' onPress={this.onSearchPress} />
</HeaderButton.Container>
)
};
@ -238,18 +241,6 @@ class TeamChannelsView extends React.Component<ITeamChannelsViewProps, ITeamChan
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
}
options.headerRight = () => (
<HeaderButton.Container>
{showCreate ? (
<HeaderButton.Item
iconName='create'
testID='team-channels-view-create'
onPress={() => navigation.navigate('AddChannelTeamView', { teamId: this.teamId, teamChannels: data })}
/>
) : null}
<HeaderButton.Item iconName='search' testID='team-channels-view-search' onPress={this.onSearchPress} />
</HeaderButton.Container>
);
navigation.setOptions(options);
};
@ -575,4 +566,4 @@ const mapStateToProps = (state: IApplicationState) => ({
displayMode: state.sortPreferences.displayMode
});
export default connect(mapStateToProps)(withDimensions(withSafeAreaInsets(withTheme(withActionSheet(TeamChannelsView)))));
export default connect(mapStateToProps)(withDimensions(withTheme(withActionSheet(TeamChannelsView))));

View File

@ -5,7 +5,7 @@ import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
import styles from '../styles';
import { themes } from '../../../lib/constants';
import { TSupportedThemes, withTheme } from '../../../theme';
import { headerHeight } from '../../../containers/Header';
import { headerHeight } from '../../../lib/methods/helpers/navigation';
import * as List from '../../../containers/List';
import { Filter } from '../filters';
import DropdownItemFilter from './DropdownItemFilter';

View File

@ -3,7 +3,6 @@ import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context';
import { StackNavigationOptions } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements';
import { Observable, Subscription } from 'rxjs';
@ -24,7 +23,6 @@ import * as HeaderButton from '../../containers/HeaderButton';
import * as List from '../../containers/List';
import BackgroundContainer from '../../containers/BackgroundContainer';
import { getBadgeColor, makeThreadName } from '../../lib/methods/helpers/room';
import { getHeaderTitlePosition } from '../../containers/Header';
import EventEmitter from '../../lib/methods/helpers/events';
import { LISTENER } from '../../containers/Toast';
import SearchHeader from '../../containers/SearchHeader';
@ -58,7 +56,6 @@ interface IThreadMessagesViewProps extends IBaseScreen<ChatsStackParamList, 'Thr
useRealName: boolean;
theme: TSupportedThemes;
isMasterDetail: boolean;
insets: EdgeInsets;
}
class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThreadMessagesViewState> {
@ -100,13 +97,6 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
this.init();
}
componentDidUpdate(prevProps: IThreadMessagesViewProps) {
const { insets } = this.props;
if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) {
this.setHeader();
}
}
componentWillUnmount() {
console.countReset(`${this.constructor.name}.render calls`);
if (this.subSubscription && this.subSubscription.unsubscribe) {
@ -119,12 +109,13 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
getHeader = (): StackNavigationOptions => {
const { isSearching } = this.state;
const { navigation, isMasterDetail, insets, theme } = this.props;
const { navigation, isMasterDetail, theme } = this.props;
if (isSearching) {
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 });
return {
headerTitleAlign: 'left',
headerTitleContainerStyle: { flex: 1, marginHorizontal: 0, marginRight: 15, maxWidth: undefined },
headerRightContainerStyle: { flexGrow: 0 },
headerLeft: () => (
<HeaderButton.Container left>
<HeaderButton.Item iconName='close' onPress={this.onCancelSearchPress} />
@ -133,35 +124,28 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
headerTitle: () => (
<SearchHeader onSearchChangeText={this.onSearchChangeText} testID='thread-messages-view-search-header' />
),
headerTitleContainerStyle: {
left: headerTitlePosition.left,
right: headerTitlePosition.right
},
headerRight: () => null
};
}
const options: StackNavigationOptions = {
headerTitleAlign: 'center',
headerTitle: I18n.t('Threads'),
headerRightContainerStyle: { flexGrow: 1 },
headerLeft: () => (
<HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={themes[theme].headerTintColor} />
),
headerTitleAlign: 'center',
headerTitle: I18n.t('Threads'),
headerTitleContainerStyle: {
left: 0,
right: 0
}
headerRight: () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={this.onSearchPress} />
</HeaderButton.Container>
)
};
if (isMasterDetail) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} />;
}
options.headerRight = () => (
<HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={this.onSearchPress} />
</HeaderButton.Container>
);
return options;
};
@ -549,4 +533,4 @@ const mapStateToProps = (state: IApplicationState) => ({
isMasterDetail: state.app.isMasterDetail
});
export default connect(mapStateToProps)(withTheme(withSafeAreaInsets(ThreadMessagesView)));
export default connect(mapStateToProps)(withTheme(ThreadMessagesView));

View File

@ -108,8 +108,13 @@ describe('Profile screen', () => {
await element(by.id('profile-view-email')).replaceText(`mobile+profileChangesNew${data.random}@rocket.chat`);
await element(by.id('profile-view-new-password')).replaceText(`${profileChangeUser.password}new`);
await element(by.id('profile-view-submit')).tap();
await element(by.type(textInputType)).replaceText(`${profileChangeUser.password}`);
await element(by[textMatcher]('Save').and(by.type(alertButtonType))).tap();
await waitFor(element(by.id('profile-view-enter-password-sheet')))
.toBeVisible()
.withTimeout(2000);
await element(by.id('profile-view-enter-password-sheet')).replaceText(`${profileChangeUser.password}`);
await element(by[textMatcher]('Save').withAncestor(by.id('action-sheet-content-with-input-and-submit')))
.atIndex(0)
.tap();
await waitForToast();
});

View File

@ -272,6 +272,9 @@ describe('Room actions screen', () => {
describe('Notification', () => {
it('should navigate to notification preference view', async () => {
await waitFor(element(by.id('room-actions-scrollview')))
.toExist()
.withTimeout(2000);
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
await waitFor(element(by.id('room-actions-notifications')))
.toExist()
@ -307,8 +310,6 @@ describe('Room actions screen', () => {
});
it('should have notification sound option', async () => {
// Ugly hack to scroll on detox
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
await waitFor(element(by.id('notification-preference-view-sound')))
.toExist()
.withTimeout(4000);
@ -338,6 +339,9 @@ describe('Room actions screen', () => {
const user = data.users.alternate;
it('should tap on leave channel and raise alert', async () => {
await waitFor(element(by.id('room-actions-scrollview')))
.toExist()
.withTimeout(2000);
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
await waitFor(element(by.id('room-actions-leave-channel')))
.toExist()

View File

@ -290,10 +290,11 @@ describe('Room info screen', () => {
.toExist()
.withTimeout(5000);
await element(by[textMatcher]('Yes, archive it!').and(by.type(alertButtonType))).tap();
await waitFor(element(by.id('room-info-edit-view-unarchive')))
.toExist()
.withTimeout(60000);
await expect(element(by.id('room-info-edit-view-archive'))).toBeNotVisible();
await waitForToast();
// await waitFor(element(by.id('room-info-edit-view-unarchive')))
// .toExist()
// .withTimeout(60000);
// await expect(element(by.id('room-info-edit-view-archive'))).toBeNotVisible();
});
it('should delete room', async () => {

View File

@ -0,0 +1,13 @@
diff --git a/node_modules/@react-navigation/elements/src/Header/HeaderBackButton.tsx b/node_modules/@react-navigation/elements/src/Header/HeaderBackButton.tsx
index 39a39b2..7a60a15 100644
--- a/node_modules/@react-navigation/elements/src/Header/HeaderBackButton.tsx
+++ b/node_modules/@react-navigation/elements/src/Header/HeaderBackButton.tsx
@@ -30,7 +30,7 @@ export default function HeaderBackButton({
titleLayout,
truncatedLabel = 'Back',
accessibilityLabel = label && label !== 'Back' ? `${label}, back` : 'Go back',
- testID,
+ testID = 'header-back',
style,
}: HeaderBackButtonProps) {
const { colors } = useTheme();

View File

@ -1,16 +1,31 @@
/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions, react/prop-types */
import React from 'react';
import { storiesOf } from '@storybook/react-native';
import { View } from 'react-native';
import { SafeAreaView } from 'react-native';
import { Header, HeaderBackground } from '@react-navigation/elements';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import * as HeaderButton from '../../app/containers/HeaderButton';
import Header from '../../app/containers/Header';
import { ThemeContext } from '../../app/theme';
import { TColors, ThemeContext, TSupportedThemes } from '../../app/theme';
import { colors } from '../../app/lib/constants';
const stories = storiesOf('Header Buttons', module);
const stories = storiesOf('Header Buttons', module).addDecorator(story => <SafeAreaProvider>{story()}</SafeAreaProvider>);
const HeaderExample = ({ left, right }) => (
<Header headerLeft={left} headerTitle={() => <View style={{ flex: 1 }} />} headerRight={right} />
interface IHeader {
left?: () => React.ReactElement | null;
right?: () => React.ReactElement;
title?: string;
colors?: TColors;
}
const HeaderExample = ({ left, right, colors, title = '' }: IHeader) => (
<SafeAreaView>
<Header
title={title}
headerLeft={left}
headerRight={right}
headerBackground={() => <HeaderBackground style={{ backgroundColor: colors?.headerBackground }} />}
/>
</SafeAreaView>
);
stories.add('title', () => (
@ -89,8 +104,8 @@ stories.add('badge', () => (
</>
));
const ThemeStory = ({ theme }) => (
<ThemeContext.Provider value={{ theme }}>
const ThemeStory = ({ theme }: { theme: TSupportedThemes }) => (
<ThemeContext.Provider value={{ theme, colors: colors[theme] }}>
<HeaderExample
left={() => (
<HeaderButton.Container left>
@ -103,6 +118,7 @@ const ThemeStory = ({ theme }) => (
<HeaderButton.Item iconName='threads' badge={() => <HeaderButton.Badge tunread={[1]} />} />
</HeaderButton.Container>
)}
colors={colors[theme]}
/>
</ThemeContext.Provider>
);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long