TimScreen.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import Constants from 'expo-constants';
  2. import * as Notifications from 'expo-notifications';
  3. import * as Permissions from 'expo-permissions';
  4. import { StackScreenProps } from '@react-navigation/stack';
  5. import * as React from 'react';
  6. import { useNavigation } from '@react-navigation/native';
  7. import { WebView } from 'react-native-webview';
  8. import {useModel,setModel} from 'flooks';
  9. import { useMount } from 'ahooks';
  10. import IM from './model';
  11. setModel("IMModel", IM);
  12. import { SoundPlay } from '../utils/SoundUtils';
  13. if (!__DEV__) {
  14. Notifications.setNotificationHandler({
  15. handleNotification: async () => ({
  16. shouldShowAlert: true,
  17. shouldPlaySound: false,
  18. shouldSetBadge: false,
  19. }),
  20. });
  21. }
  22. export default function NoticeScreen({
  23. navigation,
  24. }: StackScreenProps<RootStackParamList, 'Login'>) {
  25. const webRef = React.useRef();
  26. const {
  27. getChat,
  28. getSysNotice,
  29. userID,
  30. userSig,
  31. tim,
  32. setTim,
  33. initChat,
  34. updateChatInfo,
  35. sendPushNotification,
  36. } = useModel("IMModel");
  37. useMount(() => {
  38. initChat();
  39. });
  40. const [expoPushToken, setExpoPushToken] = React.useState('');
  41. const [notification, setNotification] = React.useState(false);
  42. const notificationListener = React.useRef();
  43. const responseListener = React.useRef();
  44. React.useEffect(() => {
  45. if (!__DEV__) {
  46. registerForPushNotificationsAsync().then((token) =>
  47. setExpoPushToken(token)
  48. );
  49. notificationListener.current = Notifications.addNotificationReceivedListener(
  50. (notification) => {
  51. setNotification(notification);
  52. }
  53. );
  54. responseListener.current = Notifications.addNotificationResponseReceivedListener(
  55. (response) => {
  56. console.log(response);
  57. }
  58. );
  59. return () => {
  60. Notifications.removeNotificationSubscription(notificationListener);
  61. Notifications.removeNotificationSubscription(responseListener);
  62. };
  63. }
  64. }, []);
  65. React.useEffect(() => {
  66. if (userSig && tim)
  67. tim.injectJavaScript(
  68. `window.chatLogin(${JSON.stringify(userID)},${JSON.stringify(userSig)})`
  69. );
  70. }, [userSig, tim]);
  71. return (
  72. <>
  73. <WebView
  74. ref={webRef}
  75. source={{
  76. uri: `http://dingdong.izouma.com/map/tim`,
  77. }}
  78. onMessage={({ nativeEvent }) => {
  79. console.log(nativeEvent);
  80. const info =
  81. nativeEvent.data.indexOf('{') !== -1
  82. ? JSON.parse(nativeEvent.data)
  83. : {};
  84. console.log(info);
  85. if (Array.isArray(info)) {
  86. getChat();
  87. const message = info[0];
  88. if (/^\d{n}$/.test(message.from)) {
  89. updateChatInfo(message);
  90. } else {
  91. getSysNotice();
  92. const { payload } = message;
  93. let body = payload ? payload.text : '';
  94. if (body.indexOf('voice_') !== -1) {
  95. const textInfo = body.split(';');
  96. body = textInfo[1];
  97. SoundPlay(textInfo[0]);
  98. }
  99. sendPushNotification('系统通知', body);
  100. }
  101. }
  102. }}
  103. onLoadEnd={() => {
  104. setTim(webRef.current);
  105. }}
  106. />
  107. </>
  108. );
  109. }
  110. async function registerForPushNotificationsAsync() {
  111. let token;
  112. if (Constants.isDevice) {
  113. const { status: existingStatus } = await Permissions.getAsync(
  114. Permissions.NOTIFICATIONS
  115. );
  116. let finalStatus = existingStatus;
  117. if (existingStatus !== 'granted') {
  118. const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
  119. finalStatus = status;
  120. }
  121. if (finalStatus !== 'granted') {
  122. alert('Failed to get push token for push notification!');
  123. return;
  124. }
  125. token = (await Notifications.getExpoPushTokenAsync()).data;
  126. console.log(token);
  127. } else {
  128. alert('Must use physical device for Push Notifications');
  129. }
  130. if (Platform.OS === 'android') {
  131. Notifications.setNotificationChannelAsync('default', {
  132. name: 'default',
  133. importance: Notifications.AndroidImportance.MAX,
  134. vibrationPattern: [0, 250, 250, 250],
  135. lightColor: '#FF231F7C',
  136. });
  137. }
  138. return token;
  139. }