From e8a97c037dd0140222c9dd29e63a346616f29f83 Mon Sep 17 00:00:00 2001
From: Brian Kendall <7917884+briankendall@users.noreply.github.com>
Date: Wed, 5 Jan 2022 13:42:56 -0500
Subject: Fix notifications, badge, and icon for The Lounge (#812)
---
recipes/thelounge/icon.svg | 2 +-
recipes/thelounge/package.json | 2 +-
recipes/thelounge/webview-unsafe.js | 7 ++++
recipes/thelounge/webview.js | 78 ++++++++++++++++++++++++++++++++++++-
4 files changed, 85 insertions(+), 4 deletions(-)
create mode 100644 recipes/thelounge/webview-unsafe.js
(limited to 'recipes/thelounge')
diff --git a/recipes/thelounge/icon.svg b/recipes/thelounge/icon.svg
index a989688..f773754 100644
--- a/recipes/thelounge/icon.svg
+++ b/recipes/thelounge/icon.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/recipes/thelounge/package.json b/recipes/thelounge/package.json
index a3f833b..d7b2632 100644
--- a/recipes/thelounge/package.json
+++ b/recipes/thelounge/package.json
@@ -1,7 +1,7 @@
{
"id": "thelounge",
"name": "The Lounge",
- "version": "1.1.2",
+ "version": "1.2.0",
"license": "MIT",
"config": {
"hasCustomUrl": true,
diff --git a/recipes/thelounge/webview-unsafe.js b/recipes/thelounge/webview-unsafe.js
new file mode 100644
index 0000000..3f1358a
--- /dev/null
+++ b/recipes/thelounge/webview-unsafe.js
@@ -0,0 +1,7 @@
+// Monkey patch ServiceWorker.postMessage so that it will actually post a notification in Ferdi:
+
+function newPostMessage(options) {
+ window.ferdi.displayNotification(options.title, options);
+}
+
+ServiceWorker.prototype.postMessage = newPostMessage;
diff --git a/recipes/thelounge/webview.js b/recipes/thelounge/webview.js
index b950e8a..394c867 100644
--- a/recipes/thelounge/webview.js
+++ b/recipes/thelounge/webview.js
@@ -1,17 +1,91 @@
+
+function countsOfUnreadMessagesAfterMarker(unreadMarker) {
+ var children = unreadMarker.parentElement.childNodes;
+ var unread = 0;
+ var unreadHighlighted = 0;
+
+ for(var i = children.length-1; i >= 0; --i) {
+ if (children[i] === unreadMarker) {
+ break;
+ }
+
+ if (children[i].classList === undefined) {
+ continue;
+ }
+
+ if (children[i].classList.contains('msg')) {
+ unread++;
+
+ if (children[i].classList.contains('highlight')) {
+ unreadHighlighted++;
+ }
+ }
+ }
+
+ return [unread, unreadHighlighted];
+}
+
module.exports = Ferdi => {
+ var unreadMessagesAtLastActivity = 0;
+ var unreadHighlightedMessagesAtLastActivity = 0;
+
const getMessages = () => {
+ // In order to get a correct tally of unread messages, we must
+ // consider both the badges on the various channels, plus the
+ // number of messages that appear after the 'unread' banner that
+ // appears in the page. In the latter case, we should ignore any
+ // messages that arrived before or while the app has focus.
+
+ let direct = 0;
+ var directElements = document.querySelectorAll('.badge.highlight');
+
+ for (const directElement of directElements) {
+ if (directElement.textContent.length > 0) {
+ direct += Ferdi.safeParseInt(directElement.textContent);
+ }
+ }
+
+ let indirect = 0;
const indirectElements = document.querySelectorAll(
'.badge:not(.highlight)',
);
- const direct = document.querySelectorAll('.badge.highlight').length;
- let indirect = 0;
for (const indirectElement of indirectElements) {
if (indirectElement.textContent.length > 0) {
indirect++;
}
}
+
+ const unreadMarkers = document.querySelectorAll('div.unread-marker');
+
+ if (unreadMarkers.length > 0) {
+ var counts = countsOfUnreadMessagesAfterMarker(unreadMarkers[0]);
+ var unread = counts[0];
+ var unreadHighlighted = counts[1];
+
+ if (document.hasFocus()) {
+ unreadMessagesAtLastActivity = unread;
+ unreadHighlightedMessagesAtLastActivity = unreadHighlighted;
+ }
+
+ if (unread > unreadMessagesAtLastActivity) {
+ if (unreadHighlighted > 0 && unreadHighlighted > unreadHighlightedMessagesAtLastActivity) {
+ direct += (unreadHighlighted - unreadHighlightedMessagesAtLastActivity);
+ } else {
+ indirect++;
+ }
+ }
+ } else {
+ unreadMessagesAtLastActivity = 0;
+ unreadHighlightedMessagesAtLastActivity = 0;
+ }
+
Ferdi.setBadge(direct, indirect);
};
Ferdi.loop(getMessages);
+
+ // We need to monkey patch ServierWorker.postMessage so that notifications
+ // will work, and that needs to be done without context isolation:
+ const path = require('path');
+ Ferdi.injectJSUnsafe(path.join(__dirname, 'webview-unsafe.js'));
};
--
cgit v1.2.3-54-g00ecf