Fix unread count taskbar badge for Windows
|
@ -591,6 +591,14 @@
|
|||
"messageformat": "{count, plural, one {# Unread Message} other {# Unread Messages}}",
|
||||
"description": "Text for unread message separator, with count"
|
||||
},
|
||||
"icu:taskbarMarkedUnread": {
|
||||
"messageformat": "Marked Unread",
|
||||
"description": "On Windows, description for screen readers for the OS taskbar icon's overlay badge when the user has marked chat(s) as unread."
|
||||
},
|
||||
"icu:taskbarUnreadMessages": {
|
||||
"messageformat": "{count, plural, one {# Unread Message} other {# Unread Messages}}",
|
||||
"description": "On Windows, description for screen readers for the OS taskbar icon's overlay badge when there are unread messages."
|
||||
},
|
||||
"icu:messageHistoryUnsynced": {
|
||||
"messageformat": "For your security, chat history isn't transferred to new linked devices.",
|
||||
"description": "Shown in the conversation history when a user links a new device to explain what is not supported."
|
||||
|
|
35
app/main.ts
|
@ -114,6 +114,7 @@ import type { ParsedSignalRoute } from '../ts/util/signalRoutes';
|
|||
import { parseSignalRoute } from '../ts/util/signalRoutes';
|
||||
import * as dns from '../ts/util/dns';
|
||||
import { ZoomFactorService } from '../ts/services/ZoomFactorService';
|
||||
import { getMarkedUnreadIcon, getUnreadIcon } from '../ts/util/unreadIcon';
|
||||
|
||||
const STICKER_CREATOR_PARTITION = 'sticker-creator';
|
||||
|
||||
|
@ -2266,10 +2267,44 @@ ipc.on(
|
|||
if (process.platform === 'darwin') {
|
||||
// Will show a ● on macOS when undefined
|
||||
app.setBadgeCount(undefined);
|
||||
} else if (process.platform === 'win32') {
|
||||
// setBadgeCount is unsupported on Windows, so we use setOverlayIcon
|
||||
let description;
|
||||
try {
|
||||
description = getResolvedMessagesLocale().i18n(
|
||||
'icu:taskbarMarkedUnread'
|
||||
);
|
||||
} catch {
|
||||
description = 'Unread';
|
||||
}
|
||||
mainWindow?.setOverlayIcon(getMarkedUnreadIcon(), description);
|
||||
} else {
|
||||
// All other OS's need a number
|
||||
app.setBadgeCount(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
if (!mainWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
let description;
|
||||
try {
|
||||
description = getResolvedMessagesLocale().i18n(
|
||||
'icu:taskbarUnreadMessages',
|
||||
{ count: badge }
|
||||
);
|
||||
} catch {
|
||||
description = String(badge);
|
||||
}
|
||||
|
||||
if (badge === 0) {
|
||||
mainWindow.setOverlayIcon(null, '');
|
||||
} else {
|
||||
mainWindow.setOverlayIcon(getUnreadIcon(badge), description);
|
||||
}
|
||||
} else {
|
||||
app.setBadgeCount(badge);
|
||||
}
|
||||
|
|
BIN
images/unread-icon/1.png
Normal file
After Width: | Height: | Size: 437 B |
BIN
images/unread-icon/2.png
Normal file
After Width: | Height: | Size: 533 B |
BIN
images/unread-icon/3.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
images/unread-icon/4.png
Normal file
After Width: | Height: | Size: 497 B |
BIN
images/unread-icon/5.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
images/unread-icon/6.png
Normal file
After Width: | Height: | Size: 571 B |
BIN
images/unread-icon/7.png
Normal file
After Width: | Height: | Size: 445 B |
BIN
images/unread-icon/8.png
Normal file
After Width: | Height: | Size: 570 B |
BIN
images/unread-icon/9-plus.png
Normal file
After Width: | Height: | Size: 604 B |
BIN
images/unread-icon/9.png
Normal file
After Width: | Height: | Size: 575 B |
BIN
images/unread-icon/marked-unread.png
Normal file
After Width: | Height: | Size: 325 B |
26
ts/util/unreadIcon.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { join } from 'path';
|
||||
import type { NativeImage } from 'electron';
|
||||
import { nativeImage } from 'electron';
|
||||
|
||||
export function getUnreadIcon(unreadCount: number): NativeImage {
|
||||
const filename =
|
||||
unreadCount > 9 ? '9-plus.png' : `${String(unreadCount)}.png`;
|
||||
const path = join(__dirname, '..', '..', 'images', 'unread-icon', filename);
|
||||
// if path does not exist, this returns an empty NativeImage
|
||||
return nativeImage.createFromPath(path);
|
||||
}
|
||||
|
||||
export function getMarkedUnreadIcon(): NativeImage {
|
||||
const path = join(
|
||||
__dirname,
|
||||
'..',
|
||||
'..',
|
||||
'images',
|
||||
'unread-icon',
|
||||
'marked-unread.png'
|
||||
);
|
||||
return nativeImage.createFromPath(path);
|
||||
}
|