Implement web toast
parent
20eaac6acd
commit
24559599f3
|
@ -36,25 +36,6 @@
|
|||
border-radius: 10px;
|
||||
box-shadow: 0 5px 10px #0005;
|
||||
}
|
||||
|
||||
/* These styles are for src/view/com/util/Toast */
|
||||
div[data-toast-container] {
|
||||
position: fixed;
|
||||
bottom: 5vh;
|
||||
right: 5vh;
|
||||
width: 350px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 10px #0005;
|
||||
}
|
||||
div[data-toast-container] > div {
|
||||
font-size: 18px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -3,7 +3,7 @@ import {SafeAreaProvider} from 'react-native-safe-area-context'
|
|||
import * as view from './view/index'
|
||||
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
||||
import {WebShell} from './view/shell/web'
|
||||
// import Toast from 'react-native-root-toast' TODO
|
||||
import {ToastContainer} from './view/com/util/Toast.web'
|
||||
|
||||
function App() {
|
||||
const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
|
||||
|
@ -26,9 +26,9 @@ function App() {
|
|||
<SafeAreaProvider>
|
||||
<WebShell />
|
||||
</SafeAreaProvider>
|
||||
<ToastContainer />
|
||||
</RootStoreProvider>
|
||||
)
|
||||
// <Toast.ToastContainer /> TODO
|
||||
}
|
||||
|
||||
export default App
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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} from '@fortawesome/react-native-fontawesome'
|
||||
|
||||
const DURATION = 3500
|
||||
|
||||
interface ActiveToast {
|
||||
text: string
|
||||
}
|
||||
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="check" size={24} style={styles.icon} />
|
||||
<Text style={styles.text}>{activeToast.text}</Text>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// methods
|
||||
// =
|
||||
export function show(text: string) {
|
||||
if (toastTimeout) {
|
||||
clearTimeout(toastTimeout)
|
||||
}
|
||||
globalSetActiveToast?.({text})
|
||||
toastTimeout = setTimeout(() => {
|
||||
globalSetActiveToast?.(undefined)
|
||||
}, DURATION)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
position: 'absolute',
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
width: 350,
|
||||
padding: 20,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#000c',
|
||||
borderRadius: 10,
|
||||
},
|
||||
icon: {
|
||||
color: '#fff',
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 18,
|
||||
marginLeft: 10,
|
||||
},
|
||||
})
|
Loading…
Reference in New Issue