Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions source/browser/conversation-list.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ipcRenderer as ipc} from 'electron-better-ipc';
import elementReady from 'element-ready';
import config from '../config';
import selectors from './selectors';

const icon = {
Expand Down Expand Up @@ -113,14 +114,16 @@ function isUnread(element: HTMLElement): boolean {
// Secondary check: Bold text
// This covers cases where the button is hidden (responsive/maximized view)
// We look for any text container that has semi-bold/bold font weight
const candidates = element.querySelectorAll('span, div');
for (const candidate of candidates) {
// Optimization: Skip elements with children to focus on leaf/text nodes
if (candidate.childElementCount > 0) {
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
let node: Node | undefined;

while ((node = walker.nextNode()!)) {
const parent = node.parentElement;
if (!parent) {
continue;
}

const {fontWeight} = getComputedStyle(candidate);
const {fontWeight} = getComputedStyle(parent);
const weight = Number.parseInt(fontWeight, 10);
// 600 is usually semi-bold, 700 is bold. Facebook often uses 600 for unread text.
if (!Number.isNaN(weight) && weight >= 600) {
Expand Down Expand Up @@ -317,13 +320,15 @@ function countUnread(mutationsList: MutationRecord[]): void {
}

// Send notification
ipc.callMain('notification', {
id: 0,
title: info.title,
body: info.body,
icon: info.icon,
silent: false,
});
if (!config.get('notificationsMuted')) {
ipc.callMain('notification', {
id: 0,
title: info.title,
body: info.body,
icon: info.icon,
silent: false,
});
}

// Update state
knownUnreadMessages.set(href, messageSignature);
Expand Down
10 changes: 10 additions & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ if (!is.development && config.get('autoUpdate')) {
let mainWindow: BrowserWindow;
let isQuitting = false;
let previousMessageCount = 0;
let currentMessageCount = 0;
let dockMenu: Menu;
let isDNDEnabled = false;

Expand Down Expand Up @@ -424,9 +425,14 @@ function createMainWindow(): BrowserWindow {

// Update badge on conversations change
ipc.answerRenderer('update-tray-icon', async (messageCount: number) => {
currentMessageCount = messageCount;
updateBadge(messageCount);
});

config.onDidChange('showUnreadBadge', () => {
updateBadge(currentMessageCount);
});

enableHiresResources();

const {webContents} = mainWindow;
Expand Down Expand Up @@ -631,6 +637,10 @@ ipc.answerRenderer(
return;
}

if (!is.macos && config.get('flashWindowOnMessage')) {
mainWindow.flashFrame(true);
}

const notification = new Notification({
title,
body: config.get('notificationMessagePreview') ? body : 'You have a new message',
Expand Down
29 changes: 0 additions & 29 deletions source/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,37 +270,17 @@ Press Command/Ctrl+R in Caprine to see your changes.
},
},
{
// TODO: Fix notifications.
// ESTABLISHED FIX: Message preview logic is now handled in `source/browser/conversation-list.ts`.
// The content extraction logic there respects this setting.
label: 'Show Message Preview in Notifications',
type: 'checkbox',
visible: is.development,
checked: config.get('notificationMessagePreview'),
click(menuItem) {
config.set('notificationMessagePreview', menuItem.checked);
},
},
{
// TODO: Fix notifications.
// ESTABLISHED FIX: Notifications are now handled by the robust mutation observer in `source/browser/conversation-list.ts`.
// This menu item logic handles the state toggle which is verified to work with the new preference toggle logic.
label: 'Show Notifications',
type: 'checkbox',
visible: is.development,
checked: !config.get('notificationsMuted'),
click(menuItem) {
config.set('notificationsMuted', !menuItem.checked);
sendAction('toggle-mute-notifications');
},
},
{
// TODO: Fix notifications.
// ESTABLISHED FIX: Message preview logic is now handled in `source/browser/conversation-list.ts` with `extractConversationInfo`.
// This toggle controls the config state which the new logic respects.
label: 'Show Message Preview',
type: 'checkbox',
visible: is.development,
checked: config.get('notificationMessagePreview'),
click(menuItem) {
config.set('notificationMessagePreview', menuItem.checked);
Expand All @@ -315,16 +295,11 @@ Press Command/Ctrl+R in Caprine to see your changes.
},
},
{
// TODO: Fix notification badge.
// ESTABLISHED FIX: Tray icon updates are handled by `updateTrayIcon` in `source/browser/conversation-list.ts`.
// This toggle controls the config state.
label: 'Show Unread Badge',
type: 'checkbox',
visible: is.development,
checked: config.get('showUnreadBadge'),
click(menuItem) {
config.set('showUnreadBadge', menuItem.checked);
sendAction('reload');
},
},
{
Expand Down Expand Up @@ -431,12 +406,8 @@ Press Command/Ctrl+R in Caprine to see your changes.
},
},
{
// TODO: Fix notifications.
// ESTABLISHED FIX: This relies on the main process `notification` event.
// Since we fixed the notification triggers in `source/browser/conversation-list.ts`, this should work downstream.
label: 'Flash Window on Message',
type: 'checkbox',
visible: is.development,
checked: config.get('flashWindowOnMessage'),
click(menuItem) {
config.set('flashWindowOnMessage', menuItem.checked);
Expand Down