fix: infinite loop in notification title counter
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-notifications': patch
|
||||
---
|
||||
|
||||
Fix infinite loop in the notification title counter
|
||||
@@ -20,9 +20,11 @@ import {
|
||||
notificationsPlugin,
|
||||
NotificationsSidebarItem,
|
||||
} from '../src';
|
||||
import { signalsPlugin } from '@backstage/plugin-signals';
|
||||
|
||||
createDevApp()
|
||||
.registerPlugin(notificationsPlugin)
|
||||
.registerPlugin(signalsPlugin)
|
||||
.addPage({
|
||||
element: (
|
||||
<NotificationsPage
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/dev-utils": "workspace:^",
|
||||
"@backstage/plugin-signals": "workspace:^",
|
||||
"@backstage/test-utils": "workspace:^",
|
||||
"@testing-library/jest-dom": "^6.0.0",
|
||||
"@testing-library/react": "^15.0.0",
|
||||
|
||||
+7
-4
@@ -96,11 +96,14 @@ export const NotificationsSidebarItem = (props?: {
|
||||
useEffect(() => {
|
||||
if (!loading && !error && value) {
|
||||
setUnreadCount(value.unread);
|
||||
if (titleCounterEnabled) {
|
||||
setNotificationCount(value.unread);
|
||||
}
|
||||
}
|
||||
}, [loading, error, value, titleCounterEnabled, setNotificationCount]);
|
||||
}, [loading, error, value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (titleCounterEnabled) {
|
||||
setNotificationCount(unreadCount);
|
||||
}
|
||||
}, [titleCounterEnabled, unreadCount, setNotificationCount]);
|
||||
|
||||
// TODO: Figure out if the count can be added to hasNotifications
|
||||
return (
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
/** @public */
|
||||
export function useTitleCounter() {
|
||||
const [title, setTitle] = useState(document.title);
|
||||
const [count, setCount] = useState(0);
|
||||
const titleTimer = useRef<undefined | number>(undefined);
|
||||
|
||||
const getPrefix = (value: number) => {
|
||||
return value === 0 ? '' : `(${value}) `;
|
||||
@@ -28,28 +29,43 @@ export function useTitleCounter() {
|
||||
return currentTitle.replace(/^\(\d+\)\s/, '');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.title = title;
|
||||
}, [title]);
|
||||
|
||||
useEffect(() => {
|
||||
const baseTitle = cleanTitle(title);
|
||||
setTitle(`${getPrefix(count)}${baseTitle}`);
|
||||
const shownTitle = `${getPrefix(count)}${baseTitle}`;
|
||||
if (document.title !== shownTitle) {
|
||||
window.clearTimeout(titleTimer.current);
|
||||
document.title = shownTitle;
|
||||
// Need to do this in timeout as the React Helmet overrides the title after this effect
|
||||
titleTimer.current = window.setTimeout(() => {
|
||||
document.title = shownTitle;
|
||||
}, 50);
|
||||
}
|
||||
return () => {
|
||||
window.clearTimeout(titleTimer.current);
|
||||
document.title = cleanTitle(title);
|
||||
};
|
||||
}, [title, count]);
|
||||
|
||||
const titleElement = document.querySelector('title');
|
||||
if (titleElement) {
|
||||
new MutationObserver(() => {
|
||||
setTitle(document.title);
|
||||
}).observe(titleElement, {
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
childList: true,
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
const titleElement = document.querySelector('title');
|
||||
let observer: MutationObserver | undefined;
|
||||
if (titleElement) {
|
||||
observer = new MutationObserver(mutations => {
|
||||
if (mutations?.[0]?.target?.textContent) {
|
||||
setTitle(mutations[0].target.textContent);
|
||||
}
|
||||
});
|
||||
observer.observe(titleElement, {
|
||||
characterData: true,
|
||||
childList: true,
|
||||
});
|
||||
}
|
||||
return () => {
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const setNotificationCount = useCallback(
|
||||
(newCount: number) => setCount(newCount),
|
||||
|
||||
@@ -6057,6 +6057,7 @@ __metadata:
|
||||
"@backstage/dev-utils": "workspace:^"
|
||||
"@backstage/errors": "workspace:^"
|
||||
"@backstage/plugin-notifications-common": "workspace:^"
|
||||
"@backstage/plugin-signals": "workspace:^"
|
||||
"@backstage/plugin-signals-react": "workspace:^"
|
||||
"@backstage/test-utils": "workspace:^"
|
||||
"@backstage/theme": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user