desktop: use native electron notifications on desktop

This commit is contained in:
Abdullah Atta
2023-01-18 10:11:16 +05:00
committed by Abdullah Atta
parent 8385bd41ea
commit cc39fac590
8 changed files with 184 additions and 16 deletions

View File

@@ -23,5 +23,6 @@ export const EVENTS = {
updateDownloadProgress: "updateDownloadProgress",
updateDownloadCompleted: "updateDownloadCompleted",
updateNotAvailable: "updateNotAvailable",
themeChanged: "themeChanged"
themeChanged: "themeChanged",
notificationClicked: "notificationClicked"
};

View File

@@ -0,0 +1,24 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
export default () => {
if (!global.win) return;
global.win.show();
global.win.moveTop();
};

View File

@@ -25,6 +25,8 @@ import open from "./open";
import saveFile from "./saveFile";
import setZoomFactor from "./setZoomFactor";
import setPrivacyMode from "./setPrivacyMode";
import showNotification from "./showNotification";
import bringToFront from "./bringToFront";
const actions = {
changeAppTheme,
@@ -34,7 +36,9 @@ const actions = {
open,
saveFile,
setZoomFactor,
setPrivacyMode
setPrivacyMode,
showNotification,
bringToFront
};
export function getAction(actionName) {

View File

@@ -0,0 +1,42 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Notification, shell } from "electron";
import { join } from "path";
import { EVENTS } from "../../events";
import { sendMessageToRenderer } from "../utils";
import { platform } from "os";
export default (args) => {
if (!global.win) return;
const notification = new Notification({
...args,
icon: join(
__dirname,
platform() === "win32" ? "app.ico" : "favicon-72x72.png"
)
});
notification.show();
if (args.urgency === "critical") {
shell.beep();
}
notification.addListener("click", () => {
sendMessageToRenderer(EVENTS.notificationClicked, { tag: args.tag });
});
};

View File

@@ -0,0 +1,24 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { invokeCommand } from "./index";
export default function bringToFront() {
invokeCommand("bringToFront");
}

View File

@@ -32,7 +32,7 @@ export function invokeCommand(type, payload = {}) {
if (isDesktop()) {
window.api.receive("fromMain", (args) => {
console.log(args);
const { type } = args;
AppEventManager.publish(type, args);
const { type, ...other } = args;
AppEventManager.publish(type, other);
});
}

View File

@@ -0,0 +1,40 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { EVENTS } from "@notesnook/desktop/events";
import { AppEventManager } from "../common/app-events";
import { invokeCommand } from "./index";
/**
*
* @param {import("electron").NotificationConstructorOptions & { tag: string }} options
* @param {() => void} onClicked
*/
export default function showNotification(options, onClicked) {
invokeCommand("showNotification", options);
const { unsubscribe } = AppEventManager.subscribe(
EVENTS.notificationClicked,
({ tag }) => {
if (tag === options.tag) {
onClicked();
unsubscribe();
}
}
);
}

View File

@@ -26,7 +26,9 @@ import { showReminderPreviewDialog } from "../common/dialog-controller";
import dayjs from "dayjs";
import Config from "../utils/config";
import { store as notestore } from "./note-store";
import { isTesting } from "../utils/platform";
import { isDesktop, isTesting } from "../utils/platform";
import showNotification from "../commands/show-notification";
import bringToFront from "../commands/bring-to-front";
class ReminderStore extends BaseStore {
reminders = [];
@@ -81,6 +83,13 @@ async function resetReminders(reminders) {
}
}
/**
*
* @param {string} id
* @param {import("@notesnook/core/collections/reminders").Reminder} reminder
* @param {string} cron
* @returns
*/
function scheduleReminder(id, reminder, cron) {
return TaskScheduler.register(`reminder:${id}`, cron, () => {
if (!Config.get("reminderNotifications", true)) return;
@@ -90,18 +99,42 @@ function scheduleReminder(id, reminder, cron) {
return;
}
const notification = new Notification(reminder.title, {
body: reminder.description,
vibrate: reminder.priority === "vibrate",
silent: reminder.priority === "silent",
tag: id,
renotify: true,
requireInteraction: true
});
if (isDesktop()) {
showNotification(
{
title: reminder.title,
body: reminder.description,
silent: reminder.priority === "silent",
timeoutType: reminder.priority === "urgent" ? "never" : "default",
urgency:
reminder.priority === "urgent"
? "critical"
: reminder.priority === "vibrate"
? "normal"
: "low",
focusOnClick: true,
tag: id
},
() => {
bringToFront();
showReminderPreviewDialog(reminder);
}
);
} else {
const notification = new Notification(reminder.title, {
body: reminder.description,
vibrate: reminder.priority === "vibrate",
silent: reminder.priority === "silent",
tag: id,
renotify: true,
requireInteraction: true
});
notification.onclick = function () {
showReminderPreviewDialog(reminder);
};
notification.onclick = function () {
window.focus();
showReminderPreviewDialog(reminder);
};
}
store.refresh(false);
});