-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathNotification.tsx
116 lines (103 loc) · 4.69 KB
/
Notification.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
* Copyright 2021-2025 Avaiga Private Limited
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
import React, { useCallback, useEffect, useMemo, useRef, SyntheticEvent } from "react";
import { SnackbarKey, useSnackbar, VariantType, CloseReason } from "notistack";
import IconButton from "@mui/material/IconButton";
import CloseIcon from "@mui/icons-material/Close";
import { NotificationMessage, createDeleteNotificationAction, createSendActionNameAction } from "../../context/taipyReducers";
import { useDispatch, useModule } from "../../utils/hooks";
interface NotificationProps {
notifications: NotificationMessage[];
}
const TaipyNotification = ({ notifications: notificationProps }: NotificationProps) => {
const notification = notificationProps.length ? notificationProps[0] : undefined;
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const snackbarIds = useRef<Record<string, string>>({});
const dispatch = useDispatch();
const module = useModule();
const closeNotifications = useCallback(
(ids: string[]) => {
ids.forEach((id) => closeSnackbar(id));
},
[closeSnackbar]
);
const notificationAction = useCallback(
(key: SnackbarKey) => (
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={() => closeNotifications([key as string])}
>
<CloseIcon fontSize="small" />
</IconButton>
),
[closeNotifications]
);
const notificationClosed = useCallback(
(event: SyntheticEvent | null, reason: CloseReason, key?: SnackbarKey, callback?: string) => {
if (callback) {
dispatch(createSendActionNameAction(notification?.notificationId, module, callback, reason === "timeout" ? "timeout" : "forced"));
}
snackbarIds.current = Object.fromEntries(
Object.entries(snackbarIds.current).filter(([id]) => id !== key)
);
},
[dispatch, module, notification?.notificationId]
);
const faviconUrl = useMemo(() => {
const nodeList = document.getElementsByTagName("link");
for (let i = 0; i < nodeList.length; i++) {
if (nodeList[i].getAttribute("rel") == "icon" || nodeList[i].getAttribute("rel") == "shortcut icon") {
return nodeList[i].getAttribute("href") || "/favicon.png";
}
}
return "/favicon.png";
}, []);
useEffect(() => {
if (notification) {
const notificationId = notification.notificationId;
if (notification.nType === "") {
if (notificationId) {
closeNotifications(
Object.entries(snackbarIds.current)
.filter(([, id]) => notificationId === id)
.map(([snackbarId]) => snackbarId)
);
}
} else {
if (notificationId) {
snackbarIds.current = {
...snackbarIds.current,
[notification.snackbarId]: notificationId,
};
}
enqueueSnackbar(notification.message, {
variant: notification.nType as VariantType,
action: notificationAction,
onClose: (event, reason, key) => notificationClosed(event, reason, key, notification.onClose),
key: notification.snackbarId,
autoHideDuration: notification.duration || null,
});
notification.system &&
new Notification(document.title || "Taipy", { body: notification.message, icon: faviconUrl });
}
dispatch(createDeleteNotificationAction(notification.snackbarId));
}
}, [notification, enqueueSnackbar, closeNotifications, notificationAction, faviconUrl, dispatch, notificationClosed]);
useEffect(() => {
notification?.system && window.Notification && Notification.requestPermission();
}, [notification?.system]);
return null;
};
export default TaipyNotification;