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