Implement web toast
parent
20eaac6acd
commit
24559599f3
|
@ -36,25 +36,6 @@
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 5px 10px #0005;
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {SafeAreaProvider} from 'react-native-safe-area-context'
|
||||||
import * as view from './view/index'
|
import * as view from './view/index'
|
||||||
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
import {RootStoreModel, setupState, RootStoreProvider} from './state'
|
||||||
import {WebShell} from './view/shell/web'
|
import {WebShell} from './view/shell/web'
|
||||||
// import Toast from 'react-native-root-toast' TODO
|
import {ToastContainer} from './view/com/util/Toast.web'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
|
const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
|
||||||
|
@ -26,9 +26,9 @@ function App() {
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<WebShell />
|
<WebShell />
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
|
<ToastContainer />
|
||||||
</RootStoreProvider>
|
</RootStoreProvider>
|
||||||
)
|
)
|
||||||
// <Toast.ToastContainer /> TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
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