在 Manus 中运行任何 Skill
一键导入
一键导入
一键在 Manus 中运行任何 Skill
开始使用notifications
星标7
分支1
更新时间2026年1月15日 19:02
Push notifications and in-app alerts
安装
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
SKILL.md
readonly菜单
Push notifications and in-app alerts
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Image caching and storage management with expo-image
Reusable component patterns and styling
URL schemes and deep link handling
Background chapter downloads and offline reading
Common patterns for Expo SDK 54 and React Native development
Paperback-compatible extension runtime and source API
基于 SOC 职业分类
| name | Notifications |
| description | Push notifications and in-app alerts |
import * as Notifications from 'expo-notifications';
// Configure handler
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
}),
});
async function requestPermissions() {
const { status } = await Notifications.requestPermissionsAsync();
return status === 'granted';
}
// Schedule immediate notification
await Notifications.scheduleNotificationAsync({
content: {
title: 'New Chapter',
body: 'Manga X has a new chapter!',
data: { mangaId: '123', type: 'new_chapter' },
},
trigger: null, // Immediate
});
// Schedule delayed notification
await Notifications.scheduleNotificationAsync({
content: {
title: 'Reminder',
body: 'Continue reading...',
},
trigger: { seconds: 3600 }, // 1 hour
});
// Cancel all
await Notifications.cancelAllScheduledNotificationsAsync();
useEffect(() => {
// Notification received while app is open
const receivedSub = Notifications.addNotificationReceivedListener(
(notification) => {
console.log('Received:', notification);
}
);
// User tapped notification
const responseSub = Notifications.addNotificationResponseReceivedListener(
(response) => {
const data = response.notification.request.content.data;
if (data.type === 'new_chapter') {
navigation.navigate('MangaDetail', { mangaId: data.mangaId });
}
}
);
return () => {
receivedSub.remove();
responseSub.remove();
};
}, []);
// services/notificationService.ts
import * as Notifications from 'expo-notifications';
export const notificationService = {
async notifyNewChapter(manga: Manga, chapter: Chapter) {
await Notifications.scheduleNotificationAsync({
content: {
title: manga.title,
body: `Chapter ${chapter.chapNum} is available`,
data: { mangaId: manga.id, chapterId: chapter.id },
},
trigger: null,
});
},
async notifyDownloadComplete(manga: Manga, chapterCount: number) {
await Notifications.scheduleNotificationAsync({
content: {
title: 'Download Complete',
body: `${manga.title} - ${chapterCount} chapters`,
data: { mangaId: manga.id, type: 'download' },
},
trigger: null,
});
},
};
// For download progress, use BackgroundService notifications
import BackgroundService from 'react-native-background-actions';
await BackgroundService.updateNotification({
taskTitle: 'Downloading',
taskDesc: `${current}/${total} pages`,
progressBar: { max: total, value: current },
});
// Set badge
await Notifications.setBadgeCountAsync(5);
// Clear badge
await Notifications.setBadgeCountAsync(0);
// Get badge
const count = await Notifications.getBadgeCountAsync();
// app.json
{
"expo": {
"plugins": [
[
"expo-notifications",
{
"icon": "./assets/icon.png",
"color": "#FA6432"
}
]
]
}
}