and though bugs are the bane of my existence, rest assured the wretched thing will get the best of care here

...
 
Commits (4)
This diff is collapsed.
...@@ -6,38 +6,38 @@ ...@@ -6,38 +6,38 @@
<div class="release-grid"> <div class="release-grid">
<div <div
v-for="release in countries" v-for="release in countries"
role="button" :key="release.id"
:aria-label="release.title" :aria-label="release.title"
:data-id="release.id"
:data-title="release.title"
class="w-40 h-40 release clickable" class="w-40 h-40 release clickable"
role="button"
@click="getTrackList" @click="getTrackList"
:data-title="release.title"
:data-id="release.id"
:key="release.id"
> >
<img class="w-full rounded coverart" :src="release.picture_medium" /> <img :src="release.picture_medium" class="w-full rounded coverart" />
</div> </div>
</div> </div>
</div> </div>
<div v-else> <div v-else>
<button class="btn btn-primary" @click="onChangeCountry">{{ $t('charts.changeCountry') }}</button> <button class="btn btn-primary" @click="onChangeCountry">{{ $t('charts.changeCountry') }}</button>
<button class="btn btn-primary" @click.stop="addToQueue" :data-link="'https://www.deezer.com/playlist/' + id"> <button :data-link="'https://www.deezer.com/playlist/' + id" class="btn btn-primary" @click.stop="addToQueue">
{{ $t('charts.download') }} {{ $t('charts.download') }}
</button> </button>
<table class="table table--charts"> <table class="table table--charts">
<tbody> <tbody>
<tr v-for="track in chart" class="track_row"> <tr v-for="track in chart" class="track_row">
<td class="p-3 text-center cursor-default" :class="{ first: track.position === 1 }"> <td :class="{ first: track.position === 1 }" class="p-3 text-center cursor-default">
{{ track.position }} {{ track.position }}
</td> </td>
<td class="table__icon table__icon--big"> <td class="table__icon table__icon--big">
<span <span
@click="playPausePreview"
class="relative inline-block rounded cursor-pointer"
:data-preview="track.preview" :data-preview="track.preview"
class="relative inline-block rounded cursor-pointer"
@click="playPausePreview"
> >
<PreviewControls v-if="track.preview" /> <PreviewControls v-if="track.preview" />
<img class="rounded coverart" :src="track.album.cover_small" /> <img :src="track.album.cover_small" class="rounded coverart" />
</span> </span>
</td> </td>
<td class="table__cell--large"> <td class="table__cell--large">
...@@ -47,16 +47,16 @@ ...@@ -47,16 +47,16 @@
}} }}
</td> </td>
<router-link <router-link
tag="td"
class="table__cell table__cell--medium table__cell--center clickable"
:to="{ name: 'Artist', params: { id: track.artist.id } }" :to="{ name: 'Artist', params: { id: track.artist.id } }"
class="table__cell table__cell--medium table__cell--center clickable"
tag="td"
> >
{{ track.artist.name }} {{ track.artist.name }}
</router-link> </router-link>
<router-link <router-link
tag="td"
class="table__cell--medium table__cell--center clickable"
:to="{ name: 'Album', params: { id: track.album.id } }" :to="{ name: 'Album', params: { id: track.album.id } }"
class="table__cell--medium table__cell--center clickable"
tag="td"
> >
{{ track.album.title }} {{ track.album.title }}
</router-link> </router-link>
...@@ -64,15 +64,15 @@ ...@@ -64,15 +64,15 @@
{{ convertDuration(track.duration) }} {{ convertDuration(track.duration) }}
</td> </td>
<td <td
class="cursor-pointer group"
@click.stop="addToQueue"
:data-link="track.link" :data-link="track.link"
role="button"
aria-label="download" aria-label="download"
class="cursor-pointer group"
role="button"
@click.stop="addToQueue"
> >
<i <i
class="transition-colors duration-150 ease-in-out material-icons group-hover:text-primary"
:title="$t('globals.download_hint')" :title="$t('globals.download_hint')"
class="transition-colors duration-150 ease-in-out material-icons group-hover:text-primary"
> >
get_app get_app
</i> </i>
...@@ -85,14 +85,14 @@ ...@@ -85,14 +85,14 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
import { socket } from '@/utils/socket' import { socket } from '@/utils/socket'
import { sendAddToQueue } from '@/utils/downloads' import { sendAddToQueue } from '@/utils/downloads'
import { convertDuration } from '@/utils/utils' import { convertDuration } from '@/utils/utils'
import { getChartsData } from '@/data/charts' import { getChartsData, getChartTracks } from '@/data/charts'
import PreviewControls from '@components/globals/PreviewControls.vue' import PreviewControls from '@components/globals/PreviewControls.vue'
import { playPausePreview } from '@components/globals/TheTrackPreview.vue' import { playPausePreview } from '@components/globals/TheTrackPreview.vue'
import { fetchData } from '@/utils/api'
export default { export default {
components: { components: {
...@@ -116,12 +116,12 @@ export default { ...@@ -116,12 +116,12 @@ export default {
} }
}, },
async created() { async created() {
socket.on('setChartTracks', this.setTracklist) // socket.on('setChartTracks', this.setTracklist)
this.$on('hook:destroyed', () => { // this.$on('hook:destroyed', () => {
socket.off('setChartTracks') // socket.off('setChartTracks')
}) // })
let chartsData = await getChartsData() let { data: chartsData } = await getChartsData()
let worldwideChart let worldwideChart
chartsData = chartsData.filter(item => { chartsData = chartsData.filter(item => {
...@@ -147,17 +147,13 @@ export default { ...@@ -147,17 +147,13 @@ export default {
const { const {
currentTarget: { currentTarget: {
dataset: { title } dataset: { title, id }
},
currentTarget: {
dataset: { id }
} }
} = event } = event
this.country = title this.country = title
localStorage.setItem('chart', this.country) localStorage.setItem('chart', this.country)
this.id = id this.id = id
socket.emit('getChartTracks', this.id)
}, },
setTracklist(data) { setTracklist(data) {
this.chart = data this.chart = data
...@@ -185,6 +181,15 @@ export default { ...@@ -185,6 +181,15 @@ export default {
localStorage.setItem('chart', this.country) localStorage.setItem('chart', this.country)
} }
} }
},
watch: {
id(newId) {
const isActualChart = newId !== 0
if (isActualChart) {
getChartTracks(newId).then(response => this.setTracklist(response.result))
}
}
} }
} }
</script> </script>
<template> <template>
<div class="relative fixed-footer bg-background-main image-header" ref="root"> <div ref="root" class="relative fixed-footer bg-background-main image-header">
<header <header
:style="{ :style="{
'background-image': 'background-image':
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<i class="material-icons">timer</i> <i class="material-icons">timer</i>
</th> </th>
<th class="table__icon table__cell--center clickable"> <th class="table__icon table__cell--center clickable">
<input @click="toggleAll" class="selectAll" type="checkbox" /> <input class="selectAll" type="checkbox" @click="toggleAll" />
</th> </th>
</tr> </tr>
</thead> </thead>
...@@ -41,15 +41,15 @@ ...@@ -41,15 +41,15 @@
<td class="table__cell--x-small table__cell--center"> <td class="table__cell--x-small table__cell--center">
<div class="table__cell-content table__cell-content--vertical-center"> <div class="table__cell-content table__cell-content--vertical-center">
<i <i
class="material-icons" v-on="{ click: track.preview ? playPausePreview : false }"
:class="{ :class="{
preview_playlist_controls: track.preview, preview_playlist_controls: track.preview,
'cursor-pointer': track.preview, 'cursor-pointer': track.preview,
disabled: !track.preview disabled: !track.preview
}" }"
v-on="{ click: track.preview ? playPausePreview : false }"
:data-preview="track.preview" :data-preview="track.preview"
:title="$t('globals.play_hint')" :title="$t('globals.play_hint')"
class="material-icons"
> >
play_arrow play_arrow
</i> </i>
...@@ -70,28 +70,28 @@ ...@@ -70,28 +70,28 @@
</div> </div>
</td> </td>
<router-link <router-link
tag="td"
class="table__cell--medium table__cell--center clickable"
:to="{ name: 'Artist', params: { id: track.artist.id } }" :to="{ name: 'Artist', params: { id: track.artist.id } }"
class="table__cell--medium table__cell--center clickable"
tag="td"
> >
{{ track.artist.name }} {{ track.artist.name }}
</router-link> </router-link>
<router-link <router-link
tag="td"
v-if="type === 'playlist'" v-if="type === 'playlist'"
class="table__cell--medium table__cell--center clickable"
:to="{ name: 'Album', params: { id: track.album.id } }" :to="{ name: 'Album', params: { id: track.album.id } }"
class="table__cell--medium table__cell--center clickable"
tag="td"
> >
{{ track.album.title }} {{ track.album.title }}
</router-link> </router-link>
<td <td
class="table__cell--center"
:class="{ 'table__cell--small': type === 'album', 'table__cell--x-small': type === 'playlist' }" :class="{ 'table__cell--small': type === 'album', 'table__cell--x-small': type === 'playlist' }"
class="table__cell--center"
> >
{{ convertDuration(track.duration) }} {{ convertDuration(track.duration) }}
</td> </td>
<td class="table__icon table__cell--center"> <td class="table__icon table__cell--center">
<input class="clickable" type="checkbox" v-model="track.selected" /> <input v-model="track.selected" class="clickable" type="checkbox" />
</td> </td>
</tr> </tr>
<tr v-else-if="track.type == 'disc_separator'" class="table__row-no-highlight" style="opacity: 0.54"> <tr v-else-if="track.type == 'disc_separator'" class="table__row-no-highlight" style="opacity: 0.54">
...@@ -112,14 +112,14 @@ ...@@ -112,14 +112,14 @@
<td> <td>
<i <i
v-if="track.preview_url" v-if="track.preview_url"
@click="playPausePreview"
class="material-icons"
:class="{ :class="{
preview_playlist_controls: track.preview_url, preview_playlist_controls: track.preview_url,
'cursor-pointer': track.preview_url 'cursor-pointer': track.preview_url
}" }"
:data-preview="track.preview_url" :data-preview="track.preview_url"
:title="$t('globals.play_hint')" :title="$t('globals.play_hint')"
class="material-icons"
@click="playPausePreview"
> >
play_arrow play_arrow
</i> </i>
...@@ -133,17 +133,17 @@ ...@@ -133,17 +133,17 @@
<td>{{ track.artists[0].name }}</td> <td>{{ track.artists[0].name }}</td>
<td>{{ track.album.name }}</td> <td>{{ track.album.name }}</td>
<td>{{ convertDuration(Math.floor(track.duration_ms / 1000)) }}</td> <td>{{ convertDuration(Math.floor(track.duration_ms / 1000)) }}</td>
<td><input class="clickable" type="checkbox" v-model="track.selected" /></td> <td><input v-model="track.selected" class="clickable" type="checkbox" /></td>
</tr> </tr>
</template> </template>
</tbody> </tbody>
</table> </table>
<span v-if="label" style="opacity: 0.4; margin-top: 8px; display: inline-block; font-size: 13px">{{ label }}</span> <span v-if="label" style="opacity: 0.4; margin-top: 8px; display: inline-block; font-size: 13px">{{ label }}</span>
<footer class="bg-background-main"> <footer class="bg-background-main">
<button class="mr-2 btn btn-primary" @click.stop="addToQueue" :data-link="link"> <button :data-link="link" class="mr-2 btn btn-primary" @click.stop="addToQueue">
{{ `${$t('globals.download', { thing: $tc(`globals.listTabs.${type}`, 1) })}` }} {{ `${$t('globals.download', { thing: $tc(`globals.listTabs.${type}`, 1) })}` }}
</button> </button>
<button class="flex items-center btn btn-primary" @click.stop="addToQueue" :data-link="selectedLinks()"> <button :data-link="selectedLinks()" class="flex items-center btn btn-primary" @click.stop="addToQueue">
{{ $t('tracklist.downloadSelection') }}<i class="ml-2 material-icons">file_download</i> {{ $t('tracklist.downloadSelection') }}<i class="ml-2 material-icons">file_download</i>
</button> </button>
</footer> </footer>
...@@ -156,6 +156,7 @@ import { socket } from '@/utils/socket' ...@@ -156,6 +156,7 @@ import { socket } from '@/utils/socket'
import { sendAddToQueue } from '@/utils/downloads' import { sendAddToQueue } from '@/utils/downloads'
import Utils from '@/utils/utils' import Utils from '@/utils/utils'
import { playPausePreview } from '@components/globals/TheTrackPreview.vue' import { playPausePreview } from '@components/globals/TheTrackPreview.vue'
import EventBus from '@/utils/EventBus'
export default { export default {
data() { data() {
...@@ -172,9 +173,9 @@ export default { ...@@ -172,9 +173,9 @@ export default {
} }
}, },
mounted() { mounted() {
socket.on('show_album', this.showAlbum) EventBus.$on('showAlbum', this.showAlbum)
socket.on('show_playlist', this.showPlaylist) EventBus.$on('showPlaylist', this.showPlaylist)
socket.on('show_spotifyplaylist', this.showSpotifyPlaylist) EventBus.$on('showSpotifyPlaylist', this.showSpotifyPlaylist)
}, },
methods: { methods: {
playPausePreview, playPausePreview,
...@@ -193,17 +194,17 @@ export default { ...@@ -193,17 +194,17 @@ export default {
}, },
toggleAll(e) { toggleAll(e) {
this.body.forEach(item => { this.body.forEach(item => {
if (item.type == 'track') { if (item.type === 'track') {
item.selected = e.currentTarget.checked item.selected = e.currentTarget.checked
} }
}) })
}, },
selectedLinks() { selectedLinks() {
var selected = [] const selected = []
if (this.body) { if (this.body) {
this.body.forEach(item => { this.body.forEach(item => {
if (item.type == 'track' && item.selected) if (item.type === 'track' && item.selected)
selected.push(this.type == 'spotifyPlaylist' ? item.uri : item.link) selected.push(this.type === 'spotifyPlaylist' ? item.uri : item.link)
}) })
} }
return selected.join(';') return selected.join(';')
...@@ -305,4 +306,3 @@ export default { ...@@ -305,4 +306,3 @@ export default {
} }
} }
</script> </script>
import { socket } from '@/utils/socket'
import { getPropertyWithFallback } from '@/utils/utils' import { getPropertyWithFallback } from '@/utils/utils'
import { fetchData } from '@/utils/api'
export function formatArtistData(artistData) { export function formatArtistData(artistData) {
return { return {
...@@ -36,15 +36,8 @@ function formatArtistReleases(artistReleases) { ...@@ -36,15 +36,8 @@ function formatArtistReleases(artistReleases) {
} }
export function getArtistData(artistID) { export function getArtistData(artistID) {
socket.emit('getTracklist', { return fetchData('getTracklist', {
type: 'artist', type: 'artist',
id: artistID id: artistID
}) })
return new Promise((resolve, reject) => {
socket.on('show_artist', data => {
socket.off('show_artist')
resolve(data)
})
})
} }
import { socket } from '@/utils/socket'
import { fetchData } from '@/utils/api' import { fetchData } from '@/utils/api'
let chartsData = {}
let cached = false
export function getChartsData() { export function getChartsData() {
if (cached) { return fetchData('getCharts')
return chartsData }
} else {
socket.emit('get_charts_data')
fetchData('getCharts')
return new Promise((resolve, reject) => {
socket.on('init_charts', data => {
chartsData = data
cached = true
socket.off('init_charts') export function getChartTracks(chartId) {
resolve(data) return fetchData('getChartTracks', { id: chartId })
})
})
}
} }
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import { socket } from '@/utils/socket'
// Pages // Pages
//import About from '@components/pages/About.vue' //import About from '@components/pages/About.vue'
...@@ -16,6 +15,7 @@ import Search from '@components/pages/Search.vue' ...@@ -16,6 +15,7 @@ import Search from '@components/pages/Search.vue'
import Settings from '@components/pages/Settings.vue' import Settings from '@components/pages/Settings.vue'
import Tracklist from '@components/pages/Tracklist.vue' import Tracklist from '@components/pages/Tracklist.vue'
import { fetchData } from '@/utils/api' import { fetchData } from '@/utils/api'
import EventBus from '@/utils/EventBus'
Vue.use(VueRouter) Vue.use(VueRouter)
...@@ -126,43 +126,50 @@ const router = new VueRouter({ ...@@ -126,43 +126,50 @@ const router = new VueRouter({
}) })
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
let getTracklistParams = null
switch (to.name) { switch (to.name) {
case 'Tracklist': case 'Tracklist': {
getTracklistParams = { // const getTracklistParams = {
type: to.params.type, // type: to.params.type,
id: to.params.id // id: to.params.id
} // }
console.warn('This should never happen.')
break break
case 'Album': }
getTracklistParams = { case 'Album': {
const getTracklistParams = {
type: 'album', type: 'album',
id: to.params.id id: to.params.id
} }
fetchData('getTracklist', getTracklistParams).then(albumData => {
EventBus.$emit('showAlbum', albumData)
})
break break
case 'Playlist': }
getTracklistParams = { case 'Playlist': {
const getTracklistParams = {
type: 'playlist', type: 'playlist',
id: to.params.id id: to.params.id
} }
fetchData('getTracklist', getTracklistParams).then(playlistData => {
EventBus.$emit('showPlaylist', playlistData)
})
break break
case 'Spotify Playlist': }
getTracklistParams = { case 'Spotify Playlist': {
const getTracklistParams = {
type: 'spotifyplaylist', type: 'spotifyplaylist',
id: to.params.id id: to.params.id
} }
fetchData('getTracklist', getTracklistParams).then(spotifyPlaylistData => {
EventBus.$emit('showSpotifyPlaylist', spotifyPlaylistData)
})
break break
}
default: default:
break break
} }
if (getTracklistParams) {
socket.emit('getTracklist', getTracklistParams)
fetchData('getTracklist', getTracklistParams)
}
next() next()
}) })
......
...@@ -21,14 +21,16 @@ async function refreshFavorites({ isInitial = false }) { ...@@ -21,14 +21,16 @@ async function refreshFavorites({ isInitial = false }) {
isRefreshingFavorites.value = true isRefreshingFavorites.value = true
} }
const favorites = await fetchData('getFavorites') const favorites = await fetchData('getUserFavorites')
setAllFavorites(favorites) setAllFavorites(favorites)
if (store.getters.isLoggedWithSpotify) { if (store.getters.isLoggedWithSpotify) {
// TODO // TODO
const res = await fetchData('getUserSpotifyPlaylists', { spotifyUser: store.getters.getSpotifyUser.id }) const spotifyPlaylists = await fetchData('getUserSpotifyPlaylists', {
// socket.emit('update_userSpotifyPlaylists', store.getters.getSpotifyUser.id) spotifyUser: store.getters.getSpotifyUser.id
})
favoriteSpotifyPlaylists.value = spotifyPlaylists
} }
} }
...@@ -47,39 +49,10 @@ export function useFavorites() { ...@@ -47,39 +49,10 @@ export function useFavorites() {
function setAllFavorites(data) { function setAllFavorites(data) {
const { tracks, albums, artists, playlists } = data const { tracks, albums, artists, playlists } = data
isRefreshingFavorites.value = false
favoriteArtists.value = artists favoriteArtists.value = artists
favoriteAlbums.value = albums favoriteAlbums.value = albums
favoritePlaylists.value = playlists favoritePlaylists.value = playlists
favoriteTracks.value = tracks favoriteTracks.value = tracks
} }
socket.on('updated_userFavorites', data => {
setAllFavorites(data)
// Commented out because the corresponding emit function is never called at the moment
// therefore isRefreshingFavorites is never set to true
// isRefreshingFavorites.value = false
})
socket.on('init_favorites', data => {
setAllFavorites(data)
isRefreshingFavorites.value = false
})
socket.on('updated_userSpotifyPlaylists', data => {
favoriteSpotifyPlaylists.value = data
})
socket.on('updated_userSpotifyPlaylists', data => {
favoriteSpotifyPlaylists.value = data
})
socket.on('updated_userPlaylists', data => {
favoritePlaylists.value = data
})
socket.on('updated_userAlbums', data => {
favoriteAlbums.value = data
})
socket.on('updated_userArtist', data => {
favoriteArtists.value = data
})
socket.on('updated_userTracks', data => {
favoriteTracks.value = data
})
...@@ -5,7 +5,9 @@ export function fetchData(key, data = {}) { ...@@ -5,7 +5,9 @@ export function fetchData(key, data = {}) {
url.searchParams.append(key, data[key]) url.searchParams.append(key, data[key])
}) })
return fetch(url.href).then(response => response.json()) return fetch(url.href)
.then(response => response.json())
.catch(() => {})
} }
export function sendToServer(key, data) { export function sendToServer(key, data) {
......