completed modularization of js files

This commit is contained in:
Roberto Tonino 2020-04-23 21:03:12 +02:00
parent 86342aec90
commit 701440cbb9
10 changed files with 405 additions and 404 deletions

View File

@ -1,17 +1,9 @@
/* ===== Imports ===== */
import * as Utils from './modules/utils.js'
/* ===== Vue components ===== */
import MainSearch from './modules/main-search.js'
import SettingsTab from './modules/settings-tab.js'
import { socket } from './modules/socket.js'
import { toast } from './modules/toasts.js'
import { resetTracklistTab } from './modules/tracklist-tab.js'
import { resetArtistTab } from './modules/artist-tab.js'
import Downloads from './modules/downloads.js'
import QualityModal from './modules/quality-modal.js'
import { Tabs } from './modules/tabs.js'
import Search from './modules/search.js'
/* ===== Socketio listeners ===== */
@ -20,14 +12,10 @@ socket.on('message', function (msg) {
console.log(msg)
})
// Needs:
// 1. toast
socket.on('logging_in', function () {
toast('Logging in', 'loading', false, 'login-toast')
})
// Needs:
// 1. toast
socket.on('logged_in', function (data) {
switch (data.status) {
case 1:
@ -70,8 +58,6 @@ socket.on('logged_in', function (data) {
}
})
// Needs:
// 1. toast
socket.on('logged_out', function () {
toast('Logged out', 'done', true, 'login-toast')
localStorage.removeItem('arl')
@ -82,37 +68,12 @@ socket.on('logged_out', function () {
$('#settings_picture').attr('src', `https://e-cdns-images.dzcdn.net/images/user/125x125-000000-80-0-0.jpg`)
})
/**
* Adds all event listeners.
* @returns {void}
* @since 0.1.0 (?)
*/
function linkEventListeners() {
document.getElementById('sidebar').addEventListener('click', handleSidebarClick)
document.getElementById('search_tab').addEventListener('click', handleTabClick)
// Back buttons
const backButtons = Array.from(document.getElementsByClassName('back-button'))
backButtons.forEach(button => {
button.addEventListener('click', backTab)
})
// Queue buttons
document.getElementById('clean_queue').addEventListener('click', () => {
socket.emit('removeFinishedDownloads')
})
document.getElementById('cancel_queue').addEventListener('click', () => {
socket.emit('cancelAllDownloads')
})
}
/* ===== App initialization ===== */
function init() {
linkEventListeners()
function startApp() {
Downloads.linkListeners()
QualityModal.init()
Tabs.linkListeners()
Search.linkListeners()
if (localStorage.getItem('arl')) {
let arl = localStorage.getItem('arl')
@ -130,204 +91,4 @@ function init() {
document.getElementById('main_home_tablink').click()
}
document.addEventListener('DOMContentLoaded', init)
/* tabs.js */
window.search_selected = ''
window.main_selected = ''
window.windows_stack = []
window.currentStack = {}
// Needs:
// 1. windows_stack
// 2. currentStack
// 3. main_selected
// 4. SettingsTab
// 5. lastSettings
// 6. search_selected
// 7. MainSearch
window.changeTab = function (evt, section, tabName) {
windows_stack = []
currentStack = {}
var i, tabcontent, tablinks
tabcontent = document.getElementsByClassName(section + '_tabcontent')
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none'
}
tablinks = document.getElementsByClassName(section + '_tablinks')
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove('active')
}
if (tabName == 'settings_tab' && main_selected != 'settings_tab') {
SettingsTab.settings = { ...lastSettings }
}
document.getElementById(tabName).style.display = 'block'
window[section + '_selected'] = tabName
// Not choosing .currentTarget beacuse the event
// is delegated
evt.target.classList.add('active')
// Check if you need to load more content in the search tab
if (
main_selected == 'search_tab' &&
['track_search', 'album_search', 'artist_search', 'playlist_search'].indexOf(search_selected) != -1 &&
MainSearch.results[search_selected.split('_')[0] + 'Tab'].data.length == 0
) {
MainSearch.search(search_selected.split('_')[0])
}
}
// Needs:
// 1. windows_stack
// 2. main_selected
// 3. currentStack
window.showTab = function (type, id, back = false) {
if (windows_stack.length == 0) windows_stack.push({ tab: main_selected })
else if (!back) windows_stack.push(currentStack)
if (type == 'artist') {
window.tab = 'artist_tab'
} else {
window.tab = 'tracklist_tab'
}
currentStack = { type: type, id: id }
let tabcontent = document.getElementsByClassName('main_tabcontent')
for (let i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none'
}
document.getElementById(tab).style.display = 'block'
}
// Needs:
// 1. windows_stack
// 2. main_selected
// 3. resetArtistTab
// 4. resetTracklistTab
// 5. socket
// 6. showTab
function backTab() {
if (windows_stack.length == 1) {
document.getElementById(`main_${main_selected}link`).click()
} else {
let tabObj = windows_stack.pop()
if (tabObj.type == 'artist') {
resetArtistTab()
} else {
resetTracklistTab()
}
socket.emit('getTracklist', { type: tabObj.type, id: tabObj.id })
showTab(tabObj.type, tabObj.id, true)
}
}
/* search.js */
// Load more content when the search page is at the end
// Needs:
// 1. main_selected
// 2. search_selected
// 3. MainSearch
$('#content').on('scroll', function () {
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
) {
MainSearch.scrolledSearch(search_selected.split('_')[0])
}
}
})
// Search section
// Needs:
// 1. QualityModal
// 2. Downloads
// 3. socket
// 4. MainSearch
// 5. main_selected
$('#searchbar').keyup(function (e) {
if (e.keyCode == 13) {
let term = this.value
if (Utils.isValidURL(term)) {
if (e.ctrlKey) {
QualityModal.open(term)
} else {
Downloads.sendAddToQueue(term)
}
} else {
if (term != MainSearch.query || main_selected == 'search_tab') {
document.getElementById('search_tab_content').style.display = 'none'
socket.emit('mainSearch', { term: term })
} else {
document.getElementById('search_all_tab').click()
document.getElementById('search_tab_content').style.display = 'block'
document.getElementById('main_search_tablink').click()
}
}
}
})
/* ===== Handlers ===== */
/**
* Handles click Event on the sidebar and changes tab
* according to clicked icon.
* Uses event delegation
* @param {Event} event
* @since 0.1.0
*/
function handleSidebarClick(event) {
let targetID = event.target.id
switch (targetID) {
case 'main_search_tablink':
changeTab(event, 'main', 'search_tab')
break
case 'main_home_tablink':
changeTab(event, 'main', 'home_tab')
break
case 'main_charts_tablink':
changeTab(event, 'main', 'charts_tab')
break
case 'main_favorites_tablink':
changeTab(event, 'main', 'favorites_tab')
break
case 'main_analyzer_tablink':
changeTab(event, 'main', 'analyzer_tab')
break
case 'main_settings_tablink':
changeTab(event, 'main', 'settings_tab')
break
case 'main_about_tablink':
changeTab(event, 'main', 'about_tab')
break
default:
break
}
}
function handleTabClick(event) {
let targetID = event.target.id
switch (targetID) {
case 'search_all_tab':
changeTab(event, 'search', 'main_search')
break
case 'search_track_tab':
changeTab(event, 'search', 'track_search')
break
case 'search_album_tab':
changeTab(event, 'search', 'album_search')
break
case 'search_artist_tab':
changeTab(event, 'search', 'artist_search')
break
case 'search_playlist_tab':
changeTab(event, 'search', 'playlist_search')
break
default:
break
}
}
document.addEventListener('DOMContentLoaded', startApp)

View File

@ -1,11 +1,11 @@
import { socket } from './socket.js'
import { albumView } from './stacked-tabs.js'
import { albumView } from './tabs.js'
import Downloads from './downloads.js'
import QualityModal from './quality-modal.js'
export const ArtistTab = new Vue({
el: '#artist_tab',
data: {
const ArtistTab = new Vue({
data() {
return {
currentTab: '',
sortKey: 'release_date',
sortOrder: 'desc',
@ -15,9 +15,21 @@ export const ArtistTab = new Vue({
link: '',
head: null,
body: null
}
},
methods: {
albumView,
reset() {
this.title = 'Loading...'
this.image = ''
this.type = ''
this.currentTab = ''
this.sortKey = 'release_date'
this.sortOrder = 'desc'
this.link = ''
this.head = []
this.body = null
},
addToQueue(e) {
e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
@ -42,14 +54,30 @@ export const ArtistTab = new Vue({
this.currentTab = tab
},
checkNewRelease(date) {
var g1 = new Date()
var g2 = new Date(date)
let g1 = new Date()
let g2 = new Date(date)
g2.setDate(g2.getDate() + 3)
g1.setHours(0, 0, 0, 0)
if (g1.getTime() <= g2.getTime()) {
return true
return g1.getTime() <= g2.getTime()
},
showArtist(data) {
this.title = data.name
this.image = data.picture_xl
this.type = 'Artist'
this.link = `https://www.deezer.com/artist/${data.id}`
this.currentTab = Object.keys(data.releases)[0]
this.sortKey = 'release_date'
this.sortOrder = 'desc'
this.head = [
{ title: 'Title', sortKey: 'title' },
{ title: 'Release Date', sortKey: 'release_date' },
{ title: '', width: '32px' }
]
if (_.isEmpty(data.releases)) {
this.body = null
} else {
return false
this.body = data.releases
}
}
},
@ -61,37 +89,9 @@ export const ArtistTab = new Vue({
},
mounted() {
console.log('artist tab mounted')
}
})
export function resetArtistTab() {
ArtistTab.title = 'Loading...'
ArtistTab.image = ''
ArtistTab.type = ''
ArtistTab.currentTab = ''
ArtistTab.sortKey = 'release_date'
ArtistTab.sortOrder = 'desc'
ArtistTab.link = ''
ArtistTab.head = []
ArtistTab.body = null
socket.on('show_artist', this.showArtist)
}
}).$mount('#artist_tab')
socket.on('show_artist', data => {
ArtistTab.title = data.name
ArtistTab.image = data.picture_xl
ArtistTab.type = 'Artist'
ArtistTab.link = `https://www.deezer.com/artist/${data.id}`
ArtistTab.currentTab = Object.keys(data.releases)[0]
ArtistTab.sortKey = 'release_date'
ArtistTab.sortOrder = 'desc'
ArtistTab.head = [
{ title: 'Title', sortKey: 'title' },
{ title: 'Release Date', sortKey: 'release_date' },
{ title: '', width: '32px' }
]
if (_.isEmpty(data.releases)) {
ArtistTab.body = null
} else {
ArtistTab.body = data.releases
}
})
export default ArtistTab

View File

@ -10,6 +10,15 @@ const downloadListEl = document.getElementById('download_list')
function linkListeners() {
downloadListEl.addEventListener('click', handleListClick)
document.getElementById('toggle_download_tab').addEventListener('click', toggleDownloadTab)
// Queue buttons
document.getElementById('clean_queue').addEventListener('click', () => {
socket.emit('removeFinishedDownloads')
})
document.getElementById('cancel_queue').addEventListener('click', () => {
socket.emit('cancelAllDownloads')
})
}
function sendAddToQueue(url, bitrate = null) {

View File

@ -1,5 +1,5 @@
import { socket } from './socket.js'
import { artistView, albumView, playlistView } from './stacked-tabs.js'
import { artistView, albumView, playlistView } from './tabs.js'
import Downloads from './downloads.js'
import QualityModal from './quality-modal.js'

View File

@ -0,0 +1,48 @@
import MainSearch from './main-search.js'
import * as Utils from './utils.js'
import QualityModal from './quality-modal.js'
import Downloads from './downloads.js'
import { socket } from './socket.js'
export default class Search {
static linkListeners() {
document.getElementById('content').addEventListener('scroll', Utils.debounce(Search.handleContentScroll, 100))
document.getElementById('searchbar').addEventListener('keyup', Search.handleSearchBarKeyup)
}
// Load more content when the search page is at the end
static handleContentScroll(event) {
let contentElement = event.target
if (contentElement.scrollTop + contentElement.clientHeight >= contentElement.scrollHeight) {
if (
main_selected === 'search_tab' &&
['track_search', 'album_search', 'artist_search', 'playlist_search'].indexOf(search_selected) != -1
) {
MainSearch.scrolledSearch(search_selected.split('_')[0])
}
}
}
static handleSearchBarKeyup(e) {
if (e.keyCode == 13) {
let term = this.value
if (Utils.isValidURL(term)) {
if (e.ctrlKey) {
QualityModal.open(term)
} else {
Downloads.sendAddToQueue(term)
}
} else {
if (term != MainSearch.query || main_selected == 'search_tab') {
document.getElementById('search_tab_content').style.display = 'none'
socket.emit('mainSearch', { term: term })
} else {
document.getElementById('search_all_tab').click()
document.getElementById('search_tab_content').style.display = 'block'
document.getElementById('main_search_tablink').click()
}
}
}
}
}

View File

@ -1,14 +1,12 @@
import { toast } from './toasts.js'
import { socket } from './socket.js'
// Globals
window.lastSettings = {}
window.lastCredentials = {}
const SettingsTab = new Vue({
data() {
return {
settings: { tags: {} },
lastSettings: {},
lastCredentials: {},
spotifyFeatures: {}
}
},
@ -25,9 +23,15 @@ const SettingsTab = new Vue({
toast('ARL copied to clipboard', 'assignment')
},
saveSettings() {
lastSettings = { ...SettingsTab.settings }
lastCredentials = { ...SettingsTab.spotifyFeatures }
socket.emit('saveSettings', lastSettings, lastCredentials)
this.lastSettings = { ...SettingsTab.settings }
this.lastCredentials = { ...SettingsTab.spotifyFeatures }
socket.emit('saveSettings', this.lastSettings, this.lastCredentials)
},
loadSettings(settings, spotifyCredentials) {
this.lastSettings = { ...settings }
this.lastCredentials = { ...spotifyCredentials }
this.settings = settings
this.spotifyFeatures = spotifyCredentials
},
login() {
let arl = this.$refs.loginInput.value
@ -37,25 +41,20 @@ const SettingsTab = new Vue({
},
logout() {
socket.emit('logout')
},
initSettings(settings, credentials) {
this.loadSettings(settings, credentials)
toast('Settings loaded!', 'settings')
},
updateSettings(settings, credentials) {
this.loadSettings(settings, credentials)
toast('Settings updated!', 'settings')
}
},
mounted() {
socket.on('init_settings', this.initSettings)
socket.on('updateSettings', this.updateSettings)
}
}).$mount('#settings_tab')
socket.on('init_settings', function (settings, credentials) {
loadSettings(settings, credentials)
toast('Settings loaded!', 'settings')
})
socket.on('updateSettings', function (settings, credentials) {
loadSettings(settings, credentials)
toast('Settings updated!', 'settings')
})
function loadSettings(settings, spotifyCredentials) {
lastSettings = { ...settings }
lastCredentials = { ...spotifyCredentials }
SettingsTab.settings = settings
SettingsTab.spotifyFeatures = spotifyCredentials
}
export default SettingsTab

View File

@ -1,26 +0,0 @@
import { resetArtistTab } from './artist-tab.js'
import { resetTracklistTab } from './tracklist-tab.js'
import { socket } from './socket.js'
export function artistView(ev) {
let id = ev.currentTarget.dataset.id
resetArtistTab()
socket.emit('getTracklist', { type: 'artist', id: id })
showTab('artist', id)
}
export function albumView(ev) {
let id = ev.currentTarget.dataset.id
console.log('album view', id)
resetTracklistTab()
socket.emit('getTracklist', { type: 'album', id: id })
showTab('album', id)
}
export function playlistView(ev) {
let id = ev.currentTarget.dataset.id
console.log('playlist view', id)
resetTracklistTab()
socket.emit('getTracklist', { type: 'playlist', id: id })
showTab('playlist', id)
}

204
public/js/modules/tabs.js Normal file
View File

@ -0,0 +1,204 @@
import ArtistTab from './artist-tab.js'
import TracklistTab from './tracklist-tab.js'
import { socket } from './socket.js'
import SettingsTab from './settings-tab.js'
import MainSearch from './main-search.js'
/* ===== Globals ====== */
window.search_selected = ''
window.main_selected = ''
window.windows_stack = []
/* ===== Locals ===== */
let currentStack = {}
export function artistView(ev) {
let id = ev.currentTarget.dataset.id
ArtistTab.reset()
socket.emit('getTracklist', { type: 'artist', id: id })
showTab('artist', id)
}
export function albumView(ev) {
let id = ev.currentTarget.dataset.id
console.log('album view', id)
TracklistTab.reset()
socket.emit('getTracklist', { type: 'album', id: id })
showTab('album', id)
}
export function playlistView(ev) {
let id = ev.currentTarget.dataset.id
console.log('playlist view', id)
TracklistTab.reset()
socket.emit('getTracklist', { type: 'playlist', id: id })
showTab('playlist', id)
}
export class Tabs {
static linkListeners() {
document.getElementById('search_tab').addEventListener('click', handleTabClick)
document.getElementById('sidebar').addEventListener('click', handleSidebarClick)
const backButtons = Array.from(document.getElementsByClassName('back-button'))
backButtons.forEach(button => {
button.addEventListener('click', backTab)
})
}
}
/**
* Handles click Event on the sidebar and changes tab
* according to clicked icon.
* Uses event delegation
* @param {Event} event
* @since 0.1.0
*/
function handleSidebarClick(event) {
let targetID = event.target.id
switch (targetID) {
case 'main_search_tablink':
changeTab(event, 'main', 'search_tab')
break
case 'main_home_tablink':
changeTab(event, 'main', 'home_tab')
break
case 'main_charts_tablink':
changeTab(event, 'main', 'charts_tab')
break
case 'main_favorites_tablink':
changeTab(event, 'main', 'favorites_tab')
break
case 'main_analyzer_tablink':
changeTab(event, 'main', 'analyzer_tab')
break
case 'main_settings_tablink':
changeTab(event, 'main', 'settings_tab')
break
case 'main_about_tablink':
changeTab(event, 'main', 'about_tab')
break
default:
break
}
}
function handleTabClick(event) {
let targetID = event.target.id
switch (targetID) {
case 'search_all_tab':
changeTab(event, 'search', 'main_search')
break
case 'search_track_tab':
changeTab(event, 'search', 'track_search')
break
case 'search_album_tab':
changeTab(event, 'search', 'album_search')
break
case 'search_artist_tab':
changeTab(event, 'search', 'artist_search')
break
case 'search_playlist_tab':
changeTab(event, 'search', 'playlist_search')
break
default:
break
}
}
// Uses:
// 1. windows_stack
// 2. currentStack
// 3. main_selected
// 4. SettingsTab
// 5. lastSettings
// 6. search_selected
// 7. MainSearch
function changeTab(evt, section, tabName) {
windows_stack = []
currentStack = {}
var i, tabcontent, tablinks
tabcontent = document.getElementsByClassName(section + '_tabcontent')
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none'
}
tablinks = document.getElementsByClassName(section + '_tablinks')
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove('active')
}
if (tabName == 'settings_tab' && main_selected != 'settings_tab') {
SettingsTab.settings = { ...SettingsTab.lastSettings }
}
document.getElementById(tabName).style.display = 'block'
if ('main' === section) {
main_selected = tabName
} else if ('search' === section) {
search_selected = tabName
}
// window[section + '_selected'] = tabName
// Not choosing .currentTarget beacuse the event
// is delegated
evt.target.classList.add('active')
// Check if you need to load more content in the search tab
if (
main_selected == 'search_tab' &&
['track_search', 'album_search', 'artist_search', 'playlist_search'].indexOf(search_selected) != -1 &&
MainSearch.results[search_selected.split('_')[0] + 'Tab'].data.length == 0
) {
MainSearch.search(search_selected.split('_')[0])
}
}
// Uses:
// 1. windows_stack
// 2. main_selected
// 3. currentStack
function showTab(type, id, back = false) {
if (windows_stack.length == 0) {
windows_stack.push({ tab: main_selected })
} else if (!back) {
windows_stack.push(currentStack)
}
window.tab = type == 'artist' ? 'artist_tab' : 'tracklist_tab'
currentStack = { type: type, id: id }
let tabcontent = document.getElementsByClassName('main_tabcontent')
for (let i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = 'none'
}
document.getElementById(tab).style.display = 'block'
}
// Uses:
// 1. windows_stack
// 2. main_selected
// 3. showTab
// 4. ArtistTab
// 5. TracklistTab
// 6. socket
function backTab() {
if (windows_stack.length == 1) {
document.getElementById(`main_${main_selected}link`).click()
} else {
let tabObj = windows_stack.pop()
if (tabObj.type == 'artist') {
ArtistTab.reset()
} else {
TracklistTab.reset()
}
socket.emit('getTracklist', { type: tabObj.type, id: tabObj.id })
showTab(tabObj.type, tabObj.id, true)
}
}

View File

@ -1,9 +1,9 @@
import { socket } from './socket.js'
import { artistView, albumView } from './stacked-tabs.js'
import { artistView, albumView } from './tabs.js'
import Downloads from './downloads.js'
import QualityModal from './quality-modal.js'
export const TracklistTab = new Vue({
const TracklistTab = new Vue({
el: '#tracklist_tab',
data: {
title: '',
@ -20,6 +20,17 @@ export const TracklistTab = new Vue({
methods: {
artistView,
albumView,
reset() {
this.title = 'Loading...'
this.image = ''
this.metadata = ''
this.label = ''
this.release_date = ''
this.explicit = false
this.type = ''
this.head = []
this.body = []
},
addToQueue: function (e) {
e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
@ -54,35 +65,17 @@ export const TracklistTab = new Vue({
ss = '0' + ss
}
return mm + ':' + ss
}
},
mounted() {
console.log('tracklist tab mounted')
}
})
export function resetTracklistTab() {
TracklistTab.title = 'Loading...'
TracklistTab.image = ''
TracklistTab.metadata = ''
TracklistTab.label = ''
TracklistTab.release_date = ''
TracklistTab.explicit = false
TracklistTab.type = ''
TracklistTab.head = []
TracklistTab.body = []
}
socket.on('show_album', data => {
TracklistTab.type = 'Album'
TracklistTab.link = `https://www.deezer.com/album/${data.id}`
TracklistTab.title = data.title
TracklistTab.explicit = data.explicit_lyrics
TracklistTab.label = data.label
TracklistTab.metadata = `${data.artist.name}${data.tracks.length} songs`
TracklistTab.release_date = data.release_date.substring(0, 10)
TracklistTab.image = data.cover_xl
TracklistTab.head = [
showAlbum(data) {
this.type = 'Album'
this.link = `https://www.deezer.com/album/${data.id}`
this.title = data.title
this.explicit = data.explicit_lyrics
this.label = data.label
this.metadata = `${data.artist.name}${data.tracks.length} songs`
this.release_date = data.release_date.substring(0, 10)
this.image = data.cover_xl
this.head = [
{ title: '<i class="material-icons">music_note</i>', width: '24px' },
{ title: '#' },
{ title: 'Song' },
@ -90,20 +83,21 @@ socket.on('show_album', data => {
{ title: '<i class="material-icons">timer</i>', width: '40px' }
]
if (_.isEmpty(data.tracks)) {
TracklistTab.body = null
} else {
TracklistTab.body = data.tracks
}
})
console.log('show e lodash ok')
socket.on('show_playlist', data => {
TracklistTab.type = 'Playlist'
TracklistTab.link = `https://www.deezer.com/playlist/${data.id}`
TracklistTab.title = data.title
TracklistTab.image = data.picture_xl
TracklistTab.release_date = data.creation_date.substring(0, 10)
TracklistTab.metadata = `by ${data.creator.name}${data.tracks.length} songs`
TracklistTab.head = [
this.body = null
} else {
this.body = data.tracks
}
},
showPlaylist(data) {
this.type = 'Playlist'
this.link = `https://www.deezer.com/playlist/${data.id}`
this.title = data.title
this.image = data.picture_xl
this.release_date = data.creation_date.substring(0, 10)
this.metadata = `by ${data.creator.name}${data.tracks.length} songs`
this.head = [
{ title: '<i class="material-icons">music_note</i>', width: '24px' },
{ title: '#' },
{ title: 'Song' },
@ -112,8 +106,18 @@ socket.on('show_playlist', data => {
{ title: '<i class="material-icons">timer</i>', width: '40px' }
]
if (_.isEmpty(data.tracks)) {
TracklistTab.body = null
this.body = null
} else {
TracklistTab.body = data.tracks
this.body = data.tracks
}
}
},
mounted() {
console.log('tracklist tab mounted')
socket.on('show_album', this.showAlbum)
socket.on('show_playlist', this.showPlaylist)
}
})
export default TracklistTab

View File

@ -27,6 +27,8 @@ export function convertDurationSeparated(duration) {
return [hh, mm, ss]
}
// On scroll event, returns currentTarget = null
// Probably on other events too
export function debounce(func, wait, immediate) {
var timeout
return function () {