chore: migrate PickerView to hooks (#5002)

* migrate ForwardLivechatView to hooks and fix some types

* fix types

* fix types

* remove useless memo

* change to useDebounce

* fix types
This commit is contained in:
Gleidson Daniel Silva 2023-06-30 11:01:01 -03:00 committed by GitHub
parent d30d4645a5
commit fea4f164d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 168 additions and 246 deletions

View File

@ -2,37 +2,40 @@ import { RouteProp } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { TNavigation } from '../stacks/stackType';
import { TColors, TSupportedThemes } from '../theme'; import { TColors, TSupportedThemes } from '../theme';
export * from './ERoomType';
export * from './IAttachment'; export * from './IAttachment';
export * from './INotification';
export * from './IPreferences';
export * from './ISubscription';
export * from './IRoom';
export * from './IMessage';
export * from './IThread';
export * from './IThreadMessage';
export * from './IEmoji';
export * from './IUpload';
export * from './ISettings';
export * from './IRole';
export * from './IPermission';
export * from './ISlashCommand';
export * from './IUser';
export * from './IServer';
export * from './ILoggedUser';
export * from './IServerHistory';
export * from './ICertificate'; export * from './ICertificate';
export * from './IUrl';
export * from './ICredentials'; export * from './ICredentials';
export * from './ISearch'; export * from './IEmoji';
export * from './TUserStatus'; export * from './ILoggedUser';
export * from './IMessage';
export * from './INotification';
export * from './IPermission';
export * from './IPreferences';
export * from './IProfile'; export * from './IProfile';
export * from './IReaction'; export * from './IReaction';
export * from './ERoomType'; export * from './IRole';
export * from './IRoom';
export * from './ISearch';
export * from './IServer';
export * from './IServerHistory';
export * from './ISettings';
export * from './ISlashCommand';
export * from './ISubscription';
export * from './IThread';
export * from './IThreadMessage';
export * from './IUpload';
export * from './IUrl';
export * from './IUser';
export * from './redux';
export * from './redux/TRootEnum';
export * from './TUserStatus';
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> { export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
navigation: StackNavigationProp<T, S>; navigation: StackNavigationProp<T & TNavigation, S>;
route: RouteProp<T, S>; route: RouteProp<T, S>;
dispatch: Dispatch; dispatch: Dispatch;
isMasterDetail: boolean; isMasterDetail: boolean;
@ -40,6 +43,3 @@ export interface IBaseScreen<T extends Record<string, object | undefined>, S ext
theme?: TSupportedThemes; theme?: TSupportedThemes;
colors: TColors; colors: TColors;
} }
export * from './redux';
export * from './redux/TRootEnum';

View File

