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