This repository has been archived by the owner on Aug 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
notificationDrawer.js
212 lines (181 loc) · 9.24 KB
/
notificationDrawer.js
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* Notification Drawer Beta 2.1 */
/* By: Lenglet Anthony */
/* Built for Seprote 2 */
/* */
/* A library that allows you to easily display windows 10 style notifications */
/* */
/* Usage: */
/* new notification( */
/* position of the notifications on the screen ('topleft', 'topright', 'bottomleft', 'bottomright'), */
/* name given to this notification 'drawer' */
/* ); */
/* */
/* notif.sendNotification( */
/* notification type ('error', 'success', 'info', 'warning'), */
/* { */
/* title: 'Notification Title', */
/* body: 'Notification body' */
/* }, */
/* time on screen (ms) */
/* ); */
import notificationItem from './notificationItem'
export default class notification {
//initiate the notification drawer
constructor(direction, drawerName) {
this.ownerDrawer = drawerName;
this.notificationDrawerName = 'notification-drawer-'+this.ownerDrawer;
this.drawerDirection = direction;
this.drawerPadding = 15;
this.spaceBetweenNotifs = 15;
//this list will contain all the notification item objects in this drawer
this.notifObjList = [];
this.notificationCount = 0;
this.notifDrawer = document.createElement("div");
this.notifDrawer.classList.add(this.notificationDrawerName);
document.body.appendChild(this.notifDrawer);
this.drawerSelector = '.'+this.notificationDrawerName;
//create css stylesheet to modify
var styleEl = document.createElement('style');
document.head.appendChild(styleEl);
this.styleSheet = styleEl.sheet;
//position the drawer according to the given placement
var beginningCSS = "."+this.notificationDrawerName+" { position: fixed;";
switch(this.drawerDirection) {
case 'topleft':
this.styleSheet.insertRule(beginningCSS+" top: "+this.drawerPadding+"px; left: "+this.drawerPadding+"px; }", 0);
break;
case 'topright':
this.styleSheet.insertRule(beginningCSS+" top: "+this.drawerPadding+"px; right: "+this.drawerPadding+"px; }", 0);
break;
case 'bottomleft':
this.styleSheet.insertRule(beginningCSS+" bottom: "+this.drawerPadding+"px; left: "+this.drawerPadding+"px; }", 0);
break;
case 'bottomright':
this.styleSheet.insertRule(beginningCSS+" bottom: "+this.drawerPadding+"px; right: "+this.drawerPadding+"px; }", 0);
break;
}
}
//create the notification item
sendNotification(type, content, timer) {
var p = this;
//create a new notificationitem object and push it to the notification list
var notifObject = new notificationItem(p.drawerDirection, p.ownerDrawer, p.drawerPadding, p.styleSheet, timer);
this.notificationCount++;
notifObject.notifID = this.notificationCount;
this.notifObjList.push(notifObject);
//create and append the displayed notification
content.owner = p.ownerDrawer;
document.querySelector(this.drawerSelector).append(notifObject.create(type, content));
//slide the notification into view
this.pushNotifOnScreen(notifObject.notifHTML);
//add notification events on mouseclick
var mousedownHandler = function(e){
e.preventDefault();
e.target.style.transform = 'scale(0.95)';
};
var mouseupHandler = function(e) {
//Close the notification
e.preventDefault();
//Before anything, make sure to disable the timeout
clearTimeout(notifObject.TimeoutFunc);
e.target.style.transform = 'scale(1)';
var drawerlist = p.notifDrawer;
p.regroupNotif(notifObject.notifID-1);
p.notifObjList.splice(notifObject.notifID-1, 1);
notifObject.destroy(p.drawerDirection);
p.notificationCount--;
};
var mouseoutHandler = function(e){
e.preventDefault();
e.target.style.transform = 'scale(1)';
};
notifObject.notifHTML.addEventListener("transitionend", function(e){
notifObject.notifHTML.addEventListener("mousedown", mousedownHandler);
notifObject.notifHTML.addEventListener("mouseup", mouseupHandler);
notifObject.notifHTML.addEventListener("mouseout", mouseoutHandler);
});
//Add timeout to automaticaly dispose of the notification
notifObject.TimeoutFunc = setTimeout(
function(){
//get index of clicked notification
var child = notifObject.notifHTML;
var i = 0;
while( (child = child.previousSibling) != null )
i++;
if(i>0){p.regroupNotif(i);}
p.notifObjList.splice(i, 1);
notifObject.destroy(p.drawerDirection);
p.notificationCount--;
},
notifObject.notifTimer
);
}
//push the notification item on screen
pushNotifOnScreen(notif) {
var p = this;
//push every possible previous notifications down or up to make space for the new one
for(var i=p.notifObjList.length-2;i>=0;i--){
switch(p.drawerDirection){
case 'topright':
case 'topleft':
p.notifObjList[i].pushForward('top', i, p.notifObjList.length-1, p.spaceBetweenNotifs, p.drawerPadding);
break;
case 'bottomright':
case 'bottomleft':
p.notifObjList[i].pushForward('bottom', i, p.notifObjList.length-1, p.spaceBetweenNotifs, p.drawerPadding);
break;
}
}
//slide the new notification into view
// BUG: Note pour les future mainteneur / dev de Seprote 3
// Celui la est bizzare, donc je passe en francais pour
// que ce soit plus facile a comprendre.
//
// Note: Le timeout est utilisé pour contourner le problème
// pour le moment, mais une correction définitive serait mieux.
//
// Recréation: Sur la page login, appuyer sur le bouton
// de connexion.
//
// Resultat: Une notification apparait sans animation, et
// les actions de clique ne marchent pas.
//
// Cause: L'élément DOM crée en javascript n'est pas encore
// entièrement chargé avant l'execution des fonctions
// ajoutant les actions et créant l'animation.
//
// Solution: Refaire cette partie du code pour faire en
// sorte qu'elle ne s'execute que lorsque l'élement DOM est
// entièrement chargé.
setTimeout(()=>{
switch(p.drawerDirection) {
case 'topleft':
case 'bottomleft':
notif.style.left = '15px';
break;
case 'topright':
case 'bottomright':
notif.style.right = '15px';
break;
}
}, 10);
// /BUG
}
//Regroup all the notifications together by moving the
//ones after the newly deleted notification up or down
regroupNotif(index) {
var p = this;
for(var i=index-1;i>=0;i--){
switch(p.drawerDirection){
case 'topright':
case 'topleft':
p.notifObjList[i].pushBackward('top', i, p.notifObjList.length-1, p.spaceBetweenNotifs, p.drawerPadding);
break;
case 'bottomright':
case 'bottomleft':
p.notifObjList[i].pushBackward('bottom', i, p.notifObjList.length-1, p.spaceBetweenNotifs, p.drawerPadding);
break;
}
}
}
}