@ -85,7 +85,7 @@ import { isIOS } from '../lib/methods/helpers';
import { TNavigation } from './stackType'; import { TNavigation } from './stackType';
// ChatsStackNavigator // ChatsStackNavigator
const ChatsStack = createStackNavigator<ChatsStackParamList>(); const ChatsStack = createStackNavigator<ChatsStackParamList & TNavigation>();
const ChatsStackNavigator = () => { const ChatsStackNavigator = () => {
const { theme } = React.useContext(ThemeContext); const { theme } = React.useContext(ThemeContext);
return ( return (
@ -122,14 +122,9 @@ const ChatsStackNavigator = () => {
<ChatsStack.Screen name='CloseLivechatView' component={CloseLivechatView} /> <ChatsStack.Screen name='CloseLivechatView' component={CloseLivechatView} />
{/* @ts-ignore */} {/* @ts-ignore */}
<ChatsStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} /> <ChatsStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
<ChatsStack.Screen name='PickerView' component={PickerView} />
{/* @ts-ignore */} {/* @ts-ignore */}
<ChatsStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} /> <ChatsStack.Screen name='ThreadMessagesView' component={ThreadMessagesView} />
<ChatsStack.Screen
name='ThreadMessagesView'
// @ts-ignore
component={ThreadMessagesView}
options={ThreadMessagesView.navigationOptions}
/>
<ChatsStack.Screen name='TeamChannelsView' component={TeamChannelsView} /> <ChatsStack.Screen name='TeamChannelsView' component={TeamChannelsView} />
<ChatsStack.Screen name='CreateChannelView' component={CreateChannelView} /> <ChatsStack.Screen name='CreateChannelView' component={CreateChannelView} />
<ChatsStack.Screen name='AddChannelTeamView' component={AddChannelTeamView} /> <ChatsStack.Screen name='AddChannelTeamView' component={AddChannelTeamView} />
@ -156,7 +151,7 @@ const ChatsStackNavigator = () => {
}; };
// ProfileStackNavigator // ProfileStackNavigator
const ProfileStack = createStackNavigator<ProfileStackParamList>(); const ProfileStack = createStackNavigator<ProfileStackParamList & TNavigation>();
const ProfileStackNavigator = () => { const ProfileStackNavigator = () => {
const { theme } = React.useContext(ThemeContext); const { theme } = React.useContext(ThemeContext);
return ( return (
@ -167,8 +162,7 @@ const ProfileStackNavigator = () => {
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} /> <ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
<ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} /> <ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
<ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} /> <ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
{/* @ts-ignore */} <ProfileStack.Screen name='PickerView' component={PickerView} />
<ProfileStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} />
</ProfileStack.Navigator> </ProfileStack.Navigator>
); );
}; };

View File

