re-organized js files, first attempt of adding Vue SFC
This commit is contained in:
parent
7824aef125
commit
dfc30468cf
@ -1,6 +1,11 @@
|
|||||||
{
|
{
|
||||||
"css": {
|
"css": {
|
||||||
"allowed_file_extensions": ["css", "scss", "sass", "less"],
|
"allowed_file_extensions": [
|
||||||
|
"css",
|
||||||
|
"scss",
|
||||||
|
"sass",
|
||||||
|
"less"
|
||||||
|
],
|
||||||
"end_with_newline": true,
|
"end_with_newline": true,
|
||||||
"indent_char": " ",
|
"indent_char": " ",
|
||||||
"indent_size": 2,
|
"indent_size": 2,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": true,
|
"useTabs": true,
|
||||||
|
"tabWidth": 2,
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"printWidth": 120,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
"vueIndentScriptAndStyle": false
|
"vueIndentScriptAndStyle": false
|
||||||
}
|
}
|
@ -42,6 +42,9 @@
|
|||||||
<button class="search_tablinks" id="search_artist_tab" onclick="changeTab(event, 'search', 'artist_search')">Artist</button>
|
<button class="search_tablinks" id="search_artist_tab" onclick="changeTab(event, 'search', 'artist_search')">Artist</button>
|
||||||
<button class="search_tablinks" id="search_playlist_tab" onclick="changeTab(event, 'search', 'playlist_search')">Playlist</button>
|
<button class="search_tablinks" id="search_playlist_tab" onclick="changeTab(event, 'search', 'playlist_search')">Playlist</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="v-app">
|
||||||
|
<app></app>
|
||||||
|
</div>
|
||||||
<div id="search_tab_content">
|
<div id="search_tab_content">
|
||||||
<!-- ### Main Search Tab ### -->
|
<!-- ### Main Search Tab ### -->
|
||||||
<div id="main_search" class="search_tabcontent">
|
<div id="main_search" class="search_tabcontent">
|
||||||
@ -53,7 +56,7 @@ <h1 v-on:click="changeSearchTab(section)">{{ names[section] }}</h1>
|
|||||||
<div class="cover_container">
|
<div class="cover_container">
|
||||||
<img v-bind:src="(results.TOP_RESULT[0].__TYPE__ == 'artist' ? 'https://e-cdns-images.dzcdn.net/images/artist/' + results.TOP_RESULT[0].ART_PICTURE : results.TOP_RESULT[0].__TYPE__ == 'album' ? 'https://e-cdns-images.dzcdn.net/images/cover/' + results.TOP_RESULT[0].ALB_PICTURE : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? 'https://e-cdns-images.dzcdn.net/images/'+ results.TOP_RESULT[0].PICTURE_TYPE +'/' + results.TOP_RESULT[0].PLAYLIST_PICTURE :'https://e-cdns-images.dzcdn.net/images/cover/') + '/156x156-000000-80-0-0.jpg'"
|
<img v-bind:src="(results.TOP_RESULT[0].__TYPE__ == 'artist' ? 'https://e-cdns-images.dzcdn.net/images/artist/' + results.TOP_RESULT[0].ART_PICTURE : results.TOP_RESULT[0].__TYPE__ == 'album' ? 'https://e-cdns-images.dzcdn.net/images/cover/' + results.TOP_RESULT[0].ALB_PICTURE : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? 'https://e-cdns-images.dzcdn.net/images/'+ results.TOP_RESULT[0].PICTURE_TYPE +'/' + results.TOP_RESULT[0].PLAYLIST_PICTURE :'https://e-cdns-images.dzcdn.net/images/cover/') + '/156x156-000000-80-0-0.jpg'"
|
||||||
v-bind:class="(results.TOP_RESULT[0].__TYPE__ == 'artist' ? 'circle' : 'rounded') + ' coverart'"></img>
|
v-bind:class="(results.TOP_RESULT[0].__TYPE__ == 'artist' ? 'circle' : 'rounded') + ' coverart'"></img>
|
||||||
<div v-on:click="addToQueue('https://deezer.com/'+results.TOP_RESULT[0].__TYPE__+'/'+(results.TOP_RESULT[0].__TYPE__ == 'artist' ? results.TOP_RESULT[0].ART_ID : results.TOP_RESULT[0].__TYPE__ == 'album' ? results.TOP_RESULT[0].ALB_ID : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? results.TOP_RESULT[0].PLAYLIST_ID : ''))" class="download_overlay"><i class="material-icons">get_app</i></div>
|
<div role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://deezer.com/'+results.TOP_RESULT[0].__TYPE__+'/'+(results.TOP_RESULT[0].__TYPE__ == 'artist' ? results.TOP_RESULT[0].ART_ID : results.TOP_RESULT[0].__TYPE__ == 'album' ? results.TOP_RESULT[0].ALB_ID : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? results.TOP_RESULT[0].PLAYLIST_ID : '')" class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info_box">
|
<div class="info_box">
|
||||||
<p class="primary-text">{{ results.TOP_RESULT[0].__TYPE__ == 'artist' ? results.TOP_RESULT[0].ART_NAME : results.TOP_RESULT[0].__TYPE__ == 'album' ? results.TOP_RESULT[0].ALB_TITLE : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? results.TOP_RESULT[0].TITLE : '' }}</p>
|
<p class="primary-text">{{ results.TOP_RESULT[0].__TYPE__ == 'artist' ? results.TOP_RESULT[0].ART_NAME : results.TOP_RESULT[0].__TYPE__ == 'album' ? results.TOP_RESULT[0].ALB_TITLE : results.TOP_RESULT[0].__TYPE__ == 'playlist' ? results.TOP_RESULT[0].TITLE : '' }}</p>
|
||||||
@ -69,7 +72,7 @@ <h1 v-on:click="changeSearchTab(section)">{{ names[section] }}</h1>
|
|||||||
<td class="breakline"><span v-for="artist in track.ARTISTS">{{artist.ART_NAME}} </span></td>
|
<td class="breakline"><span v-for="artist in track.ARTISTS">{{artist.ART_NAME}} </span></td>
|
||||||
<td class="breakline">{{track.ALB_TITLE}}</td>
|
<td class="breakline">{{track.ALB_TITLE}}</td>
|
||||||
<td>{{convertDuration(track.DURATION)}}</td>
|
<td>{{convertDuration(track.DURATION)}}</td>
|
||||||
<td v-on:click="addToQueue('https://www.deezer.com/track/'+track.SNG_ID)" style="width: 56px; text-align: center;" class="clickable"><i class="material-icons">get_app</i></td>
|
<td role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://www.deezer.com/track/'+track.SNG_ID" style="width: 56px; text-align: center;" class="clickable"><i class="material-icons">get_app</i></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -77,7 +80,7 @@ <h1 v-on:click="changeSearchTab(section)">{{ names[section] }}</h1>
|
|||||||
<div v-for="release in results[section].data.slice(0, 10)" class="release">
|
<div v-for="release in results[section].data.slice(0, 10)" class="release">
|
||||||
<div class="cover_container">
|
<div class="cover_container">
|
||||||
<img v-bind:class="(section == 'ARTIST' ? 'circle' : 'rounded') + ' coverart'" v-bind:src="(section == 'ARTIST' ? 'https://e-cdns-images.dzcdn.net/images/artist/' + release.ART_PICTURE : section == 'ALBUM' ? 'https://e-cdns-images.dzcdn.net/images/cover/' + release.ALB_PICTURE : section == 'PLAYLIST' ? 'https://e-cdns-images.dzcdn.net/images/'+ release.PICTURE_TYPE +'/' + release.PLAYLIST_PICTURE : 'https://e-cdns-images.dzcdn.net/images/cover/' ) + '/156x156-000000-80-0-0.jpg'">
|
<img v-bind:class="(section == 'ARTIST' ? 'circle' : 'rounded') + ' coverart'" v-bind:src="(section == 'ARTIST' ? 'https://e-cdns-images.dzcdn.net/images/artist/' + release.ART_PICTURE : section == 'ALBUM' ? 'https://e-cdns-images.dzcdn.net/images/cover/' + release.ALB_PICTURE : section == 'PLAYLIST' ? 'https://e-cdns-images.dzcdn.net/images/'+ release.PICTURE_TYPE +'/' + release.PLAYLIST_PICTURE : 'https://e-cdns-images.dzcdn.net/images/cover/' ) + '/156x156-000000-80-0-0.jpg'">
|
||||||
<div v-on:click="addToQueue('https://deezer.com/'+(section == 'ARTIST' ? 'artist/'+release.ART_ID : section == 'ALBUM' ? 'album/'+release.ALB_ID : section == 'PLAYLIST' ? 'playlist/'+release.PLAYLIST_ID : ''))" class="download_overlay"><i class="material-icons">get_app</i></div>
|
<div role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://deezer.com/'+(section == 'ARTIST' ? 'artist/'+release.ART_ID : section == 'ALBUM' ? 'album/'+release.ALB_ID : section == 'PLAYLIST' ? 'playlist/'+release.PLAYLIST_ID : '')" class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="primary-text">{{ section == 'ARTIST' ? release.ART_NAME : section == 'ALBUM' ? release.ALB_TITLE : section == 'PLAYLIST' ? release.TITLE : '' }}</p>
|
<p class="primary-text">{{ section == 'ARTIST' ? release.ART_NAME : section == 'ALBUM' ? release.ALB_TITLE : section == 'PLAYLIST' ? release.TITLE : '' }}</p>
|
||||||
<p class="secondary-text">{{ section == 'ARTIST' ? numberWithDots(release.NB_FAN) + ' fans' : section == 'ALBUM' ? release.ART_NAME+' - '+release.NUMBER_TRACK+' tracks' : section == 'PLAYLIST' ? release.NB_SONG+' tracks' : '' }}</p>
|
<p class="secondary-text">{{ section == 'ARTIST' ? numberWithDots(release.NB_FAN) + ' fans' : section == 'ALBUM' ? release.ART_NAME+' - '+release.NUMBER_TRACK+' tracks' : section == 'PLAYLIST' ? release.NB_SONG+' tracks' : '' }}</p>
|
||||||
@ -109,7 +112,7 @@ <h1>No Tracks found</h1>
|
|||||||
<td class="breakline"><span v-for="artist in track.ARTISTS">{{artist.ART_NAME}} </span></td>
|
<td class="breakline"><span v-for="artist in track.ARTISTS">{{artist.ART_NAME}} </span></td>
|
||||||
<td class="breakline">{{track.ALB_TITLE}}</td>
|
<td class="breakline">{{track.ALB_TITLE}}</td>
|
||||||
<td>{{convertDuration(track.DURATION)}}</td>
|
<td>{{convertDuration(track.DURATION)}}</td>
|
||||||
<td v-on:click="addToQueue('https://www.deezer.com/track/'+track.SNG_ID)" style="width: 56px; text-align: center;" class="clickable"><i class="material-icons">get_app</i></td>
|
<td role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://www.deezer.com/track/'+track.SNG_ID" style="width: 56px; text-align: center;" class="clickable"><i class="material-icons">get_app</i></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -122,7 +125,7 @@ <h1>No Albums found</h1>
|
|||||||
<div v-for="release in results.data" class="release">
|
<div v-for="release in results.data" class="release">
|
||||||
<div class="cover_container">
|
<div class="cover_container">
|
||||||
<img class="rounded coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/cover/' + release.ALB_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
<img class="rounded coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/cover/' + release.ALB_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
||||||
<div v-on:click="addToQueue('https://www.deezer.com/album/'+release.ALB_ID)" class="download_overlay"><i class="material-icons">get_app</i></div>
|
<div role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://www.deezer.com/album/'+release.ALB_ID" class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="primary-text">{{ release.ALB_TITLE }}</p>
|
<p class="primary-text">{{ release.ALB_TITLE }}</p>
|
||||||
<p class="secondary-text">{{ 'by '+release.ART_NAME }}</p>
|
<p class="secondary-text">{{ 'by '+release.ART_NAME }}</p>
|
||||||
@ -138,7 +141,7 @@ <h1>No Artists found</h1>
|
|||||||
<div v-for="release in results.data" class="release">
|
<div v-for="release in results.data" class="release">
|
||||||
<div class="cover_container">
|
<div class="cover_container">
|
||||||
<img class="circle coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/artist/' + release.ART_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
<img class="circle coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/artist/' + release.ART_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
||||||
<div v-on:click="addToQueue('https://www.deezer.com/artist/'+release.ART_ID)" class="download_overlay"><i class="material-icons">get_app</i></div>
|
<div role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://www.deezer.com/artist/'+release.ART_ID" class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="primary-text">{{ release.ART_NAME }}</p>
|
<p class="primary-text">{{ release.ART_NAME }}</p>
|
||||||
<p class="secondary-text">{{ numberWithDots(release.NB_FAN) + ' fans' }}</p>
|
<p class="secondary-text">{{ numberWithDots(release.NB_FAN) + ' fans' }}</p>
|
||||||
@ -154,7 +157,7 @@ <h1>No Playlists found</h1>
|
|||||||
<div v-for="release in results.data" class="release">
|
<div v-for="release in results.data" class="release">
|
||||||
<div class="cover_container">
|
<div class="cover_container">
|
||||||
<img class="rounded coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/'+ release.PICTURE_TYPE +'/' + release.PLAYLIST_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
<img class="rounded coverart" v-bind:src="'https://e-cdns-images.dzcdn.net/images/'+ release.PICTURE_TYPE +'/' + release.PLAYLIST_PICTURE + '/156x156-000000-80-0-0.jpg'">
|
||||||
<div v-on:click="addToQueue('https://www.deezer.com/playlist/'+release.PLAYLIST_ID)" class="download_overlay"><i class="material-icons">get_app</i></div>
|
<div role="button" aria-label="download" v-on:contextmenu="openQualityModal(event)" v-on:click="addToQueue(event)" v-bind:data-link="'https://www.deezer.com/playlist/'+release.PLAYLIST_ID" class="download_overlay"><i class="material-icons">get_app</i></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="primary-text">{{ release.TITLE }}</p>
|
<p class="primary-text">{{ release.TITLE }}</p>
|
||||||
<p class="secondary-text">{{ release.NB_SONG+' tracks' }}</p>
|
<p class="secondary-text">{{ release.NB_SONG+' tracks' }}</p>
|
||||||
@ -377,13 +380,14 @@ <h1>Settings</h1>
|
|||||||
<div id="download_list" class=""></div>
|
<div id="download_list" class=""></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="/public/js/socket.io.js"></script>
|
<script type="text/javascript" src="/public/js/vendor/httpVueLoader.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/jquery-3.3.1.min.js"></script>
|
<script type="text/javascript" src="/public/js/vendor/socket.io.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/vue.min.js"></script>
|
<script type="text/javascript" src="/public/js/vendor/jquery-3.3.1.min.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/toastify.js"></script>
|
<script type="text/javascript" src="/public/js/vendor/vue.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/public/js/vendor/toastify.js"></script>
|
||||||
|
<script type="text/javascript" src="/public/js/app/v-app.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/app/app.js"></script>
|
<script type="text/javascript" src="/public/js/app/app.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/app/utils.js"></script>
|
<script type="text/javascript" src="/public/js/app/utils.js"></script>
|
||||||
<script type="text/javascript" src="/public/js/app/search.js"></script>
|
<script type="text/javascript" src="/public/js/app/search.js"></script>
|
||||||
|
@ -1,42 +1,37 @@
|
|||||||
// Initialization
|
// Initialization
|
||||||
const socket = io.connect(window.location.href)
|
const socket = io.connect(window.location.href)
|
||||||
localStorage = window.localStorage;
|
localStorage = window.localStorage
|
||||||
// tabs stuff
|
// tabs stuff
|
||||||
search_selected = ""
|
let search_selected = ''
|
||||||
main_selected=""
|
let main_selected = ''
|
||||||
// toasts stuff
|
// toasts stuff
|
||||||
toastsWithId = {}
|
let toastsWithId = {}
|
||||||
// settings
|
// settings
|
||||||
lastSettings = {}
|
let lastSettings = {}
|
||||||
|
|
||||||
function toast(msg, icon = null, dismiss = true, id = null) {
|
function toast(msg, icon = null, dismiss = true, id = null) {
|
||||||
if (toastsWithId[id]) {
|
if (toastsWithId[id]) {
|
||||||
let toastObj = toastsWithId[id]
|
let toastObj = toastsWithId[id]
|
||||||
let toastDOM = $(`div.toastify[toast_id=${id}]`)
|
let toastDOM = $(`div.toastify[toast_id=${id}]`)
|
||||||
if (msg) {
|
if (msg) {
|
||||||
toastDOM.find(".toast-message").html(msg)
|
toastDOM.find('.toast-message').html(msg)
|
||||||
}
|
}
|
||||||
if (icon) {
|
if (icon) {
|
||||||
if (icon=='loading')
|
if (icon == 'loading') icon = `<div class="circle-loader"></div>`
|
||||||
icon = `<div class="circle-loader"></div>`
|
else icon = `<i class="material-icons">${icon}</i>`
|
||||||
else
|
toastDOM.find('.toast-icon').html(icon)
|
||||||
icon = `<i class="material-icons">${icon}</i>`
|
|
||||||
toastDOM.find(".toast-icon").html(icon)
|
|
||||||
}
|
}
|
||||||
console.log(dismiss)
|
console.log({ dismiss })
|
||||||
if (dismiss !== null && dismiss) {
|
if (dismiss !== null && dismiss) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
toastObj.hideToast()
|
toastObj.hideToast()
|
||||||
delete toastsWithId[id]
|
delete toastsWithId[id]
|
||||||
}, 3000);
|
}, 3000)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (icon == null)
|
if (icon == null) icon = ''
|
||||||
icon = ""
|
else if (icon == 'loading') icon = `<div class="circle-loader"></div>`
|
||||||
else if (icon=='loading')
|
else icon = `<i class="material-icons">${icon}</i>`
|
||||||
icon = `<div class="circle-loader"></div>`
|
|
||||||
else
|
|
||||||
icon = `<i class="material-icons">${icon}</i>`
|
|
||||||
let toastObj = Toastify({
|
let toastObj = Toastify({
|
||||||
text: `<span class="toast-icon">${icon}</span><span class="toast-message">${msg}</toast>`,
|
text: `<span class="toast-icon">${icon}</span><span class="toast-message">${msg}</toast>`,
|
||||||
duration: dismiss ? 3000 : 0,
|
duration: dismiss ? 3000 : 0,
|
||||||
@ -50,116 +45,120 @@ function toast(msg, icon=null, dismiss=true, id=null){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("toast", (data)=>{
|
socket.on('toast', data => {
|
||||||
toast(data.msg, data.icon || null, data.dismiss !== undefined ? data.dismiss : true, data.id || null)
|
toast(data.msg, data.icon || null, data.dismiss !== undefined ? data.dismiss : true, data.id || null)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Debug messages for socketio
|
// Debug messages for socketio
|
||||||
socket.on("message", function(msg){
|
socket.on('message', function (msg) {
|
||||||
console.log(msg)
|
console.log(msg)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
if (localStorage.getItem("arl")){
|
if (localStorage.getItem('arl')) {
|
||||||
socket.emit("login", localStorage.getItem("arl"));
|
socket.emit('login', localStorage.getItem('arl'))
|
||||||
$("#login_input_arl").val(localStorage.getItem("arl"))
|
$('#login_input_arl').val(localStorage.getItem('arl'))
|
||||||
}
|
}
|
||||||
// Check if download tab should be open
|
// Check if download tab should be open
|
||||||
if (eval(localStorage.getItem("downloadTabOpen")))
|
if (eval(localStorage.getItem('downloadTabOpen'))) $('#show_download_tab').click()
|
||||||
$("#show_download_tab").click()
|
else $('#hide_download_tab').click()
|
||||||
else
|
|
||||||
$("#hide_download_tab").click()
|
|
||||||
|
|
||||||
// Open default tab
|
// Open default tab
|
||||||
document.getElementById("main_home_tablink").click();
|
document.getElementById('main_home_tablink').click()
|
||||||
})
|
})
|
||||||
|
|
||||||
// Show/Hide Download Tab
|
// Show/Hide Download Tab
|
||||||
document.querySelector("#show_download_tab").onclick = (ev)=>{
|
document.querySelector('#show_download_tab').onclick = ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault()
|
||||||
document.querySelector("#download_tab_bar").style.display = "none";
|
document.querySelector('#download_tab_bar').style.display = 'none'
|
||||||
document.querySelector("#download_tab").style.display = "block";
|
document.querySelector('#download_tab').style.display = 'block'
|
||||||
localStorage.setItem("downloadTabOpen", true)
|
localStorage.setItem('downloadTabOpen', true)
|
||||||
}
|
}
|
||||||
document.querySelector("#hide_download_tab").onclick = (ev)=>{
|
document.querySelector('#hide_download_tab').onclick = ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault()
|
||||||
document.querySelector("#download_tab_bar").style.display = "block";
|
document.querySelector('#download_tab_bar').style.display = 'block'
|
||||||
document.querySelector("#download_tab").style.display = "none";
|
document.querySelector('#download_tab').style.display = 'none'
|
||||||
localStorage.setItem("downloadTabOpen", false)
|
localStorage.setItem('downloadTabOpen', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login stuff
|
// Login stuff
|
||||||
|
|
||||||
function loginButton() {
|
function loginButton() {
|
||||||
let arl = document.querySelector("#login_input_arl").value
|
let arl = document.querySelector('#login_input_arl').value
|
||||||
if (arl != "" && arl != localStorage.getItem("arl")){
|
if (arl != '' && arl != localStorage.getItem('arl')) {
|
||||||
socket.emit("login", arl, true)
|
socket.emit('login', arl, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyARLtoClipboard() {
|
function copyARLtoClipboard() {
|
||||||
$("#login_input_arl").attr("type", "text");
|
$('#login_input_arl').attr('type', 'text')
|
||||||
let copyText = document.querySelector("#login_input_arl")
|
let copyText = document.querySelector('#login_input_arl')
|
||||||
copyText.select();
|
copyText.select()
|
||||||
copyText.setSelectionRange(0, 99999);
|
copyText.setSelectionRange(0, 99999)
|
||||||
document.execCommand("copy");
|
document.execCommand('copy')
|
||||||
$("#login_input_arl").attr("type", "password");
|
$('#login_input_arl').attr('type', 'password')
|
||||||
toast("ARL copied to clipboard", 'assignment')
|
toast('ARL copied to clipboard', 'assignment')
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
socket.emit("logout");
|
socket.emit('logout')
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("logging_in", function(){
|
socket.on('logging_in', function () {
|
||||||
toast("Logging in", "loading", false, "login-toast")
|
toast('Logging in', 'loading', false, 'login-toast')
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("logged_in", function(data){
|
socket.on('logged_in', function (data) {
|
||||||
console.log(data)
|
console.log(data)
|
||||||
switch (data.status) {
|
switch (data.status) {
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
toast("Logged in", "done", true, "login-toast")
|
toast('Logged in', 'done', true, 'login-toast')
|
||||||
if (data.arl) {
|
if (data.arl) {
|
||||||
localStorage.setItem("arl", data.arl)
|
localStorage.setItem('arl', data.arl)
|
||||||
$("#login_input_arl").val(data.arl)
|
$('#login_input_arl').val(data.arl)
|
||||||
}
|
}
|
||||||
$('#open_login_prompt').hide()
|
$('#open_login_prompt').hide()
|
||||||
if (data.user) {
|
if (data.user) {
|
||||||
$("#settings_username").text(data.user.name)
|
$('#settings_username').text(data.user.name)
|
||||||
$("#settings_picture").attr("src",`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`)
|
$('#settings_picture').attr(
|
||||||
$("#logged_in_info").show()
|
'src',
|
||||||
|
`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`
|
||||||
|
)
|
||||||
|
$('#logged_in_info').show()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
case 2:
|
case 2:
|
||||||
toast("Already logged in", "done", true, "login-toast")
|
toast('Already logged in', 'done', true, 'login-toast')
|
||||||
if (data.user) {
|
if (data.user) {
|
||||||
$("#settings_username").text(data.user.name)
|
$('#settings_username').text(data.user.name)
|
||||||
$("#settings_picture").attr("src",`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`)
|
$('#settings_picture').attr(
|
||||||
$("#logged_in_info").show()
|
'src',
|
||||||
|
`https://e-cdns-images.dzcdn.net/images/user/${data.user.picture}/125x125-000000-80-0-0.jpg`
|
||||||
|
)
|
||||||
|
$('#logged_in_info').show()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
case 0:
|
case 0:
|
||||||
toast("Couldn't log in", "close", true, "login-toast")
|
toast("Couldn't log in", 'close', true, 'login-toast')
|
||||||
localStorage.removeItem("arl")
|
localStorage.removeItem('arl')
|
||||||
$("#login_input_arl").val("")
|
$('#login_input_arl').val('')
|
||||||
$('#open_login_prompt').show()
|
$('#open_login_prompt').show()
|
||||||
$("#logged_in_info").hide()
|
$('#logged_in_info').hide()
|
||||||
$("#settings_username").text("Not Logged")
|
$('#settings_username').text('Not Logged')
|
||||||
$("#settings_picture").attr("src",`https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
|
$('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("logged_out", function(){
|
socket.on('logged_out', function () {
|
||||||
toast("Logged out", "done", true, "login-toast")
|
toast('Logged out', 'done', true, 'login-toast')
|
||||||
localStorage.removeItem("arl")
|
localStorage.removeItem('arl')
|
||||||
$("#login_input_arl").val("")
|
$('#login_input_arl').val('')
|
||||||
$('#open_login_prompt').show()
|
$('#open_login_prompt').show()
|
||||||
$("#logged_in_info").hide()
|
$('#logged_in_info').hide()
|
||||||
$("#settings_username").text("Not Logged")
|
$('#settings_username').text('Not Logged')
|
||||||
$("#settings_picture").attr("src",`https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
|
$('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
|
||||||
})
|
})
|
||||||
|
|
||||||
// settings stuff
|
// settings stuff
|
||||||
@ -170,14 +169,14 @@ var settingsTab = new Vue({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("init_settings", function(settings){
|
socket.on('init_settings', function (settings) {
|
||||||
loadSettings(settings)
|
loadSettings(settings)
|
||||||
toast("Settings loaded!", 'settings')
|
toast('Settings loaded!', 'settings')
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("updateSettings", function(settings){
|
socket.on('updateSettings', function (settings) {
|
||||||
loadSettings(settings)
|
loadSettings(settings)
|
||||||
toast("Settings updated!", 'settings')
|
toast('Settings updated!', 'settings')
|
||||||
})
|
})
|
||||||
|
|
||||||
function loadSettings(settings) {
|
function loadSettings(settings) {
|
||||||
@ -187,28 +186,34 @@ function loadSettings(settings){
|
|||||||
|
|
||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
lastSettings = { ...settingsTab.settings }
|
lastSettings = { ...settingsTab.settings }
|
||||||
socket.emit("saveSettings", lastSettings)
|
socket.emit('saveSettings', lastSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tabs stuff
|
// tabs stuff
|
||||||
function changeTab(evt, section, tabName) {
|
function changeTab(evt, section, tabName) {
|
||||||
var i, tabcontent, tablinks;
|
console.log( {evt, section, tabName} );
|
||||||
tabcontent = document.getElementsByClassName(section+"_tabcontent");
|
|
||||||
|
var i, tabcontent, tablinks
|
||||||
|
tabcontent = document.getElementsByClassName(section + '_tabcontent')
|
||||||
for (i = 0; i < tabcontent.length; i++) {
|
for (i = 0; i < tabcontent.length; i++) {
|
||||||
tabcontent[i].style.display = "none";
|
tabcontent[i].style.display = 'none'
|
||||||
}
|
}
|
||||||
tablinks = document.getElementsByClassName(section+"_tablinks");
|
tablinks = document.getElementsByClassName(section + '_tablinks')
|
||||||
for (i = 0; i < tablinks.length; i++) {
|
for (i = 0; i < tablinks.length; i++) {
|
||||||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
tablinks[i].className = tablinks[i].className.replace(' active', '')
|
||||||
}
|
}
|
||||||
if (tabName == "settings_tab" && main_selected != "settings_tab"){
|
if (tabName == 'settings_tab' && main_selected != 'settings_tab') {
|
||||||
settingsTab.settings = { ...lastSettings }
|
settingsTab.settings = { ...lastSettings }
|
||||||
}
|
}
|
||||||
document.getElementById(tabName).style.display = "block";
|
document.getElementById(tabName).style.display = 'block'
|
||||||
window[section+"_selected"] = tabName
|
window[section + '_selected'] = tabName
|
||||||
evt.currentTarget.className += " active";
|
evt.currentTarget.className += ' active'
|
||||||
// Check if you need to load more content in the search tab
|
// Check if you need to load more content in the search tab
|
||||||
if (document.getElementById("content").offsetHeight >= document.getElementById("content").scrollHeight && main_selected == "search_tab" && ["track_search", "album_search", "artist_search", "playlist_search"].indexOf(search_selected) != -1){
|
if (
|
||||||
scrolledSearch(window[search_selected.split("_")[0]+"Search"])
|
document.getElementById('content').offsetHeight >= document.getElementById('content').scrollHeight &&
|
||||||
|
main_selected == 'search_tab' &&
|
||||||
|
['track_search', 'album_search', 'artist_search', 'playlist_search'].indexOf(search_selected) != -1
|
||||||
|
) {
|
||||||
|
scrolledSearch(window[search_selected.split('_')[0] + 'Search'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
public/js/app/components/App.vue
Normal file
20
public/js/app/components/App.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// const Import = httpVueLoader('./Import.vue')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: () => ({
|
||||||
|
who: 'world'
|
||||||
|
}),
|
||||||
|
mounted() {
|
||||||
|
console.log( 'First Vue SFC try' );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -2,7 +2,7 @@ var queueList = {}
|
|||||||
var queue = []
|
var queue = []
|
||||||
var queueComplete = []
|
var queueComplete = []
|
||||||
|
|
||||||
socket.on("init_downloadQueue", function(data){
|
socket.on('init_downloadQueue', function (data) {
|
||||||
console.log(data)
|
console.log(data)
|
||||||
if (data.queueComplete.length) {
|
if (data.queueComplete.length) {
|
||||||
data.queueComplete.forEach(item => {
|
data.queueComplete.forEach(item => {
|
||||||
@ -19,11 +19,9 @@ socket.on("init_downloadQueue", function(data){
|
|||||||
|
|
||||||
function addToQueue(queueItem) {
|
function addToQueue(queueItem) {
|
||||||
queueList[queueItem.uuid] = queueItem
|
queueList[queueItem.uuid] = queueItem
|
||||||
if ((queueItem.downloaded + queueItem.failed) == queueItem.size)
|
if (queueItem.downloaded + queueItem.failed == queueItem.size) queueComplete.push(queueItem.uuid)
|
||||||
queueComplete.push(queueItem.uuid)
|
else queue.push(queueItem.uuid)
|
||||||
else
|
$('#download_list').append(
|
||||||
queue.push(queueItem.uuid)
|
|
||||||
$("#download_list").append(
|
|
||||||
`<div class="download_object" id="download_${queueItem.uuid}" data-deezerid="${queueItem.id}">
|
`<div class="download_object" id="download_${queueItem.uuid}" data-deezerid="${queueItem.id}">
|
||||||
<div class="download_info">
|
<div class="download_info">
|
||||||
<img width="75px" class="rounded coverart" src="${queueItem.cover}" alt="Cover ${queueItem.title}"/>
|
<img width="75px" class="rounded coverart" src="${queueItem.cover}" alt="Cover ${queueItem.title}"/>
|
||||||
@ -32,49 +30,56 @@ function addToQueue(queueItem){
|
|||||||
<span class="secondary-text">${queueItem.artist}</span>
|
<span class="secondary-text">${queueItem.artist}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="download_info_status">
|
<div class="download_info_status">
|
||||||
<span class="download_line"><span class="queue_downloaded">${queueItem.downloaded + queueItem.failed}</span>/${queueItem.size}</span>
|
<span class="download_line"><span class="queue_downloaded">${queueItem.downloaded + queueItem.failed}</span>/${
|
||||||
|
queueItem.size
|
||||||
|
}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="download_bar">
|
<div class="download_bar">
|
||||||
<div class="progress"><div id="bar_${queueItem.uuid}" class="indeterminate"></div></div>
|
<div class="progress"><div id="bar_${queueItem.uuid}" class="indeterminate"></div></div>
|
||||||
<i onclick="downloadAction(event)" class="material-icons queue_icon" data-uuid="${queueItem.uuid}">remove</i>
|
<i onclick="downloadAction(event)" class="material-icons queue_icon" data-uuid="${queueItem.uuid}">remove</i>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`
|
||||||
|
)
|
||||||
if (queueItem.progress > 0) {
|
if (queueItem.progress > 0) {
|
||||||
$('#bar_' + queueItem.uuid).removeClass('indeterminate').addClass('determinate')
|
$('#bar_' + queueItem.uuid)
|
||||||
|
.removeClass('indeterminate')
|
||||||
|
.addClass('determinate')
|
||||||
}
|
}
|
||||||
$('#bar_' + queueItem.uuid).css('width', queueItem.progress + '%')
|
$('#bar_' + queueItem.uuid).css('width', queueItem.progress + '%')
|
||||||
if (queueItem.failed >= 1) {
|
if (queueItem.failed >= 1) {
|
||||||
$("#download_"+queueItem.uuid+" .download_info_status").append(`<span class="secondary-text inline-flex"><span class="download_slim_separator">(</span><span class="queue_failed">${queueItem.failed}</span><i class="material-icons">error_outline</i><span class="download_slim_separator">)</span></span>`)
|
$('#download_' + queueItem.uuid + ' .download_info_status').append(
|
||||||
|
`<span class="secondary-text inline-flex"><span class="download_slim_separator">(</span><span class="queue_failed">${queueItem.failed}</span><i class="material-icons">error_outline</i><span class="download_slim_separator">)</span></span>`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if ((queueItem.downloaded + queueItem.failed) == queueItem.size){
|
if (queueItem.downloaded + queueItem.failed == queueItem.size) {
|
||||||
let result_icon = $('#download_' + queueItem.uuid).find('.queue_icon')
|
let result_icon = $('#download_' + queueItem.uuid).find('.queue_icon')
|
||||||
if (queueItem.failed == 0) {
|
if (queueItem.failed == 0) {
|
||||||
result_icon.text("done")
|
result_icon.text('done')
|
||||||
} else if (queueItem.failed == queueItem.size) {
|
} else if (queueItem.failed == queueItem.size) {
|
||||||
result_icon.text("error")
|
result_icon.text('error')
|
||||||
} else {
|
} else {
|
||||||
result_icon.text("warning")
|
result_icon.text('warning')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("addedToQueue", function(queueItem){
|
socket.on('addedToQueue', function (queueItem) {
|
||||||
addToQueue(queueItem)
|
addToQueue(queueItem)
|
||||||
})
|
})
|
||||||
|
|
||||||
function downloadAction(evt) {
|
function downloadAction(evt) {
|
||||||
let icon = $(evt.currentTarget).text()
|
let icon = $(evt.currentTarget).text()
|
||||||
let uuid = $(evt.currentTarget).data("uuid")
|
let uuid = $(evt.currentTarget).data('uuid')
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
case 'remove':
|
case 'remove':
|
||||||
socket.emit('removeFromQueue', uuid)
|
socket.emit('removeFromQueue', uuid)
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on("removedFromQueue", function(uuid){
|
socket.on('removedFromQueue', function (uuid) {
|
||||||
let index = queue.indexOf(uuid)
|
let index = queue.indexOf(uuid)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
queue.splice(index, 1)
|
queue.splice(index, 1)
|
||||||
@ -83,21 +88,23 @@ socket.on("removedFromQueue", function(uuid){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("startDownload", function(uuid){
|
socket.on('startDownload', function (uuid) {
|
||||||
$('#bar_' + uuid).removeClass('indeterminate').addClass('determinate')
|
$('#bar_' + uuid)
|
||||||
|
.removeClass('indeterminate')
|
||||||
|
.addClass('determinate')
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("finishDownload", function(uuid){
|
socket.on('finishDownload', function (uuid) {
|
||||||
if (queue.indexOf(uuid) > -1) {
|
if (queue.indexOf(uuid) > -1) {
|
||||||
toast(`${queueList[uuid].title} finished downloading.`, 'done')
|
toast(`${queueList[uuid].title} finished downloading.`, 'done')
|
||||||
$('#bar_' + uuid).css('width', '100%')
|
$('#bar_' + uuid).css('width', '100%')
|
||||||
let result_icon = $('#download_' + uuid).find('.queue_icon')
|
let result_icon = $('#download_' + uuid).find('.queue_icon')
|
||||||
if (queueList[uuid].failed == 0) {
|
if (queueList[uuid].failed == 0) {
|
||||||
result_icon.text("done")
|
result_icon.text('done')
|
||||||
} else if (queueList[uuid].failed >= queueList[uuid].size) {
|
} else if (queueList[uuid].failed >= queueList[uuid].size) {
|
||||||
result_icon.text("error")
|
result_icon.text('error')
|
||||||
} else {
|
} else {
|
||||||
result_icon.text("warning")
|
result_icon.text('warning')
|
||||||
}
|
}
|
||||||
let index = queue.indexOf(uuid)
|
let index = queue.indexOf(uuid)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
@ -110,52 +117,57 @@ socket.on("finishDownload", function(uuid){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("removedAllDownloads", function(currentItem){
|
socket.on('removedAllDownloads', function (currentItem) {
|
||||||
queueComplete = []
|
queueComplete = []
|
||||||
if (currentItem == ""){
|
if (currentItem == '') {
|
||||||
queue = []
|
queue = []
|
||||||
queueList = {}
|
queueList = {}
|
||||||
$("#download_list").html("")
|
$('#download_list').html('')
|
||||||
} else {
|
} else {
|
||||||
queue = [currentItem, ]
|
queue = [currentItem]
|
||||||
tempQueueItem = queueList[currentItem]
|
tempQueueItem = queueList[currentItem]
|
||||||
queueList = {}
|
queueList = {}
|
||||||
queueList[currentItem] = tempQueueItem
|
queueList[currentItem] = tempQueueItem
|
||||||
$(".download_object").each(function(index){
|
$('.download_object').each(function (index) {
|
||||||
if ($(this).attr('id') != "download_"+currentItem)
|
if ($(this).attr('id') != 'download_' + currentItem) $(this).remove()
|
||||||
$(this).remove()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("removedFinishedDownloads", function(){
|
socket.on('removedFinishedDownloads', function () {
|
||||||
queueComplete.forEach((item) => {
|
queueComplete.forEach(item => {
|
||||||
$("#download_"+item).remove()
|
$('#download_' + item).remove()
|
||||||
})
|
})
|
||||||
queueComplete = []
|
queueComplete = []
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#clean_queue").on("click", function(){
|
$('#clean_queue').on('click', function () {
|
||||||
socket.emit("removeFinishedDownloads")
|
socket.emit('removeFinishedDownloads')
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cancel_queue").on("click", function(){
|
$('#cancel_queue').on('click', function () {
|
||||||
socket.emit("cancelAllDownloads")
|
socket.emit('cancelAllDownloads')
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("updateQueue", function(update){
|
socket.on('updateQueue', function (update) {
|
||||||
if (update.uuid && queue.indexOf(update.uuid) > -1) {
|
if (update.uuid && queue.indexOf(update.uuid) > -1) {
|
||||||
if (update.downloaded) {
|
if (update.downloaded) {
|
||||||
queueList[update.uuid].downloaded++
|
queueList[update.uuid].downloaded++
|
||||||
$("#download_"+update.uuid+" .queue_downloaded").text(queueList[update.uuid].downloaded + queueList[update.uuid].failed)
|
$('#download_' + update.uuid + ' .queue_downloaded').text(
|
||||||
|
queueList[update.uuid].downloaded + queueList[update.uuid].failed
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (update.failed) {
|
if (update.failed) {
|
||||||
queueList[update.uuid].failed++
|
queueList[update.uuid].failed++
|
||||||
$("#download_"+update.uuid+" .queue_downloaded").text(queueList[update.uuid].downloaded + queueList[update.uuid].failed)
|
$('#download_' + update.uuid + ' .queue_downloaded').text(
|
||||||
|
queueList[update.uuid].downloaded + queueList[update.uuid].failed
|
||||||
|
)
|
||||||
if (queueList[update.uuid].failed == 1) {
|
if (queueList[update.uuid].failed == 1) {
|
||||||
$("#download_"+update.uuid+" .download_info_status").append(`<span class="secondary-text inline-flex"><span class="download_slim_separator">(</span><span class="queue_failed">1</span> <i class="material-icons">error_outline</i><span class="download_slim_separator">)</span></span>`)
|
$('#download_' + update.uuid + ' .download_info_status').append(
|
||||||
|
`<span class="secondary-text inline-flex"><span class="download_slim_separator">(</span><span class="queue_failed">1</span> <i class="material-icons">error_outline</i><span class="download_slim_separator">)</span></span>`
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
$("#download_"+update.uuid+" .queue_failed").text(queueList[update.uuid].failed)
|
$('#download_' + update.uuid + ' .queue_failed').text(queueList[update.uuid].failed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (update.progress) {
|
if (update.progress) {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
// Load more content when the search page is at the end
|
// Load more content when the search page is at the end
|
||||||
$('#content').on('scroll', function () {
|
$('#content').on('scroll', function () {
|
||||||
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
|
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
|
||||||
if (main_selected == "search_tab" && ["track_search", "album_search", "artist_search", "playlist_search"].indexOf(search_selected) != -1){
|
if (
|
||||||
scrolledSearch(window[search_selected.split("_")[0]+"Search"])
|
main_selected == 'search_tab' &&
|
||||||
|
['track_search', 'album_search', 'artist_search', 'playlist_search'].indexOf(search_selected) != -1
|
||||||
|
) {
|
||||||
|
scrolledSearch(window[search_selected.split('_')[0] + 'Search'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -10,77 +13,87 @@ $('#content').on('scroll', function() {
|
|||||||
function scrolledSearch(vueTab) {
|
function scrolledSearch(vueTab) {
|
||||||
query = vueTab.query
|
query = vueTab.query
|
||||||
if (vueTab.results.next < vueTab.results.total) {
|
if (vueTab.results.next < vueTab.results.total) {
|
||||||
socket.emit("search", {term: vueTab.query, type: vueTab.type, start: vueTab.results.next, nb: vueTab.nb});
|
socket.emit('search', {
|
||||||
|
term: vueTab.query,
|
||||||
|
type: vueTab.type,
|
||||||
|
start: vueTab.results.next,
|
||||||
|
nb: vueTab.nb
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchUpadate(result) {
|
function searchUpadate(result) {
|
||||||
console.log(result)
|
console.log(result)
|
||||||
vueTab = null;
|
vueTab = null
|
||||||
switch (result.type) {
|
switch (result.type) {
|
||||||
case "TRACK":
|
case 'TRACK':
|
||||||
vueTab = trackSearch;
|
vueTab = trackSearch
|
||||||
break;
|
break
|
||||||
case "ALBUM":
|
case 'ALBUM':
|
||||||
vueTab = albumSearch;
|
vueTab = albumSearch
|
||||||
break;
|
break
|
||||||
case "ARTIST":
|
case 'ARTIST':
|
||||||
vueTab = artistSearch;
|
vueTab = artistSearch
|
||||||
break;
|
break
|
||||||
case "PLAYLIST":
|
case 'PLAYLIST':
|
||||||
vueTab = playlistSearch;
|
vueTab = playlistSearch
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
if (vueTab && vueTab.results.next != result.next) {
|
if (vueTab && vueTab.results.next != result.next) {
|
||||||
vueTab.results.next = result.next
|
vueTab.results.next = result.next
|
||||||
vueTab.results.data = vueTab.results.data.concat(result.data)
|
vueTab.results.data = vueTab.results.data.concat(result.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
socket.on("search", function(result){searchUpadate(result)})
|
socket.on('search', function (result) {
|
||||||
|
searchUpadate(result)
|
||||||
|
})
|
||||||
|
|
||||||
function clickElement(button) {
|
function clickElement(button) {
|
||||||
return document.getElementById(button).click()
|
return document.getElementById(button).click()
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendAddToQueue(url, bitrate = null) {
|
function sendAddToQueue(url, bitrate = null) {
|
||||||
socket.emit("addToQueue", {url: url, bitrate:bitrate})
|
socket.emit('addToQueue', { url: url, bitrate: bitrate })
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainSearch = new Vue({
|
let MainSearch = new Vue({
|
||||||
el: '#main_search',
|
el: '#main_search',
|
||||||
data: {
|
data() {
|
||||||
|
return {
|
||||||
names: {
|
names: {
|
||||||
"TOP_RESULT": "Top Result",
|
TOP_RESULT: 'Top Result',
|
||||||
"TRACK": "Tracks",
|
TRACK: 'Tracks',
|
||||||
"ARTIST": "Artists",
|
ARTIST: 'Artists',
|
||||||
"ALBUM": "Albums",
|
ALBUM: 'Albums',
|
||||||
"PLAYLIST": "Playlists"
|
PLAYLIST: 'Playlists'
|
||||||
},
|
},
|
||||||
results: {
|
results: {
|
||||||
QUERY: "",
|
QUERY: '',
|
||||||
ORDER: [],
|
ORDER: [],
|
||||||
ALBUM: {},
|
ALBUM: {},
|
||||||
ARTIST: {},
|
ARTIST: {},
|
||||||
TRACK: {},
|
TRACK: {},
|
||||||
TOP_RESULT: [],
|
TOP_RESULT: [],
|
||||||
PLAYLIST: {}
|
PLAYLIST: {}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeSearchTab: function (section) {
|
changeSearchTab(section) {
|
||||||
if (section != "TOP_RESULT")
|
if (section != 'TOP_RESULT') clickElement('search_' + section.toLowerCase() + '_tab')
|
||||||
clickElement('search_'+section.toLowerCase()+'_tab')
|
|
||||||
},
|
},
|
||||||
addToQueue: function(url){sendAddToQueue(url)}
|
addToQueue(url) {
|
||||||
|
sendAddToQueue(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var trackSearch = new Vue({
|
var trackSearch = new Vue({
|
||||||
el: '#track_search',
|
el: '#track_search',
|
||||||
data: {
|
data: {
|
||||||
type: "TRACK",
|
type: 'TRACK',
|
||||||
nb: 40,
|
nb: 40,
|
||||||
query: "",
|
query: '',
|
||||||
results: {
|
results: {
|
||||||
data: [],
|
data: [],
|
||||||
next: 0,
|
next: 0,
|
||||||
@ -88,16 +101,18 @@ var trackSearch = new Vue({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addToQueue: function(url){sendAddToQueue(url)}
|
addToQueue: function (url) {
|
||||||
|
sendAddToQueue(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var albumSearch = new Vue({
|
var albumSearch = new Vue({
|
||||||
el: '#album_search',
|
el: '#album_search',
|
||||||
data: {
|
data: {
|
||||||
type: "ALBUM",
|
type: 'ALBUM',
|
||||||
nb: 20,
|
nb: 20,
|
||||||
query: "",
|
query: '',
|
||||||
results: {
|
results: {
|
||||||
data: [],
|
data: [],
|
||||||
next: 0,
|
next: 0,
|
||||||
@ -105,16 +120,18 @@ var albumSearch = new Vue({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addToQueue: function(url){sendAddToQueue(url)}
|
addToQueue: function (url) {
|
||||||
|
sendAddToQueue(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var artistSearch = new Vue({
|
var artistSearch = new Vue({
|
||||||
el: '#artist_search',
|
el: '#artist_search',
|
||||||
data: {
|
data: {
|
||||||
type: "ARTIST",
|
type: 'ARTIST',
|
||||||
nb: 20,
|
nb: 20,
|
||||||
query: "",
|
query: '',
|
||||||
results: {
|
results: {
|
||||||
data: [],
|
data: [],
|
||||||
next: 0,
|
next: 0,
|
||||||
@ -122,16 +139,18 @@ var artistSearch = new Vue({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addToQueue: function(url){sendAddToQueue(url)}
|
addToQueue: function (url) {
|
||||||
|
sendAddToQueue(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var playlistSearch = new Vue({
|
var playlistSearch = new Vue({
|
||||||
el: '#playlist_search',
|
el: '#playlist_search',
|
||||||
data: {
|
data: {
|
||||||
type: "PLAYLIST",
|
type: 'PLAYLIST',
|
||||||
nb: 20,
|
nb: 20,
|
||||||
query: "",
|
query: '',
|
||||||
results: {
|
results: {
|
||||||
data: [],
|
data: [],
|
||||||
next: 0,
|
next: 0,
|
||||||
@ -139,27 +158,29 @@ var playlistSearch = new Vue({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addToQueue: function(url){sendAddToQueue(url)}
|
addToQueue: function (url) {
|
||||||
|
sendAddToQueue(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let term = null
|
||||||
|
|
||||||
// Search section
|
// Search section
|
||||||
$("#searchbar").keyup(function(e){
|
$('#searchbar').keyup(function (e) {
|
||||||
if (e.keyCode == 13) {
|
if (e.keyCode == 13) {
|
||||||
term = this.value
|
term = this.value
|
||||||
console.log(term)
|
console.log(term)
|
||||||
if (isValidURL(term))
|
if (isValidURL(term)) socket.emit('addToQueue', { url: term })
|
||||||
socket.emit("addToQueue", {url: term});
|
|
||||||
else {
|
else {
|
||||||
document.getElementById("search_tab_content").style.display = "none";
|
document.getElementById('search_tab_content').style.display = 'none'
|
||||||
socket.emit("mainSearch", {term: term});
|
socket.emit('mainSearch', { term: term })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function mainSearchHandler(result) {
|
function mainSearchHandler(result) {
|
||||||
console.log(result)
|
MainSearch.results = result
|
||||||
mainSearch.results = result
|
|
||||||
trackSearch.results = result.TRACK
|
trackSearch.results = result.TRACK
|
||||||
albumSearch.results = result.ALBUM
|
albumSearch.results = result.ALBUM
|
||||||
artistSearch.results = result.ARTIST
|
artistSearch.results = result.ARTIST
|
||||||
@ -168,8 +189,10 @@ function mainSearchHandler(result){
|
|||||||
albumSearch.query = result.QUERY
|
albumSearch.query = result.QUERY
|
||||||
artistSearch.query = result.QUERY
|
artistSearch.query = result.QUERY
|
||||||
playlistSearch.query = result.QUERY
|
playlistSearch.query = result.QUERY
|
||||||
document.getElementById("search_all_tab").click();
|
document.getElementById('search_all_tab').click()
|
||||||
document.getElementById("search_tab_content").style.display = "block";
|
document.getElementById('search_tab_content').style.display = 'block'
|
||||||
document.getElementById("main_search_tablink").click();
|
document.getElementById('main_search_tablink').click()
|
||||||
}
|
}
|
||||||
socket.on("mainSearch", function(result){mainSearchHandler(result)})
|
socket.on('mainSearch', function (result) {
|
||||||
|
mainSearchHandler(result)
|
||||||
|
})
|
@ -1,33 +1,32 @@
|
|||||||
function isValidURL(text) {
|
function isValidURL(text) {
|
||||||
if (text.toLowerCase().startsWith("http")){
|
if (text.toLowerCase().startsWith('http')) {
|
||||||
if (text.toLowerCase().indexOf("deezer.com") >= 0 || text.toLowerCase().indexOf("open.spotify.com") >= 0)
|
if (text.toLowerCase().indexOf('deezer.com') >= 0 || text.toLowerCase().indexOf('open.spotify.com') >= 0)
|
||||||
return true
|
|
||||||
}else if (text.toLowerCase().startsWith("spotify:"))
|
|
||||||
return true
|
return true
|
||||||
|
} else if (text.toLowerCase().startsWith('spotify:')) return true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertDuration(duration) {
|
function convertDuration(duration) {
|
||||||
//convert from seconds only to mm:ss format
|
//convert from seconds only to mm:ss format
|
||||||
var mm, ss
|
let mm, ss
|
||||||
mm = Math.floor(duration / 60)
|
mm = Math.floor(duration / 60)
|
||||||
ss = duration - (mm * 60)
|
ss = duration - mm * 60
|
||||||
//add leading zero if ss < 0
|
//add leading zero if ss < 0
|
||||||
if (ss < 10) {
|
if (ss < 10) {
|
||||||
ss = "0" + ss
|
ss = '0' + ss
|
||||||
}
|
}
|
||||||
return mm + ":" + ss
|
return mm + ':' + ss
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertDurationSeparated(duration) {
|
function convertDurationSeparated(duration) {
|
||||||
var hh, mm, ss
|
let hh, mm, ss
|
||||||
mm = Math.floor(duration / 60)
|
mm = Math.floor(duration / 60)
|
||||||
hh = Math.floor(mm / 60)
|
hh = Math.floor(mm / 60)
|
||||||
ss = duration - (mm * 60)
|
ss = duration - mm * 60
|
||||||
mm -= hh * 60
|
mm -= hh * 60
|
||||||
return [hh, mm, ss]
|
return [hh, mm, ss]
|
||||||
}
|
}
|
||||||
|
|
||||||
function numberWithDots(x) {
|
function numberWithDots(x) {
|
||||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
|
||||||
}
|
}
|
||||||
|
5
public/js/app/v-app.js
Normal file
5
public/js/app/v-app.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
new Vue({
|
||||||
|
components: {
|
||||||
|
'app': httpVueLoader('./public/js/app/components/App.vue')
|
||||||
|
}
|
||||||
|
}).$mount('#v-app');
|
478
public/js/vendor/httpVueLoader.js
vendored
Normal file
478
public/js/vendor/httpVueLoader.js
vendored
Normal file
@ -0,0 +1,478 @@
|
|||||||
|
(function umd(root,factory){
|
||||||
|
if(typeof module==='object' && typeof exports === 'object' )
|
||||||
|
module.exports=factory()
|
||||||
|
else if(typeof define==='function' && define.amd)
|
||||||
|
define([],factory)
|
||||||
|
else
|
||||||
|
root.httpVueLoader=factory()
|
||||||
|
})(this,function factory() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var scopeIndex = 0;
|
||||||
|
|
||||||
|
StyleContext.prototype = {
|
||||||
|
|
||||||
|
withBase: function(callback) {
|
||||||
|
|
||||||
|
var tmpBaseElt;
|
||||||
|
if ( this.component.baseURI ) {
|
||||||
|
|
||||||
|
// firefox and chrome need the <base> to be set while inserting or modifying <style> in a document.
|
||||||
|
tmpBaseElt = document.createElement('base');
|
||||||
|
tmpBaseElt.href = this.component.baseURI;
|
||||||
|
|
||||||
|
var headElt = this.component.getHead();
|
||||||
|
headElt.insertBefore(tmpBaseElt, headElt.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.call(this);
|
||||||
|
|
||||||
|
if ( tmpBaseElt )
|
||||||
|
this.component.getHead().removeChild(tmpBaseElt);
|
||||||
|
},
|
||||||
|
|
||||||
|
scopeStyles: function(styleElt, scopeName) {
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
|
||||||
|
var sheet = styleElt.sheet;
|
||||||
|
var rules = sheet.cssRules;
|
||||||
|
|
||||||
|
for ( var i = 0; i < rules.length; ++i ) {
|
||||||
|
|
||||||
|
var rule = rules[i];
|
||||||
|
if ( rule.type !== 1 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var scopedSelectors = [];
|
||||||
|
|
||||||
|
rule.selectorText.split(/\s*,\s*/).forEach(function(sel) {
|
||||||
|
|
||||||
|
scopedSelectors.push(scopeName+' '+sel);
|
||||||
|
var segments = sel.match(/([^ :]+)(.+)?/);
|
||||||
|
scopedSelectors.push(segments[1] + scopeName + (segments[2]||''));
|
||||||
|
});
|
||||||
|
|
||||||
|
var scopedRule = scopedSelectors.join(',') + rule.cssText.substr(rule.selectorText.length);
|
||||||
|
sheet.deleteRule(i);
|
||||||
|
sheet.insertRule(scopedRule, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// firefox may fail sheet.cssRules with InvalidAccessError
|
||||||
|
process();
|
||||||
|
} catch (ex) {
|
||||||
|
|
||||||
|
if ( ex instanceof DOMException && ex.code === DOMException.INVALID_ACCESS_ERR ) {
|
||||||
|
|
||||||
|
styleElt.sheet.disabled = true;
|
||||||
|
styleElt.addEventListener('load', function onStyleLoaded() {
|
||||||
|
|
||||||
|
styleElt.removeEventListener('load', onStyleLoaded);
|
||||||
|
|
||||||
|
// firefox need this timeout otherwise we have to use document.importNode(style, true)
|
||||||
|
setTimeout(function() {
|
||||||
|
|
||||||
|
process();
|
||||||
|
styleElt.sheet.disabled = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compile: function() {
|
||||||
|
|
||||||
|
var hasTemplate = this.template !== null;
|
||||||
|
|
||||||
|
var scoped = this.elt.hasAttribute('scoped');
|
||||||
|
|
||||||
|
if ( scoped ) {
|
||||||
|
|
||||||
|
// no template, no scopable style needed
|
||||||
|
if ( !hasTemplate )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// firefox does not tolerate this attribute
|
||||||
|
this.elt.removeAttribute('scoped');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.withBase(function() {
|
||||||
|
|
||||||
|
this.component.getHead().appendChild(this.elt);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( scoped )
|
||||||
|
this.scopeStyles(this.elt, '['+this.component.getScopeId()+']');
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
|
||||||
|
getContent: function() {
|
||||||
|
|
||||||
|
return this.elt.textContent;
|
||||||
|
},
|
||||||
|
|
||||||
|
setContent: function(content) {
|
||||||
|
|
||||||
|
this.withBase(function() {
|
||||||
|
|
||||||
|
this.elt.textContent = content;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function StyleContext(component, elt) {
|
||||||
|
|
||||||
|
this.component = component;
|
||||||
|
this.elt = elt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScriptContext.prototype = {
|
||||||
|
|
||||||
|
getContent: function() {
|
||||||
|
|
||||||
|
return this.elt.textContent;
|
||||||
|
},
|
||||||
|
|
||||||
|
setContent: function(content) {
|
||||||
|
|
||||||
|
this.elt.textContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
compile: function(module) {
|
||||||
|
|
||||||
|
var childModuleRequire = function(childURL) {
|
||||||
|
|
||||||
|
return httpVueLoader.require(resolveURL(this.component.baseURI, childURL));
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var childLoader = function(childURL, childName) {
|
||||||
|
|
||||||
|
return httpVueLoader(resolveURL(this.component.baseURI, childURL), childName);
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Function('exports', 'require', 'httpVueLoader', 'module', this.getContent()).call(this.module.exports, this.module.exports, childModuleRequire, childLoader, this.module);
|
||||||
|
} catch(ex) {
|
||||||
|
|
||||||
|
if ( !('lineNumber' in ex) ) {
|
||||||
|
|
||||||
|
return Promise.reject(ex);
|
||||||
|
}
|
||||||
|
var vueFileData = responseText.replace(/\r?\n/g, '\n');
|
||||||
|
var lineNumber = vueFileData.substr(0, vueFileData.indexOf(script)).split('\n').length + ex.lineNumber - 1;
|
||||||
|
throw new (ex.constructor)(ex.message, url, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(this.module.exports)
|
||||||
|
.then(httpVueLoader.scriptExportsHandler.bind(this))
|
||||||
|
.then(function(exports) {
|
||||||
|
|
||||||
|
this.module.exports = exports;
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function ScriptContext(component, elt) {
|
||||||
|
|
||||||
|
this.component = component;
|
||||||
|
this.elt = elt;
|
||||||
|
this.module = { exports:{} };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TemplateContext.prototype = {
|
||||||
|
|
||||||
|
getContent: function() {
|
||||||
|
|
||||||
|
return this.elt.innerHTML;
|
||||||
|
},
|
||||||
|
|
||||||
|
setContent: function(content) {
|
||||||
|
|
||||||
|
this.elt.innerHTML = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
getRootElt: function() {
|
||||||
|
|
||||||
|
var tplElt = this.elt.content || this.elt;
|
||||||
|
|
||||||
|
if ( 'firstElementChild' in tplElt )
|
||||||
|
return tplElt.firstElementChild;
|
||||||
|
|
||||||
|
for ( tplElt = tplElt.firstChild; tplElt !== null; tplElt = tplElt.nextSibling )
|
||||||
|
if ( tplElt.nodeType === Node.ELEMENT_NODE )
|
||||||
|
return tplElt;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
compile: function() {
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function TemplateContext(component, elt) {
|
||||||
|
|
||||||
|
this.component = component;
|
||||||
|
this.elt = elt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Component.prototype = {
|
||||||
|
|
||||||
|
getHead: function() {
|
||||||
|
|
||||||
|
return document.head || document.getElementsByTagName('head')[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
getScopeId: function() {
|
||||||
|
|
||||||
|
if ( this._scopeId === '' ) {
|
||||||
|
|
||||||
|
this._scopeId = 'data-s-' + (scopeIndex++).toString(36);
|
||||||
|
this.template.getRootElt().setAttribute(this._scopeId, '');
|
||||||
|
}
|
||||||
|
return this._scopeId;
|
||||||
|
},
|
||||||
|
|
||||||
|
load: function(componentURL) {
|
||||||
|
|
||||||
|
return httpVueLoader.httpRequest(componentURL)
|
||||||
|
.then(function(responseText) {
|
||||||
|
|
||||||
|
this.baseURI = componentURL.substr(0, componentURL.lastIndexOf('/')+1);
|
||||||
|
var doc = document.implementation.createHTMLDocument('');
|
||||||
|
|
||||||
|
// IE requires the <base> to come with <style>
|
||||||
|
doc.body.innerHTML = (this.baseURI ? '<base href="'+this.baseURI+'">' : '') + responseText;
|
||||||
|
|
||||||
|
for ( var it = doc.body.firstChild; it; it = it.nextSibling ) {
|
||||||
|
|
||||||
|
switch ( it.nodeName ) {
|
||||||
|
case 'TEMPLATE':
|
||||||
|
this.template = new TemplateContext(this, it);
|
||||||
|
break;
|
||||||
|
case 'SCRIPT':
|
||||||
|
this.script = new ScriptContext(this, it);
|
||||||
|
break;
|
||||||
|
case 'STYLE':
|
||||||
|
this.styles.push(new StyleContext(this, it));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_normalizeSection: function(eltCx) {
|
||||||
|
|
||||||
|
var p;
|
||||||
|
|
||||||
|
if ( eltCx === null || !eltCx.elt.hasAttribute('src') ) {
|
||||||
|
|
||||||
|
p = Promise.resolve(null);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
p = httpVueLoader.httpRequest(eltCx.elt.getAttribute('src'))
|
||||||
|
.then(function(content) {
|
||||||
|
|
||||||
|
eltCx.elt.removeAttribute('src');
|
||||||
|
return content;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
.then(function(content) {
|
||||||
|
|
||||||
|
if ( eltCx !== null && eltCx.elt.hasAttribute('lang') ) {
|
||||||
|
|
||||||
|
var lang = eltCx.elt.getAttribute('lang');
|
||||||
|
eltCx.elt.removeAttribute('lang');
|
||||||
|
return httpVueLoader.langProcessor[lang.toLowerCase()].call(this, content === null ? eltCx.getContent() : content);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}.bind(this))
|
||||||
|
.then(function(content) {
|
||||||
|
|
||||||
|
if ( content !== null )
|
||||||
|
eltCx.setContent(content);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
normalize: function() {
|
||||||
|
|
||||||
|
return Promise.all(Array.prototype.concat(
|
||||||
|
this._normalizeSection(this.template),
|
||||||
|
this._normalizeSection(this.script),
|
||||||
|
this.styles.map(this._normalizeSection)
|
||||||
|
))
|
||||||
|
.then(function() {
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
compile: function() {
|
||||||
|
|
||||||
|
return Promise.all(Array.prototype.concat(
|
||||||
|
this.template && this.template.compile(),
|
||||||
|
this.script && this.script.compile(),
|
||||||
|
this.styles.map(function(style) { return style.compile(); })
|
||||||
|
))
|
||||||
|
.then(function() {
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Component(name) {
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.template = null;
|
||||||
|
this.script = null;
|
||||||
|
this.styles = [];
|
||||||
|
this._scopeId = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function identity(value) {
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseComponentURL(url) {
|
||||||
|
|
||||||
|
var comp = url.match(/(.*?)([^/]+?)\/?(\.vue)?(\?.*|#.*|$)/);
|
||||||
|
return {
|
||||||
|
name: comp[2],
|
||||||
|
url: comp[1] + comp[2] + (comp[3] === undefined ? '/index.vue' : comp[3]) + comp[4]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveURL(baseURL, url) {
|
||||||
|
|
||||||
|
if (url.substr(0, 2) === './' || url.substr(0, 3) === '../') {
|
||||||
|
return baseURL + url;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
httpVueLoader.load = function(url, name) {
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
|
||||||
|
return new Component(name).load(url)
|
||||||
|
.then(function(component) {
|
||||||
|
|
||||||
|
return component.normalize();
|
||||||
|
})
|
||||||
|
.then(function(component) {
|
||||||
|
|
||||||
|
return component.compile();
|
||||||
|
})
|
||||||
|
.then(function(component) {
|
||||||
|
|
||||||
|
var exports = component.script !== null ? component.script.module.exports : {};
|
||||||
|
|
||||||
|
if ( component.template !== null )
|
||||||
|
exports.template = component.template.getContent();
|
||||||
|
|
||||||
|
if ( exports.name === undefined )
|
||||||
|
if ( component.name !== undefined )
|
||||||
|
exports.name = component.name;
|
||||||
|
|
||||||
|
exports._baseURI = component.baseURI;
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
httpVueLoader.register = function(Vue, url) {
|
||||||
|
|
||||||
|
var comp = parseComponentURL(url);
|
||||||
|
Vue.component(comp.name, httpVueLoader.load(comp.url));
|
||||||
|
};
|
||||||
|
|
||||||
|
httpVueLoader.install = function(Vue) {
|
||||||
|
|
||||||
|
Vue.mixin({
|
||||||
|
|
||||||
|
beforeCreate: function () {
|
||||||
|
|
||||||
|
var components = this.$options.components;
|
||||||
|
|
||||||
|
for ( var componentName in components ) {
|
||||||
|
|
||||||
|
if ( typeof(components[componentName]) === 'string' && components[componentName].substr(0, 4) === 'url:' ) {
|
||||||
|
|
||||||
|
var comp = parseComponentURL(components[componentName].substr(4));
|
||||||
|
|
||||||
|
var componentURL = ('_baseURI' in this.$options) ? resolveURL(this.$options._baseURI, comp.url) : comp.url;
|
||||||
|
|
||||||
|
if ( isNaN(componentName) )
|
||||||
|
components[componentName] = httpVueLoader.load(componentURL, componentName);
|
||||||
|
else
|
||||||
|
components[componentName] = Vue.component(comp.name, httpVueLoader.load(componentURL, comp.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
httpVueLoader.require = function(moduleName) {
|
||||||
|
|
||||||
|
return window[moduleName];
|
||||||
|
};
|
||||||
|
|
||||||
|
httpVueLoader.httpRequest = function(url) {
|
||||||
|
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', url);
|
||||||
|
xhr.responseType = 'text';
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
|
||||||
|
if ( xhr.readyState === 4 ) {
|
||||||
|
|
||||||
|
if ( xhr.status >= 200 && xhr.status < 300 )
|
||||||
|
resolve(xhr.responseText);
|
||||||
|
else
|
||||||
|
reject(xhr.status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send(null);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
httpVueLoader.langProcessor = {
|
||||||
|
html: identity,
|
||||||
|
js: identity,
|
||||||
|
css: identity
|
||||||
|
};
|
||||||
|
|
||||||
|
httpVueLoader.scriptExportsHandler = identity;
|
||||||
|
|
||||||
|
function httpVueLoader(url, name) {
|
||||||
|
|
||||||
|
var comp = parseComponentURL(url);
|
||||||
|
return httpVueLoader.load(comp.url, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpVueLoader;
|
||||||
|
});
|
0
public/js/jquery-3.3.1.min.js → public/js/vendor/jquery-3.3.1.min.js
vendored
Executable file → Normal file
0
public/js/jquery-3.3.1.min.js → public/js/vendor/jquery-3.3.1.min.js
vendored
Executable file → Normal file
0
public/js/socket.io.js → public/js/vendor/socket.io.js
generated
vendored
0
public/js/socket.io.js → public/js/vendor/socket.io.js
generated
vendored
0
public/js/socket.io.js.map → public/js/vendor/socket.io.js.map
generated
vendored
Executable file → Normal file
0
public/js/socket.io.js.map → public/js/vendor/socket.io.js.map
generated
vendored
Executable file → Normal file
0
public/js/vue.min.js → public/js/vendor/vue.min.js
vendored
Executable file → Normal file
0
public/js/vue.min.js → public/js/vendor/vue.min.js
vendored
Executable file → Normal file
Loading…
Reference in New Issue
Block a user