feat: avoid removing notification when mouse hover
This commit is contained in:
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user