feat: improved routing removing display none/block on route change; feat: improved favorites data rendering; feat: added type checking for socket.io

This commit is contained in:
Roberto Tonino
2020-08-31 22:14:14 +02:00
parent fdd4b0317a
commit d965c1e65b
20 changed files with 368 additions and 150 deletions

View File

@@ -184,7 +184,7 @@ export default {
}
},
mounted() {
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
console.log('artist mounted')
socket.on('show_artist', this.showArtist)
@@ -194,7 +194,7 @@ export default {
},
beforeDestroy() {
console.log('artist bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -201,11 +201,11 @@ export default {
}),
mounted() {
console.log('about mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
},
beforeDestroy() {
console.log('about bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -105,6 +105,7 @@
</template>
<script>
import { mapGetters } from 'vuex'
import { socket } from '@/utils/socket'
import { showView } from '@js/tabs.js'
import Downloads from '@/utils/downloads'
@@ -122,9 +123,41 @@ export default {
chart: []
}
},
computed: {
...mapGetters(['getCharts']),
needToWait() {
return this.getCharts.length === 0
}
},
mounted() {
console.log('charts mounted')
// this.$refs.root.style.display = 'block'
this.waitCharts()
// socket.on('init_charts', this.initCharts)
socket.on('setChartTracks', this.setTracklist)
},
beforeDestroy() {
console.log('charts bef dest')
// this.$refs.root.style.display = 'none'
},
methods: {
artistView: showView.bind(null, 'artist'),
albumView: showView.bind(null, 'album'),
waitCharts() {
if (this.needToWait) {
// Checking if the saving of the settings is completed
let unsub = this.$store.subscribeAction({
after: (action, state) => {
if (action.type === 'cacheCharts') {
this.initCharts()
unsub()
}
}
})
} else {
this.initCharts()
}
},
playPausePreview(e) {
EventBus.$emit('trackPreview:playPausePreview', e)
},
@@ -164,9 +197,9 @@ export default {
this.country = ''
this.id = 0
},
initCharts(data) {
initCharts() {
console.log('init charts')
this.countries = data
this.countries = this.getCharts
this.country = localStorage.getItem('chart') || ''
if (!this.country) return
@@ -184,16 +217,6 @@ export default {
localStorage.setItem('chart', this.country)
}
}
},
mounted() {
console.log('charts mounted')
this.$refs.root.style.display = 'block'
socket.on('init_charts', this.initCharts)
socket.on('setChartTracks', this.setTracklist)
},
beforeDestroy() {
console.log('charts bef dest')
this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -43,13 +43,13 @@ export default {
},
mounted() {
console.log('errors mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
EventBus.$on('showTabErrors', this.showErrors)
this.$root.$on('showTabErrors', this.showErrors)
},
beforeDestroy() {
console.log('errors bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div id="favorites_tab" class="main_tabcontent" @click="handleFavoritesTabClick" ref="root">
<div id="favorites_tab" class="main_tabcontent">
<h2 class="page_heading">
{{ $t('favorites.title') }}
<div
@@ -13,21 +13,18 @@
</div>
</h2>
<div class="section-tabs">
<div class="section-tabs__tab favorites_tablinks" id="favorites_playlist_tab">
{{ $tc('globals.listTabs.playlist', 2) }}
</div>
<div class="section-tabs__tab favorites_tablinks" id="favorites_album_tab">
{{ $tc('globals.listTabs.album', 2) }}
</div>
<div class="section-tabs__tab favorites_tablinks" id="favorites_artist_tab">
{{ $tc('globals.listTabs.artist', 2) }}
</div>
<div class="section-tabs__tab favorites_tablinks" id="favorites_track_tab">
{{ $tc('globals.listTabs.track', 2) }}
<div
class="section-tabs__tab favorites_tablinks"
:class="{ active: activeTab === tab }"
@click="activeTab = tab"
v-for="tab in tabs"
:key="tab"
>
{{ $tc(`globals.listTabs.${tab}`, 2) }}
</div>
</div>
<div id="playlist_favorites" class="favorites_tabcontent">
<div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'playlist' }">
<div v-if="playlists.length == 0">
<h1>{{ $t('favorites.noPlaylists') }}</h1>
</div>
@@ -75,7 +72,8 @@
</div>
</div>
</div>
<div id="album_favorites" class="favorites_tabcontent">
<div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'album' }">
<div v-if="albums.length == 0">
<h1>{{ $t('favorites.noAlbums') }}</h1>
</div>
@@ -98,7 +96,8 @@
</div>
</div>
</div>
<div id="artist_favorites" class="favorites_tabcontent">
<div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'artist' }">
<div v-if="artists.length == 0">
<h1>{{ $t('favorites.noArtists') }}</h1>
</div>
@@ -120,7 +119,8 @@
</div>
</div>
</div>
<div id="track_favorites" class="favorites_tabcontent">
<div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'track' }">
<div v-if="tracks.length == 0">
<h1>{{ $t('favorites.noTracks') }}</h1>
</div>
@@ -189,29 +189,76 @@
</div>
</template>
<style lang="scss">
.favorites_tabcontent {
display: none;
&--active {
display: block;
}
}
</style>
<script>
import { mapGetters } from 'vuex'
import { socket } from '@/utils/socket'
import { showView, changeTab } from '@js/tabs.js'
import { showView } from '@js/tabs'
import Downloads from '@/utils/downloads'
import Utils from '@/utils/utils'
import { convertDuration } from '@/utils/utils'
import { toast } from '@/utils/toasts'
export default {
name: 'the-favorites-tab',
data() {
return {
tracks: [],
albums: [],
artists: [],
playlists: [],
spotifyPlaylists: []
spotifyPlaylists: [],
activeTab: 'playlist',
tabs: ['playlist', 'album', 'artist', 'track']
}
},
computed: {
...mapGetters(['getFavorites']),
needToWait() {
return Object.keys(this.getFavorites).length === 0
}
},
mounted() {
console.log('favorites mounted')
// ! Need to implement memorization of the last tab clicked
// ! Use router query
this.waitFavorites()
socket.on('updated_userFavorites', this.updated_userFavorites)
socket.on('updated_userSpotifyPlaylists', this.updated_userSpotifyPlaylists)
socket.on('updated_userPlaylists', this.updated_userPlaylists)
socket.on('updated_userAlbums', this.updated_userAlbums)
socket.on('updated_userArtist', this.updated_userArtist)
socket.on('updated_userTracks', this.updated_userTracks)
},
methods: {
artistView: showView.bind(null, 'artist'),
albumView: showView.bind(null, 'album'),
playlistView: showView.bind(null, 'playlist'),
spotifyPlaylistView: showView.bind(null, 'spotifyplaylist'),
waitFavorites() {
if (this.needToWait) {
// Checking if the saving of the settings is completed
let unsub = this.$store.subscribeAction({
after: (action, state) => {
if (action.type === 'setFavorites') {
this.initFavorites()
unsub()
}
}
})
} else {
this.initFavorites()
}
},
playPausePreview(e) {
EventBus.$emit('trackPreview:playPausePreview', e)
},
@@ -221,36 +268,7 @@ export default {
previewMouseLeave(e) {
EventBus.$emit('trackPreview:previewMouseLeave', e)
},
convertDuration: Utils.convertDuration,
handleFavoritesTabClick(event) {
const {
target,
target: { id }
} = event
let selectedTab = null
switch (id) {
case 'favorites_playlist_tab':
selectedTab = 'playlist_favorites'
break
case 'favorites_album_tab':
selectedTab = 'album_favorites'
break
case 'favorites_artist_tab':
selectedTab = 'artist_favorites'
break
case 'favorites_track_tab':
selectedTab = 'track_favorites'
break
default:
break
}
if (!selectedTab) return
changeTab(target, 'favorites', selectedTab)
},
convertDuration,
addToQueue(e) {
e.stopPropagation()
Downloads.sendAddToQueue(e.currentTarget.dataset.link)
@@ -294,28 +312,9 @@ export default {
{ once: true }
)
},
initFavorites(data) {
this.updated_userFavorites(data)
document.getElementById('favorites_playlist_tab').click()
initFavorites() {
this.updated_userFavorites(this.getFavorites)
}
},
mounted() {
console.log('favorites mounted')
this.$refs.root.style.display = 'block'
socket.on('init_favorites', this.initFavorites)
socket.on('updated_userFavorites', this.updated_userFavorites)
socket.on('updated_userSpotifyPlaylists', this.updated_userSpotifyPlaylists)
socket.on('updated_userPlaylists', this.updated_userPlaylists)
socket.on('updated_userAlbums', this.updated_userAlbums)
socket.on('updated_userArtist', this.updated_userArtist)
socket.on('updated_userTracks', this.updated_userTracks)
},
beforeDestroy() {
console.log('favorites bef dest')
this.$refs.root.style.display = 'none'
}
}
</script>
<style>
</style>

View File

@@ -123,7 +123,7 @@ export default {
},
mounted() {
console.log('home mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
if (localStorage.getItem('arl')) {
this.$refs.notLogged.classList.add('hide')
@@ -135,7 +135,7 @@ export default {
},
beforeDestroy() {
console.log('home bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -192,7 +192,7 @@ export default {
},
mounted() {
console.log('link analyzer mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
EventBus.$on('linkAnalyzerTab:reset', this.reset)
socket.on('analyze_track', this.showTrack)
@@ -201,7 +201,7 @@ export default {
},
beforeDestroy() {
console.log('link analyzer bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -641,11 +641,11 @@ export default {
}),
beforeDestroy() {
console.log('settings bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
},
mounted() {
console.log('settings mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
this.locales = this.$i18n.availableLocales

View File

@@ -1,30 +1,72 @@
<template>
<aside id="sidebar" role="navigation" @click="handleSidebarClick">
<span id="main_home_tablink" class="main_tablinks" role="link" aria-label="home">
<span
id="main_home_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'home' }"
role="link"
aria-label="home"
>
<i class="material-icons side_icon">home</i>
<span class="main_tablinks_text">{{ $t('sidebar.home') }}</span>
</span>
<span id="main_search_tablink" class="main_tablinks" role="link" aria-label="search">
<span
id="main_search_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'search' }"
role="link"
aria-label="search"
>
<i class="material-icons side_icon">search</i>
<span class="main_tablinks_text">{{ $t('sidebar.search') }}</span>
</span>
<span id="main_charts_tablink" class="main_tablinks" role="link" aria-label="charts">
<span
id="main_charts_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'charts' }"
role="link"
aria-label="charts"
>
<i class="material-icons side_icon">show_chart</i>
<span class="main_tablinks_text">{{ $t('sidebar.charts') }}</span>
</span>
<span id="main_favorites_tablink" class="main_tablinks" role="link" aria-label="favorites">
<span
id="main_favorites_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'favorites' }"
role="link"
aria-label="favorites"
>
<i class="material-icons side_icon">star</i>
<span class="main_tablinks_text">{{ $t('sidebar.favorites') }}</span>
</span>
<span id="main_analyzer_tablink" class="main_tablinks" role="link" aria-label="link analyzer">
<span
id="main_analyzer_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'analyzer' }"
role="link"
aria-label="link analyzer"
>
<i class="material-icons side_icon">link</i>
<span class="main_tablinks_text">{{ $t('sidebar.linkAnalyzer') }}</span>
</span>
<span id="main_settings_tablink" class="main_tablinks" role="link" aria-label="settings">
<span
id="main_settings_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'settings' }"
role="link"
aria-label="settings"
>
<i class="material-icons side_icon">settings</i>
<span class="main_tablinks_text">{{ $t('sidebar.settings') }}</span>
</span>
<span id="main_about_tablink" class="main_tablinks" role="link" aria-label="info">
<span
id="main_about_tablink"
class="main_tablinks"
:class="{ active: activeTablink === 'about' }"
role="link"
aria-label="info"
>
<i class="material-icons side_icon">info</i>
<span class="main_tablinks_text">{{ $t('sidebar.about') }}</span>
</span>
@@ -84,7 +126,8 @@ export default {
data: () => ({
appOnline: null,
activeTheme: 'light',
themes: ['purple', 'dark', 'light']
themes: ['purple', 'dark', 'light'],
activeTablink: 'home'
}),
mounted() {
/* === Online status handling === */
@@ -139,6 +182,8 @@ export default {
let targetID = sidebarEl.id
let selectedTab = null
this.activeTablink = targetID.match(/main_(\w+)_tablink/)[1]
switch (targetID) {
case 'main_search_tablink':
selectedTab = 'search_tab'
@@ -162,6 +207,9 @@ export default {
selectedTab = 'favorites_tab'
this.$router.push({
name: 'Favorites'
// query: {
// tab: 'playlist'
// }
})
break
case 'main_analyzer_tablink':

View File

@@ -296,7 +296,7 @@ export default {
},
mounted() {
console.log('tracklist mounted')
this.$refs.root.style.display = 'block'
// this.$refs.root.style.display = 'block'
EventBus.$on('tracklistTab:selectRow', this.selectRow)
socket.on('show_album', this.showAlbum)
@@ -305,7 +305,7 @@ export default {
},
beforeDestroy() {
console.log('tracklist bef dest')
this.$refs.root.style.display = 'none'
// this.$refs.root.style.display = 'none'
}
}
</script>

View File

@@ -15,46 +15,36 @@ window.currentStack = {}
* Needs EventBus
*/
export function changeTab(sidebarEl, section, tabName) {
// console.error('CHANGE TAB')
window.windows_stack = []
window.currentStack = {}
// * The visualized content of the tab
// ! Can be more than one per tab, happens in MainSearch and Favorites tab
// ! because they have more tablinks (see below)
const tabContent = document.getElementsByClassName(`${section}_tabcontent`)
// hideTabContent(section)
// * Only in section search
updateTabLink(section)
for (let i = 0; i < tabContent.length; i++) {
if (!tabContent[i]) continue
// * Only when clicking the settings icon in the sidebar
resetSettings(tabName)
tabContent[i].style.display = 'none'
}
// showSelectedTab(tabName)
// * Tabs inside the actual tab (like albums, tracks, playlists...)
const tabLinks = document.getElementsByClassName(`${section}_tablinks`)
// * Only in section main & search
setSelectedTab(section, tabName)
for (let i = 0; i < tabLinks.length; i++) {
tabLinks[i].classList.remove('active')
}
// setSidebarElementActive(sidebarEl)
if (tabName === 'settings_tab' && window.main_selected !== 'settings_tab') {
EventBus.$emit('settingsTab:revertSettings')
EventBus.$emit('settingsTab:revertCredentials')
}
// * The tab we want to show
if (document.getElementById(tabName)) {
document.getElementById(tabName).style.display = 'block'
}
// * Only if window.main_selected === 'search_tab'
checkNeedToLoadMoreContent()
}
function setSelectedTab(section, tabName) {
if (section === 'main') {
window.main_selected = tabName
} else if (section === 'search') {
window.search_selected = tabName
}
}
sidebarEl.classList.add('active')
function checkNeedToLoadMoreContent() {
// * Check if you need to load more content in the search tab
// * Happens when the user changes the tab in the main search
if (
@@ -65,6 +55,53 @@ export function changeTab(sidebarEl, section, tabName) {
}
}
function setSidebarElementActive(sidebarEl) {
sidebarEl.classList.add('active')
}
function showSelectedTab(tabName) {
// * The tab we want to show
console.log('Tabs who get display block')
if (document.getElementById(tabName)) {
document.getElementById(tabName).style.display = 'block'
}
}
function resetSettings(tabName) {
if (tabName === 'settings_tab' && window.main_selected !== 'settings_tab') {
EventBus.$emit('settingsTab:revertSettings')
EventBus.$emit('settingsTab:revertCredentials')
}
}
function hideTabContent(section) {
// * The visualized content of the tab
// ! Can be more than one per tab, happens in MainSearch and Favorites tab
// ! because they have more tablinks (see below)
const tabContent = document.getElementsByClassName(`${section}_tabcontent`)
for (let i = 0; i < tabContent.length; i++) {
if (!tabContent[i] || tabContent[i].matches('.main_tabcontent')) continue
tabContent[i].style.display = 'none'
}
}
function updateTabLink(section) {
// * Tabs inside the actual tab (like albums, tracks, playlists...)
// * or sidebar links
if (section == 'main') return
const tabLinks = document.getElementsByClassName(`${section}_tablinks`)
// console.log(tabLinks)
// console.trace()
for (let i = 0; i < tabLinks.length; i++) {
tabLinks[i].classList.remove('active')
}
}
export function showView(viewType, event) {
const {
currentTarget: {
@@ -90,9 +127,9 @@ export function showView(viewType, event) {
*/
function showTab(type, id, back = false) {
return
updateStack(type, id, back)
// updateStack(type, id, back)
window.tab = type === 'artist' ? 'artist_tab' : 'tracklist_tab'
displayTabs()
// displayTabs()
}
function updateStack(type, id, back) {

View File

@@ -8,5 +8,8 @@
"@components/*": ["./components/*"]
}
},
"typeAcquisition": {
"include": ["socket.io-client"]
},
"exclude": ["assets/**/*", "styles/**/*"]
}

View File

@@ -85,7 +85,6 @@ const router = new VueRouter({
})
router.beforeEach((to, from, next) => {
console.log('before route change', to)
let getTracklistParams = null
switch (to.name) {

View File

@@ -5,6 +5,8 @@ import home from '@/store/modules/home'
import settings from '@/store/modules/settings'
import defaultSettings from '@/store/modules/defaultSettings'
import spotifyCredentials from '@/store/modules/spotifyCredentials'
import charts from '@/store/modules/charts'
import favorites from '@/store/modules/favorites'
// Load Vuex
Vue.use(Vuex)
@@ -15,7 +17,9 @@ export default new Vuex.Store({
home,
settings,
defaultSettings,
credentials: spotifyCredentials
spotifyCredentials,
charts,
favorites
},
strict: process.env.NODE_ENV !== 'production'
})

View File

@@ -0,0 +1,40 @@
import Vue from 'vue'
const state = {
list: []
}
let chartsCached = false
const actions = {
/**
* @param {object} context
* @param {object[]} payload
*/
cacheCharts({ commit }, payload) {
if (chartsCached) return
payload.forEach((chartObj, index) => {
commit('SET_UNKNOWN_CHART', { index, chartObj })
})
chartsCached = true
}
}
const getters = {
getCharts: state => state.list
}
const mutations = {
SET_UNKNOWN_CHART(state, payload) {
Vue.set(state.list, payload.index, payload.chartObj)
}
}
export default {
state,
getters,
actions,
mutations
}

View File

@@ -0,0 +1,61 @@
import Vue from 'vue'
const state = {
albums: [],
artists: [],
playlists: [],
tracks: []
}
const actions = {
setFavorites({ commit, dispatch }, payload) {
payload.playlists.forEach((playlist, index) => {
commit('SET_FAVORITES_PLAYLISTS', { index, data: playlist })
})
payload.albums.forEach((album, index) => {
commit('SET_FAVORITES_ALBUMS', { index, data: album })
})
payload.artists.forEach((artist, index) => {
commit('SET_FAVORITES_ARTISTS', { index, data: artist })
})
dispatch('setFavoritesTracks', payload.tracks)
},
setFavoritesTracks({ commit }, payload) {
payload.forEach((track, index) => {
commit('SET_FAVORITES_TRACKS', { index, data: track })
})
}
}
const getters = {
getFavorites: state => state,
getFavoritesAlbums: state => state.albums,
getFavoritesArtists: state => state.artists,
getFavoritesPlaylists: state => state.playlists,
getFavoritesTracks: state => state.tracks
}
const mutations = {
SET_FAVORITES_ALBUMS: (state, payload) => {
Vue.set(state.albums, payload.index, payload.data)
},
SET_FAVORITES_ARTISTS: (state, payload) => {
Vue.set(state.artists, payload.index, payload.data)
},
SET_FAVORITES_PLAYLISTS: (state, payload) => {
Vue.set(state.playlists, payload.index, payload.data)
},
SET_FAVORITES_TRACKS: (state, payload) => {
Vue.set(state.tracks, payload.index, payload.data)
}
}
export default {
state,
actions,
getters,
mutations
}

View File

@@ -1,8 +1,9 @@
.search_tabcontent,
.main_tabcontent,
.favorites_tabcontent {
display: none;
}
// .search_tabcontent
// .main_tabcontent,
// .favorites_tabcontent
// {
// display: none;
// }
.main_tabcontent {
h1 {

View File

@@ -6,12 +6,15 @@ socket.on('connect', () => {
document.getElementById('start_app_placeholder').classList.add('loading_placeholder--hidden')
})
// socket.on('init_charts', data => {
// console.log(data)
// })
socket.on('init_charts', charts => {
store.dispatch('cacheCharts', charts)
})
socket.on('init_favorites', favorites => {
store.dispatch('setFavorites', favorites)
})
socket.on('init_settings', (settings, credentials, defaults) => {
console.log(credentials)
store.dispatch('setSettings', settings)
store.dispatch('setDefaultSettings', defaults)
store.dispatch('setCredentials', credentials)