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

You need to sign in or sign up before continuing.
...
 
Commits (4)
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -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) {
......