-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnotification.js
More file actions
101 lines (85 loc) · 3.34 KB
/
Copy pathnotification.js
File metadata and controls
101 lines (85 loc) · 3.34 KB
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
// ==================== Notification plugin ====================
const notificationContainerClass = "ff-notification-container";
const notificationBoxClass = "ff-notification-box";
const notificationMsgClass = "ff-notification-msg";
const notificationBarClass = "ff-notification-bar";
let activeNotifications = [];
let messageGap = 5;
// Shows a notification message at the top of the window. Multiple concurrent notifications stack
// vertically.
//
// text: The plain text to display.
// type: The display style: "error", "warning", "success" or other
// options: An object with additional options.
// - timeout: The timeout to automatically hide the notification, in milliseconds. Default: 8000
// - quick: Changes the default timeout to 3000.
// - permanent: If true, the notification has no timeout and cannot be closed by the user.
// - onclose: A callback function that is called when the notification is closed. It receives the
// close reason as first argument ("click", "timeout").
//
// The returned object contains methods and properties to manipulate the notification.
// - close(reason): Closes the notification. Can be called at any time. The first parameter is
// passed to the onclose callback.
// - isOpen: Determines whether the notification is still open. This property is read-only.
F.notify = function (text, type, options) {
if (!options)
options = {};
if (options.timeout === undefined)
options.timeout = options.quick ? 3000 : 8000;
let newTop = activeNotifications.map(c => c.F.height + messageGap).reduce((a, b) => a + b, 0);
let container = F.c("div");
container.classList.add(notificationContainerClass);
container.style.top = newTop + "px";
let box = F.c("div");
box.classList.add(notificationBoxClass);
if (type)
box.classList.add(type);
box.style.cursor = options.permanent ? "default" : "pointer";
container.append(box);
let msg = F.c("div");
msg.classList.add(notificationMsgClass);
msg.textContent = text;
box.append(msg);
let bar = F.c("div");
bar.classList.add(notificationBarClass);
box.append(bar);
document.body.append(container);
activeNotifications.push(container);
if (options.timeout && !options.permanent) {
bar.F.animateFromTo({ width: [0, "100%"] }, options.timeout, "linear", false);
}
let isOpen = true;
let timeout;
let close = reason => {
if (!isOpen)
return;
let height = container.F.height + messageGap;
box.style.opacity = "0";
container.style.top = parseFloat(container.style.top) - (height / 2) + "px";
box.F.afterTransition("opacity", () => container.remove());
let index = activeNotifications.indexOf(container);
if (index !== -1)
activeNotifications.splice(index, 1);
for (let i = index; i < activeNotifications.length; i++) {
activeNotifications[i].style.top = parseFloat(activeNotifications[i].style.top) - height + "px";
}
isOpen = false;
clearTimeout(timeout);
options.onclose && options.onclose(reason);
};
if (options.timeout && !options.permanent)
timeout = setTimeout(() => close("timeout"), options.timeout);
if (!options.permanent) {
box.F.on("click", () => close("click"));
}
// Create returned object
// Add all methods
let ret = {
close
};
// Define properties
Object.defineProperty(ret, "isOpen", {
get: () => isOpen
});
return ret;
};