Skip to content

Commit e52c2bc

Browse files
committed
添加toast
1 parent 064cf41 commit e52c2bc

File tree

22 files changed

+219
-55
lines changed

22 files changed

+219
-55
lines changed

App.tsx

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,32 @@
88
* @format
99
*/
1010

11-
import React, { type PropsWithChildren } from 'react';
11+
import React, { type PropsWithChildren } from 'react'
1212
import {
13-
Alert,
14-
Button,
13+
Button,
1514
SafeAreaView,
1615
ScrollView,
1716
StatusBar,
1817
StyleSheet,
1918
Text,
2019
useColorScheme,
2120
View,
22-
} from 'react-native';
21+
} from 'react-native'
2322

2423
import {
2524
Colors,
2625
DebugInstructions,
2726
Header,
2827
LearnMoreLinks,
2928
ReloadInstructions,
30-
} from 'react-native/Libraries/NewAppScreen';
29+
} from 'react-native/Libraries/NewAppScreen'
3130

3231
const Section: React.FC<
3332
PropsWithChildren<{
34-
title: string;
33+
title: string
3534
}>
3635
> = ({ children, title }) => {
37-
const isDarkMode = useColorScheme() === 'dark';
36+
const isDarkMode = useColorScheme() === 'dark'
3837
return (
3938
<View style={styles.sectionContainer}>
4039
<Text
@@ -43,7 +42,8 @@ const Section: React.FC<
4342
{
4443
color: isDarkMode ? Colors.white : Colors.black,
4544
},
46-
]}>
45+
]}
46+
>
4747
{title}
4848
</Text>
4949
<Text
@@ -52,19 +52,20 @@ const Section: React.FC<
5252
{
5353
color: isDarkMode ? Colors.light : Colors.dark,
5454
},
55-
]}>
55+
]}
56+
>
5657
{children}
5758
</Text>
5859
</View>
59-
);
60-
};
60+
)
61+
}
6162

6263
const App = () => {
63-
const isDarkMode = useColorScheme() === 'dark';
64+
const isDarkMode = useColorScheme() === 'dark'
6465

6566
const backgroundStyle = {
6667
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
67-
};
68+
}
6869

6970
return (
7071
<SafeAreaView style={backgroundStyle}>
@@ -74,13 +75,15 @@ const App = () => {
7475
/>
7576
<ScrollView
7677
contentInsetAdjustmentBehavior="automatic"
77-
style={backgroundStyle}>
78+
style={backgroundStyle}
79+
>
7880
<Header />
7981
<Button title="点击" testID="id" />
8082
<View
8183
style={{
8284
backgroundColor: isDarkMode ? Colors.black : Colors.white,
83-
}}>
85+
}}
86+
>
8487
<Section title="Step One">
8588
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
8689
screen and then come back to see your edits.
@@ -98,8 +101,8 @@ const App = () => {
98101
</View>
99102
</ScrollView>
100103
</SafeAreaView>
101-
);
102-
};
104+
)
105+
}
103106

104107
const styles = StyleSheet.create({
105108
sectionContainer: {
@@ -118,6 +121,6 @@ const styles = StyleSheet.create({
118121
highlight: {
119122
fontWeight: '700',
120123
},
121-
});
124+
})
122125

123-
export default App;
126+
export default App

__tests__/App-test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
* @format
33
*/
44

5-
import 'react-native';
6-
import React from 'react';
7-
import App from '../App';
5+
import 'react-native'
6+
import React from 'react'
7+
import App from '../App'
88

99
// Note: test renderer must be required after react-native.
10-
import renderer from 'react-test-renderer';
10+
import renderer from 'react-test-renderer'
1111

1212
it('renders correctly', () => {
13-
renderer.create(<App />);
14-
});
13+
renderer.create(<App />)
14+
})

app/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import * as React from 'react'
44
import { NavigationContainer } from '@react-navigation/native'
55
import { createNativeStackNavigator } from '@react-navigation/native-stack'
66
import { routerConfig } from './router.config'
7-
import { SafeAreaProvider } from 'react-native-safe-area-context'
87
import ErrorBoundary from './components/ErrorBoundary'
98
import { LogBox } from 'react-native'
9+
import { SafeAreaProvider } from 'react-native-safe-area-context'
1010

1111
const Stack = createNativeStackNavigator()
12-
LogBox.ignoreLogs(['AsyncModal Cancel'])
12+
LogBox.ignoreLogs(['ModalConfirm Cancel'])
1313

