diff --git a/public/icon/down-arrow.svg b/public/icon/down-arrow.svg new file mode 100644 index 0000000..ecff9ac --- /dev/null +++ b/public/icon/down-arrow.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/index.css b/public/index.css index 5e0ef4a..ad798c7 100644 --- a/public/index.css +++ b/public/index.css @@ -47,6 +47,9 @@ table { border-spacing: 0; border-collapse: collapse; } +th { + text-align: left; +} th.small { width: 5%; } @@ -163,21 +166,24 @@ tr:nth-child(even) { .ctx-menu ul li { display: block; } -.ctx-item { +.ctx-item, .dropdown-content div { padding: 10px; cursor: pointer; display: block; } -.ctx-item:nth-child(even) { +.ctx-item:nth-child(even), .dropdown-content div:nth-child(even) { background-color: #0b1f2f; } -.ctx-item:hover { +.ctx-item:hover, .dropdown-content div:hover { background-color: #0c273c; } -.playing-flex { +.inline-flex { display: flex; flex-direction: row; } +.inline-flex input { + flex-grow: 1; +} .queue-tag { padding: 10px; background-color: #007d32; @@ -185,6 +191,41 @@ tr:nth-child(even) { font-weight: bold; border-right: 5px solid #005c25; } +.dropdown { + position: relative; + display: inline-block; +} +.dropdown-button { + background-color: #112330; + position: relative; + padding: 25px 30px; + cursor: pointer; +} +.dropdown-button::after { + content: ""; + background: url(icon/down-arrow.svg) no-repeat; + background-size: auto auto; + background-size: 16px; + position: absolute; + width: 16px; + height: 16px; + right: 5px; + top: 40%; +} +.dropdown-content { + display: none; + position: absolute; + background-color: #112330; + min-width: 160px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; +} +.dropdown-content div { + padding: 20px; +} +.dropdown:hover .dropdown-content { + display: block; +} @media only screen and (max-width: 600px) { tr td:nth-child(1), th:nth-child(1) { display: none; diff --git a/public/index.html b/public/index.html index 0f4856e..6e2a542 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,16 @@
- +
+ + +
@@ -31,7 +40,7 @@
>>
-
+
Nothing playing
diff --git a/public/index.js b/public/index.js index ddc2f5e..7bfe6a4 100644 --- a/public/index.js +++ b/public/index.js @@ -30,11 +30,16 @@ var queue = [] var qTag = document.getElementById('queue') + // Playlists + var playlist = null + var pSel = document.getElementById('playlist-select') + window.mobilecheck = function() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); return check } + window.isMobile = window.mobilecheck() // Seconds into HH:MM:SS function toHHMMSS (numbr) { @@ -150,6 +155,13 @@ } } + function removeFromQueue (id) { + var index = queue.indexOf(id) + if (index > -1) { + queue.splice(index, 1) + } + } + var ctxState = 0 function ctxHide () { ctxState = 0 @@ -157,6 +169,7 @@ } function updateQT (q) { + if (playlist === 0) showTracks(pageNum) if (q) { qTag.style.display = 'block' var cnt = '+' + queue.length @@ -175,7 +188,10 @@ play(ctxState) break case 'queue': - queue.push(ctxState) + if (playlist === 0) + removeFromQueue(ctxState) + else + queue.push(ctxState) break case 'download': audio.pause() @@ -186,46 +202,75 @@ updateQT(qTag.style.display === 'block') } - function ctxTrack (xid, ev) { + function ctxTrack (xid, ev, qe) { positionMenu(ev) menu.style.display = 'block' + + let qbtn = menu.querySelector('.ctx-item[data-action="queue"]') + qbtn.innerHTML = qe ? 'Remove from Queue' : 'Queue Track' + ctxState = xid } + function trackDataRow (track) { + let title = window.isMobile ? shortTitle(track.title, track.artist) : track.title + let trTag = document.createElement('tr') + trTag.className = 'track' + trTag.setAttribute('data-id', track.id) + trTag.innerHTML += '
' + trTag.innerHTML += '' + trTag.innerHTML += '' + trTag.innerHTML += '' + trTag.innerHTML += '' + trTag.innerHTML += '' + return trTag + } + function constructList (tracks) { table.innerHTML = tableHead + for (let i in tracks) { let track = tracks[i] - let title = window.mobilecheck() ? shortTitle(track.title, track.artist) : track.title - let htmlAdder = '' - htmlAdder += '' - htmlAdder += '' - htmlAdder += '' - htmlAdder += '' - htmlAdder += '' - htmlAdder += '' - htmlAdder += '' - table.innerHTML += htmlAdder - } + let tag = trackDataRow(track) - let trid = document.querySelectorAll('table .track') - for (let e in trid) { - let trelem = trid[e] - if (!(trelem instanceof Element)) continue - let tride = trelem.querySelector('td') - let id = parseInt(tride.innerHTML) - - trelem.addEventListener('click', function (e) { - play(id) + tag.addEventListener('click', function (e) { + play(track.id) }, false) - trelem.addEventListener('contextmenu', function (e) { + tag.addEventListener('contextmenu', function (e) { e.preventDefault() - ctxTrack(id, e) + ctxTrack(track.id, e) }, false) + + table.appendChild(tag) } } + function recursionQueueList (index) { + let qid = queue[index] + if (!qid || playlist !== 0) return + + httpGet('/api/track/' + qid).then(function (data) { + let tag = trackDataRow(data) + + tag.addEventListener('contextmenu', function (e) { + e.preventDefault() + ctxTrack(qid, e, true) + }, false) + + table.appendChild(tag) + + recursionQueueList(index + 1) + }, function (e) { + console.log(e) + }) + } + + function constructQueue () { + table.innerHTML = tableHead + recursionQueueList(0) + } + function updatePaging () { if (pages > 1) { paginator.style.display = 'flex' @@ -249,6 +294,10 @@ if (page < 1) return updatePaging() + if (playlist === 0) { + return constructQueue() + } + if (query.trim() === '') { return httpGet('/api/tracks?page=' + page).then(function (data) { pageNum = page @@ -295,6 +344,36 @@ play(queue.shift(), true) } + function showPlaylist (pid) { + + } + + function handleSelect () { + let btn = pSel.querySelector('.dropdown-button') + let btns = pSel.querySelectorAll('.dropdown-content div') + + for (let i in btns) { + let btni = btns[i] + if (!(btni instanceof Element)) continue + let cnt = btni.getAttribute('data-value') + + btni.addEventListener('click', function (e) { + btn.innerHTML = btni.innerHTML + switch (cnt) { + case 'all': + playlist = null + break + case 'queue': + playlist = 0 + break + default: + showPlaylist(cnt) + } + showTracks(pageNum) + }, false) + } + } + input.addEventListener('keyup', function (e) { e.which === 13 && showTracks(input.value.trim() === '' ? (pagePrev !== 0 ? pagePrev : 1) : 1) }, false) @@ -348,4 +427,5 @@ showTracks(1) handleHash(window.location.hash) + handleSelect() })()
' + track.id + '' + title + '' + (track.artist || '') + '' + (track.album || '') + '' + (track.year || '') + '' + toHHMMSS(track.duration) + '
' + track.id + '' + title + '' + (track.artist || '') + '' + (track.album || '') + '' + (track.year || '') + '' + toHHMMSS(track.duration) + '