PickerView.tsx 3.52 KB
Newer Older
1
import React from 'react';
2
3
import { StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/native';
4
import { FlatList, StyleSheet, Text, View } from 'react-native';
5
6
7
8

import I18n from '../i18n';
import { withTheme } from '../theme';
import { themes } from '../constants/colors';
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
9
import debounce from '../utils/debounce';
10
import * as List from '../containers/List';
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
11
import SearchBox from '../containers/SearchBox';
12
import SafeAreaView from '../containers/SafeAreaView';
13
import sharedStyles from './Styles';
14
15
import { ChatsStackParamList } from '../stacks/types';
import { IOptionsField } from './NotificationPreferencesView/options';
16
17

const styles = StyleSheet.create({
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
18
19
20
21
22
23
24
	search: {
		width: '100%',
		height: 56
	},
	noResult: {
		fontSize: 16,
		paddingVertical: 56,
25
26
		...sharedStyles.textSemibold,
		...sharedStyles.textAlignCenter
27
28
29
	}
});

30
interface IItem {
31
	item: IOptionsField;
32
33
34
35
36
37
	selected: boolean;
	onItemPress: () => void;
	theme: string;
}

interface IPickerViewState {
38
	data: IOptionsField[];
39
40
41
42
	value: string;
}

interface IPickerViewProps {
43
44
	navigation: StackNavigationProp<ChatsStackParamList, 'PickerView'>;
	route: RouteProp<ChatsStackParamList, 'PickerView'>;
45
46
47
48
	theme: string;
}

const Item = React.memo(({ item, selected, onItemPress, theme }: IItem) => (
49
	<List.Item
50
		title={I18n.t(item.label, { defaultValue: item.label, second: item?.second })}
51
		right={selected && (() => <List.Icon name='check' color={themes[theme].tintColor} />)}
52
		onPress={onItemPress}
53
		translateTitle={false}
54
55
56
	/>
));

57
class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState> {
58
	private onSearch?: ((text: string) => IOptionsField[]) | ((term?: string | undefined) => Promise<any>);
59
60

	static navigationOptions = ({ route }: IPickerViewProps) => ({
61
		title: route.params?.title ?? I18n.t('Select_an_option')
62
	});
63

64
	constructor(props: IPickerViewProps) {
65
		super(props);
66
67
		const data = props.route.params?.data ?? [];
		const value = props.route.params?.value;
68
		this.state = { data, value };
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
69

70
		this.onSearch = props.route.params?.onChangeText;
71
72
	}

73
	onChangeValue = (value: string) => {
74
75
76
		const { navigation, route } = this.props;
		const goBack = route.params?.goBack ?? true;
		const onChange = route.params?.onChangeValue ?? (() => {});
77
		onChange(value);
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
78
79
80
		if (goBack) {
			navigation.goBack();
		}
81
	};
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
82

83
	onChangeText = debounce(
84
		async (text: string) => {
85
86
87
88
89
90
91
92
			if (this.onSearch) {
				const data = await this.onSearch(text);
				this.setState({ data });
			}
		},
		300,
		true
	);
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
93
94
95
96
97
98
99
100
101
102
103

	renderSearch() {
		if (!this.onSearch) {
			return null;
		}

		return (
			<View style={styles.search}>
				<SearchBox onChangeText={this.onChangeText} />
			</View>
		);
104
105
106
107
108
109
110
	}

	render() {
		const { data, value } = this.state;
		const { theme } = this.props;

		return (
111
			<SafeAreaView>
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
112
113
114
				{this.renderSearch()}
				<FlatList
					data={data}
115
					keyExtractor={item => item.value as string}
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
116
117
118
119
120
					renderItem={({ item }) => (
						<Item
							item={item}
							theme={theme}
							selected={!this.onSearch && (value || data[0]?.value) === item.value}
121
							onItemPress={() => this.onChangeValue(item.value as string)}
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
122
123
						/>
					)}
124
125
126
					ItemSeparatorComponent={List.Separator}
					ListHeaderComponent={List.Separator}
					ListFooterComponent={List.Separator}
127
128
129
					ListEmptyComponent={() => (
						<Text style={[styles.noResult, { color: themes[theme].titleText }]}>{I18n.t('No_results_found')}</Text>
					)}
130
					contentContainerStyle={[List.styles.contentContainerStyleFlatList]}
Djorkaeff Alexandre's avatar
Djorkaeff Alexandre committed
131
				/>
132
			</SafeAreaView>
133
134
135
136
137
		);
	}
}

export default withTheme(PickerView);