fix: song controls disappear during filtering (#1864)

This commit is contained in:
Phan An 2024-10-28 15:19:32 +07:00 committed by GitHub
parent 167494ce6d
commit 63f2dc5241
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 32 additions and 17 deletions

View file

@ -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?.()
})
}

View file

@ -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: {},

View file

@ -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

View file

@ -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],

View file

@ -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, [{}])

View file

@ -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))],
},
},

View file

@ -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>>()

View file

@ -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)

View file

@ -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')