1414
function App() {
1515
return (

app/components/AsyncModal/components/Modal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/**
2+
* 基于原Modal封装了显示盒隐藏
23
* @Author: Aceh
34
* @Date: 2022-11-25 08:19:33
45
* @Last Modified by: aceh
5-
* @Last Modified time: 2022-11-25 21:11:09
6+
* @Last Modified time: 2022-11-26 12:00:18
67
*/
78
import React from 'react'
89
import { Modal as MD, ModalProps } from 'react-native'

app/components/AsyncModal/hooks.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react'
2+
import { ToastDuration } from '../Toast/constants'
23

3-
type i_ShowParams = {
4+
type i_ModalConfirmShowParams = {
45
/** 标题 */
56
title?: string
67

@@ -14,6 +15,15 @@ type i_ShowParams = {
1415
cancelText?: string
1516
}
1617

18+
export type i_ToastShowParams = {
19+
/** 要显示的内容 */
20+
content?: string
21+
/** 持续时间 */
22+
duration?: ToastDuration
23+
}
24+
25+
type i_ShowParams = i_ModalConfirmShowParams & i_ToastShowParams
26+
1727
export type i_ModalIns = {
1828
/** resolve时表示OK, reject表示cancel */
1929
show(data?: i_ShowParams): Promise<void>

app/components/AsyncModal/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import ModalConfirm from './components/Confirm'
2-
31
/**
42
* @Author: Aceh
53
* @Date: 2022-11-25 21:21:37
64
* @Last Modified by: aceh
7-
* @Last Modified time: 2022-11-25 21:22:18
5+
* @Last Modified time: 2022-11-26 12:02:16
86
*/
9-
export default ModalConfirm
7+
import ModalConfirm from './components/Confirm'
8+
import Modal from './components/Modal'
9+
10+
export { ModalConfirm, Modal }

app/components/ErrorBoundary/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react'
2+
import { Text } from 'react-native'
23

34
export default class ErrorBoundary extends React.Component<{
45
fallback?: any
@@ -31,7 +32,7 @@ export default class ErrorBoundary extends React.Component<{
3132
render() {
3233
if (this.state.hasError) {
3334
// You can render any custom fallback UI
34-
return <div>我是错误信息</div>
35+
return <Text>我是错误信息</Text>
3536
}
3637

3738
return this.props.children

app/components/Toast/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum ToastDuration {
2+
LONG,
3+
SHORT,
4+
}

app/components/Toast/index.tsx

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,88 @@
11
import React from 'react'
2-
import { View, Text } from 'react-native'
2+
import { Text, StyleSheet, Dimensions, Animated } from 'react-native'
3+
import { Modal } from '../AsyncModal'
4+
import { i_ModalIns, i_ToastShowParams, useModal } from '../AsyncModal/hooks'
5+
6+
const height = Dimensions.get('window').height
7+
8+
type i_ToastProps = {
9+
modal: i_ModalIns
10+
}
11+
12+
const Toast: React.FC<i_ToastProps> = ({ modal: propsModal }) => {
13+
const modal = useModal(propsModal)
14+
const opacity = React.useRef<Animated.Value>(new Animated.Value(1)).current
15+
const [state, setState] = React.useState<string>('')
16+
17+
const durationRef = React.useRef<any>()
18+
19+
const handleShowAnimation = () => {
20+
Animated.timing(opacity, {
21+
toValue: 1,
22+
useNativeDriver: true,
23+
duration: 300,
24+
}).start(() => {
25+
Animated.timing(opacity, {
26+
toValue: 0,
27+
useNativeDriver: true,
28+
duration: 200,
29+
delay: durationRef.current,
30+
}).start(() => {
31+
modal.hide()
32+
})
33+
})
34+
}
35+
36+
const handleChange = (visible: boolean) => {
37+
if (visible) {
38+
handleShowAnimation()
39+
return
40+
}
41+
// opacity.setValue(0)
42+
// TODO: hide
43+
}
44+
45+
const handleShow = (data: i_ToastShowParams) => {
46+
durationRef.current = data.duration
47+
setState(data.content as string)
48+
}
349

4-
const Toast: React.FC<any> = () => {
550
return (
6-
<View>
7-
<Text>Toast</Text>
8-
</View>
51+
<Modal
52+
modal={modal}
53+
transparent={true}
54+
onVisibleChange={handleChange}
55+
showMiddle={handleShow}
56+
>
57+
<Animated.View style={[styles.container, { opacity }]}>
58+
<Text style={styles.content}>{state}</Text>
59+
</Animated.View>
60+
</Modal>
961
)
1062
}
1163

1264
Toast.displayName = 'Toast'
1365

1466
export default Toast
67+
68+
const styles = StyleSheet.create({
69+
container: {
70+
backgroundColor: 'rgba(0,0,0,.7)',
71+
position: 'absolute',
72+
height: 35,
73+
alignItems: 'center',
74+
flexDirection: 'row',
75+
justifyContent: 'center',
76+
alignSelf: 'center',
77+
borderRadius: 50,
78+
paddingLeft: 20,
79+
paddingRight: 20,
80+
shadowColor: 'rgba(0,0,0,1)',
81+
shadowOpacity: 0.3,
82+
shadowOffset: { width: 5, height: 5 },
83+
top: height * 0.4,
84+
},
85+
content: {
86+
color: 'white',
87+
},
88+
})

app/screens/Home/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const Home: React.FC<i_RouterParams> = ({ navigation }) => {
99
{routerConfig.map(item => (
1010
<Button
1111
key={item.name}
12+
testID={item.name}
1213
onPress={() => navigation.navigate(item.name)}
1314
title={(item.options as any).title || item.name}
1415
/>

app/screens/Toast/index.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1+
import Toast from 'app/components/Toast'
2+
import Button from 'app/components/Button'
13
import React from 'react'
2-
import { View, Text } from 'react-native'
4+
import { StyleSheet, View } from 'react-native'
5+
import { useModal } from 'app/components/AsyncModal/hooks'
6+
7+
const ToastScreen: React.FC<any> = () => {
8+
const modal = useModal()
9+
10+
const handleShow = () => {
11+
modal.show({ content: '心怀感恩,负重前行', duration: 2000 })
12+
}
313

4-
const Toast: React.FC<any> = () => {
514
return (
6-
<View>
7-
<Text>Toast</Text>
15+
<View style={styles.container}>
16+
<Toast modal={modal} />
17+
<Button title="显示toast" onPress={handleShow} />
818
</View>
919
)
1020
}
1121

12-
Toast.displayName = 'Toast'
22+
ToastScreen.displayName = 'ToastScreen'
1323

14-
export default Toast
24+
export default ToastScreen
25+
const styles = StyleSheet.create({
26+
container: {
27+
flex: 1,
28+
backgroundColor: 'red',
29+
justifyContent: 'center',
30+
alignItems: 'center',
31+
},
32+
})

0 commit comments

Comments
 (0)