feat: avoid removing notification when mouse hover

This commit is contained in:
2026-07-22 18:23:09 +02:00
parent 9e3f3803a6
commit 5cee5a2047
3 changed files with 33 additions and 7 deletions

View File

@ -3,15 +3,22 @@ import type { Notification } from '../types/types';
type Props = {
notifications: Notification[];
onRemove: (id: number) => void;
onHover: (id: number, hovering: boolean) => void;
};
export default function Notifications({ notifications, onRemove }: Props) {
export default function Notifications({
notifications,
onRemove,
onHover,
}: Props) {
return (
<div className="notifications">
{notifications.map((n) => (
<div
key={n.id}
className={`notification ${n.type} ${n.removing ? 'notification-out' : ''}`}
onMouseEnter={() => onHover(n.id, true)}
onMouseLeave={() => onHover(n.id, false)}
>
<span className="notification-message" title={n.message}>
{n.message}

View File

@ -16,7 +16,7 @@ function App() {
const [dsps, setDsps] = useState<DSP[]>([]);
const [selected, setSelected] = useState<number | null>(null);
const [page, setPage] = useState<AppPage>('home');
const { notifications, notify, removeNotification } = useNotifications();
const { notifications, notify, removeNotification, hoverNotification } = useNotifications();
async function addDSP(dsp: Omit<DSP, 'id' | 'status'>) {
try {
@ -126,7 +126,7 @@ function App() {
return (
<div className="app">
<Notifications notifications={notifications} onRemove={removeNotification} />
<Notifications notifications={notifications} onRemove={removeNotification} onHover={hoverNotification}/>
<TopBar
dsps={dsps}

View File

@ -1,8 +1,9 @@
import { useState, useCallback } from 'react';
import { useState, useCallback, useRef } from 'react';
import { NotificationType, Notification } from '../types/types';
export function useNotifications() {
const [notifications, setNotifications] = useState<Notification[]>([]);
const hovered = useRef<Set<number>>(new Set());
const notify = useCallback(
(message: string, type: NotificationType = 'error', dspName?: string) => {
@ -19,24 +20,42 @@ export function useNotifications() {
},
]);
setTimeout(() => {
const removeLater = () => {
if (hovered.current.has(id)) {
setTimeout(removeLater, 1000);
return;
}
setNotifications((prev) => prev.filter((n) => n.id !== id));
}, 5000);
};
setTimeout(removeLater, 5000);
},
[]
);
const removeNotification = useCallback((id: number) => {
setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, removing: true } : n)));
setNotifications((prev) =>
prev.map((n) => (n.id === id ? { ...n, removing: true } : n))
);
setTimeout(() => {
setNotifications((prev) => prev.filter((n) => n.id !== id));
}, 250);
}, []);
const hoverNotification = useCallback((id: number, hovering: boolean) => {
if (hovering) {
hovered.current.add(id);
} else {
hovered.current.delete(id);
}
}, []);
return {
notifications,
notify,
removeNotification,
hoverNotification,
};
}