Notification是什么?
对于渲染进程,Electron 允许开发者使用通知中API,来运行系统的原生通知进行显示。
如何实现系统Notification?
const { Notification } = require('electron');
const isAllowed = Notification.isSupported();
if (isAllowed) {
const options = {
title: '标题',
body: '正文文本,显示在标题下方',
silent: true, // 系统默认的通知声音
icon: '', // 通知图标
}
const notification = new Notification(argConig);
notification.on('click', () => { });
notification.on('show', () => { });
notification.on('close', () => { });
notification.show();
}
系统Notification的困扰
1)受限于当前系统是否支持
系统通知,在mac或windows电脑的设置中,需特别注意是否允许通知。
2)样式单一,只能是系统自带的样式,对于不同业务场景无法满足;
3)mac与window各自对于一些功能不支持。比如:
timeoutType(通知的超时持续时间),只有window与linux支持。
closeButtonText(自定义关闭按钮提示内容),只有mac支持。
那么怎么实现我们既定的需求呢?
我在网上也查了很多资料,但并没有得到很理想的结果,所以只能借助于Electron提供的能力来尝试实现 自定义通知。
自定义通知
优势在于不受限于系统,样式可以按照自己的想法设计。
实现通知
通知窗体实现
通过使用BrowserWindow()窗口来实现,设置好需要的自定义通知的尺寸与位置。
const { BrowserWindow, screen } = require('electron')
const win = new BrowserWindow({
width: 800,
height: 600,
show: false,
y: 0,
x: 0,
frame: false, // 无边框
skipTaskbar: true, // 使窗口不显示在任务栏中
movable: false, // 禁止窗口被用户移动
resizable: false, // 禁止窗口手动调整窗口大小
fullscreenable: false, // 禁止窗口可以进入全屏状态
alwaysOnTop: true, // 窗口是否永远在别的窗口的上面
})
win.loadFile('./html/customNotification.html')
// 定位到桌面右上角
const sizeObj = screen.getPrimaryDisplay().workAreaSize;
const { width, height } = sizeObj;
const [cwidth, cheight] = win.getContentSize();
const left = parseInt(width - (cwidth || 0) - 5);
const top = 10;
win.setPosition(left, top);
win.showInactive(); // 显示但不聚焦于窗口(建议做延时处理)
这种方式的实现相当于是类通知
。
因为类通知的实现是通过Electron创建窗口实现的。故需要关闭窗口的一些默认特性,也需要开启某些特性(详见上侧代码)。
通知UI样式
win.loadFile('./html/customNotification.html')
loadFile可以将React或者Vue等开发编译后的代码加载展现出来。
管理通知
业务场景:
桌面应用接收发送的通知消息,在电脑桌面右上角进行展示;
接收到第一条通知消息,显示UI设计的通知;
关闭当前通知才可以展示下一条通知消息。
分析:
通知不可能只有一条消息,可能会是多条,也有可能会是同时多条(并发)。
如何管理以上这种情况呢?
我做了两个概念(有序消息池
、消息队列
)的思路,供大家参考(也可用于其他业务下的并发处理,已实践)。
这里主要是重思路,就不写代码了......
有序消息池
用于存储消息数据。
由于数据不同,有时需要对数据进行处理,这个过程是耗时的,而这期间如果多条或者并发的数据出现,容易导致数据出现混乱、无序。
同时如果出现重复、整合的数据,就没必要再执行一次了。
1、重复:多条数据以最后一条为准,其他舍弃。
2、整合:多条数据同属于同一个数据,该数据需要将其他的数据整合起来。
或者有些情况下是可以直接异步展示所有数据的。
消息队列
用于推送消息。
队列里面有消息就推送,不需要推送,就静默。
可以同时异步推送多条消息,也可以只推一条。
思路
1、消息整合
对于接收到的数据不做任何处理。
生成消息的唯一Key(服务端不生成的情况下),push进有序消息池
。
2、有序消息池
对于数据复杂、数据量大的情况下,做有序消息池映射处理(建议使用Map)。
3、switch
开关,是否执行生成消息队列 && 是否有序数据池有数据。
false,否,停止流程。
true,是,进入生成消息队列操作
4、生成消息队列
关闭switch开关。
读取有序消息池数据。
遵循业务规则对数据做重复、整合处理。
将唯一Key按序添加到消息队列中。
5、消息队列
判断通知是否存在,如果已存在,再次进入2有序数据池
节点执行。
反之通知未存在,创建通知,进入有序数据池节点执行。
6、关闭通知
关闭通知后,再次进入5消息队列
节点执行。
扩展
这同时也是可以解决多条、并发情况下的思路。
从逻辑图中的 5、消息队列
往后,是为了通知
业务需求而做的。
如果有的业务允许多条消息同时更新,那么5、消息队列
这里可以执行异步更新,就没必要按照通知这种同步执行了。
思路有不完美的地方,欢迎大家积极指正沟通,共同学习,共同进步~~