mirror of
https://github.com/koel/koel
synced 2024-11-14 00:17:13 +00:00
fix: song controls disappear during filtering (#1864)
This commit is contained in:
parent
167494ce6d
commit
63f2dc5241
9 changed files with 32 additions and 17 deletions
|
@ -66,7 +66,7 @@ export default abstract class UnitTestCase {
|
|||
commonStore.state.uses_i_tunes = true
|
||||
commonStore.state.supports_batch_downloading = true
|
||||
commonStore.state.supports_transcoding = true
|
||||
cb && cb()
|
||||
cb?.()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ export default abstract class UnitTestCase {
|
|||
cleanup()
|
||||
this.restoreAllMocks()
|
||||
this.disablePlusEdition()
|
||||
cb && cb()
|
||||
cb?.()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ export default (faker: Faker): Podcast => {
|
|||
description: faker.lorem.paragraph(),
|
||||
author: faker.name.findName(),
|
||||
subscribed_at: faker.date.past().toISOString(),
|
||||
created_at: faker.date.past().toISOString(),
|
||||
last_played_at: faker.date.past().toISOString(),
|
||||
state: {
|
||||
current_episode: null,
|
||||
progresses: {},
|
||||
|
|
|
@ -194,6 +194,11 @@ watch(playlistId, async id => {
|
|||
// reset this config value to its default to not cause rows to be mal-rendered
|
||||
listConfig.collaborative = false
|
||||
|
||||
// Since this component is responsible for all playlists, reset these values
|
||||
// so that they're not shared between lists
|
||||
songs.value = []
|
||||
selectedPlayables.value = []
|
||||
|
||||
if (playlist.value) {
|
||||
await fetchDetails()
|
||||
listConfig.collaborative = playlist.value.is_collaborative
|
||||
|
|
|
@ -4,10 +4,10 @@ import UnitTestCase from '@/__tests__/UnitTestCase'
|
|||
import factory from '@/__tests__/factory'
|
||||
import { arrayify } from '@/utils/helpers'
|
||||
import {
|
||||
FilteredPlayablesKey,
|
||||
PlayableListConfigKey,
|
||||
PlayableListContextKey,
|
||||
PlayableListSortFieldKey,
|
||||
PlayablesKey,
|
||||
SelectedPlayablesKey,
|
||||
SongListSortOrderKey,
|
||||
} from '@/symbols'
|
||||
|
@ -54,7 +54,7 @@ new class extends UnitTestCase {
|
|||
SongListHeader: this.stub('song-list-header'),
|
||||
},
|
||||
provide: {
|
||||
[<symbol>PlayablesKey]: [ref(songs)],
|
||||
[<symbol>FilteredPlayablesKey]: [ref(songs)],
|
||||
[<symbol>SelectedPlayablesKey]: [ref(selectedPlayables), (value: Playable[]) => (selectedPlayables = value)],
|
||||
[<symbol>PlayableListConfigKey]: [config],
|
||||
[<symbol>PlayableListContextKey]: [context],
|
||||
|
|
|
@ -48,10 +48,10 @@ import { queueStore } from '@/stores/queueStore'
|
|||
import { useDraggable, useDroppable } from '@/composables/useDragAndDrop'
|
||||
import { playbackService } from '@/services/playbackService'
|
||||
import {
|
||||
FilteredPlayablesKey,
|
||||
PlayableListConfigKey,
|
||||
PlayableListContextKey,
|
||||
PlayableListSortFieldKey,
|
||||
PlayablesKey,
|
||||
SelectedPlayablesKey,
|
||||
} from '@/symbols'
|
||||
|
||||
|
@ -71,7 +71,7 @@ const emit = defineEmits<{
|
|||
const { startDragging } = useDraggable('playables')
|
||||
const { getDroppedData, acceptsDrop } = useDroppable(['playables'])
|
||||
|
||||
const [playables] = requireInjection<[Ref<Playable[]>]>(PlayablesKey)
|
||||
const [playables] = requireInjection<[Ref<Playable[]>]>(FilteredPlayablesKey)
|
||||
const [selectedPlayables, setSelectedPlayables] = requireInjection<[Ref<Playable[]>, Closure]>(SelectedPlayablesKey)
|
||||
const [sortField] = requireInjection<[Ref<MaybeArray<PlayableListSortField>>, Closure]>(PlayableListSortFieldKey)
|
||||
const [config] = requireInjection<[Partial<PlayableListConfig>]>(PlayableListConfigKey, [{}])
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ref } from 'vue'
|
|||
import { expect, it } from 'vitest'
|
||||
import UnitTestCase from '@/__tests__/UnitTestCase'
|
||||
import factory from '@/__tests__/factory'
|
||||
import { PlayablesKey, SelectedPlayablesKey } from '@/symbols'
|
||||
import { FilteredPlayablesKey, PlayablesKey, SelectedPlayablesKey } from '@/symbols'
|
||||
import SongListControls from './SongListControls.vue'
|
||||
|
||||
new class extends UnitTestCase {
|
||||
|
@ -79,6 +79,7 @@ new class extends UnitTestCase {
|
|||
global: {
|
||||
provide: {
|
||||
[<symbol>PlayablesKey]: [ref(songs)],
|
||||
[<symbol>FilteredPlayablesKey]: [ref(songs)],
|
||||
[<symbol>SelectedPlayablesKey]: [ref(take(songs, selectedSongCount))],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<BtnGroup uppercase>
|
||||
<template v-if="altPressed">
|
||||
<Btn
|
||||
v-if="selectedPlayables.length < 2 && playables.length"
|
||||
v-if="selectedPlayables.length < 2 && filteredPlayables.length"
|
||||
v-koel-tooltip.bottom
|
||||
class="btn-play-all"
|
||||
highlight
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
<template v-else>
|
||||
<Btn
|
||||
v-if="selectedPlayables.length < 2 && playables.length"
|
||||
v-if="selectedPlayables.length < 2 && filteredPlayables.length"
|
||||
v-koel-tooltip.bottom
|
||||
class="btn-shuffle-all"
|
||||
data-testid="btn-shuffle-all"
|
||||
|
@ -85,7 +85,7 @@
|
|||
</Btn>
|
||||
</BtnGroup>
|
||||
|
||||
<BtnGroup v-if="config.filter && playables.length">
|
||||
<BtnGroup v-if="config.filter && allPlayables.length">
|
||||
<SongListFilter @change="filter" />
|
||||
</BtnGroup>
|
||||
</div>
|
||||
|
@ -103,7 +103,7 @@ import { faPlay, faRandom, faRotateRight, faTrashCan } from '@fortawesome/free-s
|
|||
import type { Ref } from 'vue'
|
||||
import { computed, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, toRef, watch } from 'vue'
|
||||
import { OnClickOutside } from '@vueuse/components'
|
||||
import { PlayablesKey, SelectedPlayablesKey } from '@/symbols'
|
||||
import { FilteredPlayablesKey, PlayablesKey, SelectedPlayablesKey } from '@/symbols'
|
||||
import { requireInjection } from '@/utils/helpers'
|
||||
import { useFloatingUi } from '@/composables/useFloatingUi'
|
||||
|
||||
|
@ -123,7 +123,8 @@ const SongListFilter = defineAsyncComponent(() => import('@/components/song/song
|
|||
|
||||
const config = toRef(props, 'config')
|
||||
|
||||
const [playables] = requireInjection<[Ref<Playable[]>]>(PlayablesKey)
|
||||
const [allPlayables] = requireInjection<[Ref<Playable[]>]>(PlayablesKey)
|
||||
const [filteredPlayables] = requireInjection<[Ref<Playable[]>]>(FilteredPlayablesKey)
|
||||
const [selectedPlayables] = requireInjection(SelectedPlayablesKey)
|
||||
|
||||
const addToButton = ref<InstanceType<typeof Btn>>()
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useFuzzySearch } from '@/composables/useFuzzySearch'
|
|||
import { useRouter } from '@/composables/useRouter'
|
||||
|
||||
import {
|
||||
FilteredPlayablesKey,
|
||||
PlayableListConfigKey,
|
||||
PlayableListContextKey,
|
||||
PlayableListSortFieldKey,
|
||||
|
@ -40,7 +41,7 @@ export const useSongList = (
|
|||
config = reactive(config)
|
||||
context = reactive(context)
|
||||
|
||||
const { isCurrentScreen, go } = useRouter()
|
||||
const { isCurrentScreen, go, url } = useRouter()
|
||||
|
||||
const fuzzy = config.filterable
|
||||
? useFuzzySearch(playables, [
|
||||
|
@ -64,12 +65,15 @@ export const useSongList = (
|
|||
if (!config.sortable) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (isCurrentScreen('Artist', 'Album')) {
|
||||
return 'track'
|
||||
}
|
||||
|
||||
if (isCurrentScreen('Search.Songs', 'Queue', 'RecentlyPlayed')) {
|
||||
return null
|
||||
}
|
||||
|
||||
return 'title'
|
||||
})())
|
||||
|
||||
|
@ -108,9 +112,11 @@ export const useSongList = (
|
|||
if (!commonStore.state.allows_download) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (playables.value.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
return playables.value.length === 1 || commonStore.state.supports_batch_downloading
|
||||
})
|
||||
|
||||
|
@ -127,7 +133,7 @@ export const useSongList = (
|
|||
|
||||
const playAll = (shuffle: boolean) => {
|
||||
playbackService.queueAndPlay(getPlayablesToPlay(), shuffle)
|
||||
go('queue')
|
||||
go(url('queue'))
|
||||
}
|
||||
|
||||
const playSelected = (shuffle: boolean) => playbackService.queueAndPlay(selectedPlayables.value, shuffle)
|
||||
|
@ -185,7 +191,8 @@ export const useSongList = (
|
|||
|
||||
eventBus.on('SONGS_DELETED', deletedSongs => (playables.value = differenceBy(playables.value, deletedSongs, 'id')))
|
||||
|
||||
provideReadonly(PlayablesKey, filteredPlayables, false)
|
||||
provideReadonly(PlayablesKey, playables, false)
|
||||
provideReadonly(FilteredPlayablesKey, filteredPlayables, false)
|
||||
provideReadonly(SelectedPlayablesKey, selectedPlayables, false)
|
||||
provideReadonly(PlayableListConfigKey, config)
|
||||
provideReadonly(PlayableListContextKey, context)
|
||||
|
|
|
@ -11,7 +11,8 @@ export const OverlayKey: InjectionKey<Ref<InstanceType<typeof Overlay>>> = Symbo
|
|||
export const DialogBoxKey: InjectionKey<Ref<InstanceType<typeof DialogBox>>> = Symbol('DialogBox')
|
||||
export const MessageToasterKey: InjectionKey<Ref<InstanceType<typeof MessageToaster>>> = Symbol('MessageToaster')
|
||||
|
||||
export const PlayablesKey: ReadonlyInjectionKey<Ref<Playable[]>> | InjectionKey<Ref<Playable[]>> = Symbol('Playables')
|
||||
export const PlayablesKey: ReadonlyInjectionKey<Ref<Playable[]>> | InjectionKey<Ref<Playable[]>> = Symbol('PlayablesKey')
|
||||
export const FilteredPlayablesKey: ReadonlyInjectionKey<Ref<Playable[]>> | InjectionKey<Ref<Playable[]>> = Symbol('FilteredPlayablesKey')
|
||||
export const CurrentPlayableKey: InjectionKey<Ref<Playable | undefined>> = Symbol('CurrentPlayable')
|
||||
export const SelectedPlayablesKey: ReadonlyInjectionKey<Ref<Playable[]>> = Symbol('SelectedPlayables')
|
||||
export const PlayableListConfigKey: ReadonlyInjectionKey<Partial<PlayableListConfig>> = Symbol('SongListConfig')
|
||||
|
|
Loading…
Reference in a new issue