react-native-elements#ListItem TypeScript Examples
The following examples show how to use
react-native-elements#ListItem.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: HomeScreen.tsx From react-native-sdk with MIT License | 6 votes |
render() {
return (
<View>
{
coffees.map((coffee, i) => (
<ListItem
onPress={() => {
this.props.navigation.navigate('Detail', { coffee: coffee })
}}
key={i}
leftAvatar={{ source: coffee.icon }}
title={coffee.name}
subtitle={coffee.subtitle}
bottomDivider
chevron
/>
))
}
</View>
)
}
Example #2
Source File: draft-item.tsx From bext with MIT License | 6 votes |
DraftItem: FC<{
draft: Draft;
onDelete: () => void;
onPress: () => void;
}> = ({ draft, onDelete, onPress }) => {
const updateAt = useMemo(
() => dayjs(draft.update_at).format('LLL'),
[draft.update_at],
);
return (
<ListItem.Swipeable
bottomDivider
onPress={onPress}
rightContent={
<Button
title="删除"
buttonStyle={styles.deleteButton}
icon={{ name: 'delete', color: 'white' }}
onPress={onDelete}
/>
}
>
<ListItem.Content>
<ListItem.Title>{draft.name}</ListItem.Title>
<ListItem.Subtitle>更新于 {updateAt}</ListItem.Subtitle>
</ListItem.Content>
<ListItem.Chevron />
</ListItem.Swipeable>
);
}
Example #3
Source File: HeaderListItem.tsx From react-native-network-client with Apache License 2.0 | 6 votes |
HeaderListItem = ({
index,
header,
updateHeader,
disabled,
testID,
}: HeaderListItemProps) => {
const updateHeaderKey = (key: string) =>
updateHeader && updateHeader({ ...header, key }, index);
const updateHeaderValue = (value: string) =>
updateHeader && updateHeader({ ...header, value }, index);
return (
<ListItem>
<Input
containerStyle={{ flex: 1 }}
onChangeText={updateHeaderKey}
placeholder="key"
value={header.key}
disabled={disabled}
testID={`${testID}.${index}.key.input`}
/>
<Input
containerStyle={{ flex: 1 }}
onChangeText={updateHeaderValue}
placeholder="value"
value={header.value}
disabled={disabled}
testID={`${testID}.${index}.value.input`}
/>
</ListItem>
);
}
Example #4
Source File: CartListItem.tsx From magento_react_native_graphql with MIT License | 6 votes |
CartListItem = ({
item,
index,
onPress,
onRemovePress,
}: Props): React.ReactElement => {
const renderImage = () => {
const uri = `${item.product.small_image.url}?width=${DIMENS.cartScreen.imageSize}`;
return <Image source={{ uri }} style={styles.image} />;
};
return (
<ListItem onPress={() => onPress(index)} bottomDivider>
{renderImage()}
<ListItem.Content>
<ListItem.Title>{item.product.name}</ListItem.Title>
<ListItem.Subtitle>{`${translate('common.quantity')} : ${
item.quantity
}`}</ListItem.Subtitle>
<ListItem.Subtitle>{`${translate('common.price')} : ${formatPrice(
item.prices.rowTotal,
)}`}</ListItem.Subtitle>
</ListItem.Content>
<ListItem.Chevron name="delete" onPress={() => onRemovePress(index)} />
</ListItem>
);
}
Example #5
Source File: ClientListItem.tsx From react-native-network-client with Apache License 2.0 | 5 votes |
ClientListItem = (props: ClientListItemProps) => {
const {
index,
deleteClient,
item: { name, client, type },
} = props;
const viewClient = () => {
let screen = "GenericClientRequest";
if (type === ClientType.API) {
screen = "APIClient";
} else if (type === ClientType.WEBSOCKET) {
screen = "WebSocketClient";
}
props.navigate(screen, { item: props.item });
};
const invalidateClient = () => {
if ("invalidate" in client) {
client.invalidate();
deleteClient(index);
}
};
const removeClient = () => {
"invalidate" in client &&
Alert.alert(
"Remove Client",
"",
[{ text: "Cancel" }, { text: "OK", onPress: invalidateClient }],
{ cancelable: true }
);
};
const Subtitle = () => {
if ("baseUrl" in client) {
return (
<ListItem.Subtitle testID="client_list_item.subtitle">
{client.baseUrl}
</ListItem.Subtitle>
);
} else if ("url" in client) {
return (
<ListItem.Subtitle testID="client_list_item.subtitle">
{client.url}
</ListItem.Subtitle>
);
}
return null;
};
return (
<ListItem
onPress={viewClient}
onLongPress={removeClient}
bottomDivider
testID="client_list_item.item"
>
<ListItem.Content testID="client_list_item.content">
<ListItem.Title testID="client_list_item.title">
{name}
</ListItem.Title>
<Subtitle />
</ListItem.Content>
<ListItem.Chevron testID="client_list_item.chevron" />
</ListItem>
);
}
Example #6
Source File: MultipartListItem.tsx From react-native-network-client with Apache License 2.0 | 5 votes |
MultipartListItem = ({
index,
multipart,
updateMultipart,
removeMultipart,
disabled,
testID,
}: MultipartListItemProps) => {
const updateMultipartKey = (key: string) =>
updateMultipart && updateMultipart({ ...multipart, key }, index);
const updateMultipartValue = (value: string) =>
updateMultipart && updateMultipart({ ...multipart, value }, index);
return (
<ListItem>
<Input
containerStyle={{ flex: 1 }}
onChangeText={updateMultipartKey}
placeholder="key"
value={multipart.key}
disabled={disabled}
testID={`${testID}.${index}.key.input`}
/>
<Input
containerStyle={{ flex: 1 }}
onChangeText={updateMultipartValue}
placeholder="value"
value={multipart.value}
disabled={disabled}
testID={`${testID}.${index}.value.input`}
/>
<Button
type="clear"
icon={<Icon name="trash" size={24} />}
onPress={() => removeMultipart(index)}
testID="remove_multipart.button"
/>
</ListItem>
);
}
Example #7
Source File: CategoryListItem.tsx From magento_react_native_graphql with MIT License | 5 votes |
CategoryListItem = ({ item, navigation }: Props): React.ReactElement => {
const [disabled] = useState<boolean>(
+item.childrenCount < 1 && item.productCount < 1,
);
const onCategoryPress = () => {
if (+item.childrenCount > 0) {
navigation.navigate(Routes.NAVIGATION_TO_CATEGORIES_SCREEN, {
categoryId: item.id,
name: item.name,
});
return;
}
navigation.navigate(Routes.NAVIGATION_TO_PRODUCT_LIST_SCREEN, {
categoryId: item.id,
name: item.name,
});
};
const renderImage = () => {
const rawUri =
item.image ?? item.productPreviewImage?.items?.[0]?.smallImage?.url;
if (!rawUri) {
return null;
}
const uri = `${rawUri ?? ''}?width=100`;
return <Image source={{ uri }} resizeMode="cover" style={styles.image} />;
};
const renderContent = () => {
return (
<>
<ListItem.Content>
<ListItem.Title>{item.name}</ListItem.Title>
</ListItem.Content>
</>
);
};
return (
<ListItem
containerStyle={styles.conatiner}
disabled={disabled}
onPress={onCategoryPress}
bottomDivider
>
{renderImage()}
{renderContent()}
</ListItem>
);
}
Example #8
Source File: Mobility.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function Mobility({ item }: { item: EntryType }) {
const [visible, setVisible] = useState(false);
return (
<View>
<ListItem
onPress={() => setVisible(true)}
title={
<Text
style={{
fontWeight: '800',
}}>{`${item.t_pos_start} - ${item.t_pos_end}`}</Text>
}
subtitle={
<View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Text style={{ fontSize: 12 }}>{item.t_no}</Text>
<Text style={{ fontSize: 12 }}>{item.who}</Text>
</View>
{Boolean(item.t_memo) && (
<Text style={{ color: '#717171' }}>({item.t_memo})</Text>
)}
</View>
}
leftAvatar={
<View style={{ width: 50 }}>
<Text style={{ fontSize: 13, fontWeight: 'bold' }}>
{typeMap[item.t_type].label}
</Text>
</View>
}
rightIcon={{ name: 'unfold-more' }}
/>
<WebViewModal
title={`${item.t_pos_start} - ${item.t_pos_end}`}
uri={item.source}
visible={visible}
onClose={() => setVisible(false)}
/>
</View>
);
}
Example #9
Source File: News.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function Entry(props: EntryPropsType) {
const [visible, setVisible] = useState(false);
const [loadingWebview, setLoading] = useState(true);
return (
<View>
<ListItem
onPress={() => setVisible(true)}
Component={TouchableOpacity}
title={
<Text style={{ fontWeight: '800' }}>
{props.content.slice(0, 50)}
</Text>
}
subtitle={
<View
style={{
paddingTop: 4,
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Text style={{ fontSize: 12 }}>时间: {props.sendTime}</Text>
<Text style={{ fontSize: 12 }}>来源: {props.fromName}</Text>
</View>
}
rightIcon={{ name: 'unfold-more' }}
/>
<Modal
animationType="fade"
presentationStyle="pageSheet"
visible={visible}
onDismiss={() => {
setVisible(false);
}}
onRequestClose={() => {
setVisible(false);
}}>
<View style={{ padding: 16, justifyContent: 'space-between' }}>
<View style={{ height: height - 150 }}>
{loadingWebview ? (
<ActivityIndicator size="large" color="red" />
) : null}
<WebView
onLoad={() => setLoading(true)}
onLoadEnd={() => setLoading(false)}
source={{ uri: props.url }}
/>
</View>
<View>
<Button
buttonStyle={styles.button}
title="关闭预览"
onPress={() => {
setVisible(false);
}}
/>
</View>
</View>
</Modal>
</View>
);
}
Example #10
Source File: RecommendationList.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function Entry(props: EntryPropsType) {
const [visible, setVisible] = useState(false);
const [loadingWebview, setLoading] = useState(true);
return (
<View>
<ListItem
onPress={() => setVisible(true)}
Component={TouchableOpacity}
title={<Text style={{ fontWeight: '800' }}>{props.title}</Text>}
subtitle={
<Text style={{ fontSize: 12, paddingTop: 3 }}>
修改时间:
{formatDate(props.modifyTime)} from {props.operator}
</Text>
}
leftAvatar={{ source: { uri: props.imgUrl } }}
rightIcon={{ name: 'unfold-more' }}
/>
<Modal
animationType="fade"
presentationStyle="pageSheet"
visible={visible}
onDismiss={() => {
setVisible(false);
}}
onRequestClose={() => {
setVisible(false);
}}>
<View style={{ padding: 16, justifyContent: 'space-between' }}>
{loadingWebview ? (
<ActivityIndicator size="large" color="red" />
) : null}
<View style={{ height: height - 150 }}>
<WebView
onLoad={() => setLoading(true)}
onLoadEnd={() => setLoading(false)}
source={{ uri: props.linkUrl }}
/>
</View>
<View>
<Button
buttonStyle={styles.button}
title="关闭预览"
onPress={() => {
setVisible(false);
}}
/>
</View>
</View>
</Modal>
</View>
);
}
Example #11
Source File: Timeline.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function Entry(props: EntryPropsType) {
const [visible, setVisible] = useState(false);
return (
<View>
<ListItem
onPress={() => setVisible(true)}
Component={TouchableOpacity}
title={<Text style={{ fontWeight: '800' }}>{props.title}</Text>}
subtitle={`${props.summary.slice(0, 50)}...`}
leftAvatar={
<View>
{props.latest ? (
<Badge
value="最新"
status="error"
textStyle={{ fontSize: 13, fontWeight: 'bold' }}
/>
) : null}
<Text style={{ fontSize: 13, fontWeight: 'bold' }}>
{props.pubDateStr}
</Text>
<Text style={{ fontSize: 12, color: '#717171' }}>
{formatTime(props.modifyTime)}
</Text>
</View>
}
rightAvatar={
<View style={{ justifyContent: 'flex-end', alignItems: 'flex-end' }}>
<Text style={{ fontSize: 12, color: '#717171' }}>
{props.infoSource}
</Text>
</View>
}
/>
<Modal
animationType="fade"
presentationStyle="pageSheet"
visible={visible}
onDismiss={() => {
setVisible(false);
}}
onRequestClose={() => {
setVisible(false);
}}>
<View style={{ padding: 16, justifyContent: 'space-between' }}>
<View style={{ height: height - 150 }}>
<Text
style={{ fontSize: 20, fontWeight: 'bold', paddingBottom: 20 }}>
{props.title}
</Text>
<Text style={{ fontSize: 16, lineHeight: 22 }}>
{props.summary}
</Text>
<View style={{ alignSelf: 'flex-end', paddingTop: 20 }}>
<Text style={{ fontWeight: '800' }}>
新闻来源:{props.infoSource}
</Text>
<Text style={{ fontWeight: '800' }}>
时间:{props.pubDateStr}
</Text>
</View>
</View>
<View>
<Button
buttonStyle={styles.button}
title="关闭预览"
onPress={() => {
setVisible(false);
}}
/>
</View>
</View>
</Modal>
</View>
);
}
Example #12
Source File: Wuhan2020.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function ResourceList({ navigation }) {
return (
<View>
<ListItem
titleStyle={styles.title}
key="hospital"
title="医院"
onPress={() => {
navigation.navigate({ routeName: 'Hospital' });
}}
chevron
bottomDivider
/>
<ListItem
titleStyle={styles.title}
key="logistic"
title="物流"
onPress={() => {
navigation.navigate({ routeName: 'Logistic' });
}}
bottomDivider
chevron
/>
<ListItem
titleStyle={styles.title}
key="donation"
title="捐款"
onPress={() => {
navigation.navigate({ routeName: 'Donation' });
}}
bottomDivider
chevron
/>
<ListItem
titleStyle={styles.title}
key="consultation"
title="义诊"
onPress={() => {
navigation.navigate({ routeName: 'Consultation' });
}}
bottomDivider
chevron
/>
<ListItem
titleStyle={styles.title}
key="hotel"
title="指定接待酒店"
onPress={() => {
navigation.navigate({ routeName: 'Hotel' });
}}
chevron
/>
</View>
);
}
Example #13
Source File: ProductListScreen.tsx From magento_react_native_graphql with MIT License | 4 votes |
ProductListScreen = ({
navigation,
route: {
params: { categoryId },
},
}: Props): React.ReactElement => {
const { data, networkStatus, error, refresh, loadMore } = useCategoryProducts(
{
categoryId,
},
);
const { isVisible, selectedIndex, setVisible, sortOptions } = useSort({
onPress: refresh,
});
const { theme } = useContext(ThemeContext);
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<CustomHeaderButtons>
<CustomHeaderItem
title={translate('common.sort')}
iconName="sort"
onPress={() => setVisible(true)}
/>
</CustomHeaderButtons>
),
});
}, [navigation]);
const onProductItemClicked = (index: number) => {
if (data?.products?.items) {
navigation.navigate(Routes.NAVIGATION_TO_PRODUCT_DETAILS_SCREEN, {
name: data.products.items[index].name,
sku: data.products.items[index].sku,
});
}
};
const renderItem = ({
item,
index,
}: {
item: ProductInListType;
index: number;
}) => {
return (
<ProductListItem
item={item}
index={index}
onPress={onProductItemClicked}
/>
);
};
const renderFooterComponent = () =>
(networkStatus === NetworkStatus.fetchMore && (
<View style={styles.footerContainer}>
<Spinner />
</View>
)) || <></>;
return (
<GenericTemplate errorMessage={error?.message}>
<FlatList
numColumns={2}
data={data?.products?.items ?? []}
renderItem={renderItem}
keyExtractor={item => `productListItem${item.sku}`}
refreshControl={
<RefreshControl
refreshing={
networkStatus === NetworkStatus.refetch ||
networkStatus === NetworkStatus.loading
}
onRefresh={refresh}
/>
}
onEndReached={loadMore}
ListFooterComponent={renderFooterComponent}
/>
<BottomSheet isVisible={isVisible} containerStyle={styles.sortContainer}>
{sortOptions.map((option, index) => (
<ListItem
key={option.title}
containerStyle={[
option.containerStyle,
selectedIndex === index && {
backgroundColor: theme.colors?.grey5,
},
]}
onPress={option.onPress}
>
<ListItem.Content>
<ListItem.Title style={option.titleStyle}>
{option.title}
</ListItem.Title>
</ListItem.Content>
</ListItem>
))}
</BottomSheet>
</GenericTemplate>
);
}
Example #14
Source File: FoodList.tsx From save-food with MIT License | 4 votes |
FoodList = ({ navigation }: Props) => {
const moveButton = useRef(new Animated.Value(100)).current
const { useSubscribe } = useSettingsContext()
const settings = useSubscribe((s) => s.settings)
const translations = useSubscribe((s) => ({
...s.translations.FoodList,
...s.translations.common,
}))
const [list, setList] = useState<WastedFood[]>()
const [amount, setAmount] = useState(0)
const [visibleData, setVisibleData] = useState(8)
const [loading, setLoading] = useState(true)
const [wait, setWait] = useState(false)
const [selectedId, setSelectedId] = useState<number>()
const [showModal, setShowModal] = useState(false)
const initWastedList = async (showMessage = false) => {
const wastedFoods = await fetchWastedFood()
const list = wastedFoods.map((food) => {
let resize: ResizeMode = 'cover'
if (food.image) {
getResizeMode(food.image, (resizeMode) => {
resize = resizeMode
})
}
return {
...food,
resizeMode: resize,
}
})
setList(list)
setAmount(getAmount(list))
setLoading(false)
setWait(false)
if (showMessage) showSuccessMessage()
}
const checkFood = async () => {
const ids = navigation.getParam('ids', undefined)
if (ids) {
setLoading(true)
await Promise.all(
ids.map(async (id: number) => {
await paidFood(id)
await Promise.resolve()
}),
)
await initWastedList(true)
} else {
await initWastedList()
}
}
const showSuccessMessage = () => {
const message: MessageOptions = {
message: translations.paymentSuccessTitle,
type: 'success',
icon: { icon: 'success', position: 'left' },
duration: 2500,
}
showMessage(message)
}
const getAmount = (list: WastedFood[]): number =>
+list
.filter((item) => !!item.selected)
.reduce((a, i) => a + i.price * i.productQuantity, 0)
.toFixed(2)
const hideButton = () => {
Animated.timing(moveButton, {
toValue: 100,
duration: 250,
useNativeDriver: true,
}).start()
}
const showButton = () => {
Animated.timing(moveButton, {
toValue: -25,
duration: 250,
useNativeDriver: true,
}).start()
}
const selectItem = async (item: WastedFood) => {
if (!wait) {
setWait(true)
if (item.selected) {
await selectFood(item.id, 0)
} else {
await selectFood(item.id, 1)
}
await initWastedList()
}
}
const removeItemHandler = async (id: number) => {
await removeFood(id)
await initWastedList()
toggleModal()
}
const addFoodQuantity = async (item: WastedFood, value: number) => {
const newQuantity = +item.productQuantity + value
if (!wait && newQuantity < 100 && newQuantity > 0) {
setWait(true)
await saveFood({ ...item, productQuantity: newQuantity })
await initWastedList()
}
}
const loadNextData = () => {
if (list && visibleData < list.length) {
setVisibleData(visibleData + 8)
}
}
const toggleModal = (id?: number) => {
if (id) setSelectedId(id)
setShowModal(!showModal)
}
const goToPayment = () => {
navigation.navigate('Payment', {
ids: list?.filter((item) => !!item.selected).map((i) => i.id),
amount,
})
}
const renderItemRow = ({ item }: { item: WastedFood }) => (
<ListItem containerStyle={[styles.listItemContainer, shadow]}>
<ListItem.Content>
<TouchableOpacity
style={styles.listItem}
onPress={() => navigation.navigate('Food', { ...item })}
>
<View style={styles.details}>
<View style={styles.leftElement}>
<Image
style={[styles.image, { resizeMode: item.resizeMode }]}
onError={(ev) => {
if (ev.target) {
// @ts-ignore
ev.target.src = '../../assets/common/dish.png'
}
}}
source={getImage(item.image)}
/>
<View style={styles.productDetails}>
<Text numberOfLines={2} style={styles.productName}>
{!item.name || item.name === '' ? translations.noData : item.name}
</Text>
<Text numberOfLines={1} style={styles.text}>
{translations.quantity}:{' '}
{item.quantity
? `${item.quantity} ${getQuantitySuffix(item.quantitySuffixIndex)}`
: translations.noData}
</Text>
<Text numberOfLines={1} style={styles.text}>
{translations.percent}: {item.percentage}%
</Text>
</View>
</View>
<View style={styles.rightElement}>
<Icon
size={22}
style={styles.quantityAddIcon}
name='add'
type='material'
color={blackColor}
onPress={() => addFoodQuantity(item, 1)}
/>
<Icon
size={22}
style={styles.quantityMinusIcon}
name='minus'
type='entypo'
color={blackColor}
onPress={() => addFoodQuantity(item, -1)}
/>
</View>
</View>
<View style={styles.itemListFooter}>
<TouchableOpacity onPress={() => selectItem(item)} style={styles.priceContainer}>
<CheckBox
checked={!!item.selected}
onPress={() => selectItem(item)}
containerStyle={styles.checkbox}
checkedColor={primaryColor}
/>
<View style={styles.priceWrapper}>
<Text style={styles.priceText}>
{(item.price * item.productQuantity).toFixed(2)} {settings.currency}
</Text>
{item.productQuantity > 1 && (
<Text style={styles.quantityText}>
({item.price} {settings.currency} x{item.productQuantity})
</Text>
)}
</View>
</TouchableOpacity>
<Icon
size={22}
onPress={() => toggleModal(item.id)}
style={styles.deleteProductIcon}
color={redColor}
name='trash'
type='font-awesome-5'
/>
</View>
</TouchableOpacity>
</ListItem.Content>
</ListItem>
)
useAsyncEffect(async () => {
await checkFood()
}, [navigation])
useEffect(() => {
if (list?.some((item) => !!item.selected)) {
showButton()
} else {
hideButton()
}
}, [list])
useAsyncEffect(async () => {
await initWastedList()
}, [])
if (!list) {
return <Spinner size={64} />
}
return (
<Background>
<Header
leftComponent={<Icon variant='backIcon' onPress={() => navigation.replace('Home')} />}
centerComponent={<Text style={styles.headerTitle}>{translations.foodList}</Text>}
rightComponent={
<Icon
style={styles.openScannerIcon}
name='plus'
type='antdesign'
onPress={() => navigation.navigate('Scanner')}
/>
}
centerSize={6}
/>
<Modal
visible={showModal}
toggleModal={toggleModal}
title={translations.deleteProduct}
buttons={[
{ text: translations.yes, onPress: () => selectedId && removeItemHandler(selectedId) },
{ text: translations.cancel, onPress: toggleModal },
]}
>
<Text style={styles.deleteProductDescription}>{translations.deleteProductDescription}</Text>
</Modal>
<View style={styles.container}>
<FlatList
keyboardShouldPersistTaps='always'
keyboardDismissMode='interactive'
scrollEventThrottle={16}
refreshControl={
<RefreshControl refreshing={loading} tintColor='#fff' onRefresh={initWastedList} />
}
ListEmptyComponent={<EmptyList navigation={navigation} />}
data={list}
initialNumToRender={8}
onEndReachedThreshold={0.2}
onEndReached={loadNextData}
renderItem={renderItemRow}
keyExtractor={(item) => `${item.id}`}
onRefresh={initWastedList}
refreshing={loading}
ListFooterComponent={
list.length > visibleData ? (
<Spinner bgColor='transparency' />
) : (
<View style={styles.listFooter} />
)
}
/>
</View>
<Animated.View
style={[{ transform: [{ translateY: moveButton }] }, styles.paymentButtonContainer, shadow]}
>
<View style={styles.paymentButtonWrapper}>
<Button
buttonStyle={styles.paymentButton}
titleStyle={styles.paymentButtonTitle}
onPress={goToPayment}
disabled={amount === 0}
title={`${translations.donate} ${getPrice(amount)} ${settings.currency}`}
/>
</View>
</Animated.View>
</Background>
)
}
Example #15
Source File: Settings.tsx From save-food with MIT License | 4 votes |
Settings = ({ navigation }: Props) => {
const { useSubscribe, setSettings } = useSettingsContext()
const settings = useSubscribe((s) => s.settings)
const translations = useSubscribe((s) => ({
...s.translations.Settings,
...s.translations.common,
}))
const [modalType, setModalType] = useState<ModalType>('language')
const [modalContent, setModalContent] = useState<ReactNode>()
const [showModal, setShowModal] = useState(false)
const languageMap: LanguageMap = {
en: translations.english,
pl: translations.polish,
}
const changeLanguageHandler = async (lang: Language) => {
setSettings(await changeLang(lang))
setShowModal(false)
}
const changeCurrencyHandler = async (currency: Currency) => {
setSettings(await changeCurrency(currency))
setShowModal(false)
}
const clearDatabaseHandler = async () => {
setSettings(await clearDatabase())
setShowModal(false)
showSuccessMessage()
}
const setModalContentHandler = (type: ModalType) => {
if (type === 'language') {
setModalContent(
<View>
{(Object.keys(languageMap) as Array<keyof LanguageMap>).map((lang) => (
<TouchableOpacity key={lang} onPress={() => changeLanguageHandler(lang)}>
<ListItem bottomDivider>
<ListItem.Content>
<ListItem.Title
style={{ color: lang === settings.lang ? primaryColor : blackColor }}
>
{languageMap[lang]}
</ListItem.Title>
</ListItem.Content>
</ListItem>
</TouchableOpacity>
))}
</View>,
)
} else if (type === 'currency') {
setModalContent(
<View>
{currencyList.map((item) => (
<TouchableOpacity key={item} onPress={() => changeCurrencyHandler(item)}>
<ListItem bottomDivider>
<ListItem.Content>
<ListItem.Title
style={{ color: item === settings.currency ? primaryColor : blackColor }}
>
{item}
</ListItem.Title>
</ListItem.Content>
</ListItem>
</TouchableOpacity>
))}
</View>,
)
} else if (type === 'clearTheDatabase') {
setModalContent(
<Text style={styles.clearTheDatabase}>{translations.clearTheDatabaseModal}</Text>,
)
}
setModalType(type)
setShowModal(true)
}
const toggleModal = (type?: ModalType) => {
if (!showModal && type) {
setModalContentHandler(type)
} else {
setShowModal(false)
}
}
const showSuccessMessage = () => {
const message: MessageOptions = {
message: translations.clearTheDatabaseSuccess,
type: 'success',
icon: { icon: 'success', position: 'left' },
duration: 2500,
}
showMessage(message)
}
return (
<View style={styles.container}>
<Header
leftComponent={<Icon onPress={() => navigation.replace('Home')} variant='backIcon' />}
centerComponent={<Text style={styles.headerTitle}>{translations.settings}</Text>}
/>
<Modal
visible={showModal}
toggleModal={toggleModal}
title={translations[modalType]}
buttons={
modalType === 'clearTheDatabase'
? [
{ text: translations.yes, onPress: clearDatabaseHandler },
{ text: translations.cancel, onPress: toggleModal },
]
: []
}
>
{modalContent}
</Modal>
<View style={styles.settingsWrapper}>
<InfoWindow
color1={blackColor}
color2={orangeGradient}
title={translations.language}
value={languageMap[settings.lang]}
colorTitle={whiteColor}
onPress={() => toggleModal('language')}
/>
<InfoWindow
color1={blackColor}
color2={redGradient}
title={translations.currency}
value={settings.currency}
colorTitle={whiteColor}
onPress={() => toggleModal('currency')}
/>
<TouchableOpacity style={styles.clear} onPress={() => toggleModal('clearTheDatabase')}>
<Text style={styles.clearText}>{`${translations.clearTheDatabase} `}</Text>
<Icon
onPress={() => toggleModal('clearTheDatabase')}
size={28}
name='trash-o'
type='font-awesome'
/>
</TouchableOpacity>
</View>
<View style={styles.footerContainer}>
<Text style={styles.versionText}>
{translations.version}: {settings.version}
</Text>
<TouchableOpacity onPress={() => WebBrowser.openBrowserAsync(config.FOOD_API)}>
<Text style={styles.linkText}>API: {config.FOOD_API}</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => WebBrowser.openBrowserAsync(config.WS_URL)}>
<Text style={styles.linkText}>
{translations.authors}: {config.WS_URL}
</Text>
</TouchableOpacity>
</View>
</View>
)
}
Example #16
Source File: About.tsx From wuhan2020-frontend-react-native-app with MIT License | 4 votes |
function About() {
const [loadingWebview, setLoading] = useState(true);
return (
<StatusBarSafeLayout>
<ScrollView>
<View style={styles.container}>
<View>
<Text style={styles.header}>数据来源</Text>
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://github.com/wuhan2020/wuhan2020')
}>
https://github.com/wuhan2020/wuhan2020
</Text>
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://3g.dxy.cn/newh5/view/pneumonia')
}>
丁香园
</Text>
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://2019ncov.nosugartech.com/')
}>
https://2019ncov.nosugartech.com/
</Text>
<Text
style={styles.link}
onPress={() =>
Linking.openURL('http://ncov.news.dragon-yuan.me/')
}>
http://ncov.news.dragon-yuan.me/
</Text>
</View>
<Divider style={styles.divider} />
<View>
<Text style={styles.header}>wuhan2020</Text>
<Text style={{ lineHeight: 18 }}>
我们是 GitHub
开源社区的志愿者核心团队,在抗击非冠病毒的战役中,我们希望通过共同构建一个开源信息共享项目,帮助武汉自组织救援工作更有效、更准确地开展。我们当前在做的事是:建立一个医院、工厂、采购等信息实时同步的数据服务,同时召集所有希望对这次抗击病毒战役进行贡献的人,让每个具有相关技能的人都可以参与相关主题的开发工作,用开源的社区文化,以自组织协作的方式完成。
</Text>
</View>
<Divider style={styles.divider} />
<View>
<Text style={styles.header}>加入我们</Text>
<Text style={{ lineHeight: 18 }}>
如果你也想加入我们,可以通过以下方式:
</Text>
<View>
<ListItem
title="加入我们"
rightAvatar={
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://github.com/wuhan2020/wuhan2020')
}>
点击此链接了解详情
</Text>
}
/>
<ListItem
title="GitHub"
rightAvatar={
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://github.com/wuhan2020/wuhan2020')
}>
GitHub
</Text>
}
/>
</View>
</View>
<Divider style={styles.divider} />
<View>
<Text style={styles.header}>建议</Text>
<Text style={{ lineHeight: 18 }}>
如果你有任何好的建议,无论是对我们的项目还是这个App都可以发邮件至
</Text>
<Text
style={[styles.link, { marginVertical: 5 }]}
onPress={() => Linking.openURL('mailto:[email protected]')}>
[email protected]
</Text>
</View>
<Divider style={styles.divider} />
<View>
<Text style={styles.header}>其他信息</Text>
<ListItem title="版本" rightAvatar={<Text>1.0.0</Text>} />
<ListItem title="技术" rightAvatar={<Text>React Native</Text>} />
<ListItem
title="代码库"
rightAvatar={
<Text
style={styles.link}
onPress={() =>
Linking.openURL(
'https://github.com/wuhan2020/wuhan2020-frontend-react-native-app',
)
}>
GitHub
</Text>
}
/>
<ListItem
title="作者"
rightAvatar={
<Text
style={styles.link}
onPress={() =>
Linking.openURL('https://github.com/geastwood')
}>
geastwood(飞)
</Text>
}
/>
</View>
<Divider style={styles.divider} />
</View>
</ScrollView>
</StatusBarSafeLayout>
);
}