2022-04-15 14:24:30 +00:00
|
|
|
|
<template>
|
|
|
|
|
<section id="homeWrapper">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<ScreenHeader>{{ greeting }}</ScreenHeader>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<div class="main-scroll-wrap" @scroll="scrolling">
|
2022-04-15 14:24:30 +00:00
|
|
|
|
<div class="two-cols">
|
|
|
|
|
<section v-if="top.songs.length">
|
|
|
|
|
<h1>Most Played</h1>
|
|
|
|
|
|
|
|
|
|
<ol class="top-song-list">
|
|
|
|
|
<li v-for="song in top.songs" :key="song.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<SongCard :song="song" :top-play-count="top.songs.length ? top.songs[0].playCount : 0"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section class="recent">
|
|
|
|
|
<h1>
|
|
|
|
|
Recently Played
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<Btn
|
2022-04-15 14:24:30 +00:00
|
|
|
|
data-testid="home-view-all-recently-played-btn"
|
|
|
|
|
@click.prevent="goToRecentlyPlayedScreen"
|
|
|
|
|
rounded
|
|
|
|
|
small
|
|
|
|
|
orange
|
|
|
|
|
>
|
|
|
|
|
View All
|
2022-04-15 17:00:08 +00:00
|
|
|
|
</Btn>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</h1>
|
|
|
|
|
|
2022-04-23 22:01:40 +00:00
|
|
|
|
<ol v-if="recentSongs.length" class="recent-song-list">
|
2022-04-15 14:24:30 +00:00
|
|
|
|
<li v-for="song in recentSongs" :key="song.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<SongCard :song="song" :top-play-count="top.songs.length ? top.songs[0].playCount : 0"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
|
2022-04-23 22:01:40 +00:00
|
|
|
|
<p v-show="!recentSongs.length" class="text-secondary">
|
2022-04-15 14:24:30 +00:00
|
|
|
|
Your recently played songs will be displayed here.<br/>
|
|
|
|
|
Start listening!
|
|
|
|
|
</p>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section v-if="showRecentlyAddedSection">
|
|
|
|
|
<h1>Recently Added</h1>
|
|
|
|
|
<div class="two-cols">
|
|
|
|
|
<ol class="recently-added-album-list">
|
|
|
|
|
<li v-for="album in recentlyAdded.albums" :key="album.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<AlbumCard :album="album" layout="compact"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
2022-04-23 22:01:40 +00:00
|
|
|
|
<ol v-show="recentlyAdded.songs.length" class="recently-added-song-list">
|
2022-04-15 14:24:30 +00:00
|
|
|
|
<li v-for="song in recentlyAdded.songs" :key="song.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<SongCard :song="song"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-if="top.artists.length">
|
|
|
|
|
<h1>Top Artists</h1>
|
|
|
|
|
<ol class="two-cols top-artist-list">
|
|
|
|
|
<li v-for="artist in top.artists" :key="artist.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<ArtistCard :artist="artist" layout="compact"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section v-if="top.albums.length">
|
|
|
|
|
<h1>Top Albums</h1>
|
|
|
|
|
<ol class="two-cols top-album-list">
|
|
|
|
|
<li v-for="album in top.albums" :key="album.id">
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<AlbumCard :album="album" layout="compact"/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</section>
|
|
|
|
|
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<ToTopButton/>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
</template>
|
|
|
|
|
|
2022-04-15 17:00:08 +00:00
|
|
|
|
<script lang="ts" setup>
|
2022-04-15 14:24:30 +00:00
|
|
|
|
import { sample } from 'lodash'
|
2022-04-21 23:06:12 +00:00
|
|
|
|
import { computed, defineAsyncComponent, reactive, ref } from 'vue'
|
2022-04-15 14:24:30 +00:00
|
|
|
|
|
|
|
|
|
import { eventBus } from '@/utils'
|
2022-04-23 22:01:40 +00:00
|
|
|
|
import { albumStore, artistStore, recentlyPlayedStore, songStore, userStore } from '@/stores'
|
2022-04-15 17:00:08 +00:00
|
|
|
|
import { useInfiniteScroll } from '@/composables'
|
2022-04-21 23:06:12 +00:00
|
|
|
|
import router from '@/router'
|
2022-04-15 17:00:08 +00:00
|
|
|
|
|
2022-04-21 16:06:45 +00:00
|
|
|
|
const ScreenHeader = defineAsyncComponent(() => import('@/components/ui/ScreenHeader.vue'))
|
2022-04-21 21:51:17 +00:00
|
|
|
|
const AlbumCard = defineAsyncComponent(() => import('@/components/album/AlbumCard.vue'))
|
|
|
|
|
const ArtistCard = defineAsyncComponent(() => import('@/components/artist/ArtistCard.vue'))
|
2022-04-23 22:15:08 +00:00
|
|
|
|
const SongCard = defineAsyncComponent(() => import('@/components/song/SongCard.vue'))
|
2022-04-21 18:39:18 +00:00
|
|
|
|
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
|
2022-04-15 17:00:08 +00:00
|
|
|
|
|
|
|
|
|
const { ToTopButton, scrolling } = useInfiniteScroll()
|
|
|
|
|
|
|
|
|
|
const greetings = [
|
|
|
|
|
'Oh hai!',
|
|
|
|
|
'Hey, %s!',
|
|
|
|
|
'Howdy, %s!',
|
|
|
|
|
'Yo!',
|
|
|
|
|
'How’s it going, %s?',
|
|
|
|
|
'Sup, %s?',
|
|
|
|
|
'How’s life, %s?',
|
|
|
|
|
'How’s your day, %s?',
|
|
|
|
|
'How have you been, %s?'
|
|
|
|
|
]
|
|
|
|
|
|
2022-05-15 15:25:02 +00:00
|
|
|
|
const greeting = ref('')
|
2022-04-15 17:00:08 +00:00
|
|
|
|
const recentSongs = ref<Song[]>([])
|
|
|
|
|
|
|
|
|
|
const top = reactive({
|
|
|
|
|
songs: [] as Song[],
|
|
|
|
|
albums: [] as Album[],
|
|
|
|
|
artists: [] as Artist[]
|
|
|
|
|
})
|
2022-04-15 14:24:30 +00:00
|
|
|
|
|
2022-04-15 17:00:08 +00:00
|
|
|
|
const recentlyAdded = reactive({
|
|
|
|
|
albums: [] as Album[],
|
|
|
|
|
songs: [] as Song[]
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const showRecentlyAddedSection = computed(() => Boolean(recentlyAdded.albums.length || recentlyAdded.songs.length))
|
|
|
|
|
|
|
|
|
|
const refreshDashboard = () => {
|
|
|
|
|
top.songs = songStore.getMostPlayed(7)
|
|
|
|
|
top.albums = albumStore.getMostPlayed(6)
|
|
|
|
|
top.artists = artistStore.getMostPlayed(6)
|
|
|
|
|
recentlyAdded.albums = albumStore.getRecentlyAdded(6)
|
|
|
|
|
recentlyAdded.songs = songStore.getRecentlyAdded(10)
|
|
|
|
|
recentSongs.value = recentlyPlayedStore.excerptState.songs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const goToRecentlyPlayedScreen = () => router.go('recently-played')
|
|
|
|
|
|
2022-04-23 22:01:40 +00:00
|
|
|
|
eventBus.on(['KOEL_READY', 'SONG_STARTED', 'SONG_UPLOADED'], () => refreshDashboard())
|
2022-05-15 15:25:02 +00:00
|
|
|
|
eventBus.on('KOEL_READY', () => (greeting.value = sample(greetings)!.replace('%s', userStore.current.name)))
|
2022-04-15 14:24:30 +00:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
#homeWrapper {
|
|
|
|
|
.two-cols {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
|
|
|
grid-gap: .7em 1em;
|
|
|
|
|
|
|
|
|
|
ol, li {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.recent {
|
|
|
|
|
h1 button {
|
|
|
|
|
float: right;
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
margin-top: -3px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ol {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-gap: .7em 1em;
|
|
|
|
|
align-content: start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.main-scroll-wrap {
|
|
|
|
|
section {
|
|
|
|
|
margin-bottom: 48px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
|
font-size: 1.4rem;
|
|
|
|
|
margin: 0 0 1.8rem;
|
|
|
|
|
font-weight: var(--font-weight-thin);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media only screen and (max-width: 768px) {
|
|
|
|
|
.two-cols {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|