1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/*
* Note: the dataSet properties are used to leverage custom CSS in public/index.html
*/
import React, {useState, useEffect} from 'react'
import {StyleSheet, Text, View} from 'react-native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
Props as FontAwesomeProps,
} from '@fortawesome/react-native-fontawesome'
const DURATION = 3500
interface ActiveToast {
text: string
icon: FontAwesomeProps['icon']
}
type GlobalSetActiveToast = (_activeToast: ActiveToast | undefined) => void
// globals
// =
let globalSetActiveToast: GlobalSetActiveToast | undefined
let toastTimeout: NodeJS.Timeout | undefined
// components
// =
type ToastContainerProps = {}
export const ToastContainer: React.FC<ToastContainerProps> = ({}) => {
const [activeToast, setActiveToast] = useState<ActiveToast | undefined>()
useEffect(() => {
globalSetActiveToast = (t: ActiveToast | undefined) => {
setActiveToast(t)
}
})
return (
<>
{activeToast && (
<View style={styles.container}>
<FontAwesomeIcon
icon={activeToast.icon}
size={24}
style={styles.icon as FontAwesomeIconStyle}
/>
<Text style={styles.text}>{activeToast.text}</Text>
</View>
)}
</>
)
}
// methods
// =
export function show(text: string, icon: FontAwesomeProps['icon'] = 'check') {
if (toastTimeout) {
clearTimeout(toastTimeout)
}
globalSetActiveToast?.({text, icon})
toastTimeout = setTimeout(() => {
globalSetActiveToast?.(undefined)
}, DURATION)
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
left: 20,
bottom: 20,
// @ts-ignore web only
width: 'calc(100% - 40px)',
maxWidth: 350,
padding: 20,
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#000c',
borderRadius: 10,
},
icon: {
color: '#fff',
},
text: {
color: '#fff',
fontSize: 18,
marginLeft: 10,
},
})
|