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、消息隊列
這里可以執行異步更新,就沒必要按照通知這種同步執行了。
思路有不完美的地方,歡迎大家積極指正溝通,共同學習,共同進步~~