feat: decouple YouTube from Song

This commit is contained in:
Phan An 2022-07-08 01:15:38 +02:00
parent 1e6358fd11
commit 2b09e1e855
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
9 changed files with 26 additions and 37 deletions

View file

@ -11,12 +11,7 @@ let song: Song
new class extends UnitTestCase {
private renderComponent () {
song = factory<Song>('song', {
youtube: {
items: factory<YouTubeVideo>('video', 5),
nextPageToken: 'f00'
}
})
song = factory<Song>('song')
return this.render(YouTubeVideoList, {
props: {
@ -37,7 +32,7 @@ new class extends UnitTestCase {
})
it('loads more videos', async () => {
const mock = this.mock(youTubeService, 'searchVideosRelatedToSong').mockResolvedValue({
const mock = this.mock(youTubeService, 'searchVideosBySong').mockResolvedValue({
nextPageToken: 'b4r',
items: factory<YouTubeVideo>('video', 5)
})

View file

@ -14,7 +14,7 @@
</template>
<script lang="ts" setup>
import { defineAsyncComponent, ref, toRefs, watchEffect } from 'vue'
import { defineAsyncComponent, ref, toRefs, watch } from 'vue'
import { youTubeService } from '@/services'
const Btn = defineAsyncComponent(() => import('@/components/ui/Btn.vue'))
@ -26,17 +26,15 @@ const { song } = toRefs(props)
const loading = ref(false)
const videos = ref<YouTubeVideo[]>([])
let nextPageToken = ''
const loadMore = async () => {
loading.value = true
try {
song.value.youtube = song.value.youtube || { nextPageToken: '', items: [] }
const result = await youTubeService.searchVideosRelatedToSong(song.value, song.value.youtube.nextPageToken!)
song.value.youtube.nextPageToken = result.nextPageToken
song.value.youtube.items.push(...result.items as YouTubeVideo[])
videos.value = song.value.youtube.items
const result = await youTubeService.searchVideosBySong(song.value, nextPageToken)
nextPageToken = result.nextPageToken
videos.value.push(...result.items)
} catch (err) {
console.error(err)
} finally {
@ -44,13 +42,11 @@ const loadMore = async () => {
}
}
watchEffect(() => {
videos.value = song.value.youtube?.items || []
if (videos.value.length === 0) {
loadMore()
}
})
watch(song, () => {
videos.value = []
nextPageToken = ''
loadMore()
}, { immediate: true })
</script>
<style lang="scss" scoped>

View file

@ -7,3 +7,4 @@ export * from './socketService'
export * from './audioService'
export * from './uploadService'
export * from './authService'
export * from './Cache'

View file

@ -1,4 +1,4 @@
import { httpService } from '@/services'
import { Cache, httpService } from '@/services'
import { eventBus } from '@/utils'
import router from '@/router'
@ -8,8 +8,13 @@ interface YouTubeSearchResult {
}
export const youTubeService = {
searchVideosRelatedToSong: async (song: Song, nextPageToken: string) => {
return await httpService.get<YouTubeSearchResult>(`youtube/search/song/${song.id}?pageToken=${nextPageToken}`)
searchVideosBySong: async (song: Song, nextPageToken: string) => {
return await Cache.resolve<YouTubeSearchResult>(
['youtube.search', song.id, nextPageToken],
async () => await httpService.get<YouTubeSearchResult>(
`youtube/search/song/${song.id}?pageToken=${nextPageToken}`
)
)
},
play: (video: YouTubeVideo): void => {

View file

@ -1,9 +1,8 @@
import { reactive } from 'vue'
import { difference, orderBy, take, union } from 'lodash'
import { httpService } from '@/services'
import { Cache, httpService } from '@/services'
import { arrayify } from '@/utils'
import { songStore } from '@/stores'
import { Cache } from '@/services/cache'
const UNKNOWN_ALBUM_ID = 1

View file

@ -1,8 +1,7 @@
import { reactive } from 'vue'
import { difference, orderBy, take, union } from 'lodash'
import { httpService } from '@/services'
import { Cache, httpService } from '@/services'
import { arrayify } from '@/utils'
import { Cache } from '@/services/cache'
const UNKNOWN_ARTIST_ID = 1
const VARIOUS_ARTISTS_ID = 2

View file

@ -1,10 +1,9 @@
import { difference, orderBy, union } from 'lodash'
import { reactive } from 'vue'
import { httpService } from '@/services'
import { Cache, httpService } from '@/services'
import models from '@/config/smart-playlist/models'
import operators from '@/config/smart-playlist/operators'
import { Cache } from '@/services/cache'
export const playlistStore = {
state: reactive({

View file

@ -3,9 +3,8 @@ import slugify from 'slugify'
import { orderBy, take, union } from 'lodash'
import { reactive, watch } from 'vue'
import { arrayify, eventBus, secondsToHis, use } from '@/utils'
import { authService, httpService } from '@/services'
import { authService, Cache, httpService } from '@/services'
import { albumStore, artistStore, commonStore, overviewStore, preferenceStore } from '@/stores'
import { Cache } from '@/services/cache'
interface BroadcastSongData {
song: {

View file

@ -185,10 +185,6 @@ interface Song {
track: number | null
disc: number | null
lyrics: string
youtube?: {
items: YouTubeVideo[]
nextPageToken: string
},
play_count_registered?: boolean
preloaded?: boolean
playback_state?: PlaybackState