mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
fix: buggy Spotify integration (#1731)
This fixes a bug with Spotify integration that occurs if an installation isn't connected to Last.fm. Closing #1730 and #1653.
This commit is contained in:
parent
07f3554fe1
commit
abb0438c8d
9 changed files with 141 additions and 21 deletions
|
@ -12,6 +12,7 @@ use App\Repositories\SongRepository;
|
|||
use App\Services\ApplicationInformationService;
|
||||
use App\Services\ITunesService;
|
||||
use App\Services\LastfmService;
|
||||
use App\Services\SpotifyService;
|
||||
use App\Services\YouTubeService;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
|
||||
|
@ -35,6 +36,7 @@ class DataController extends Controller
|
|||
'playlist_folders' => PlaylistFolderResource::collection($this->user->playlist_folders),
|
||||
'current_user' => UserResource::make($this->user, true),
|
||||
'use_last_fm' => LastfmService::used(),
|
||||
'use_spotify' => SpotifyService::enabled(),
|
||||
'use_you_tube' => YouTubeService::enabled(),
|
||||
'use_i_tunes' => $this->iTunesService->used(),
|
||||
'allow_download' => config('koel.download.allow'),
|
||||
|
|
|
@ -39,6 +39,7 @@ import { mediaInfoService, playbackService } from '@/services'
|
|||
import { useRouter, useThirdPartyServices } from '@/composables'
|
||||
|
||||
import AlbumThumbnail from '@/components/ui/AlbumArtistThumbnail.vue'
|
||||
import { defaultCover } from '@/utils'
|
||||
|
||||
const TrackList = defineAsyncComponent(() => import('@/components/album/AlbumTrackList.vue'))
|
||||
|
||||
|
@ -46,7 +47,7 @@ const props = withDefaults(defineProps<{ album: Album, mode?: MediaInfoDisplayMo
|
|||
const { album, mode } = toRefs(props)
|
||||
|
||||
const { go } = useRouter()
|
||||
const { useLastfm } = useThirdPartyServices()
|
||||
const { useLastfm, useSpotify } = useThirdPartyServices()
|
||||
|
||||
const info = ref<AlbumInfo | null>(null)
|
||||
const showingFullWiki = ref(false)
|
||||
|
@ -54,7 +55,10 @@ const showingFullWiki = ref(false)
|
|||
watch(album, async () => {
|
||||
showingFullWiki.value = false
|
||||
info.value = null
|
||||
useLastfm.value && (info.value = await mediaInfoService.fetchForAlbum(album.value))
|
||||
|
||||
if (useLastfm.value || useSpotify.value) {
|
||||
info.value = await mediaInfoService.fetchForAlbum(album.value)
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const showSummary = computed(() => mode.value !== 'full' && !showingFullWiki.value)
|
||||
|
|
|
@ -42,7 +42,7 @@ const props = withDefaults(defineProps<{ artist: Artist, mode?: MediaInfoDisplay
|
|||
const { artist, mode } = toRefs(props)
|
||||
|
||||
const { go } = useRouter()
|
||||
const { useLastfm } = useThirdPartyServices()
|
||||
const { useLastfm, useSpotify } = useThirdPartyServices()
|
||||
|
||||
const info = ref<ArtistInfo | null>(null)
|
||||
const showingFullBio = ref(false)
|
||||
|
@ -50,7 +50,10 @@ const showingFullBio = ref(false)
|
|||
watch(artist, async () => {
|
||||
showingFullBio.value = false
|
||||
info.value = null
|
||||
useLastfm.value && (info.value = await mediaInfoService.fetchForArtist(artist.value))
|
||||
|
||||
if (useLastfm.value || useSpotify.value) {
|
||||
info.value = await mediaInfoService.fetchForArtist(artist.value)
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const showSummary = computed(() => mode.value !== 'full' && !showingFullBio.value)
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<template>
|
||||
<section class="text-secondary">
|
||||
<h1>Last.fm Integration</h1>
|
||||
<h1>
|
||||
<span class="lastfm-icon">
|
||||
<Icon :icon="faLastfm" />
|
||||
</span>
|
||||
Last.fm Integration
|
||||
</h1>
|
||||
|
||||
<div v-if="useLastfm" data-testid="lastfm-integrated">
|
||||
<p>
|
||||
This installation of Koel integrates with Last.fm.
|
||||
<span v-if="connected">
|
||||
It appears that you have connected your Last.fm account as well – Perfect!
|
||||
</span>
|
||||
<span v-else>It appears that you haven’t connected to your Last.fm account though.</span>
|
||||
<p>Last.fm integration is enabled. Koel will attempt to retrieve album and artist information from Last.fm.</p>
|
||||
<p v-if="connected">
|
||||
It appears that you have connected your Last.fm account as well – Perfect!
|
||||
</p>
|
||||
<p v-else>You can also connect your Last.fm account here.</p>
|
||||
<p>
|
||||
Connecting Koel and your Last.fm account enables such exciting features as
|
||||
<a
|
||||
|
@ -21,7 +24,6 @@
|
|||
</p>
|
||||
<div class="buttons">
|
||||
<Btn class="connect" @click.prevent="connect">
|
||||
<Icon :icon="faLastfm" />
|
||||
{{ connected ? 'Reconnect' : 'Connect' }}
|
||||
</Btn>
|
||||
|
||||
|
@ -31,7 +33,7 @@
|
|||
|
||||
<div v-else data-testid="lastfm-not-integrated">
|
||||
<p>
|
||||
This installation of Koel has no Last.fm integration.
|
||||
Last.fm integration is not enabled on this installation of Koel.
|
||||
<span v-if="isAdmin" data-testid="lastfm-admin-instruction">
|
||||
Visit
|
||||
<a href="https://docs.koel.dev/3rd-party.html#last-fm" class="text-highlight" target="_blank">Koel’s Wiki</a>
|
||||
|
@ -77,6 +79,11 @@ const disconnect = async () => {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.lastfm-icon {
|
||||
color: #d31f27; // Last.fm red
|
||||
margin-right: .4rem;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-top: 1.25rem;
|
||||
|
||||
|
@ -85,7 +92,7 @@ const disconnect = async () => {
|
|||
}
|
||||
|
||||
.connect {
|
||||
background: #d31f27; // Last.fm color yo!
|
||||
background: #d31f27;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import { expect, it } from 'vitest'
|
||||
import UnitTestCase from '@/__tests__/UnitTestCase'
|
||||
import { commonStore } from '@/stores'
|
||||
import SpotifyIntegration from './SpotifyIntegration.vue'
|
||||
|
||||
new class extends UnitTestCase {
|
||||
protected test () {
|
||||
it.each<[boolean, boolean]>([[false, false], [false, true], [true, false], [true, true]])
|
||||
('renders proper content with Spotify integration status %s, current user admin status %s',
|
||||
(useSpotify, isAdmin) => {
|
||||
commonStore.state.use_spotify = useSpotify
|
||||
|
||||
if (isAdmin) {
|
||||
this.actingAsAdmin()
|
||||
} else {
|
||||
this.actingAs()
|
||||
}
|
||||
|
||||
expect(this.render(SpotifyIntegration).html()).toMatchSnapshot();
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<section class="text-secondary">
|
||||
<h1>
|
||||
<span class="spotify-icon">
|
||||
<Icon :icon="faSpotify" />
|
||||
</span>
|
||||
Spotify Integration
|
||||
</h1>
|
||||
|
||||
<div v-if="useSpotify">
|
||||
<p>
|
||||
Spotify integration is enabled.
|
||||
Koel will attempt to retrieve album arts and artist images from Spotify when a song is played, if needed.
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>
|
||||
Spotify integration is not enabled.
|
||||
<span v-if="isAdmin" data-testid="spotify-admin-instruction">
|
||||
Visit
|
||||
<a href="https://docs.koel.dev/3rd-party.html#spotify" class="text-highlight" target="_blank">Koel’s Wiki</a>
|
||||
for a quick how-to.
|
||||
</span>
|
||||
<span v-else data-testid="spotify-user-instruction">
|
||||
Try politely asking an administrator to enable it.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faSpotify } from '@fortawesome/free-brands-svg-icons'
|
||||
import { useAuthorization, useThirdPartyServices } from '@/composables';
|
||||
|
||||
const { currentUser, isAdmin } = useAuthorization();
|
||||
const { useSpotify } = useThirdPartyServices();
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.spotify-icon {
|
||||
margin-right: .4rem;
|
||||
color: #1db954; // Spotify green
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,37 @@
|
|||
// Vitest Snapshot v1
|
||||
|
||||
exports[`renders proper content with Spotify integration status false, current user admin status false 1`] = `
|
||||
<section data-v-49dda1f9="" class="text-secondary">
|
||||
<h1 data-v-49dda1f9=""><span data-v-49dda1f9="" class="spotify-icon"><br data-v-49dda1f9="" data-testid="Icon" icon="[object Object]"></span> Spotify Integration </h1>
|
||||
<div data-v-49dda1f9="">
|
||||
<p data-v-49dda1f9=""> Spotify integration is not enabled. <span data-v-49dda1f9="" data-testid="spotify-user-instruction"> Try politely asking an administrator to enable it. </span></p>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`renders proper content with Spotify integration status false, current user admin status true 1`] = `
|
||||
<section data-v-49dda1f9="" class="text-secondary">
|
||||
<h1 data-v-49dda1f9=""><span data-v-49dda1f9="" class="spotify-icon"><br data-v-49dda1f9="" data-testid="Icon" icon="[object Object]"></span> Spotify Integration </h1>
|
||||
<div data-v-49dda1f9="">
|
||||
<p data-v-49dda1f9=""> Spotify integration is not enabled. <span data-v-49dda1f9="" data-testid="spotify-admin-instruction"> Visit <a data-v-49dda1f9="" href="https://docs.koel.dev/3rd-party.html#spotify" class="text-highlight" target="_blank">Koel’s Wiki</a> for a quick how-to. </span></p>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`renders proper content with Spotify integration status true, current user admin status false 1`] = `
|
||||
<section data-v-49dda1f9="" class="text-secondary">
|
||||
<h1 data-v-49dda1f9=""><span data-v-49dda1f9="" class="spotify-icon"><br data-v-49dda1f9="" data-testid="Icon" icon="[object Object]"></span> Spotify Integration </h1>
|
||||
<div data-v-49dda1f9="">
|
||||
<p data-v-49dda1f9=""> Spotify integration is enabled. Koel will attempt to retrieve album arts and artist images from Spotify when a song is played, if needed. </p>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`renders proper content with Spotify integration status true, current user admin status true 1`] = `
|
||||
<section data-v-49dda1f9="" class="text-secondary">
|
||||
<h1 data-v-49dda1f9=""><span data-v-49dda1f9="" class="spotify-icon"><br data-v-49dda1f9="" data-testid="Icon" icon="[object Object]"></span> Spotify Integration </h1>
|
||||
<div data-v-49dda1f9="">
|
||||
<p data-v-49dda1f9=""> Spotify integration is enabled. Koel will attempt to retrieve album arts and artist images from Spotify when a song is played, if needed. </p>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
|
@ -6,6 +6,7 @@
|
|||
<ProfileForm />
|
||||
<ThemeList />
|
||||
<PreferencesForm />
|
||||
<SpotifyIntegration />
|
||||
<LastfmIntegration />
|
||||
</div>
|
||||
</section>
|
||||
|
@ -14,6 +15,7 @@
|
|||
<script lang="ts" setup>
|
||||
import ScreenHeader from '@/components/ui/ScreenHeader.vue'
|
||||
import ProfileForm from '@/components/profile-preferences/ProfileForm.vue'
|
||||
import SpotifyIntegration from '@/components/profile-preferences/SpotifyIntegration.vue'
|
||||
import LastfmIntegration from '@/components/profile-preferences/LastfmIntegration.vue'
|
||||
import PreferencesForm from '@/components/profile-preferences/PreferencesForm.vue'
|
||||
import ThemeList from '@/components/profile-preferences/ThemeList.vue'
|
||||
|
|
|
@ -2,13 +2,10 @@ import { toRef } from 'vue'
|
|||
import { commonStore } from '@/stores'
|
||||
|
||||
export const useThirdPartyServices = () => {
|
||||
const useLastfm = toRef(commonStore.state, 'use_last_fm')
|
||||
const useYouTube = toRef(commonStore.state, 'use_you_tube')
|
||||
const useAppleMusic = toRef(commonStore.state, 'use_i_tunes')
|
||||
|
||||
return {
|
||||
useLastfm,
|
||||
useYouTube,
|
||||
useAppleMusic
|
||||
useLastfm: toRef(commonStore.state, 'use_last_fm'),
|
||||
useYouTube: toRef(commonStore.state, 'use_you_tube'),
|
||||
useAppleMusic: toRef(commonStore.state, 'use_i_tunes'),
|
||||
useSpotify: toRef(commonStore.state, 'use_spotify')
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue