-
Notifications
You must be signed in to change notification settings - Fork 0
/
music.js
238 lines (224 loc) · 7.15 KB
/
music.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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
class Music {
/**
* construct the object with the information of the parsed JSON
* @param {object} obj anonymous object from parsed JSON
*/
constructor(obj, index) {
this.id = obj.id;
this.title = obj.title;
this.artist = obj.artist;
this.tags = [];
if (typeof (obj.tags) !== "undefined") {
for (let i = 0, len = obj.tags.length; i < len; i++) {
const tag = obj.tags[i];
this.tags.push(new Tag(tag, this.id, i));
}
}
this.requester = new Requester(obj.requester);
this.index = index;
this.htmlPrint();
this.dom = $('#id' + this.id);
this.lastUpdatedTime = '';
}
/**
* log all the properties of the object, debug purpose only
*/
log() {
console.log(this.id, this.title, this.artist, this.tags, this.requester, this.index);
}
/**
* return the html markup to display the list of tags
* @return {template literal} html markup
*/
htmlTags() {
let html = "";
for (var i = 0; i < this.tags.length; i++) {
html += this.tags[i].toHtml();
}
return html;
}
/**
* append the object to the wrapper
*/
htmlPrint() {
let list = $('.playlist_list'),
length = list.eq(0).children().length,
html = `<div id="id${this.id}" class="playlist_item playlist_item_hidden" style="transform: translateY(${this.index * 8.5}em)">
<div class="playlist_item__tags fadable">
${this.htmlTags()}
</div>
<div class="playlist_item__title">
<p>${this.title}</p>
</div>
<div class="playlist_item__artiste">
<p>${this.artist}</p>
</div>
<div class="playlist_item__id">
<p>${this.id}</p>
</div>
<div class="playlist_item__requester fadable">
${this.requester.toHTML()}
</div>
</div>`;
// insert dom object at this.index
if (0 <= this.index && this.index < length) {
list.children().eq(this.index).before(html);
}
else {
list.append(html);
}
// add tags' custom class
for (let i = 0, len = this.tags.length; i < len; i++) {
const tag = this.tags[i];
tag.updateParentClass()
}
// show up the item
setTimeout(function () {
$('#id' + this.id).removeClass('playlist_item_hidden');
}.bind(this), 10);
}
/**
* remove the item
*/
delete() {
this.dom.toggleClass('playlist_item_hidden', true);
setTimeout(function () {
this.dom[0].remove();
}.bind(this), 300);
}
/**
* move the item to the desired location
* @param {int} index index to move the item to visualy
*/
move(index) {
if (index !== this.index) {
// if the item move at the first position
if (index === 0) {
this.dom.prependTo('.playlist_list');
}
// if the item move anywhere else
else {
this.dom.insertAfter('.playlist_item:nth-child(' + index + ')')
}
this.index = index;
}
setTimeout(function () {
this.dom[0].style.transform = 'translateY(' + (index * 8.5) + 'em)';
}.bind(this), 10);
}
/**
* edit the music item with the information from the new parsed json
* @param {object} obj anonymous object from parsed JSON - music
*/
update(obj) {
if (typeof obj !== 'undefined') {
// compare title
if (this.title !== obj.title) {
this.title = obj.title;
$('#id' + this.id + ' .playlist_item__title>p').html(this.title);
}
// compare artist name
if (this.artist !== obj.artist) {
this.artist = obj.artist;
$('#id' + this.id + ' .playlist_item__artiste>p').html(this.artist);
}
// compare the requester
if (!this.requester.isSame(obj.requester)) {
this.requester = new Requester(obj.requester);
let requester = $('#id' + this.id + ' .playlist_item__requester');
// fade the requester out
requester.toggleClass('fade', true);
setTimeout((requester) => {
// when the animation end, update the requester displayed
requester.html(this.requester.toHTML());
// fade the requester in
requester.toggleClass('fade', false);
}, 300, requester);
}
// update tags list
this.updateTags(obj.tags);
}
else {
// throw error in the console
console.trace('no argument provided to update music object', this);
}
}
/**
* update the tag list if needed
* @param {object} obj JSON parsed object - tag list
* @return {Boolean} either or not something changed
*/
updateTags(obj) {
// if obj is provided
if (typeof obj !== 'undefined') {
let tagList = Array.from(this.tags);
// loop through an image of the list and delete all tags that are not present anymore
for (let i = 0, len = tagList.length; i < len; i++) {
const currentTag = tagList[i];
// get the index of the tag in obj
let objTagIndex = obj.findIndex(function (tag) {
return tag.id === currentTag.id;
})
if (objTagIndex === -1) {
// visualy delete the tag
currentTag.delete();
// get the index of the tag in the tag list
let index = this.tags.findIndex(function (tag) {
return tag.id === currentTag.id;
})
// pop the tag of the list
this.tags.splice(index, 1);
}
}
// loop througth all the tag of the received obj
for (let i = 0, len = obj.length; i < len; i++) {
const objTag = obj[i];
// find the index of the current tag in the current tag list
let tagIndex = this.tags.findIndex(function (tag) {
return tag.id === objTag.id;
})
// if the current tag is not present add it
if (tagIndex === -1) {
let tag = new Tag(objTag, this.id, i),
tagWrapper = this.dom.children().eq(0),
tagWrapperLen = tagWrapper.children().length;
// add the tag to this.tags
this.tags.splice(i, 0, tag);
// add the new tag object to the list at the good index
if (0 <= i && i < tagWrapperLen) {
// insert the tag before the i-th tag
tagWrapper.children().eq(i).before(tag.toHtml());
}
else {
// insert the tag at the end of the list
tagWrapper.append(tag.toHtml());
}
// update the parent with the tag's custom class
tag.updateParentClass();
}
else {
let tag = this.tags[tagIndex];
// else if the tag index is not the same as the current one move it accordingly
if (tagIndex !== i) {
// move the tag visualy
tag.move(i);
// move the tag form its current position (tagIndex) to its new one (i) in the list
this.tags.splice(i, 0, this.tags.splice(tagIndex, 1)[0]);
}
// in all cases, trigger the tag update method
tag.update(objTag)
}
}
}
// else, if obj.tags is not set
else {
// delete all tags from the dom
for (let i = 0, len = this.tags.length; i < len; i++) {
const tag = this.tags[i];
tag.delete();
}
// clear the tags list
this.tags = [];
}
}
}