diff --git a/src/css/index.scss b/src/css/index.scss
index 426959a..5923ab4 100644
--- a/src/css/index.scss
+++ b/src/css/index.scss
@@ -37,6 +37,9 @@ $aplayer-height-lrc: $aplayer-height + $lrc-height - 6;
.aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-menu {
display: inline;
}
+ .aplayer-icon-order {
+ display: inline;
+ }
}
&.aplayer-withlrc {
@@ -116,6 +119,10 @@ $aplayer-height-lrc: $aplayer-height + $lrc-height - 6;
}
}
+ .aplayer-icon-order {
+ display: none;
+ }
+
.aplayer-lrc-content {
display: none;
}
diff --git a/src/js/controller.js b/src/js/controller.js
index 539a5cf..ca8ea22 100644
--- a/src/js/controller.js
+++ b/src/js/controller.js
@@ -6,11 +6,8 @@ class Controller {
this.player = player;
this.initPlayButton();
- this.initList();
this.initPlayBar();
- if (this.player.isMultiple()) {
- this.initOrderButton();
- }
+ this.initOrderButton();
this.initLoopButton();
this.initMenuButton();
if (!utils.isMobile) {
@@ -24,26 +21,6 @@ class Controller {
});
}
- initList () {
- this.player.template.list.addEventListener('click', (e) => {
- let target;
- if (e.target.tagName.toUpperCase() === 'LI') {
- target = e.target;
- }
- else {
- target = e.target.parentElement;
- }
- const audioIndex = parseInt(target.getElementsByClassName('aplayer-list-index')[0].innerHTML) - 1;
- if (audioIndex !== this.player.playIndex) {
- this.player.switchAudio(audioIndex);
- this.player.play();
- }
- else {
- this.player.toggle();
- }
- });
- }
-
initPlayBar () {
const thumbMove = (e) => {
let percentage = ((e.clientX || e.changedTouches[0].clientX) - utils.getElementViewLeft(this.player.template.barWrap)) / this.player.template.barWrap.clientWidth;
@@ -156,12 +133,7 @@ class Controller {
this.player.template.list.style.height = 33 * this.player.options.audio.length - 1 + 'px';
this.player.template.listOl.style.height = 33 * this.player.options.audio.length - 1 + 'px';
this.player.template.menu.addEventListener('click', () => {
- if (!this.player.template.list.classList.contains('aplayer-list-hide')) {
- this.player.template.list.classList.add('aplayer-list-hide');
- }
- else {
- this.player.template.list.classList.remove('aplayer-list-hide');
- }
+ this.player.list.toggle();
});
}
}
diff --git a/src/js/list.js b/src/js/list.js
new file mode 100644
index 0000000..a99c60f
--- /dev/null
+++ b/src/js/list.js
@@ -0,0 +1,145 @@
+import tplListItem from '../template/list-item.art';
+import utils from './utils';
+
+class List {
+ constructor (player) {
+ this.player = player;
+ this.index = 0;
+ this.audios = this.player.options.audio;
+
+ this.bindEvents();
+ }
+
+ bindEvents () {
+ this.player.template.list.addEventListener('click', (e) => {
+ let target;
+ if (e.target.tagName.toUpperCase() === 'LI') {
+ target = e.target;
+ }
+ else {
+ target = e.target.parentElement;
+ }
+ const audioIndex = parseInt(target.getElementsByClassName('aplayer-list-index')[0].innerHTML) - 1;
+ if (audioIndex !== this.index) {
+ this.switch(audioIndex);
+ this.player.play();
+ }
+ else {
+ this.player.toggle();
+ }
+ });
+ }
+
+ show () {
+ this.player.events.trigger('listshow');
+ this.player.template.list.classList.remove('aplayer-list-hide');
+ }
+
+ hide () {
+ this.player.events.trigger('listhide');
+ this.player.template.list.classList.add('aplayer-list-hide');
+ }
+
+ toggle () {
+ if (!this.player.template.list.classList.contains('aplayer-list-hide')) {
+ this.hide();
+ }
+ else {
+ this.show();
+ }
+ }
+
+ add (audios) {
+ this.player.events.trigger('listadd', audios);
+ const wasSingle = !(this.audios.length > 1);
+
+ this.player.template.listOl.innerHTML += tplListItem({
+ theme: this.player.options.theme,
+ audio: audios,
+ index: this.audios.length + 1
+ });
+
+ this.audios = this.audios.concat(audios);
+
+ if (wasSingle && this.audios.length > 1) {
+ this.player.container.classList.add('aplayer-withlist');
+ }
+ this.player.template.list.style.height = this.audios.length * 33 - 1 + 'px';
+ this.player.template.listOl.style.height = this.audios.length * 33 - 1 + 'px';
+
+ this.player.randomOrder = utils.randomOrder(this.audios.length);
+ this.player.template.listCurs = this.player.container.querySelectorAll('.aplayer-list-cur');
+
+ this.player.template.listCurs[this.audios.length - 1].style.backgroundColor = audios.theme || this.player.options.theme;
+ }
+
+ remove (index) {
+ this.player.events.trigger('listremove', index);
+ if (this.audios[index] && this.audios.length > 1) {
+ const list = this.player.container.querySelectorAll('.aplayer-list li');
+ list[index].remove();
+
+ this.audios.splice(index, 1);
+
+ if (index === this.index) {
+ if (this.audios[index + 1]) {
+ this.switch(index);
+ }
+ else {
+ this.switch(index - 1);
+ }
+ }
+ if (this.index > index) {
+ this.index--;
+ }
+
+ for (let i = index; i < list.length; i++) {
+ list[i].getElementsByClassName('aplayer-list-index')[0].textContent = i;
+ }
+ if (this.audios.length === 1) {
+ this.player.container.classList.remove('aplayer-withlist');
+ }
+ this.player.template.list.style.height = this.audios.length * 33 - 1 + 'px';
+ this.player.template.listOl.style.height = this.audios.length * 33 - 1 + 'px';
+
+ this.player.template.listCurs = this.player.container.querySelectorAll('.aplayer-list-cur');
+ }
+ else {
+ // TODO
+ }
+ }
+
+ switch (index) {
+ this.player.events.trigger('listswitch', index);
+ if (typeof index !== 'undefined') {
+ this.index = index;
+ }
+
+ const audio = this.audios[this.index];
+
+ // set html
+ this.player.template.pic.style.backgroundImage = audio.cover ? `url('${audio.cover}')` : '';
+ this.player.theme(this.audios[this.index].theme || this.player.options.theme, this.index);
+ this.player.template.title.innerHTML = audio.name;
+ this.player.template.author.innerHTML = audio.artist ? ' - ' + audio.artist : '';
+
+ const light = this.player.container.getElementsByClassName('aplayer-list-light')[0];
+ if (light) {
+ light.classList.remove('aplayer-list-light');
+ }
+ this.player.container.querySelectorAll('.aplayer-list li')[this.index].classList.add('aplayer-list-light');
+
+ this.player.template.list.scrollTop = this.index * 33;
+
+ this.player.setAudio(audio);
+
+ this.player.lrc && this.player.lrc.switch(this.index);
+
+ // set duration time
+ if (this.player.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first
+ this.player.template.dtime.innerHTML = this.player.audio.duration ? utils.secondToTime(this.player.audio.duration) : '00:00';
+ }
+ }
+}
+
+export default List;
\ No newline at end of file
diff --git a/src/js/player.js b/src/js/player.js
index 361c2c3..d1b344e 100644
--- a/src/js/player.js
+++ b/src/js/player.js
@@ -10,7 +10,7 @@ import Lrc from './lrc';
import Controller from './controller';
import Timer from './timer';
import Events from './events';
-import tplListItem from '../template/list-item.art';
+import List from './list';
const instances = [];
@@ -25,7 +25,6 @@ class APlayer {
constructor (options) {
this.options = handleOption(options);
this.container = this.options.container;
- this.playIndex = 0;
this.paused = true;
this.playedPromise = Promise.resolve();
this.mode = 'normal';
@@ -84,13 +83,14 @@ class APlayer {
this.bar = new Bar(this.template);
this.controller = new Controller(this);
this.timer = new Timer(this);
+ this.list = new List(this);
this.initAudio();
if (this.options.order === 'random') {
- this.switchAudio(this.randomOrder[0]);
+ this.list.switch(this.randomOrder[0]);
}
else {
- this.switchAudio(0);
+ this.list.switch(0);
}
// autoplay
@@ -156,36 +156,36 @@ class APlayer {
this.on('ended', () => {
if (this.options.loop === 'none') {
if (this.options.order === 'list') {
- if (this.playIndex < this.options.audio.length - 1) {
- this.switchAudio((this.playIndex + 1) % this.options.audio.length);
+ if (this.list.index < this.list.audios.length - 1) {
+ this.list.switch((this.list.index + 1) % this.list.audios.length);
this.play();
}
else {
- this.switchAudio((this.playIndex + 1) % this.options.audio.length);
+ this.list.switch((this.list.index + 1) % this.list.audios.length);
this.pause();
}
}
else if (this.options.order === 'random') {
- if (this.randomOrder.indexOf(this.playIndex) < this.randomOrder.length - 1) {
- this.switchAudio(this.nextRandomNum());
+ if (this.randomOrder.indexOf(this.list.index) < this.randomOrder.length - 1) {
+ this.list.switch(this.nextRandomNum());
this.play();
}
else {
- this.switchAudio(this.nextRandomNum());
+ this.list.switch(this.nextRandomNum());
this.pause();
}
}
}
else if (this.options.loop === 'one') {
- this.switchAudio(this.playIndex);
+ this.list.switch(this.list.index);
this.play();
}
else if (this.options.loop === 'all') {
if (this.options.order === 'list') {
- this.switchAudio((this.playIndex + 1) % this.options.audio.length);
+ this.list.switch((this.list.index + 1) % this.list.audios.length);
}
else if (this.options.order === 'random') {
- this.switchAudio(this.nextRandomNum());
+ this.list.switch(this.nextRandomNum());
}
this.play();
}
@@ -194,32 +194,7 @@ class APlayer {
this.volume(this.user.get('volume'), true);
}
- switchAudio (index) {
- this.events.trigger('switchaudio', index);
- if (typeof index !== 'undefined') {
- this.playIndex = index;
- }
-
- const audio = this.options.audio[this.playIndex];
- // set html
- if (audio.cover) {
- this.template.pic.style.backgroundImage = `url('${audio.cover}')`;
- }
- else {
- this.template.pic.style.backgroundImage = '';
- }
- this.theme();
- this.template.title.innerHTML = audio.name;
- this.template.author.innerHTML = audio.artist ? ' - ' + audio.artist : '';
- const light = this.container.getElementsByClassName('aplayer-list-light')[0];
- if (light) {
- light.classList.remove('aplayer-list-light');
- }
- this.container.querySelectorAll('.aplayer-list li')[this.playIndex].classList.add('aplayer-list-light');
-
- this.template.list.scrollTop = this.playIndex * 33;
-
- // mse
+ setAudio (audio) {
if (this.hls) {
this.hls.destroy();
this.hls = null;
@@ -259,25 +234,17 @@ class APlayer {
this.audio.src = audio.url;
}
}
-
this.seek(0);
if (!this.paused) {
this.audio.play();
}
-
- this.lrc && this.lrc.switch(this.playIndex);
-
- // set duration time
- if (this.audio.duration !== 1) { // compatibility: Android browsers will output 1 at first
- this.template.dtime.innerHTML = this.audio.duration ? utils.secondToTime(this.audio.duration) : '00:00';
- }
}
- theme (color = this.options.audio[this.playIndex].theme, index = this.playIndex) {
- this.options.audio[index].theme = color;
+ theme (color = this.list.audios[this.list.index].theme || this.options.theme, index = this.list.index) {
+ this.list.audios[index].theme = color;
this.template.listCurs[index].style.backgroundColor = color;
- if (index === this.playIndex) {
+ if (index === this.list.index) {
this.template.pic.style.backgroundColor = color;
this.template.played.style.background = color;
this.template.thumb.style.background = color;
@@ -415,19 +382,12 @@ class APlayer {
}
}
- /**
- * get whether multiple audio definitions are loaded
- */
- isMultiple () {
- return this.options.audio.length > 1;
- }
-
/**
* get next random number
*/
nextRandomNum () {
- if (this.isMultiple()) {
- const index = this.randomOrder.indexOf(this.playIndex);
+ if (this.list.audios.length > 1) {
+ const index = this.randomOrder.indexOf(this.list.index);
if (index === this.randomOrder.length - 1) {
return this.randomOrder[0];
}
@@ -440,67 +400,19 @@ class APlayer {
}
}
- /**
- * add audio dynamically
- *
- * @param {Array} newMusic
- */
- addAudio (newMusic) {
- this.events.trigger('addaudio', newMusic);
- const wasSingle = !this.isMultiple();
-
- this.template.listOl.innerHTML += tplListItem({
- theme: this.options.theme,
- audio: newMusic,
- index: this.options.audio.length + 1
- });
-
- this.options.audio = this.options.audio.concat(newMusic);
-
- if (wasSingle && this.isMultiple()) {
- this.container.classList.add('aplayer-withlist');
- }
- this.template.list.style.height = this.options.audio.length * 33 - 1 + 'px';
- this.template.listOl.style.height = this.options.audio.length * 33 - 1 + 'px';
-
- this.randomOrder = utils.randomOrder(this.options.audio.length);
- this.template.listCurs = this.container.querySelectorAll('.aplayer-list-cur');
+ // abandoned
+ switchAudio (index) {
+ this.list.switch(index);
}
- /**
- * Remove song from playlist
- */
+ // abandoned
+ addAudio (audios) {
+ this.list.add(audios);
+ }
+
+ // abandoned
removeAudio (index) {
- this.events.trigger('removeaudio', index);
- if (this.options.audio[index] && this.options.audio.length > 1) {
- const list = this.container.querySelectorAll('.aplayer-list li');
-
- this.options.audio.splice(index, 1);
-
- if (index === this.playIndex) {
- if (this.options.audio[index + 1]) {
- this.switchAudio(index);
- }
- else {
- this.switchAudio(index - 1);
- }
- }
- if (this.playIndex > index) {
- this.playIndex--;
- }
-
- list[index].remove();
- for (let i = index; i < list.length; i++) {
- list[i].getElementsByClassName('aplayer-list-index')[0].textContent = i;
- }
- if (this.options.audio.length === 1) {
- this.container.classList.remove('aplayer-withlist');
- }
- this.template.list.style.height = this.options.audio.length * 33 - 1 + 'px';
- this.template.listOl.style.height = this.options.audio.length * 33 - 1 + 'px';
-
- this.template.listCurs = this.container.querySelectorAll('.aplayer-list-cur');
- }
+ this.list.remove(index);
}
/**
diff --git a/src/js/utils.js b/src/js/utils.js
index 88d9fbc..ec978f3 100644
--- a/src/js/utils.js
+++ b/src/js/utils.js
@@ -70,7 +70,7 @@ const utils = {
/**
* get random order, using Fisher–Yates shuffle
*/
- randomOrder: (length = this.options.audio.length) => {
+ randomOrder: (length) => {
function shuffle (arr) {
for (let i = arr.length - 1; i >= 0; i--) {
const randomIndex = Math.floor(Math.random() * (i + 1));
diff --git a/src/template/player.art b/src/template/player.art
index b7be18d..5a9a2a3 100644
--- a/src/template/player.art
+++ b/src/template/player.art
@@ -35,11 +35,9 @@
- {{ if options.audio.length > 1 }}
- {{ /if }}