-
Notifications
You must be signed in to change notification settings - Fork 0
/
tag.js
189 lines (177 loc) · 5.87 KB
/
tag.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
class Tag {
/**
* Tag constructor
* @param {object} obj JSON parsed object from AJAX
* @param {int} parentId id of the parent music item
* @param {int} index index of the tag in the list
*/
constructor(obj, parentId, index) {
this.id = obj.id;
this.parentId = parentId;
this.index = index;
// if no type is specified assume it to text
this.type = typeof obj.type !== 'undefined' ? obj.type : 'text';
// if the type is timer and the time specified store it, if not store now() otherwise undefined
this.time = this.type === 'timer' ? typeof obj.time !== 'undefined' ? obj.time : Date.now() : undefined;
this.text = obj.text;
this.icon = typeof obj.icon !== 'undefined' ? obj.icon : '';
this.color = typeof obj.color !== 'undefined' ? obj.color : undefined;
this.ariaLabel = typeof obj.ariaLabel !== 'undefined' ? obj.ariaLabel : '';
this.fontColor = typeof obj.fontColor !== 'undefined' ? obj.fontColor : undefined;
this.class = typeof obj.class !== 'undefined' ? obj.class : '';
this.lastTimer = this.getTimer();
if (this.type === 'timer') {
this.timer = setInterval(() => {
$('#tag' + this.parentId + '-' + this.id).replaceWith(this.toHtml())
}, 60000);
}
return this.html;
}
/**
* @returns formated HTML for the tag
*/
toHtml() {
let timer = this.getTimer(),
text = this.text.replace('%TIME%', timer),
ariaLabel = this.ariaLabel.replace('%TIME%', timer),
img = this.icon !== '' ? `<img class="badge" src="${this.icon}" aria-label="${ariaLabel}">` : '';
return `
<figure id="${'tag' + this.parentId + '-' + this.id}" class="playlist_item__tag" style="background:#${this.color === undefined ? '333' : this.color};color:#${this.fontColor === undefined ? 'fff' : this.fontColor}">
${img}
<figcaption>${text}</figcaption>
</figure>`;
}
/**
* add custom class to parent music item or update it with new provided class
* @param {string} newClass new CSS class OPTIONAL
*/
updateParentClass(newClass) {
let parent = $('#id' + this.parentId);
// if new class is set and different from this.class
if (typeof newClass !== 'undefined' && newClass !== this.class) {
parent.toggleClass(this.class, false);
this.class = newClass;
parent.toggleClass(this.class, true);
}
// else if this.class is not empty
else if (this.class !== '') {
parent.toggleClass(this.class, true);
}
}
/**
* update the tag if needed
* @param {object} obj parsed JSON from AJAX request
* @returns {boolean} either or not the tag updated itself
*/
update(obj) {
let timer = this.getTimer();
if (!this.isSameAs(obj) || timer != this.lastTimer) {
this.lastTimer = timer;
this.html = this.toHtml();
$('#tag' + this.parentId + '-' + this.id).replaceWith(this.html);
return true;
}
return false;
}
/**
* remove the item from the dom
*/
delete() {
$('#tag' + this.parentId + '-' + this.id).remove();
$('#id' + this.parentId).toggleClass(this.class, false);
if (typeof this.timer !== 'undefined') {
clearInterval(this.timer);
}
}
/**
* compare the passed obj to this object, update the properties as needed and notify it
* @param {object} obj parsed JSON from AJAX request
* @returns {boolean} the tag is the same / the tag as bein updated
*/
isSameAs(obj) {
obj.text = typeof obj.text !== 'undefined' ? obj.text : undefined;
obj.icon = typeof obj.icon !== 'undefined' ? obj.icon : '';
obj.color = typeof obj.color !== 'undefined' ? obj.color : undefined;
obj.fontColor = typeof obj.fontColor !== 'undefined' ? obj.fontColor : undefined;
obj.time = typeof obj.time !== 'undefined' ? obj.time : undefined;
obj.ariaLabel = typeof obj.ariaLabel !== 'undefined' ? obj.ariaLabel : '';
obj.class = typeof obj.class !== 'undefined' ? obj.class : '';
let same = true;
if (this.text !== obj.text) {
this.text = obj.text;
same = false;
}
if (this.icon !== obj.icon) {
this.icon = obj.icon;
same = false;
}
if (this.color !== obj.color) {
this.color = obj.color;
same = false;
}
if (this.fontColor !== obj.fontColor) {
this.fontColor = obj.fontColor;
same = false;
}
if (this.time !== obj.time) {
this.time = obj.time;
same = false;
}
if (this.ariaLabel !== obj.ariaLabel) {
this.ariaLabel = obj.ariaLabel;
same = false;
}
if (this.class !== obj.class) {
this.updateParentClass(obj.class);
}
return same;
}
/**
* return the formated timer if this.type = timer, undefine otherwise
* @returns {string} formated timer
*/
getTimer() {
if (this.type === 'timer') {
let delta = Math.trunc((Date.now() - this.time) / 1000),
min = Math.trunc(delta / 60) % 60,
hours = Math.trunc(delta / 3600),
time = "error";
if (hours === 0) {
time = min + 'min';
}
else if (min === 0) {
time = hours + 'h';
}
else {
time = hours + 'h ' + min + 'min';
}
return time;
}
else {
return undefined;
}
}
/**
* move the tag to the desired location
* @param {int} index index to move the item to visualy
*/
move(index) {
let dom = $('#tag' + this.parentId + '-' + this.id);
if (typeof index !== 'undefined') {
// if the tag move at the first position
if (index !== this.index) {
if (index === 0) {
dom.prependTo('#id' + this.parentId + '>.playlist_item__tags');
}
// if the item move anywhere else
else {
dom.insertAfter('#id' + this.parentId + ' .playlist_item__tag:nth-child(' + index + ')')
}
}
}
else {
// throw error in the console
console.trace('no argument provided to update tag object', this);
}
}
}