NotificationManager 是 ZerOS 内核的通知管理系统,负责系统通知的创建、显示、管理和交互。支持两种通知类型:快照(snapshot)和依赖(dependent),并提供水滴展开动画效果。
TaskbarManager - 任务栏管理器(用于获取任务栏位置和显示通知图标)ProcessManager - 进程管理器(用于获取程序信息)PermissionManager - 权限管理器(用于权限检查和验证)GUIManager - GUI 管理器(用于窗口管理)AnimateManager - 动画管理器(用于水滴动画效果)通知管理器在系统启动时自动初始化,无需手动调用。
// 自动初始化(在 BootLoader 中)
await NotificationManager.init();
通知管理器提供了 CONFIG 常量对象,包含所有配置项:
NotificationManager.CONFIG = {
// 容器配置
CONTAINER_WIDTH: 380,
CONTAINER_TOP: 20,
CONTAINER_SIDE: 20,
CONTAINER_MIN_HEIGHT: 100,
CONTAINER_Z_INDEX: 10000,
// 蒙版层配置
OVERLAY_WIDTH: '45vw',
OVERLAY_Z_INDEX: 9998,
// 动画配置
ANIMATION: {
SHOW_DURATION: 250,
HIDE_DURATION: 200,
OVERLAY_FADE: 150,
DEPENDENT_EXPAND: 300,
DEPENDENT_REMOVE: 200,
SNAPSHOT_REMOVE: 150,
GLOBAL_CHECK_DELAY: 150,
MOUSE_LEAVE_DELAY: 100
},
// 样式配置
STYLES: {
NOTIFICATION_PADDING_SNAPSHOT: '16px',
NOTIFICATION_PADDING_DEPENDENT: '12px',
NOTIFICATION_GAP_SNAPSHOT: '12px',
NOTIFICATION_GAP_DEPENDENT: '0',
CLOSE_BUTTON_SIZE: 24,
CLOSE_BUTTON_SIZE_CONTAINER: 32,
BORDER_RADIUS: '16px',
BLUR_AMOUNT: 20
},
// 水滴动画初始状态
WATER_DROP: {
INITIAL_SIZE: 50,
INITIAL_SCALE: 0.2,
INITIAL_TRANSLATE_X: 80,
TARGET_BORDER_RADIUS: '16px'
}
};
独立通知,显示标题和内容,有标题栏和关闭按钮。适用于一次性通知消息。
特点:
依赖通知,紧贴在快照通知下方,从圆形展开为矩形。适用于程序持续显示的内容(如音乐播放器)。
特点:
createNotification(pid, options)创建通知。需要 SYSTEM_NOTIFICATION 权限,会自动进行权限检查。
参数:
pid (number): 程序 PIDoptions (Object): 通知选项
type (string): 通知类型,'snapshot' 或 'dependent',默认 'snapshot'title (string): 通知标题(可选,仅 snapshot 类型)content (string|HTMLElement): 通知内容,可以是 HTML 字符串或 HTMLElementduration (number): 自动关闭时长(毫秒,0 表示不自动关闭,可选)onClose (Function): 关闭回调(可选,仅 dependent 类型),(notificationId, pid) => {}返回值: Promise<string> - 通知 ID
权限检查:
SYSTEM_NOTIFICATION 权限(普通权限,自动授予)__info__ 中声明 SYSTEM_NOTIFICATION 权限示例:
// 创建快照通知(异步,需要 await)
try {
const notificationId = await NotificationManager.createNotification(this.pid, {
type: 'snapshot',
title: '系统通知',
content: '这是一条通知消息',
duration: 5000 // 5秒后自动关闭
});
console.log('通知已创建:', notificationId);
} catch (e) {
if (e.message.includes('没有权限')) {
console.error('权限被拒绝,无法创建通知');
} else {
console.error('创建通知失败:', e.message);
}
}
// 创建依赖通知(异步,需要 await)
const contentElement = document.createElement('div');
contentElement.innerHTML = '<div>音乐播放器内容</div>';
try {
const dependentId = await NotificationManager.createNotification(this.pid, {
type: 'dependent',
content: contentElement,
onClose: (notificationId, pid) => {
console.log('通知已关闭:', notificationId);
}
});
console.log('依赖通知已创建:', dependentId);
} catch (e) {
console.error('创建依赖通知失败:', e.message);
}
removeNotification(notificationId, silent)移除通知。需要 SYSTEM_NOTIFICATION 权限,会自动进行权限检查。
参数:
notificationId (string): 通知 IDsilent (boolean): 是否静默移除(不触发回调),默认 false返回值: Promise<boolean> - 是否成功
权限检查:
SYSTEM_NOTIFICATION 权限(普通权限,自动授予)__info__ 中声明 SYSTEM_NOTIFICATION 权限示例:
// 移除通知(触发回调)
NotificationManager.removeNotification(notificationId);
// 静默移除(不触发回调)
NotificationManager.removeNotification(notificationId, true);
updateNotificationContent(notificationId, content)更新通知内容。
参数:
notificationId (string): 通知 IDcontent (string|HTMLElement): 新内容示例:
// 更新为 HTML 字符串
NotificationManager.updateNotificationContent(notificationId, '<div>新内容</div>');
// 更新为 HTMLElement
const newElement = document.createElement('div');
newElement.textContent = '新内容';
NotificationManager.updateNotificationContent(notificationId, newElement);
getNotificationContentContainer(notificationId)获取通知内容容器(用于动态更新内容)。
参数:
notificationId (string): 通知 ID返回值: HTMLElement|null - 内容容器元素
示例:
const container = NotificationManager.getNotificationContentContainer(notificationId);
if (container) {
// 动态更新内容
const progressBar = container.querySelector('.progress-bar');
if (progressBar) {
progressBar.style.width = '50%';
}
}
getNotificationCount()获取通知数量。
返回值: number - 通知数量
getNotificationsByPid(pid)获取程序的所有通知 ID。
参数:
pid (number): 程序 PID返回值: Array<string> - 通知 ID 数组
getNotificationInfo(notificationId)获取通知信息。
参数:
notificationId (string): 通知 ID返回值: Object|null - 通知信息对象
{
id: string,
pid: number,
type: string,
title: string,
duration: number,
createdAt: number
}
getAllNotifications(pid)获取所有通知信息。
参数:
pid (number|null): 可选,如果提供则只返回该程序的通知返回值: Array<Object> - 通知信息数组
hasNotification(notificationId)检查通知是否存在。
参数:
notificationId (string): 通知 ID返回值: boolean - 是否存在
cleanupProgramNotifications(pid, triggerCallbacks, onlyDependent)清理程序的所有通知。
参数:
pid (number): 程序 PIDtriggerCallbacks (boolean): 是否触发依赖类型的关闭回调,默认 falseonlyDependent (boolean): 是否只清理依赖类型的通知,默认 true示例:
// 只清理依赖类型通知,不触发回调
NotificationManager.cleanupProgramNotifications(this.pid, false, true);
// 清理所有通知,触发回调
NotificationManager.cleanupProgramNotifications(this.pid, true, false);
toggleNotificationContainer()切换通知栏显示状态。
示例:
// 切换显示/隐藏
NotificationManager.toggleNotificationContainer();
isShowing()获取通知栏显示状态。
返回值: boolean - 是否正在显示
示例:
if (NotificationManager.isShowing()) {
console.log('通知栏正在显示');
}
checkStatus()检查初始化状态(用于调试)。
返回值: Object - 状态信息对象
{
initialized: boolean,
containerExists: boolean,
hoverZoneExists: boolean,
emptyStateExists: boolean,
notificationCount: number,
isShowing: boolean,
hoverZonePosition: Object,
containerPosition: Object,
taskbarPosition: string
}
testShow()手动触发显示(用于测试)。
testHide()手动触发隐藏(用于测试)。
// 在程序中使用
const notificationId = NotificationManager.createNotification(this.pid, {
type: 'snapshot',
title: '操作成功',
content: '文件已保存',
duration: 3000 // 3秒后自动关闭
});
// 创建音乐播放器通知
const createMusicPlayerNotification = () => {
const content = document.createElement('div');
content.className = 'music-player-content';
content.innerHTML = `
<div class="cover">
<img src="cover.jpg" alt="Cover">
</div>
<div class="info">
<div class="song">歌曲名称</div>
<div class="artist">艺术家</div>
</div>
<div class="controls">
<button class="prev">⏮</button>
<button class="play">▶</button>
<button class="next">⏭</button>
</div>
`;
const notificationId = NotificationManager.createNotification(this.pid, {
type: 'dependent',
content: content,
onClose: (notificationId, pid) => {
// 清理资源
console.log('音乐播放器通知已关闭');
}
});
// 保存通知 ID 以便后续更新
this._notificationId = notificationId;
};
// 更新播放进度
const updateProgress = (progress) => {
const container = NotificationManager.getNotificationContentContainer(this._notificationId);
if (container) {
const progressBar = container.querySelector('.progress-bar');
if (progressBar) {
progressBar.style.width = `${progress}%`;
}
}
};
__exit__: async function() {
// 清理所有通知(只清理依赖类型,触发回调)
NotificationManager.cleanupProgramNotifications(this.pid, true, true);
// 其他清理逻辑...
}
通知栏容器使用水滴展开动画:
依赖类型通知使用水滴展开动画:
通知管理器与任务栏集成:
_triggerBadgeUpdate() 方法)notification-{counter}getNotificationContentContainer() 获取容器后,可以直接操作 DOMonClose 回调在通知被移除时调用duration 为 0 表示不自动关闭通知管理器使用 KernelLogger 记录错误和警告:
// 查看控制台日志
KernelLogger.setLevel(3); // DEBUG 级别
常见错误: