feat: download all button in Favorites page, this solves #37

This commit is contained in:
Roberto Tonino 2020-10-07 20:29:20 +02:00
parent 1646f6b0e5
commit d3e1b71faf
6 changed files with 90 additions and 21 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
<template> <template>
<div id="favorites_tab" class="main_tabcontent"> <div class="main_tabcontent">
<h2 class="page_heading"> <h2 class="page_heading">
{{ $t('favorites.title') }} {{ $t('favorites.title') }}
<div <div
@ -12,6 +12,7 @@
<i class="material-icons">sync</i> <i class="material-icons">sync</i>
</div> </div>
</h2> </h2>
<div class="section-tabs"> <div class="section-tabs">
<div <div
class="section-tabs__tab favorites_tablinks" class="section-tabs__tab favorites_tablinks"
@ -24,6 +25,10 @@
</div> </div>
</div> </div>
<button v-if="!activeTabEmpty" style="margin-bottom: 2rem" @click="downloadAllOfType">
{{ $t('globals.downloadAll', { thing: $tc(`globals.listTabs.${activeTab}`, 2) }) }}
</button>
<div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'playlist' }"> <div class="favorites_tabcontent" :class="{ 'favorites_tabcontent--active': activeTab === 'playlist' }">
<div v-if="playlists.length == 0"> <div v-if="playlists.length == 0">
<h1>{{ $t('favorites.noPlaylists') }}</h1> <h1>{{ $t('favorites.noPlaylists') }}</h1>
@ -222,7 +227,7 @@
</div> </div>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.favorites_tabcontent { .favorites_tabcontent {
display: none; display: none;
@ -234,7 +239,7 @@
<script> <script>
import { socket } from '@/utils/socket' import { socket } from '@/utils/socket'
import { sendAddToQueue } from '@/utils/downloads' import { sendAddToQueue, aggregateDownloadLinks } from '@/utils/downloads'
import { convertDuration } from '@/utils/utils' import { convertDuration } from '@/utils/utils'
import { toast } from '@/utils/toasts' import { toast } from '@/utils/toasts'
@ -252,6 +257,13 @@ export default {
tabs: ['playlist', 'album', 'artist', 'track'] tabs: ['playlist', 'album', 'artist', 'track']
} }
}, },
computed: {
activeTabEmpty() {
let toCheck = this.getActiveRelease()
return toCheck.length === 0
}
},
async created() { async created() {
const favoritesData = await getFavoritesData() const favoritesData = await getFavoritesData()
@ -288,6 +300,21 @@ export default {
EventBus.$emit('trackPreview:previewMouseLeave', e) EventBus.$emit('trackPreview:previewMouseLeave', e)
}, },
convertDuration, convertDuration,
downloadAllOfType() {
try {
let toDownload = this.getActiveRelease()
if (this.activeTab === 'track') {
let lovedTracks = this.getLovedTracksPlaylist()
sendAddToQueue(lovedTracks.link)
} else {
sendAddToQueue(aggregateDownloadLinks(toDownload))
}
} catch (error) {
console.error(error.message)
}
},
addToQueue(e) { addToQueue(e) {
sendAddToQueue(e.currentTarget.dataset.link) sendAddToQueue(e.currentTarget.dataset.link)
}, },
@ -336,6 +363,40 @@ export default {
this.albums = albums this.albums = albums
this.artists = artists this.artists = artists
this.playlists = playlists this.playlists = playlists
},
getActiveRelease(tab = this.activeTab) {
let toDownload
switch (tab) {
case 'playlist':
toDownload = this.playlists
break
case 'album':
toDownload = this.albums
break
case 'artist':
toDownload = this.artists
break
case 'track':
toDownload = this.tracks
break
default:
break
}
return toDownload
},
getLovedTracksPlaylist() {
let lovedTracks = this.playlists.filter(playlist => {
return playlist.is_loved_track
})
if (lovedTracks.length !== 0) {
return lovedTracks[0]
} else {
throw new Error('No loved tracks playlist!')
}
} }
} }
} }

View File

