tooot/src/components/toast.tsx

136 lines
3.1 KiB
TypeScript
Raw Normal View History

import Icon from '@components/Icon'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
2020-11-28 17:07:30 +01:00
import React from 'react'
2021-01-14 00:43:35 +01:00
import { Platform, StyleSheet, Text, ToastAndroid, View } from 'react-native'
2020-11-28 17:07:30 +01:00
import { SafeAreaView } from 'react-native-safe-area-context'
import Toast from 'react-native-toast-message'
import * as Sentry from 'sentry-expo'
2020-11-28 17:07:30 +01:00
export interface Params {
type: 'success' | 'error' | 'warning'
position?: 'top' | 'bottom'
2021-01-01 23:10:47 +01:00
message: string
2020-11-28 17:07:30 +01:00
description?: string
autoHide?: boolean
onShow?: () => void
onHide?: () => void
}
type Config = {
type: Params['type']
position: Params['position']
2021-01-01 23:10:47 +01:00
text1: Params['message']
2020-11-28 17:07:30 +01:00
text2: Params['description']
}
const toast = ({
type,
position = 'top',
2021-01-01 23:10:47 +01:00
message,
2020-11-28 17:07:30 +01:00
description,
autoHide = true,
onShow,
onHide
}: Params) => {
2021-01-14 00:43:35 +01:00
switch (Platform.OS) {
case 'ios':
return Toast.show({
type,
position,
text1: message,
text2: description,
visibilityTime: 1500,
autoHide,
topOffset: 0,
bottomOffset: 0,
onShow: onShow,
onHide: onHide
})
case 'android':
return ToastAndroid.show(message, ToastAndroid.SHORT)
}
2020-11-28 17:07:30 +01:00
}
const ToastBase = ({ config }: { config: Config }) => {
const { theme } = useTheme()
const iconSet = {
success: 'CheckCircle',
error: 'XCircle',
warning: 'AlertCircle'
2020-11-28 17:07:30 +01:00
}
2020-12-26 00:40:27 +01:00
enum colorMapping {
success = 'blue',
error = 'red',
2020-12-26 14:40:10 +01:00
warning = 'secondary'
2020-12-26 00:40:27 +01:00
}
2020-11-28 17:07:30 +01:00
return (
<SafeAreaView
style={[
styles.base,
2020-12-29 16:19:04 +01:00
{ backgroundColor: theme.background, borderBottomColor: theme.primary }
2020-11-28 17:07:30 +01:00
]}
>
<View style={styles.container}>
<Icon
2020-11-28 17:07:30 +01:00
name={iconSet[config.type]}
size={StyleConstants.Font.Size.M}
2020-12-26 00:40:27 +01:00
color={theme[colorMapping[config.type]]}
2020-11-28 17:07:30 +01:00
/>
<View style={styles.texts}>
<Text
style={[styles.text1, { color: theme.primary }]}
numberOfLines={2}
>
{config.text1}
</Text>
{config.text2 && (
<Text
style={[styles.text2, { color: theme.secondary }]}
numberOfLines={2}
>
{config.text2}
</Text>
)}
</View>
2020-11-28 17:07:30 +01:00
</View>
</SafeAreaView>
)
}
const toastConfig = {
success: (config: Config) => <ToastBase config={config} />,
warning: (config: Config) => <ToastBase config={config} />,
error: (config: Config) => {
// Sentry.Native.captureException([config.text1, config.text2])
return <ToastBase config={config} />
}
2020-11-28 17:07:30 +01:00
}
const styles = StyleSheet.create({
base: {
width: '100%',
2020-12-29 16:19:04 +01:00
borderBottomWidth: 1
2020-11-28 17:07:30 +01:00
},
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
padding: StyleConstants.Spacing.M
2020-11-28 17:07:30 +01:00
},
texts: {
2020-11-30 00:24:53 +01:00
marginLeft: StyleConstants.Spacing.S
},
text1: {
...StyleConstants.FontStyle.M
},
text2: {
...StyleConstants.FontStyle.S,
marginTop: StyleConstants.Spacing.XS
2020-11-28 17:07:30 +01:00
}
})
export { toast, toastConfig }