style: added new release style; refactor: Artist page with composition API (to finish); refactor: extracted new release check logic
This commit is contained in:
parent
d04439857a
commit
ced8650ee6
File diff suppressed because one or more lines are too long
@ -17,7 +17,7 @@
|
||||
<li
|
||||
v-for="(item, name) in artistReleases"
|
||||
:key="name"
|
||||
class="section-tabs__tab"
|
||||
class="section-tabs__tab uppercase-first-letter"
|
||||
@click="changeTab(name)"
|
||||
:class="{ active: currentTab === name }"
|
||||
>
|
||||
@ -33,6 +33,7 @@
|
||||
:key="data.title"
|
||||
@click="data.sortKey ? sortBy(data.sortKey) : null"
|
||||
:style="{ width: data.width ? data.width : 'auto' }"
|
||||
class="uppercase-first-letter"
|
||||
:class="{
|
||||
'sort-asc': data.sortKey == sortKey && sortOrder == 'asc',
|
||||
'sort-desc': data.sortKey == sortKey && sortOrder == 'desc',
|
||||
@ -46,8 +47,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="release in showTable">
|
||||
<router-link
|
||||
<tr v-for="release in sortedData" :key="release.releaseID">
|
||||
<RouterLink
|
||||
tag="td"
|
||||
class="flex items-center clickable"
|
||||
:to="{ name: 'Album', params: { id: release.releaseID } }"
|
||||
@ -57,12 +58,17 @@
|
||||
:src="release.releaseCover"
|
||||
style="margin-right: 16px; width: 56px; height: 56px"
|
||||
/>
|
||||
<i v-if="release.isReleaseExplicit" class="material-icons explicit-icon">explicit</i>
|
||||
<i v-if="release.isReleaseExplicit" class="material-icons title-icon title-icon--explicit">explicit</i>
|
||||
{{ release.releaseTitle }}
|
||||
<i v-if="checkNewRelease(release.releaseDate)" class="material-icons" style="color: #ff7300">fiber_new</i>
|
||||
</router-link>
|
||||
<td>{{ release.releaseDate }}</td>
|
||||
<td>{{ release.releaseTracksNumber }}</td>
|
||||
<i
|
||||
v-if="checkNewRelease(release.releaseDate)"
|
||||
class="material-icons title-icon title-icon--new title-icon--right"
|
||||
>
|
||||
fiber_new
|
||||
</i>
|
||||
</RouterLink>
|
||||
<td class="text-center">{{ release.releaseDate }}</td>
|
||||
<td class="text-center">{{ release.releaseTracksNumber }}</td>
|
||||
<td @click.stop="sendAddToQueue(release.releaseLink)" class="clickable">
|
||||
<i class="material-icons" :title="$t('globals.download_hint')"> file_download </i>
|
||||
</td>
|
||||
@ -73,80 +79,75 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, unref, reactive, computed, onMounted, toRefs } from '@vue/composition-api'
|
||||
import { orderBy } from 'lodash-es'
|
||||
|
||||
import { socket } from '@/utils/socket'
|
||||
import { sendAddToQueue } from '@/utils/downloads'
|
||||
import EventBus from '@/utils/EventBus'
|
||||
import { formatArtistData } from '@/data/artist'
|
||||
import { checkNewRelease } from '@/utils/dates'
|
||||
import { formatArtistData, getArtistData } from '@/data/artist'
|
||||
import { standardizeData } from '@/data/standardize'
|
||||
import { ref, reactive, computed, onMounted, toRefs, onDeactivated } from '@vue/composition-api'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
export default defineComponent({
|
||||
setup(props, ctx) {
|
||||
const state = reactive({
|
||||
currentTab: '',
|
||||
sortKey: 'releaseDate',
|
||||
sortOrder: 'desc',
|
||||
artistReleases: {},
|
||||
artistID: '',
|
||||
artistName: '',
|
||||
artistPicture: ''
|
||||
artistPicture: '',
|
||||
currentRelease: computed(() => state.artistReleases[state.currentTab])
|
||||
})
|
||||
|
||||
const currentRelease = computed(() => state.artistReleases[state.currentTab])
|
||||
const artistID = computed(() => ctx.root.$router.currentRoute.params.id)
|
||||
const hasDataLoaded = ref(false)
|
||||
|
||||
getArtistData(unref(artistID))
|
||||
.then(artistData => {
|
||||
hasDataLoaded.value = true
|
||||
|
||||
const setupData = data => {
|
||||
const {
|
||||
data: [{ artistID, artistName, artistPictureXL, artistReleases }]
|
||||
} = standardizeData({ data: [data], hasLoaded: true }, formatArtistData)
|
||||
data: [{ artistName, artistPictureXL, artistReleases }]
|
||||
} = standardizeData({ data: [artistData], hasLoaded: unref(hasDataLoaded) }, formatArtistData)
|
||||
|
||||
Object.assign(state, {
|
||||
artistID,
|
||||
artistName,
|
||||
artistPicture: artistPictureXL,
|
||||
artistReleases
|
||||
artistReleases,
|
||||
currentTab: Object.keys(artistReleases)[0]
|
||||
})
|
||||
})
|
||||
.catch(err => console.error(err))
|
||||
|
||||
// ? Is it not granted that it's always 'all' ?
|
||||
state.currentTab = Object.keys(artistReleases)[0]
|
||||
const sortedData = computed(() => {
|
||||
if (!unref(hasDataLoaded)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
state.currentTab = ''
|
||||
state.sortKey = 'releaseDate'
|
||||
state.sortOrder = 'desc'
|
||||
}
|
||||
|
||||
onDeactivated(reset)
|
||||
|
||||
onMounted(() => {
|
||||
socket.on('show_artist', setupData)
|
||||
})
|
||||
|
||||
const showTable = computed(() => {
|
||||
if (Object.keys(state.artistReleases).length !== 0) {
|
||||
let sortKey = state.sortKey
|
||||
|
||||
if (sortKey == 'releaseTracksNumber') {
|
||||
if (sortKey === 'releaseTracksNumber') {
|
||||
sortKey = o => new Number(o.releaseTracksNumber)
|
||||
}
|
||||
|
||||
return orderBy(currentRelease.value, sortKey, state.sortOrder)
|
||||
}
|
||||
|
||||
return []
|
||||
return orderBy(state.currentRelease, sortKey, state.sortOrder)
|
||||
})
|
||||
|
||||
const changeTab = newTab => {
|
||||
state.currentTab = newTab
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
downloadLink: computed(() => `https://www.deezer.com/artist/${state.artistID}`),
|
||||
downloadLink: computed(() => `https://www.deezer.com/artist/${unref(artistID)}`),
|
||||
headerStyle: computed(() => ({
|
||||
backgroundImage: `linear-gradient(to bottom, transparent 0%, var(--main-background) 100%), url(${state.artistPicture})`
|
||||
})),
|
||||
showTable,
|
||||
sortedData,
|
||||
sendAddToQueue,
|
||||
currentRelease
|
||||
checkNewRelease,
|
||||
changeTab
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -170,19 +171,8 @@ export default {
|
||||
this.sortKey = key
|
||||
this.sortOrder = 'asc'
|
||||
}
|
||||
},
|
||||
changeTab(tab) {
|
||||
this.currentTab = tab
|
||||
},
|
||||
checkNewRelease(date) {
|
||||
let g1 = new Date()
|
||||
let g2 = new Date(date)
|
||||
g2.setDate(g2.getDate() + 3)
|
||||
g1.setHours(0, 0, 0, 0)
|
||||
|
||||
return g1.getTime() <= g2.getTime()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
}"
|
||||
>
|
||||
<h1 class="flex items-center m-0 text-5xl">
|
||||
{{ title }} <i v-if="explicit" class="material-icons explicit-icon explicit-icon--right">explicit</i>
|
||||
{{ title }} <i v-if="explicit" class="material-icons title-icon title-icon--right">explicit</i>
|
||||
</h1>
|
||||
|
||||
<h2 class="m-0 mb-3 text-lg">
|
||||
@ -60,7 +60,7 @@
|
||||
</td>
|
||||
<td class="table__cell--large table__cell--with-icon">
|
||||
<div class="table__cell-content table__cell-content--vertical-center">
|
||||
<i v-if="track.explicit_lyrics" class="material-icons explicit-icon"> explicit </i>
|
||||
<i v-if="track.explicit_lyrics" class="material-icons title-icon"> explicit </i>
|
||||
{{
|
||||
track.title +
|
||||
(track.title_version && track.title.indexOf(track.title_version) == -1
|
||||
@ -127,7 +127,7 @@
|
||||
</td>
|
||||
<td>{{ i + 1 }}</td>
|
||||
<td class="flex items-center">
|
||||
<i v-if="track.explicit" class="material-icons explicit-icon">explicit</i>
|
||||
<i v-if="track.explicit" class="material-icons title-icon">explicit</i>
|
||||
{{ track.name }}
|
||||
</td>
|
||||
<td>{{ track.artists[0].name }}</td>
|
||||
|
@ -20,7 +20,7 @@
|
||||
<span class="primary-text">
|
||||
<i
|
||||
v-if="release.isAlbumExplicit"
|
||||
class="material-icons explicit-icon"
|
||||
class="material-icons title-icon"
|
||||
style="font-size: 1.0625rem !important"
|
||||
>
|
||||
explicit
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
<td class="table__cell table__cell--large">
|
||||
<div class="break-words table__cell-content table__cell-content--vertical-center">
|
||||
<i v-if="track.isTrackExplicit" class="material-icons explicit-icon">explicit</i>
|
||||
<i v-if="track.isTrackExplicit" class="material-icons title-icon">explicit</i>
|
||||
{{ formatTitle(track) }}
|
||||
</div>
|
||||
</td>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { socket } from '@/utils/socket'
|
||||
import { getPropertyWithFallback } from '@/utils/utils'
|
||||
|
||||
export function formatArtistData(artistData) {
|
||||
return {
|
||||
artistID: getPropertyWithFallback(artistData, 'id'),
|
||||
artistName: getPropertyWithFallback(artistData, 'name'),
|
||||
artistPictureXL: getPropertyWithFallback(artistData, 'picture_xl'),
|
||||
artistReleases: formatArtistReleases(getPropertyWithFallback(artistData, 'releases'))
|
||||
@ -33,3 +33,27 @@ function formatArtistReleases(artistReleases) {
|
||||
|
||||
return formattedReleases
|
||||
}
|
||||
|
||||
let artistData = {}
|
||||
let cached = false
|
||||
|
||||
export function getArtistData(artistID) {
|
||||
if (cached) {
|
||||
return artistData
|
||||
} else {
|
||||
socket.emit('getTracklist', {
|
||||
type: 'artist',
|
||||
id: artistID
|
||||
})
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
socket.on('show_artist', data => {
|
||||
artistData = data
|
||||
// cached = true
|
||||
|
||||
socket.off('show_artist')
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,10 @@ const routes = [
|
||||
{
|
||||
path: '/artist/:id',
|
||||
name: 'Artist',
|
||||
component: Artist
|
||||
component: Artist,
|
||||
meta: {
|
||||
notKeepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/album/:id',
|
||||
@ -123,12 +126,6 @@ router.beforeEach((to, from, next) => {
|
||||
let getTracklistParams = null
|
||||
|
||||
switch (to.name) {
|
||||
case 'Artist':
|
||||
getTracklistParams = {
|
||||
type: 'artist',
|
||||
id: to.params.id
|
||||
}
|
||||
break
|
||||
case 'Tracklist':
|
||||
getTracklistParams = {
|
||||
type: to.params.type,
|
||||
|
15
src/styles/vendor/material-icons.css
vendored
15
src/styles/vendor/material-icons.css
vendored
@ -26,15 +26,22 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.material-icons.explicit-icon {
|
||||
.material-icons.title-icon {
|
||||
margin-right: 0.3125em;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.material-icons.title-icon.title-icon--right {
|
||||
margin-right: 0px;
|
||||
margin-left: 0.3125em;
|
||||
}
|
||||
|
||||
.material-icons.title-icon.title-icon--explicit {
|
||||
color: hsl(240, 5%, 59%);
|
||||
}
|
||||
|
||||
.material-icons.explicit-icon.explicit-icon--right {
|
||||
margin-right: 0px;
|
||||
margin-left: 0.3125em;
|
||||
.material-icons.title-icon.title-icon--new {
|
||||
color: hsl(27, 100%, 50%);
|
||||
}
|
||||
|
||||
.material-icons.disabled {
|
||||
|
14
src/utils/dates.js
Normal file
14
src/utils/dates.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @param {Date} dateToCheck
|
||||
* @returns {boolean} The passed date is less than 3 days distant from today,
|
||||
* therefore it's considered a new release, if referring to a track or album
|
||||
*/
|
||||
export function checkNewRelease(dateToCheck) {
|
||||
let now = new Date()
|
||||
now.setHours(0, 0, 0, 0)
|
||||
|
||||
dateToCheck = new Date(dateToCheck)
|
||||
dateToCheck.setDate(dateToCheck.getDate() + 3)
|
||||
|
||||
return now.getTime() <= dateToCheck.getTime()
|
||||
}
|
Loading…
Reference in New Issue
Block a user