feat: 集成推送通知功能及相关组件
- 在项目中引入expo-notifications库,支持本地推送通知功能 - 实现通知权限管理,用户可选择开启或关闭通知 - 新增通知发送、定时通知和重复通知功能 - 更新个人页面,集成通知开关和权限请求逻辑 - 编写推送通知功能实现文档,详细描述功能和使用方法 - 优化心情日历页面,确保数据实时刷新
This commit is contained in:
157
hooks/useNotifications.ts
Normal file
157
hooks/useNotifications.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user