@ -104,7 +104,7 @@ export interface INavigation {
navigation: StackNavigationProp<ModalStackParamList>; navigation: StackNavigationProp<ModalStackParamList>;
} }
const ModalStack = createStackNavigator<ModalStackParamList>(); const ModalStack = createStackNavigator<ModalStackParamList & TNavigation>();
const ModalStackNavigator = React.memo(({ navigation }: INavigation) => { const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
const { theme } = React.useContext(ThemeContext); const { theme } = React.useContext(ThemeContext);
return ( return (
@ -155,8 +155,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
<ModalStack.Screen name='CannedResponseDetail' component={CannedResponseDetail} /> <ModalStack.Screen name='CannedResponseDetail' component={CannedResponseDetail} />
{/* @ts-ignore */} {/* @ts-ignore */}
<ModalStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} /> <ModalStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
{/* @ts-ignore */} <ModalStack.Screen name='PickerView' component={PickerView} />
<ModalStack.Screen name='PickerView' component={PickerView} options={PickerView.navigationOptions} />
{/* @ts-ignore */} {/* @ts-ignore */}
<ModalStack.Screen name='ThreadMessagesView' component={ThreadMessagesView} /> <ModalStack.Screen name='ThreadMessagesView' component={ThreadMessagesView} />
{/* @ts-ignore */} {/* @ts-ignore */}

View File

@ -1,12 +1,11 @@
import { TextInputProps } from 'react-native';
import { NavigatorScreenParams } from '@react-navigation/core'; import { NavigatorScreenParams } from '@react-navigation/core';
import { TServerModel, TThreadModel } from '../../definitions';
import { IAttachment } from '../../definitions/IAttachment'; import { IAttachment } from '../../definitions/IAttachment';
import { IMessage } from '../../definitions/IMessage';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../../definitions/ISubscription';
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment'; import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
import { ILivechatTag } from '../../definitions/ILivechatTag'; import { ILivechatTag } from '../../definitions/ILivechatTag';
import { TServerModel, TThreadModel } from '../../definitions'; import { IMessage } from '../../definitions/IMessage';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../../definitions/ISubscription';
import { TChangeAvatarViewContext } from '../../definitions/TChangeAvatarViewContext'; import { TChangeAvatarViewContext } from '../../definitions/TChangeAvatarViewContext';
export type MasterDetailChatsStackParamList = { export type MasterDetailChatsStackParamList = {
@ -119,9 +118,6 @@ export type ModalStackParamList = {
rid: string; rid: string;
room: ISubscription; room: ISubscription;
}; };
ForwardLivechatView: {
rid: string;
};
CloseLivechatView: { CloseLivechatView: {
rid: string; rid: string;
departmentId?: string; departmentId?: string;
@ -144,14 +140,6 @@ export type ModalStackParamList = {
room: ISubscription; room: ISubscription;
roomUser: any; // TODO: Change roomUser: any; // TODO: Change
}; };
PickerView: {
title: string;
data: []; // TODO: Change
value: any; // TODO: Change
onChangeText: TextInputProps['onChangeText'];
goBack: Function;
onChangeValue: Function;
};
ThreadMessagesView: { ThreadMessagesView: {
rid: string; rid: string;
t: SubscriptionType; t: SubscriptionType;

View File

@ -1,19 +1,18 @@
import { NavigatorScreenParams } from '@react-navigation/core'; import { NavigatorScreenParams } from '@react-navigation/core';
import { TextInputProps } from 'react-native';
import { IItem } from '../views/TeamChannelsView'; import { TThreadModel } from '../definitions';
import { IOptionsField } from '../views/NotificationPreferencesView/options';
import { TServerModel } from '../definitions/IServer';
import { IAttachment } from '../definitions/IAttachment'; import { IAttachment } from '../definitions/IAttachment';
import { IMessage, TAnyMessageModel, TMessageModel } from '../definitions/IMessage';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
import { ICannedResponse } from '../definitions/ICannedResponse'; import { ICannedResponse } from '../definitions/ICannedResponse';
import { TDataSelect } from '../definitions/IDataSelect'; import { TDataSelect } from '../definitions/IDataSelect';
import { MasterDetailInsideStackParamList, ModalStackParamList } from './MasterDetailStack/types';
import { TThreadModel } from '../definitions';
import { ILivechatDepartment } from '../definitions/ILivechatDepartment'; import { ILivechatDepartment } from '../definitions/ILivechatDepartment';
import { ILivechatTag } from '../definitions/ILivechatTag'; import { ILivechatTag } from '../definitions/ILivechatTag';
import { IMessage, TAnyMessageModel, TMessageModel } from '../definitions/IMessage';
import { TServerModel } from '../definitions/IServer';
import { ISubscription, SubscriptionType, TSubscriptionModel } from '../definitions/ISubscription';
import { TChangeAvatarViewContext } from '../definitions/TChangeAvatarViewContext'; import { TChangeAvatarViewContext } from '../definitions/TChangeAvatarViewContext';
import { IItem } from '../views/TeamChannelsView';
import { MasterDetailInsideStackParamList, ModalStackParamList } from './MasterDetailStack/types';
import { TNavigation } from './stackType';
export type SetUsernameStackParamList = { export type SetUsernameStackParamList = {
SetUsernameView: { SetUsernameView: {
@ -30,7 +29,7 @@ export type StackParamList = {
}; };
export type ChatsStackParamList = { export type ChatsStackParamList = {
ModalStackNavigator: NavigatorScreenParams<ModalStackParamList>; ModalStackNavigator: NavigatorScreenParams<ModalStackParamList & TNavigation>;
E2ESaveYourPasswordStackNavigator: NavigatorScreenParams<E2ESaveYourPasswordStackParamList>; E2ESaveYourPasswordStackNavigator: NavigatorScreenParams<E2ESaveYourPasswordStackParamList>;
E2EEnterYourPasswordStackNavigator: NavigatorScreenParams<E2EEnterYourPasswordStackParamList>; E2EEnterYourPasswordStackNavigator: NavigatorScreenParams<E2EEnterYourPasswordStackParamList>;
SettingsView: any; SettingsView: any;
@ -132,9 +131,6 @@ export type ChatsStackParamList = {
rid: string; rid: string;
room: TSubscriptionModel; room: TSubscriptionModel;
}; };
ForwardLivechatView: {
rid: string;
};
CloseLivechatView: { CloseLivechatView: {
rid: string; rid: string;
departmentId?: string; departmentId?: string;
@ -145,16 +141,6 @@ export type ChatsStackParamList = {
room: ISubscription; room: ISubscription;
roomUser?: any; // TODO: Change roomUser?: any; // TODO: Change
}; };
PickerView: {
title: string;
data: IOptionsField[];
value?: string;
onSearch?: (text?: string) => Promise<any>;
onEndReached?: (text: string, offset?: number) => Promise<any>;
total?: number;
goBack?: boolean;
onChangeValue: Function;
};
ThreadMessagesView: { ThreadMessagesView: {
rid: string; rid: string;
t: SubscriptionType; t: SubscriptionType;
@ -208,14 +194,6 @@ export type ProfileStackParamList = {
ProfileView: undefined; ProfileView: undefined;
UserPreferencesView: undefined; UserPreferencesView: undefined;
UserNotificationPrefView: undefined; UserNotificationPrefView: undefined;
PickerView: {
title: string;
data: IOptionsField[];
value: any; // TODO: Change
onChangeText?: TextInputProps['onChangeText'];
goBack?: Function;
onChangeValue: Function;
};
ChangeAvatarView: { ChangeAvatarView: {
context: TChangeAvatarViewContext; context: TChangeAvatarViewContext;
titleHeader?: string; titleHeader?: string;

View File

@ -6,12 +6,13 @@ import { useDispatch } from 'react-redux';
import { forwardRoom, ITransferData } from '../actions/room'; import { forwardRoom, ITransferData } from '../actions/room';
import OrSeparator from '../containers/OrSeparator'; import OrSeparator from '../containers/OrSeparator';
import Input from '../containers/UIKit/MultiSelect/Input'; import Input from '../containers/UIKit/MultiSelect/Input';
import { IBaseScreen, IServerRoom } from '../definitions'; import { IServerRoom } from '../definitions';
import I18n from '../i18n'; import I18n from '../i18n';
import { ChatsStackParamList } from '../stacks/types'; import { useAppNavigation, useAppRoute } from '../lib/hooks/navigation';
import { Services } from '../lib/services';
import { TNavigation } from '../stacks/stackType';
import { useTheme } from '../theme'; import { useTheme } from '../theme';
import { IOptionsField } from './NotificationPreferencesView/options'; import { IOptionsField } from './NotificationPreferencesView/options';
import { Services } from '../lib/services';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -20,15 +21,14 @@ const styles = StyleSheet.create({
} }
}); });
interface IParsedData {
label: string;
value: string;
}
const COUNT_DEPARTMENT = 50; const COUNT_DEPARTMENT = 50;
const ForwardLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamList, 'ForwardLivechatView'>) => { const ForwardLivechatView = (): React.ReactElement => {
const [departments, setDepartments] = useState<IParsedData[]>([]); const { navigate, setOptions } = useAppNavigation<TNavigation, 'PickerView'>();
const {
params: { rid }
} = useAppRoute<TNavigation, 'ForwardLivechatView'>();
const [departments, setDepartments] = useState<IOptionsField[]>([]);
const [departmentId, setDepartment] = useState(''); const [departmentId, setDepartment] = useState('');
const [departmentTotal, setDepartmentTotal] = useState(0); const [departmentTotal, setDepartmentTotal] = useState(0);
const [users, setUsers] = useState<IOptionsField[]>([]); const [users, setUsers] = useState<IOptionsField[]>([]);
@ -37,8 +37,6 @@ const ForwardLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamL
const dispatch = useDispatch(); const dispatch = useDispatch();
const { theme, colors } = useTheme(); const { theme, colors } = useTheme();
const rid = route.params?.rid;
const getDepartments = async (text = '', offset = 0) => { const getDepartments = async (text = '', offset = 0) => {
try { try {
const result = await Services.getDepartments({ count: COUNT_DEPARTMENT, text, offset }); const result = await Services.getDepartments({ count: COUNT_DEPARTMENT, text, offset });
@ -106,7 +104,7 @@ const ForwardLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamL
}; };
useEffect(() => { useEffect(() => {
navigation.setOptions({ setOptions({
title: I18n.t('Forward_Chat') title: I18n.t('Forward_Chat')
}); });
getRoom(); getRoom();
@ -126,25 +124,23 @@ const ForwardLivechatView = ({ navigation, route }: IBaseScreen<ChatsStackParamL
}, [departmentId, userId]); }, [departmentId, userId]);
const onPressDepartment = () => { const onPressDepartment = () => {
navigation.navigate('PickerView', { navigate('PickerView', {
title: I18n.t('Forward_to_department'), title: I18n.t('Forward_to_department'),
value: room?.departmentId, value: room?.departmentId,
data: departments, data: departments,
onChangeValue: setDepartment, onChangeValue: setDepartment,
onSearch: getDepartments, onSearch: getDepartments,
onEndReached: getDepartments, onEndReached: getDepartments,
total: departmentTotal, total: departmentTotal
goBack: false
}); });
}; };
const onPressUser = () => { const onPressUser = () => {
navigation.navigate('PickerView', { navigate('PickerView', {
title: I18n.t('Forward_to_user'), title: I18n.t('Forward_to_user'),
data: users, data: users,
onChangeValue: setUser, onChangeValue: setUser,
onSearch: getUsers, onSearch: getUsers
goBack: false
}); });
}; };

View File

@ -1,17 +1,16 @@
import React from 'react'; import React, { useLayoutEffect, useState } from 'react';
import { FlatList, StyleSheet, Text } from 'react-native'; import { FlatList, StyleSheet, Text, TextInputProps } from 'react-native';
import { IBaseScreen } from '../definitions';
import I18n from '../i18n';
import { TSupportedThemes, withTheme } from '../theme';
import { themes } from '../lib/constants';
import { debounce } from '../lib/methods/helpers';
import * as List from '../containers/List'; import * as List from '../containers/List';
import SearchBox from '../containers/SearchBox';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import sharedStyles from './Styles'; import SearchBox from '../containers/SearchBox';
import { ChatsStackParamList } from '../stacks/types'; import I18n from '../i18n';
import { useAppNavigation, useAppRoute } from '../lib/hooks/navigation';
import { useDebounce } from '../lib/methods/helpers';
import { TNavigation } from '../stacks/stackType';
import { useTheme } from '../theme';
import { IOptionsField } from './NotificationPreferencesView/options'; import { IOptionsField } from './NotificationPreferencesView/options';
import sharedStyles from './Styles';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
noResult: { noResult: {
@ -19,9 +18,6 @@ const styles = StyleSheet.create({
paddingVertical: 56, paddingVertical: 56,
...sharedStyles.textSemibold, ...sharedStyles.textSemibold,
...sharedStyles.textAlignCenter ...sharedStyles.textAlignCenter
},
listNoHeader: {
marginTop: 32
} }
}); });
@ -29,120 +25,91 @@ interface IItem {
item: IOptionsField; item: IOptionsField;
selected: boolean; selected: boolean;
onItemPress: () => void; onItemPress: () => void;
theme?: TSupportedThemes;
} }
interface IRenderSearch { const Item = ({ item, selected, onItemPress }: IItem) => {
hasSearch: boolean; const { colors } = useTheme();
onChangeText: (text: string) => void;
}
interface IPickerViewState {
data: IOptionsField[];
value: string;
total: number;
searchText: string;
}
type IPickerViewProps = IBaseScreen<ChatsStackParamList, 'PickerView'>;
const Item = React.memo(({ item, selected, onItemPress, theme }: IItem) => (
<List.Item
title={I18n.t(item.label, { defaultValue: item.label, second: item?.second })}
right={() => (selected ? <List.Icon name='check' color={themes[theme!].tintColor} /> : null)}
onPress={onItemPress}
translateTitle={false}
/>
));
const RenderSearch = ({ hasSearch, onChangeText }: IRenderSearch) => {
if (!hasSearch) {
return <List.Separator style={styles.listNoHeader} />;
}
return ( return (
<> <List.Item
<SearchBox onChangeText={onChangeText} /> title={I18n.t(item.label, { defaultValue: item.label, second: item?.second })}
<List.Separator /> right={() => (selected ? <List.Icon name='check' color={colors.tintColor} /> : null)}
</> onPress={onItemPress}
translateTitle={false}
/>
); );
}; };
class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState> { const RenderSearch = ({ onChangeText }: TextInputProps) => (
private onSearch?: (text?: string) => Promise<any>; <>
<SearchBox onChangeText={onChangeText} />
<List.Separator />
</>
);
static navigationOptions = ({ route }: IPickerViewProps) => ({ const PickerView = (): React.ReactElement => {
title: route.params?.title ?? I18n.t('Select_an_option') const navigation = useAppNavigation();
}); const {
params: { title, data: paramData, value: paramValue, total: paramTotal, onSearch, onChangeValue, onEndReached }
} = useAppRoute<TNavigation, 'PickerView'>();
constructor(props: IPickerViewProps) { const { colors } = useTheme();
super(props);
const data = props.route.params?.data ?? [];
const value = props.route.params?.value ?? '';
const total = props.route.params?.total ?? 0;
this.state = { data, value, total, searchText: '' };
this.onSearch = props.route.params?.onSearch;
}
onChangeValue = (value: string) => { const [data, setData] = useState(paramData);
const { navigation, route } = this.props; const [total, setTotal] = useState(paramTotal ?? 0);
const goBack = route.params?.goBack ?? true; const [searchText, setSearchText] = useState('');
const onChange = route.params?.onChangeValue ?? (() => {});
onChange(value); useLayoutEffect(() => {
if (goBack) { navigation.setOptions({
navigation.goBack(); title: title ?? I18n.t('Select_an_option')
} });
}, [navigation, title]);
const handleChangeValue = (value: string | number) => {
onChangeValue(value);
navigation.goBack();
}; };
onChangeText = debounce(async (searchText: string) => { const onChangeText = useDebounce(async (text: string) => {
if (this.onSearch) { const search = await onSearch(text);
const data = await this.onSearch(searchText); if (search?.data) {
if (data?.data) { setSearchText(text);
this.setState({ ...data, searchText }); setData(search?.data);
}
} }
}, 500); }, 500);
onEndReached = async () => { const handleOnEndReached = async () => {
const { route } = this.props; if (onEndReached && total && data.length < total) {
const { data, total, searchText } = this.state; const end = await onEndReached(searchText, data.length);
const onEndReached = route.params?.onEndReached; if (end?.data) {
if (onEndReached && data.length < total) { setData([...data, ...end.data]);
const val = await onEndReached(searchText, data.length); setTotal(end.total);
if (val?.data) {
this.setState({ ...val, data: [...data, ...val.data] });
} }
} }
}; };
render() { return (
const { data, value } = this.state; <SafeAreaView>
const { theme } = this.props; <FlatList
data={data}
keyExtractor={item => item.value as string}
renderItem={({ item }) => (
<Item
item={item}
selected={(paramValue || data[0]?.value) === item.value}
onItemPress={() => handleChangeValue(item.value)}
/>
)}
onEndReached={handleOnEndReached}
onEndReachedThreshold={0.5}
ItemSeparatorComponent={List.Separator}
ListHeaderComponent={<RenderSearch onChangeText={onChangeText} />}
ListFooterComponent={List.Separator}
ListEmptyComponent={() => (
<Text style={[styles.noResult, { color: colors.titleText }]}>{I18n.t('No_results_found')}</Text>
)}
/>
</SafeAreaView>
);
};
return ( export default PickerView;
<SafeAreaView>
<FlatList
data={data}
keyExtractor={item => item.value as string}
renderItem={({ item }) => (
<Item
item={item}
theme={theme}
selected={!this.onSearch && (value || data[0]?.value) === item.value}
onItemPress={() => this.onChangeValue(item.value as string)}
/>
)}
onEndReached={() => this.onEndReached()}
onEndReachedThreshold={0.5}
ItemSeparatorComponent={List.Separator}
ListHeaderComponent={<RenderSearch hasSearch={!!this.onSearch} onChangeText={this.onChangeText} />}
ListFooterComponent={List.Separator}
ListEmptyComponent={() => (
<Text style={[styles.noResult, { color: themes[theme!].titleText }]}>{I18n.t('No_results_found')}</Text>
)}
/>
</SafeAreaView>
);
}
}
export default withTheme(PickerView);

View File

@ -52,12 +52,15 @@ import { closeLivechat } from '../../lib/methods/helpers/closeLivechat';
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment'; import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
import { ILivechatTag } from '../../definitions/ILivechatTag'; import { ILivechatTag } from '../../definitions/ILivechatTag';
import CallSection from './components/CallSection'; import CallSection from './components/CallSection';
import { TNavigation } from '../../stacks/stackType';
type StackType = ChatsStackParamList & TNavigation;
interface IOnPressTouch { interface IOnPressTouch {
<T extends keyof ChatsStackParamList>(item: { route?: T; params?: ChatsStackParamList[T]; event?: Function }): void; <T extends keyof StackType>(item: { route?: T; params?: StackType[T]; event?: Function }): void;
} }
interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen<ChatsStackParamList, 'RoomActionsView'> { interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen<StackType, 'RoomActionsView'> {
userId: string; userId: string;
jitsiEnabled: boolean; jitsiEnabled: boolean;
jitsiEnableTeams: boolean; jitsiEnableTeams: boolean;
@ -76,7 +79,7 @@ interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen<ChatsS
livechatRequestComment?: boolean; livechatRequestComment?: boolean;
navigation: CompositeNavigationProp< navigation: CompositeNavigationProp<
StackNavigationProp<ChatsStackParamList, 'RoomActionsView'>, StackNavigationProp<ChatsStackParamList, 'RoomActionsView'>,
StackNavigationProp<MasterDetailInsideStackParamList> StackNavigationProp<MasterDetailInsideStackParamList & TNavigation>
>; >;
videoConf_Enable_DMs: boolean; videoConf_Enable_DMs: boolean;
videoConf_Enable_Channels: boolean; videoConf_Enable_Channels: boolean;
@ -252,8 +255,8 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
}; };
onPressTouchable: IOnPressTouch = (item: { onPressTouchable: IOnPressTouch = (item: {
route?: keyof ChatsStackParamList; route?: keyof StackType;
params?: ChatsStackParamList[keyof ChatsStackParamList]; params?: StackType[keyof StackType];
event?: Function; event?: Function;
}) => { }) => {
const { route, event, params } = item; const { route, event, params } = item;

View File

@ -1,13 +1,12 @@
import React, { useCallback } from 'react';
import { StyleSheet, Platform } from 'react-native';
import { StackNavigationProp } from '@react-navigation/stack';
import { HeaderBackButton } from '@react-navigation/elements'; import { HeaderBackButton } from '@react-navigation/elements';
import React, { useCallback } from 'react';
import { Platform, StyleSheet } from 'react-native';
import { themes } from '../../lib/constants';
import Avatar from '../../containers/Avatar'; import Avatar from '../../containers/Avatar';
import { ChatsStackParamList } from '../../stacks/types'; import { themes } from '../../lib/constants';
import { TSupportedThemes } from '../../theme'; import { useAppNavigation } from '../../lib/hooks/navigation';
import { isIOS } from '../../lib/methods/helpers'; import { isIOS } from '../../lib/methods/helpers';
import { TSupportedThemes } from '../../theme';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -27,7 +26,6 @@ interface ILeftButtonsProps {
rid?: string; rid?: string;
tmid?: string; tmid?: string;
unreadsCount: number | null; unreadsCount: number | null;
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>;
baseUrl: string; baseUrl: string;
userId?: string; userId?: string;
token?: string; token?: string;
@ -42,7 +40,6 @@ const LeftButtons = ({
rid, rid,
tmid, tmid,
unreadsCount, unreadsCount,
navigation,
baseUrl, baseUrl,
userId, userId,
token, token,
@ -52,10 +49,10 @@ const LeftButtons = ({
goRoomActionsView, goRoomActionsView,
isMasterDetail isMasterDetail
}: ILeftButtonsProps): React.ReactElement | null => { }: ILeftButtonsProps): React.ReactElement | null => {
const { goBack } = useAppNavigation();
const onPress = useCallback(() => goRoomActionsView(), []); const onPress = useCallback(() => goRoomActionsView(), []);
if (!isMasterDetail || tmid) { if (!isMasterDetail || tmid) {
const onPress = () => navigation.goBack();
let label = ' '; let label = ' ';
let labelLength = 1; let labelLength = 1;
let marginLeft = 0; let marginLeft = 0;
@ -70,7 +67,7 @@ const LeftButtons = ({
<HeaderBackButton <HeaderBackButton
label={label} label={label}
labelVisible={isIOS} labelVisible={isIOS}
onPress={onPress} onPress={goBack}
tintColor={themes[theme].headerTintColor} tintColor={themes[theme].headerTintColor}
labelStyle={{ fontSize, marginLeft }} labelStyle={{ fontSize, marginLeft }}
style={styles.container} style={styles.container}

View File

@ -1,24 +1,25 @@
import { StackNavigationProp } from '@react-navigation/stack';
import { dequal } from 'dequal';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { dequal } from 'dequal';
import { Observable, Subscription } from 'rxjs';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { StackNavigationProp } from '@react-navigation/stack'; import { Observable, Subscription } from 'rxjs';
import { ILivechatTag } from '../../definitions/ILivechatTag';
import * as HeaderButton from '../../containers/HeaderButton';
import database from '../../lib/database';
import { getUserSelector } from '../../selectors/login';
import { events, logEvent } from '../../lib/methods/helpers/log';
import { IApplicationState, ISubscription, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
import { ChatsStackParamList } from '../../stacks/types';
import { TActionSheetOptionsItem } from '../../containers/ActionSheet'; import { TActionSheetOptionsItem } from '../../containers/ActionSheet';
import i18n from '../../i18n'; import * as HeaderButton from '../../containers/HeaderButton';
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers'; import { IApplicationState, ISubscription, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions';
import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
import { closeLivechat as closeLivechatService } from '../../lib/methods/helpers/closeLivechat';
import { Services } from '../../lib/services';
import { ILivechatDepartment } from '../../definitions/ILivechatDepartment'; import { ILivechatDepartment } from '../../definitions/ILivechatDepartment';
import { ILivechatTag } from '../../definitions/ILivechatTag';
import i18n from '../../i18n';
import database from '../../lib/database';
import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
import { closeLivechat as closeLivechatService } from '../../lib/methods/helpers/closeLivechat';
import { events, logEvent } from '../../lib/methods/helpers/log';
import { Services } from '../../lib/services';
import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi';
import { getUserSelector } from '../../selectors/login';
import { TNavigation } from '../../stacks/stackType';
import { ChatsStackParamList } from '../../stacks/types';
import HeaderCallButton from './components/HeaderCallButton'; import HeaderCallButton from './components/HeaderCallButton';
interface IRightButtonsProps extends Pick<ISubscription, 't'> { interface IRightButtonsProps extends Pick<ISubscription, 't'> {
@ -32,7 +33,7 @@ interface IRightButtonsProps extends Pick<ISubscription, 't'> {
status?: string; status?: string;
dispatch: Dispatch; dispatch: Dispatch;
encrypted?: boolean; encrypted?: boolean;
navigation: StackNavigationProp<ChatsStackParamList, 'RoomView'>; navigation: StackNavigationProp<ChatsStackParamList & TNavigation, 'RoomView'>;
omnichannelPermissions: { omnichannelPermissions: {
canForwardGuest: boolean; canForwardGuest: boolean;
canReturnQueue: boolean; canReturnQueue: boolean;

View File

@ -574,7 +574,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
rid={rid} rid={rid}
tmid={tmid} tmid={tmid}
unreadsCount={unreadsCount} unreadsCount={unreadsCount}
navigation={navigation}
baseUrl={baseUrl} baseUrl={baseUrl}
userId={userId} userId={userId}
token={token} token={token}