- 在项目中引入expo-notifications库,支持本地推送通知功能 - 实现通知权限管理,用户可选择开启或关闭通知 - 新增通知发送、定时通知和重复通知功能 - 更新个人页面,集成通知开关和权限请求逻辑 - 编写推送通知功能实现文档,详细描述功能和使用方法 - 优化心情日历页面,确保数据实时刷新
158 lines
5.0 KiB
TypeScript
158 lines
5.0 KiB
TypeScript
import { useEffect, useState, useCallback } from 'react';
|
|
import { notificationService, NotificationData, NotificationTypes } from '../services/notifications';
|
|
import * as Notifications from 'expo-notifications';
|
|
|
|
export interface UseNotificationsReturn {
|
|
isInitialized: boolean;
|
|
permissionStatus: Notifications.PermissionStatus | null;
|
|
initialize: () => Promise<void>;
|
|
requestPermission: () => Promise<Notifications.PermissionStatus>;
|
|
sendNotification: (notification: NotificationData) => Promise<string>;
|
|
scheduleNotification: (notification: NotificationData, date: Date) => Promise<string>;
|
|
scheduleRepeatingNotification: (
|
|
notification: NotificationData,
|
|
interval: {
|
|
seconds?: number;
|
|
minutes?: number;
|
|
hours?: number;
|
|
days?: number;
|
|
weeks?: number;
|
|
months?: number;
|
|
years?: number;
|
|
}
|
|
) => Promise<string>;
|
|
cancelNotification: (notificationId: string) => Promise<void>;
|
|
cancelAllNotifications: () => Promise<void>;
|
|
getAllScheduledNotifications: () => Promise<Notifications.NotificationRequest[]>;
|
|
sendWorkoutReminder: (title: string, body: string, date?: Date) => Promise<string>;
|
|
sendGoalAchievement: (title: string, body: string) => Promise<string>;
|
|
sendMoodCheckinReminder: (title: string, body: string, date?: Date) => Promise<string>;
|
|
}
|
|
|
|
export const useNotifications = (): UseNotificationsReturn => {
|
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
const [permissionStatus, setPermissionStatus] = useState<Notifications.PermissionStatus | null>(null);
|
|
|
|
const initialize = useCallback(async () => {
|
|
try {
|
|
await notificationService.initialize();
|
|
const status = await notificationService.getPermissionStatus();
|
|
setPermissionStatus(status);
|
|
setIsInitialized(true);
|
|
} catch (error) {
|
|
console.error('初始化通知服务失败:', error);
|
|
}
|
|
}, []);
|
|
|
|
const requestPermission = useCallback(async () => {
|
|
try {
|
|
const status = await notificationService.requestPermission();
|
|
setPermissionStatus(status);
|
|
return status;
|
|
} catch (error) {
|
|
console.error('请求通知权限失败:', error);
|
|
throw error;
|
|
}
|
|
}, []);
|
|
|
|
const sendNotification = useCallback(async (notification: NotificationData) => {
|
|
return notificationService.sendImmediateNotification(notification);
|
|
}, []);
|
|
|
|
const scheduleNotification = useCallback(async (notification: NotificationData, date: Date) => {
|
|
return notificationService.scheduleNotificationAtDate(notification, date);
|
|
}, []);
|
|
|
|
const scheduleRepeatingNotification = useCallback(async (
|
|
notification: NotificationData,
|
|
interval: {
|
|
seconds?: number;
|
|
minutes?: number;
|
|
hours?: number;
|
|
days?: number;
|
|
weeks?: number;
|
|
months?: number;
|
|
years?: number;
|
|
}
|
|
) => {
|
|
return notificationService.scheduleRepeatingNotification(notification, interval);
|
|
}, []);
|
|
|
|
const cancelNotification = useCallback(async (notificationId: string) => {
|
|
return notificationService.cancelNotification(notificationId);
|
|
}, []);
|
|
|
|
const cancelAllNotifications = useCallback(async () => {
|
|
return notificationService.cancelAllNotifications();
|
|
}, []);
|
|
|
|
const getAllScheduledNotifications = useCallback(async () => {
|
|
return notificationService.getAllScheduledNotifications();
|
|
}, []);
|
|
|
|
const sendWorkoutReminder = useCallback(async (title: string, body: string, date?: Date) => {
|
|
const notification: NotificationData = {
|
|
title,
|
|
body,
|
|
data: { type: NotificationTypes.WORKOUT_REMINDER },
|
|
sound: true,
|
|
priority: 'high',
|
|
};
|
|
|
|
if (date) {
|
|
return notificationService.scheduleNotificationAtDate(notification, date);
|
|
} else {
|
|
return notificationService.sendImmediateNotification(notification);
|
|
}
|
|
}, []);
|
|
|
|
const sendGoalAchievement = useCallback(async (title: string, body: string) => {
|
|
const notification: NotificationData = {
|
|
title,
|
|
body,
|
|
data: { type: NotificationTypes.GOAL_ACHIEVEMENT },
|
|
sound: true,
|
|
priority: 'high',
|
|
};
|
|
|
|
return notificationService.sendImmediateNotification(notification);
|
|
}, []);
|
|
|
|
const sendMoodCheckinReminder = useCallback(async (title: string, body: string, date?: Date) => {
|
|
const notification: NotificationData = {
|
|
title,
|
|
body,
|
|
data: { type: NotificationTypes.MOOD_CHECKIN },
|
|
sound: true,
|
|
priority: 'normal',
|
|
};
|
|
|
|
if (date) {
|
|
return notificationService.scheduleNotificationAtDate(notification, date);
|
|
} else {
|
|
return notificationService.sendImmediateNotification(notification);
|
|
}
|
|
}, []);
|
|
|
|
// 组件挂载时自动初始化
|
|
useEffect(() => {
|
|
initialize();
|
|
}, [initialize]);
|
|
|
|
return {
|
|
isInitialized,
|
|
permissionStatus,
|
|
initialize,
|
|
requestPermission,
|
|
sendNotification,
|
|
scheduleNotification,
|
|
scheduleRepeatingNotification,
|
|
cancelNotification,
|
|
cancelAllNotifications,
|
|
getAllScheduledNotifications,
|
|
sendWorkoutReminder,
|
|
sendGoalAchievement,
|
|
sendMoodCheckinReminder,
|
|
};
|
|
};
|