import { useEffect, useState, useRef } from 'react'; import * as Notifications from 'expo-notifications'; import * as Device from 'expo-device'; import Constants from 'expo-constants'; import { Platform } from 'react-native'; export interface PushNotificationState { notification?: Notifications.Notification; expoPushToken?: Notifications.ExpoPushToken; } export const usePushNotifications = (): PushNotificationState => { const [expoPushToken, setExpoPushToken] = useState(); const [notification, setNotification] = useState(); const notificationListener = useRef(); const responseListener = useRef(); useEffect(() => { Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldPlaySound: true, shouldShowAlert: true, shouldSetBadge: true, vibrate: true, shouldShowWhenInForeground: true } as any) }); registerForPushNotificationAsync().then((token) => { setExpoPushToken(token); }); notificationListener.current = Notifications.addNotificationReceivedListener((notification) => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => { }); return () => { Notifications.removeNotificationSubscription(notificationListener.current!); Notifications.removeNotificationSubscription(responseListener.current!); }; }, []); return { expoPushToken, notification }; }; async function registerForPushNotificationAsync() { let token; // Check if the device is a physical device, because this only works for physical devices not simulators if (Device.isDevice) { const { status: existingStatus } = await Notifications.getPermissionsAsync(); let finalStatus = existingStatus; if (existingStatus !== 'granted') { const { status } = await Notifications.requestPermissionsAsync(); finalStatus = status; } if (finalStatus !== 'granted') { alert('需要通知權限才能接收充電狀態更新。請前往「設定」>「通知」中開啟 CrazyCharge 的通知權限。'); return; } //if we have permission, then get the token token = await Notifications.getExpoPushTokenAsync({ projectId: Constants.expoConfig?.extra?.eas?.projectId }); if (Platform.OS === 'android') { Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#FF231F7C' }); } return token; } else { } }