Chore: Migrate CannedResponsesListView to Typescript (#3553)

* Chore: Migrate CannedResponsesListView to TS

* Moved IcannedResponse to definitions and fixed the index

* Chore: Migrate CannedResponseDetail to TS

* minor tweaks

* refactor: update new types and interfaces for use ISubscription

* fix lint error and canned responses's dropdown

Co-authored-by: AlexAlexandre <alexalexandrejr@gmail.com>
Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Reinaldo Neto 2022-02-04 19:15:01 -03:00 committed by GitHub
parent b95cad71eb
commit 6933278fd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 211 additions and 163 deletions

View File

@ -22,7 +22,7 @@ const styles = StyleSheet.create({
interface ISearchHeaderProps { interface ISearchHeaderProps {
onSearchChangeText?: (text: string) => void; onSearchChangeText?: (text: string) => void;
testID: string; testID?: string;
} }
const SearchHeader = ({ onSearchChangeText, testID }: ISearchHeaderProps): JSX.Element => { const SearchHeader = ({ onSearchChangeText, testID }: ISearchHeaderProps): JSX.Element => {

View File

@ -0,0 +1,31 @@
export interface IDepartment {
_id: string;
enabled: boolean;
name: string;
description: string;
showOnRegistration: boolean;
showOnOfflineForm: boolean;
requestTagBeforeClosingChat: boolean;
email: string;
chatClosingTags: string[];
offlineMessageChannelName: string;
maxNumberSimultaneousChat: number;
abandonedRoomsCloseCustomMessage: string;
waitingQueueMessage: string;
departmentsAllowedToForward: string;
_updatedAt: Date;
numAgents: number;
ancestors: string[];
}
export interface ICannedResponse {
_id: string;
shortcut: string;
text: string;
scope: string;
tags: string[];
createdBy: { _id: string; username: string };
userId: string;
scopeName: string;
departmentId?: string;
}

View File

@ -8,6 +8,7 @@ import { IServer } from '../definitions/IServer';
import { IAttachment } from '../definitions/IAttachment'; import { IAttachment } from '../definitions/IAttachment';
import { IMessage } from '../definitions/IMessage'; import { IMessage } from '../definitions/IMessage';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription'; import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
import { ICannedResponse } from '../definitions/ICannedResponse';
export type ChatsStackParamList = { export type ChatsStackParamList = {
RoomsListView: undefined; RoomsListView: undefined;
@ -137,12 +138,7 @@ export type ChatsStackParamList = {
rid: string; rid: string;
}; };
CannedResponseDetail: { CannedResponseDetail: {
cannedResponse: { cannedResponse: ICannedResponse;
shortcut: string;
text: string;
scopeName: string;
tags: string[];
};
room: ISubscription; room: ISubscription;
}; };
}; };

View File

@ -44,6 +44,7 @@ export const goRoom = async ({
isMasterDetail: boolean; isMasterDetail: boolean;
navigationMethod?: any; navigationMethod?: any;
jumpToMessageId?: string; jumpToMessageId?: string;
usedCannedResponse?: string;
}): Promise<void> => { }): Promise<void> => {
if (item.t === SubscriptionType.DIRECT && item?.search) { if (item.t === SubscriptionType.DIRECT && item?.search) {
// if user is using the search we need first to join/create room // if user is using the search we need first to join/create room
@ -54,7 +55,7 @@ export const goRoom = async ({
return navigate({ return navigate({
item: { item: {
rid: result.room._id, rid: result.room._id,
name: username, name: username || '',
t: SubscriptionType.DIRECT t: SubscriptionType.DIRECT
}, },
isMasterDetail, isMasterDetail,

View File

@ -1,5 +1,6 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import PropTypes from 'prop-types'; import { StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/native';
import { StyleSheet, Text, View, ScrollView } from 'react-native'; import { StyleSheet, Text, View, ScrollView } from 'react-native';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
@ -13,6 +14,8 @@ import Navigation from '../lib/Navigation';
import { goRoom } from '../utils/goRoom'; import { goRoom } from '../utils/goRoom';
import { themes } from '../constants/colors'; import { themes } from '../constants/colors';
import Markdown from '../containers/markdown'; import Markdown from '../containers/markdown';
import { ICannedResponse } from '../definitions/ICannedResponse';
import { ChatsStackParamList } from '../stacks/types';
import sharedStyles from './Styles'; import sharedStyles from './Styles';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -68,27 +71,34 @@ const styles = StyleSheet.create({
} }
}); });
const Item = ({ label, content, theme, testID }) => interface IItem {
label: string;
content?: string;
theme: string;
testID?: string;
}
const Item = ({ label, content, theme, testID }: IItem) =>
content ? ( content ? (
<View style={styles.item} testID={testID}> <View style={styles.item} testID={testID}>
<Text accessibilityLabel={label} style={[styles.itemLabel, { color: themes[theme].titleText }]}> <Text accessibilityLabel={label} style={[styles.itemLabel, { color: themes[theme].titleText }]}>
{label} {label}
</Text> </Text>
{/* @ts-ignore */}
<Markdown style={[styles.itemContent, { color: themes[theme].auxiliaryText }]} msg={content} theme={theme} /> <Markdown style={[styles.itemContent, { color: themes[theme].auxiliaryText }]} msg={content} theme={theme} />
</View> </View>
) : null; ) : null;
Item.propTypes = {
label: PropTypes.string,
content: PropTypes.string,
theme: PropTypes.string,
testID: PropTypes.string
};
const CannedResponseDetail = ({ navigation, route }) => { interface ICannedResponseDetailProps {
navigation: StackNavigationProp<ChatsStackParamList, 'CannedResponseDetail'>;
route: RouteProp<ChatsStackParamList, 'CannedResponseDetail'>;
}
const CannedResponseDetail = ({ navigation, route }: ICannedResponseDetailProps): JSX.Element => {
const { cannedResponse } = route?.params; const { cannedResponse } = route?.params;
const { theme } = useTheme(); const { theme } = useTheme();
const { isMasterDetail } = useSelector(state => state.app); const { isMasterDetail } = useSelector((state: any) => state.app);
const { rooms } = useSelector(state => state.room); const { rooms } = useSelector((state: any) => state.room);
useEffect(() => { useEffect(() => {
navigation.setOptions({ navigation.setOptions({
@ -96,15 +106,14 @@ const CannedResponseDetail = ({ navigation, route }) => {
}); });
}, []); }, []);
const navigateToRoom = item => { const navigateToRoom = (item: ICannedResponse) => {
const { room } = route.params; const { room } = route.params;
const { name, username } = room; const { name } = room;
const params = { const params = {
rid: room.rid, rid: room.rid,
name: RocketChat.getRoomTitle({ name: RocketChat.getRoomTitle({
t: room.t, t: room.t,
fname: name, fname: name
name: username
}), }),
t: room.t, t: room.t,
roomUserId: RocketChat.getUidDirectMessage(room), roomUserId: RocketChat.getUidDirectMessage(room),
@ -115,7 +124,7 @@ const CannedResponseDetail = ({ navigation, route }) => {
// if it's on master detail layout, we close the modal and replace RoomView // if it's on master detail layout, we close the modal and replace RoomView
if (isMasterDetail) { if (isMasterDetail) {
Navigation.navigate('DrawerNavigator'); Navigation.navigate('DrawerNavigator');
goRoom({ item: params, isMasterDetail, usedCannedResponse: item.text }); goRoom({ item: params, isMasterDetail });
} else { } else {
let navigate = navigation.push; let navigate = navigation.push;
// if this is a room focused // if this is a room focused
@ -163,9 +172,4 @@ const CannedResponseDetail = ({ navigation, route }) => {
); );
}; };
CannedResponseDetail.propTypes = {
navigation: PropTypes.object,
route: PropTypes.object
};
export default CannedResponseDetail; export default CannedResponseDetail;

View File

@ -1,14 +1,31 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { View, Text } from 'react-native'; import { View, Text } from 'react-native';
import Touchable from 'react-native-platform-touchable'; import Touchable from 'react-native-platform-touchable';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import Button from '../../containers/Button'; import Button from '../../containers/Button';
import I18n from '../../i18n'; import I18n from '../../i18n';
import styles from './styles'; import styles from './styles';
const CannedResponseItem = ({ theme, onPressDetail, shortcut, scope, onPressUse, text, tags }) => ( interface ICannedResponseItem {
theme: string;
onPressDetail: () => void;
shortcut: string;
scope: string;
onPressUse: () => void;
text: string;
tags: string[];
}
const CannedResponseItem = ({
theme,
onPressDetail = () => {},
shortcut,
scope,
onPressUse = () => {},
text,
tags
}: ICannedResponseItem): JSX.Element => (
<Touchable onPress={onPressDetail} style={[styles.wrapCannedItem, { backgroundColor: themes[theme].messageboxBackground }]}> <Touchable onPress={onPressDetail} style={[styles.wrapCannedItem, { backgroundColor: themes[theme].messageboxBackground }]}>
<> <>
<View style={styles.cannedRow}> <View style={styles.cannedRow}>
@ -43,19 +60,4 @@ const CannedResponseItem = ({ theme, onPressDetail, shortcut, scope, onPressUse,
</Touchable> </Touchable>
); );
CannedResponseItem.propTypes = {
theme: PropTypes.string,
onPressDetail: PropTypes.func,
shortcut: PropTypes.string,
scope: PropTypes.string,
onPressUse: PropTypes.func,
text: PropTypes.string,
tags: PropTypes.array
};
CannedResponseItem.defaultProps = {
onPressDetail: () => {},
onPressUse: () => {}
};
export default CannedResponseItem; export default CannedResponseItem;

View File

@ -1,44 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, Text, View } from 'react-native';
import { themes } from '../../../constants/colors';
import { withTheme } from '../../../theme';
import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons';
import sharedStyles from '../../Styles';
export const ROW_HEIGHT = 44;
const styles = StyleSheet.create({
container: {
paddingVertical: 11,
height: ROW_HEIGHT,
paddingHorizontal: 16,
flexDirection: 'row',
alignItems: 'center'
},
text: {
flex: 1,
fontSize: 16,
...sharedStyles.textRegular
}
});
const DropdownItem = React.memo(({ theme, onPress, iconName, text }) => (
<Touch theme={theme} onPress={onPress} style={{ backgroundColor: themes[theme].backgroundColor }}>
<View style={styles.container}>
<Text style={[styles.text, { color: themes[theme].auxiliaryText }]}>{text}</Text>
{iconName ? <CustomIcon name={iconName} size={22} color={themes[theme].auxiliaryText} /> : null}
</View>
</Touch>
));
DropdownItem.propTypes = {
text: PropTypes.string,
iconName: PropTypes.string,
theme: PropTypes.string,
onPress: PropTypes.func
};
export default withTheme(DropdownItem);

View File

@ -0,0 +1,46 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons';
import sharedStyles from '../../Styles';
export const ROW_HEIGHT = 44;
const styles = StyleSheet.create({
container: {
paddingVertical: 11,
height: ROW_HEIGHT,
paddingHorizontal: 16,
flexDirection: 'row',
alignItems: 'center'
},
text: {
flex: 1,
fontSize: 16,
...sharedStyles.textRegular
}
});
interface IDropdownItem {
text: string;
iconName: string | null;
onPress: () => void;
}
const DropdownItem = React.memo(({ onPress, iconName, text }: IDropdownItem) => {
const { theme } = useTheme();
return (
<Touch theme={theme} onPress={onPress} style={{ backgroundColor: themes[theme].backgroundColor }}>
<View style={styles.container}>
<Text style={[styles.text, { color: themes[theme].auxiliaryText }]}>{text}</Text>
{iconName ? <CustomIcon name={iconName} size={22} color={themes[theme].auxiliaryText} /> : null}
</View>
</Touch>
);
});
export default DropdownItem;

View File

@ -1,9 +1,15 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { IDepartment } from '../../../definitions/ICannedResponse';
import DropdownItem from './DropdownItem'; import DropdownItem from './DropdownItem';
const DropdownItemFilter = ({ currentDepartment, value, onPress }) => ( interface IDropdownItemFilter {
currentDepartment: IDepartment;
value: IDepartment;
onPress: (value: IDepartment) => void;
}
const DropdownItemFilter = ({ currentDepartment, value, onPress }: IDropdownItemFilter): JSX.Element => (
<DropdownItem <DropdownItem
text={value?.name} text={value?.name}
iconName={currentDepartment?._id === value?._id ? 'check' : null} iconName={currentDepartment?._id === value?._id ? 'check' : null}
@ -11,10 +17,4 @@ const DropdownItemFilter = ({ currentDepartment, value, onPress }) => (
/> />
); );
DropdownItemFilter.propTypes = {
currentDepartment: PropTypes.object,
value: PropTypes.string,
onPress: PropTypes.func
};
export default DropdownItemFilter; export default DropdownItemFilter;

View File

@ -1,15 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import DropdownItem from './DropdownItem';
const DropdownItemHeader = ({ department, onPress }) => (
<DropdownItem text={department?.name} iconName='filter' onPress={onPress} />
);
DropdownItemHeader.propTypes = {
department: PropTypes.object,
onPress: PropTypes.func
};
export default DropdownItemHeader;

View File

@ -0,0 +1,15 @@
import React from 'react';
import { IDepartment } from '../../../definitions/ICannedResponse';
import DropdownItem from './DropdownItem';
interface IDropdownItemHeader {
department: IDepartment;
onPress: () => void;
}
const DropdownItemHeader = ({ department, onPress }: IDropdownItemHeader): JSX.Element => (
<DropdownItem text={department?.name} iconName='filter' onPress={onPress} />
);
export default DropdownItemHeader;

View File

@ -1,31 +1,30 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { Animated, Easing, FlatList, TouchableWithoutFeedback } from 'react-native'; import { Animated, Easing, FlatList, TouchableWithoutFeedback } from 'react-native';
import { withSafeAreaInsets } from 'react-native-safe-area-context'; import { withSafeAreaInsets } from 'react-native-safe-area-context';
import styles from '../styles'; import styles from '../styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { withTheme } from '../../../theme'; import { withTheme } from '../../../theme';
import { headerHeight } from '../../../containers/Header';
import * as List from '../../../containers/List'; import * as List from '../../../containers/List';
import { IDepartment } from '../../../definitions/ICannedResponse';
import DropdownItemFilter from './DropdownItemFilter'; import DropdownItemFilter from './DropdownItemFilter';
import DropdownItemHeader from './DropdownItemHeader'; import DropdownItemHeader from './DropdownItemHeader';
import { ROW_HEIGHT } from './DropdownItem'; import { ROW_HEIGHT } from './DropdownItem';
const ANIMATION_DURATION = 200; const ANIMATION_DURATION = 200;
class Dropdown extends React.Component { interface IDropdownProps {
static propTypes = { theme?: string;
isMasterDetail: PropTypes.bool, currentDepartment: IDepartment;
theme: PropTypes.string, onClose: () => void;
insets: PropTypes.object, onDepartmentSelected: (value: IDepartment) => void;
currentDepartment: PropTypes.object, departments: IDepartment[];
onClose: PropTypes.func, }
onDepartmentSelected: PropTypes.func,
departments: PropTypes.array
};
constructor(props) { class Dropdown extends React.Component<IDropdownProps> {
private animatedValue: Animated.Value;
constructor(props: IDropdownProps) {
super(props); super(props);
this.animatedValue = new Animated.Value(0); this.animatedValue = new Animated.Value(0);
} }
@ -50,16 +49,15 @@ class Dropdown extends React.Component {
}; };
render() { render() {
const { isMasterDetail, insets, theme, currentDepartment, onDepartmentSelected, departments } = this.props; const { theme, currentDepartment, onDepartmentSelected, departments } = this.props;
const statusBarHeight = insets?.top ?? 0; const heightDestination = 0;
const heightDestination = isMasterDetail ? headerHeight + statusBarHeight : 0;
const translateY = this.animatedValue.interpolate({ const translateY = this.animatedValue.interpolate({
inputRange: [0, 1], inputRange: [0, 1],
outputRange: [-300, heightDestination] // approximated height of the component when closed/open outputRange: [-300, heightDestination] // approximated height of the component when closed/open
}); });
const backdropOpacity = this.animatedValue.interpolate({ const backdropOpacity = this.animatedValue.interpolate({
inputRange: [0, 1], inputRange: [0, 1],
outputRange: [0, themes[theme].backdropOpacity] outputRange: [0, themes[theme!].backdropOpacity]
}); });
const maxRows = 5; const maxRows = 5;
@ -70,7 +68,7 @@ class Dropdown extends React.Component {
style={[ style={[
styles.backdrop, styles.backdrop,
{ {
backgroundColor: themes[theme].backdropColor, backgroundColor: themes[theme!].backdropColor,
opacity: backdropOpacity, opacity: backdropOpacity,
top: heightDestination top: heightDestination
} }
@ -82,8 +80,8 @@ class Dropdown extends React.Component {
styles.dropdownContainer, styles.dropdownContainer,
{ {
transform: [{ translateY }], transform: [{ translateY }],
backgroundColor: themes[theme].backgroundColor, backgroundColor: themes[theme!].backgroundColor,
borderColor: themes[theme].separatorColor borderColor: themes[theme!].separatorColor
} }
]}> ]}>
<DropdownItemHeader department={currentDepartment} onPress={this.close} /> <DropdownItemHeader department={currentDepartment} onPress={this.close} />

View File

@ -1,9 +1,9 @@
import React, { useEffect, useState, useCallback } from 'react'; import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { FlatList } from 'react-native'; import { FlatList } from 'react-native';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { HeaderBackButton } from '@react-navigation/stack'; import { RouteProp } from '@react-navigation/native';
import { HeaderBackButton, StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack';
import database from '../../lib/database'; import database from '../../lib/database';
import I18n from '../../i18n'; import I18n from '../../i18n';
@ -26,6 +26,9 @@ import CannedResponseItem from './CannedResponseItem';
import Dropdown from './Dropdown'; import Dropdown from './Dropdown';
import DropdownItemHeader from './Dropdown/DropdownItemHeader'; import DropdownItemHeader from './Dropdown/DropdownItemHeader';
import styles from './styles'; import styles from './styles';
import { ICannedResponse, IDepartment } from '../../definitions/ICannedResponse';
import { ChatsStackParamList } from '../../stacks/types';
import { ISubscription } from '../../definitions/ISubscription';
const COUNT = 25; const COUNT = 25;
@ -42,14 +45,19 @@ const fixedScopes = [
_id: 'user', _id: 'user',
name: I18n.t('Private') name: I18n.t('Private')
} }
]; ] as IDepartment[];
const CannedResponsesListView = ({ navigation, route }) => { interface ICannedResponsesListViewProps {
const [room, setRoom] = useState(null); navigation: StackNavigationProp<ChatsStackParamList, 'CannedResponsesListView'>;
route: RouteProp<ChatsStackParamList, 'CannedResponsesListView'>;
}
const [cannedResponses, setCannedResponses] = useState([]); const CannedResponsesListView = ({ navigation, route }: ICannedResponsesListViewProps): JSX.Element => {
const [cannedResponsesScopeName, setCannedResponsesScopeName] = useState([]); const [room, setRoom] = useState<ISubscription | null>(null);
const [departments, setDepartments] = useState([]);
const [cannedResponses, setCannedResponses] = useState<ICannedResponse[]>([]);
const [cannedResponsesScopeName, setCannedResponsesScopeName] = useState<ICannedResponse[]>([]);
const [departments, setDepartments] = useState<IDepartment[]>([]);
// states used by the filter in Header and Dropdown // states used by the filter in Header and Dropdown
const [isSearching, setIsSearching] = useState(false); const [isSearching, setIsSearching] = useState(false);
@ -65,8 +73,8 @@ const CannedResponsesListView = ({ navigation, route }) => {
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const { theme } = useTheme(); const { theme } = useTheme();
const { isMasterDetail } = useSelector(state => state.app); const { isMasterDetail } = useSelector((state: any) => state.app);
const { rooms } = useSelector(state => state.room); const { rooms } = useSelector((state: any) => state.room);
const getRoomFromDb = async () => { const getRoomFromDb = async () => {
const { rid } = route.params; const { rid } = route.params;
@ -93,21 +101,22 @@ const CannedResponsesListView = ({ navigation, route }) => {
} }
}, 300); }, 300);
const goToDetail = item => { const goToDetail = (item: ICannedResponse) => {
navigation.navigate('CannedResponseDetail', { cannedResponse: item, room }); if (room) {
navigation.navigate('CannedResponseDetail', { cannedResponse: item, room });
}
}; };
const navigateToRoom = item => { const navigateToRoom = (item: ICannedResponse) => {
if (!room) { if (!room) {
return; return;
} }
const { name, username } = room; const { name } = room;
const params = { const params = {
rid: room.rid, rid: room.rid,
name: RocketChat.getRoomTitle({ name: RocketChat.getRoomTitle({
t: room.t, t: room.t,
fname: name, fname: name
name: username
}), }),
t: room.t, t: room.t,
roomUserId: RocketChat.getUidDirectMessage(room), roomUserId: RocketChat.getUidDirectMessage(room),
@ -118,7 +127,7 @@ const CannedResponsesListView = ({ navigation, route }) => {
// if it's on master detail layout, we close the modal and replace RoomView // if it's on master detail layout, we close the modal and replace RoomView
if (isMasterDetail) { if (isMasterDetail) {
Navigation.navigate('DrawerNavigator'); Navigation.navigate('DrawerNavigator');
goRoom({ item: params, isMasterDetail, usedCannedResponse: item.text }); goRoom({ item: params, isMasterDetail });
} else { } else {
let navigate = navigation.push; let navigate = navigation.push;
// if this is a room focused // if this is a room focused
@ -130,7 +139,17 @@ const CannedResponsesListView = ({ navigation, route }) => {
} }
}; };
const getListCannedResponse = async ({ text, department, depId, debounced }) => { const getListCannedResponse = async ({
text,
department,
depId,
debounced
}: {
text: string;
department: string;
depId: string;
debounced: boolean;
}) => {
try { try {
const res = await RocketChat.getListCannedResponse({ const res = await RocketChat.getListCannedResponse({
text, text,
@ -188,13 +207,13 @@ const CannedResponsesListView = ({ navigation, route }) => {
setOffset(0); setOffset(0);
}; };
const onChangeText = text => { const onChangeText = (text: string) => {
newSearch(); newSearch();
setSearchText(text); setSearchText(text);
searchCallback(text, scope, departmentId); searchCallback(text, scope, departmentId);
}; };
const onDepartmentSelect = value => { const onDepartmentSelect = (value: IDepartment) => {
let department = ''; let department = '';
let depId = ''; let depId = '';
@ -225,7 +244,7 @@ const CannedResponsesListView = ({ navigation, route }) => {
await getListCannedResponse({ text: searchText, department: scope, depId: departmentId, debounced: false }); await getListCannedResponse({ text: searchText, department: scope, depId: departmentId, debounced: false });
}; };
const getHeader = () => { const getHeader = (): StackNavigationOptions => {
if (isSearching) { if (isSearching) {
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 }); const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: 1 });
return { return {
@ -235,7 +254,7 @@ const CannedResponsesListView = ({ navigation, route }) => {
<HeaderButton.Item <HeaderButton.Item
iconName='close' iconName='close'
onPress={() => { onPress={() => {
onChangeText(); onChangeText('');
setIsSearching(false); setIsSearching(false);
}} }}
/> />
@ -250,7 +269,7 @@ const CannedResponsesListView = ({ navigation, route }) => {
}; };
} }
const options = { const options: StackNavigationOptions = {
headerLeft: () => ( headerLeft: () => (
<HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={themes[theme].headerTintColor} /> <HeaderBackButton labelVisible={false} onPress={() => navigation.pop()} tintColor={themes[theme].headerTintColor} />
), ),
@ -355,9 +374,4 @@ const CannedResponsesListView = ({ navigation, route }) => {
); );
}; };
CannedResponsesListView.propTypes = {
navigation: PropTypes.object,
route: PropTypes.object
};
export default CannedResponsesListView; export default CannedResponsesListView;

View File

@ -13,7 +13,7 @@ export default StyleSheet.create({
borderBottomWidth: StyleSheet.hairlineWidth borderBottomWidth: StyleSheet.hairlineWidth
}, },
backdrop: { backdrop: {
...StyleSheet.absoluteFill ...StyleSheet.absoluteFillObject
}, },
wrapCannedItem: { wrapCannedItem: {
minHeight: 117, minHeight: 117,