TimScreen.tsx 4.3 KB

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