@ -4,6 +4,7 @@ const en = {
back: 'back', back: 'back',
loading: 'loading', loading: 'loading',
download: 'Download {thing}', download: 'Download {thing}',
downloadAll: 'Download all {thing}',
by: 'by {artist}', by: 'by {artist}',
in: 'in {album}', in: 'in {album}',
download_hint: 'Download', download_hint: 'Download',
@ -105,7 +106,7 @@ const en = {
no360RA: 'Track is not available in Reality Audio 360.', no360RA: 'Track is not available in Reality Audio 360.',
notAvailable: "Track not available on Deezer's servers!", notAvailable: "Track not available on Deezer's servers!",
notAvailableNoAlternative: "Track not available on Deezer's servers and no alternative found!", notAvailableNoAlternative: "Track not available on Deezer's servers and no alternative found!",
noSpaceLeft: "No space left on the device!", noSpaceLeft: 'No space left on the device!',
albumDoesntExists: "Track's album doesn't exist, failed to gather info" albumDoesntExists: "Track's album doesn't exist, failed to gather info"
} }
}, },
@ -126,7 +127,8 @@ const en = {
}, },
linkAnalyzer: { linkAnalyzer: {
info: 'You can use this section to find more information about the link you are trying to download.', info: 'You can use this section to find more information about the link you are trying to download.',
useful: "This is useful if you're trying to download some tracks that are not available in your country and want to know where they are available, for instance.", useful:
"This is useful if you're trying to download some tracks that are not available in your country and want to know where they are available, for instance.",
linkNotSupported: 'This link is not yet supported', linkNotSupported: 'This link is not yet supported',
linkNotSupportedYet: 'Seems like this link is not yet supported, try analyzing another one.', linkNotSupportedYet: 'Seems like this link is not yet supported, try analyzing another one.',
table: { table: {
@ -146,7 +148,8 @@ const en = {
}, },
search: { search: {
startSearching: 'Start searching!', startSearching: 'Start searching!',
description: 'You can search a track, a whole album, an artist, a playlist.... everything! You can also paste a Deezer link', description:
'You can search a track, a whole album, an artist, a playlist.... everything! You can also paste a Deezer link',
fans: '{n} fans', fans: '{n} fans',
noResults: 'No results', noResults: 'No results',
noResultsTrack: 'No Tracks found', noResultsTrack: 'No Tracks found',

View File

@ -4,6 +4,7 @@ const it = {
back: 'indietro', back: 'indietro',
loading: 'caricamento', loading: 'caricamento',
download: 'Scarica {thing}', download: 'Scarica {thing}',
downloadAll: 'Scarica ogni {thing}',
by: 'di {artist}', by: 'di {artist}',
in: 'in {album}', in: 'in {album}',
download_hint: 'Scarica', download_hint: 'Scarica',
@ -108,8 +109,8 @@ const it = {
no360RA: 'Brano non disponibile in Reality Audio 360.', no360RA: 'Brano non disponibile in Reality Audio 360.',
notAvailable: 'Brano non presente sui server di Deezer!', notAvailable: 'Brano non presente sui server di Deezer!',
notAvailableNoAlternative: 'Brano non presente sui server di Deezer e nessuna alternativa trovata!', notAvailableNoAlternative: 'Brano non presente sui server di Deezer e nessuna alternativa trovata!',
noSpaceLeft: "Spazio su disco esaurito!", noSpaceLeft: 'Spazio su disco esaurito!',
albumDoesntExists: "Il brano non ha nessun album, impossibile ottenere informazioni" albumDoesntExists: 'Il brano non ha nessun album, impossibile ottenere informazioni'
} }
}, },
favorites: { favorites: {
@ -244,7 +245,7 @@ const it = {
n: 'No, non sovrascrivere i file', n: 'No, non sovrascrivere i file',
t: 'Sovrascrivi solo i tag', t: 'Sovrascrivi solo i tag',
b: 'No, mantieni entrambi i file e aggiungi un numero al duplicato', b: 'No, mantieni entrambi i file e aggiungi un numero al duplicato',
e: "No, e non tener conto della estensione del file" e: 'No, e non tener conto della estensione del file'
}, },
fallbackBitrate: 'Utilizza bitrate più bassi se il bitrate preferito non è disponibile', fallbackBitrate: 'Utilizza bitrate più bassi se il bitrate preferito non è disponibile',
fallbackSearch: 'Cerca il brano se il link originale non è disponibile', fallbackSearch: 'Cerca il brano se il link originale non è disponibile',
@ -272,7 +273,8 @@ const it = {
jpegImageQuality: 'Qualità immagine JPEG', jpegImageQuality: 'Qualità immagine JPEG',
embeddedArtworkPNG: 'Salva copertina incorporata come PNG', embeddedArtworkPNG: 'Salva copertina incorporata come PNG',
embeddedPNGWarning: 'Le immagini PNG non sono usate ufficialmente da Deezer e potrebbero dare problemi', embeddedPNGWarning: 'Le immagini PNG non sono usate ufficialmente da Deezer e potrebbero dare problemi',
imageSizeWarning: 'Dimensioni maggiori di x1200 non sono usate ufficialmente da Deezer, potresti incontrare problemi', imageSizeWarning:
'Dimensioni maggiori di x1200 non sono usate ufficialmente da Deezer, potresti incontrare problemi',
coverDescriptionUTF8: 'Salva la descrizione della copertina in UTF8 (iTunes Cover Fix)' coverDescriptionUTF8: 'Salva la descrizione della copertina in UTF8 (iTunes Cover Fix)'
}, },
tags: { tags: {

View File

@ -1,10 +1,3 @@
// .search_tabcontent
// .main_tabcontent,
// .favorites_tabcontent
// {
// display: none;
// }
.main_tabcontent { .main_tabcontent {
h1 { h1 {
margin-bottom: 12px; margin-bottom: 12px;

View File

@ -1,11 +1,21 @@
import { socket } from '@/utils/socket' import { socket } from '@/utils/socket'
export function sendAddToQueue(url, bitrate = null) { export function sendAddToQueue(url, bitrate = null) {
if (!url) return if (!url) throw new Error('No URL given to sendAddToQueue function!')
socket.emit('addToQueue', { url, bitrate }, () => {}) socket.emit('addToQueue', { url, bitrate }, () => {})
} }
export function aggregateDownloadLinks(releases) {
let links = []
releases.forEach(release => {
links.push(release.link)
})
return links.join(';')
}
export default { export default {
sendAddToQueue sendAddToQueue
} }