fix: shuffle all button disappear on phone (closes #1488)

This commit is contained in:
Phan An 2022-09-11 15:06:34 +07:00
parent fe606b4b8e
commit 95724de695
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
13 changed files with 33 additions and 191 deletions

View file

@ -4,7 +4,7 @@
<ScreenHeader v-if="!loading && album" :layout="songs.length === 0 ? 'collapsed' : headerLayout">
{{ album.name }}
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<AlbumThumbnail :entity="album"/>
@ -87,7 +87,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint
} = useSongList(songs, 'album', { columns: ['track', 'title', 'artist', 'length'] })

View file

@ -2,7 +2,7 @@
<section id="songsWrapper">
<ScreenHeader :layout="headerLayout">
All Songs
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -62,7 +62,6 @@ const {
isPhone,
onPressEnter,
playSelected,
toggleControls,
onScrollBreakpoint
} = useSongList(toRef(songStore.state, 'songs'), 'all-songs')

View file

@ -4,7 +4,7 @@
<ScreenHeader v-if="!loading && artist" :layout="songs.length === 0 ? 'collapsed' : headerLayout">
{{ artist.name }}
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ArtistThumbnail :entity="artist"/>
@ -84,7 +84,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint
} = useSongList(songs, 'artist', { columns: ['track', 'title', 'album', 'length'] })

View file

@ -2,7 +2,7 @@
<section id="favoritesWrapper">
<ScreenHeader :layout="songs.length === 0 ? 'collapsed' : headerLayout">
Songs You Love
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -86,7 +86,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint,
sort
} = useSongList(toRef(favoriteStore.state, 'songs'), 'favorites')

View file

@ -2,7 +2,7 @@
<section id="playlistWrapper" v-if="playlist">
<ScreenHeader :layout="songs.length === 0 ? 'collapsed' : headerLayout">
{{ playlist.name }}
<ControlsToggle v-if="songs.length" :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-if="songs.length" v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -98,7 +98,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint,
sort
} = useSongList(ref<Song[]>([]), 'playlist')

View file

@ -2,7 +2,7 @@
<section id="queueWrapper">
<ScreenHeader :layout="songs.length === 0 ? 'collapsed' : headerLayout">
Current Queue
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -81,7 +81,6 @@ const {
showingControls,
isPhone,
playSelected,
toggleControls,
onScrollBreakpoint
} = useSongList(toRef(queueStore.state, 'songs'), 'queue', { sortable: false })

View file

@ -2,7 +2,7 @@
<section id="recentlyPlayedWrapper">
<ScreenHeader :layout="songs.length === 0 ? 'collapsed' : headerLayout">
Recently Played
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -63,7 +63,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint
} = useSongList(recentlyPlayedSongs, 'recently-played', { sortable: false })

View file

@ -2,7 +2,7 @@
<section id="usersWrapper">
<ScreenHeader layout="collapsed">
Users
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:controls>
<BtnGroup uppercased v-if="showingControls || !isPhone">
@ -42,7 +42,6 @@ const users = toRef(userStore.state, 'users')
const isPhone = isMobile.phone
const showingControls = ref(false)
const toggleControls = () => (showingControls.value = !showingControls.value)
const showAddUserForm = () => eventBus.emit('MODAL_SHOW_ADD_USER_FORM')
onMounted(async () => await userStore.fetch())

View file

@ -1,166 +1,6 @@
// Vitest Snapshot v1
exports[`renders 1`] = `
<section id="songsWrapper">
<header class="screen-header expanded">
<div class="thumbnail-wrapper">
<div class="thumbnail-stack mono" style="background-image: url(undefined/resources/assets/img/covers/default.svg);" data-v-2978c570=""><span data-v-2978c570=""></span></div>
</div>
<div class="right">
<div class="heading-wrapper">
<h1 class="name"> All Songs
<!--v-if-->
</h1><span class="meta text-secondary"><span>420 songs</span><span>34:17:36</span></span>
</div>
<div class="song-list-controls" data-testid="song-list-controls" data-v-cee28c08=""><span class="btn-group" uppercased="" data-v-cee28c08=""><button type="button" class="btn-shuffle-all" data-testid="btn-shuffle-all" orange="" title="Shuffle all songs" data-v-27deb898="" data-v-cee28c08=""><svg class="svg-inline--fa fa-shuffle" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shuffle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-v-cee28c08=""><path class="" fill="currentColor" d="M424.1 287c-15.13-15.12-40.1-4.426-40.1 16.97V352H336L153.6 108.8C147.6 100.8 138.1 96 128 96H32C14.31 96 0 110.3 0 128s14.31 32 32 32h80l182.4 243.2C300.4 411.3 309.9 416 320 416h63.97v47.94c0 21.39 25.86 32.12 40.99 17l79.1-79.98c9.387-9.387 9.387-24.59 0-33.97L424.1 287zM336 160h47.97v48.03c0 21.39 25.87 32.09 40.1 16.97l79.1-79.98c9.387-9.391 9.385-24.59-.0013-33.97l-79.1-79.98c-15.13-15.12-40.99-4.391-40.99 17V96H320c-10.06 0-19.56 4.75-25.59 12.81L254 162.7L293.1 216L336 160zM112 352H32c-17.69 0-32 14.31-32 32s14.31 32 32 32h96c10.06 0 19.56-4.75 25.59-12.81l40.4-53.87L154 296L112 352z"></path></svg> All </button><!--v-if--><!--v-if--><!--v-if--><!--v-if--></span>
<div class="add-to" data-testid="add-to-menu" tabindex="0" data-v-0351ff38="" data-v-cee28c08="" style="display: none;">
<section class="existing-playlists" data-v-0351ff38="">
<p data-v-0351ff38="">Add 0 songs to</p>
<ul data-v-0351ff38="">
<li data-testid="queue" tabindex="0" data-v-0351ff38="">Queue</li>
<li class="favorites" data-testid="add-to-favorites" tabindex="0" data-v-0351ff38=""> Favorites </li>
</ul>
</section>
<section class="new-playlist" data-testid="new-playlist" data-v-0351ff38="">
<p data-v-0351ff38="">or create a new playlist</p>
<form class="form-save form-simple form-new-playlist" data-v-0351ff38=""><input data-testid="new-playlist-name" placeholder="Playlist name" required="" type="text" data-v-0351ff38=""><button type="submit" title="Save" data-v-27deb898="" data-v-0351ff38="">⏎</button></form>
</section>
</div>
</div>
</div>
</header><br data-testid="song-list">
</section>
`;
exports[`renders 2`] = `
<section id="songsWrapper">
<header class="screen-header expanded">
<div class="thumbnail-wrapper">
<div class="thumbnail-stack single" style="background-image: url(undefined/resources/assets/img/covers/default.svg);" data-v-2978c570=""><span data-testid="thumbnail" data-v-2978c570=""></span></div>
</div>
<div class="right">
<div class="heading-wrapper">
<h1 class="name"> All Songs
<!--v-if-->
</h1><span class="meta text-secondary"><span>420 songs</span><span>34:17:36</span></span>
</div>
<div class="song-list-controls" data-testid="song-list-controls" data-v-cee28c08=""><span class="btn-group" uppercased="" data-v-cee28c08=""><button type="button" class="btn-shuffle-all" data-testid="btn-shuffle-all" orange="" title="Shuffle all songs" data-v-27deb898="" data-v-cee28c08=""><svg class="svg-inline--fa fa-shuffle" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shuffle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-v-cee28c08=""><path class="" fill="currentColor" d="M424.1 287c-15.13-15.12-40.1-4.426-40.1 16.97V352H336L153.6 108.8C147.6 100.8 138.1 96 128 96H32C14.31 96 0 110.3 0 128s14.31 32 32 32h80l182.4 243.2C300.4 411.3 309.9 416 320 416h63.97v47.94c0 21.39 25.86 32.12 40.99 17l79.1-79.98c9.387-9.387 9.387-24.59 0-33.97L424.1 287zM336 160h47.97v48.03c0 21.39 25.87 32.09 40.1 16.97l79.1-79.98c9.387-9.391 9.385-24.59-.0013-33.97l-79.1-79.98c-15.13-15.12-40.99-4.391-40.99 17V96H320c-10.06 0-19.56 4.75-25.59 12.81L254 162.7L293.1 216L336 160zM112 352H32c-17.69 0-32 14.31-32 32s14.31 32 32 32h96c10.06 0 19.56-4.75 25.59-12.81l40.4-53.87L154 296L112 352z"></path></svg> All </button><!--v-if--><!--v-if--><!--v-if--><!--v-if--></span>
<div class="add-to" data-testid="add-to-menu" tabindex="0" data-v-0351ff38="" data-v-cee28c08="" style="display: none;">
<section class="existing-playlists" data-v-0351ff38="">
<p data-v-0351ff38="">Add 0 songs to</p>
<ul data-v-0351ff38="">
<li data-testid="queue" tabindex="0" data-v-0351ff38="">Queue</li>
<li class="favorites" data-testid="add-to-favorites" tabindex="0" data-v-0351ff38=""> Favorites </li>
</ul>
</section>
<section class="new-playlist" data-testid="new-playlist" data-v-0351ff38="">
<p data-v-0351ff38="">or create a new playlist</p>
<form class="form-save form-simple form-new-playlist" data-v-0351ff38=""><input data-testid="new-playlist-name" placeholder="Playlist name" required="" type="text" data-v-0351ff38=""><button type="submit" title="Save" data-v-27deb898="" data-v-0351ff38="">⏎</button></form>
</section>
</div>
</div>
</div>
</header><br data-testid="song-list">
</section>
`;
exports[`renders 3`] = `
<section id="songsWrapper">
<header class="screen-header expanded">
<div class="thumbnail-wrapper">
<div class="thumbnail-stack single" style="background-image: url(undefined/resources/assets/img/covers/default.svg);" data-v-2978c570=""><span data-testid="thumbnail" data-v-2978c570=""></span></div>
</div>
<div class="right">
<div class="heading-wrapper">
<h1 class="name"> All Songs
<!--v-if-->
</h1><span class="meta text-secondary"><span>420 songs</span><span>34:17:36</span></span>
</div>
<div class="song-list-controls" data-testid="song-list-controls" data-v-cee28c08=""><span class="btn-group" uppercased="" data-v-cee28c08=""><button type="button" class="btn-shuffle-all" data-testid="btn-shuffle-all" orange="" title="Shuffle all songs" data-v-27deb898="" data-v-cee28c08=""><icon icon="[object Object]" data-v-cee28c08=""></icon> All </button><!--v-if--><!--v-if--><!--v-if--><!--v-if--></span>
<div class="add-to" data-testid="add-to-menu" tabindex="0" data-v-0351ff38="" data-v-cee28c08="" style="display: none;">
<section class="existing-playlists" data-v-0351ff38="">
<p data-v-0351ff38="">Add 0 songs to</p>
<ul data-v-0351ff38="">
<li data-testid="queue" tabindex="0" data-v-0351ff38="">Queue</li>
<li class="favorites" data-testid="add-to-favorites" tabindex="0" data-v-0351ff38=""> Favorites </li>
</ul>
</section>
<section class="new-playlist" data-testid="new-playlist" data-v-0351ff38="">
<p data-v-0351ff38="">or create a new playlist</p>
<form class="form-save form-simple form-new-playlist" data-v-0351ff38=""><input data-testid="new-playlist-name" placeholder="Playlist name" required="" type="text" data-v-0351ff38=""><button type="submit" title="Save" data-v-27deb898="" data-v-0351ff38="">⏎</button></form>
</section>
</div>
</div>
</div>
</header><br data-testid="song-list">
</section>
`;
exports[`renders 4`] = `
<section id="songsWrapper">
<header class="screen-header expanded">
<div class="thumbnail-wrapper">
<div class="thumbnail-stack single" style="background-image: url(undefined/resources/assets/img/covers/default.svg);" data-v-2978c570=""><span data-testid="thumbnail" data-v-2978c570=""></span></div>
</div>
<div class="right">
<div class="heading-wrapper">
<h1 class="name"> All Songs
<!--v-if-->
</h1><span class="meta text-secondary"><span>420 songs</span><span>34:17:36</span></span>
</div>
<div class="song-list-controls" data-testid="song-list-controls" data-v-cee28c08=""><span class="btn-group" uppercased="" data-v-cee28c08=""><button type="button" class="btn-shuffle-all" data-testid="btn-shuffle-all" orange="" title="Shuffle all songs" data-v-27deb898="" data-v-cee28c08=""><br data-testid="icon" icon="[object Object]" data-v-cee28c08=""> All </button><!--v-if--><!--v-if--><!--v-if--><!--v-if--></span>
<div class="add-to" data-testid="add-to-menu" tabindex="0" data-v-0351ff38="" data-v-cee28c08="" style="display: none;">
<section class="existing-playlists" data-v-0351ff38="">
<p data-v-0351ff38="">Add 0 songs to</p>
<ul data-v-0351ff38="">
<li data-testid="queue" tabindex="0" data-v-0351ff38="">Queue</li>
<li class="favorites" data-testid="add-to-favorites" tabindex="0" data-v-0351ff38=""> Favorites </li>
</ul>
</section>
<section class="new-playlist" data-testid="new-playlist" data-v-0351ff38="">
<p data-v-0351ff38="">or create a new playlist</p>
<form class="form-save form-simple form-new-playlist" data-v-0351ff38=""><input data-testid="new-playlist-name" placeholder="Playlist name" required="" type="text" data-v-0351ff38=""><button type="submit" title="Save" data-v-27deb898="" data-v-0351ff38="">⏎</button></form>
</section>
</div>
</div>
</div>
</header><br data-testid="song-list">
</section>
`;
exports[`renders 5`] = `
<section id="songsWrapper">
<header class="screen-header expanded">
<aside class="thumbnail-wrapper">
<div class="thumbnail-stack single" style="background-image: url(undefined/resources/assets/img/covers/default.svg);" data-v-2978c570=""><span data-testid="thumbnail" data-v-2978c570=""></span></div>
</aside>
<main>
<div class="heading-wrapper">
<h1 class="name"> All Songs
<!--v-if-->
</h1><span class="meta text-secondary"><span>420 songs</span><span>34:17:36</span></span>
</div>
<div class="song-list-controls" data-testid="song-list-controls" data-v-cee28c08=""><span class="btn-group" uppercased="" data-v-cee28c08=""><button type="button" class="btn-shuffle-all" data-testid="btn-shuffle-all" orange="" title="Shuffle all songs" data-v-27deb898="" data-v-cee28c08=""><br data-testid="icon" icon="[object Object]" data-v-cee28c08=""> All </button><!--v-if--><!--v-if--><!--v-if--><!--v-if--></span>
<div class="add-to" data-testid="add-to-menu" tabindex="0" data-v-0351ff38="" data-v-cee28c08="" style="display: none;">
<section class="existing-playlists" data-v-0351ff38="">
<p data-v-0351ff38="">Add 0 songs to</p>
<ul data-v-0351ff38="">
<li data-testid="queue" tabindex="0" data-v-0351ff38="">Queue</li>
<li class="favorites" data-testid="add-to-favorites" tabindex="0" data-v-0351ff38=""> Favorites </li>
</ul>
</section>
<section class="new-playlist" data-testid="new-playlist" data-v-0351ff38="">
<p data-v-0351ff38="">or create a new playlist</p>
<form class="form-save form-simple form-new-playlist" data-v-0351ff38=""><input data-testid="new-playlist-name" placeholder="Playlist name" required="" type="text" data-v-0351ff38=""><button type="submit" title="Save" data-v-27deb898="" data-v-0351ff38="">⏎</button></form>
</section>
</div>
</div>
</main>
</header><br data-testid="song-list">
</section>
`;
exports[`renders 6`] = `
<section id="songsWrapper">
<header class="screen-header expanded" data-v-661f8f0d="">
<aside class="thumbnail-wrapper" data-v-661f8f0d="">

View file

@ -2,7 +2,7 @@
<section id="songResultsWrapper">
<ScreenHeader :layout="songs.length === 0 ? 'collapsed' : headerLayout">
Songs for <span class="text-thin">{{ decodedQ }}</span>
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
<ControlsToggle v-model="showingControls"/>
<template v-slot:thumbnail>
<ThumbnailStack :thumbnails="thumbnails"/>
@ -54,7 +54,6 @@ const {
onPressEnter,
playAll,
playSelected,
toggleControls,
sort,
onScrollBreakpoint
} = useSongList(toRef(searchStore.state, 'songs'), 'search-results')

View file

@ -1,6 +1,6 @@
import isMobile from 'ismobilejs'
import { expect, it } from 'vitest'
import { fireEvent } from '@testing-library/vue'
import { fireEvent, getByRole } from '@testing-library/vue'
import UnitTestCase from '@/__tests__/UnitTestCase'
import ScreenControlsToggle from './ScreenControlsToggle.vue'
@ -8,11 +8,11 @@ new class extends UnitTestCase {
protected test () {
it('renders and emits an event on mobile', async () => {
isMobile.phone = true
const { emitted, getByTestId } = this.render(ScreenControlsToggle)
const { emitted, getByRole } = this.render(ScreenControlsToggle)
await fireEvent.click(getByTestId('controls-toggle'))
await fireEvent.click(getByRole('checkbox'))
expect(emitted().toggleControls).toBeTruthy()
expect(emitted()['update:modelValue']).toBeTruthy()
})
}
}

View file

@ -1,21 +1,34 @@
<template>
<span v-if="isMobile.phone" class="text-highlight" data-testid="controls-toggle" @click="$emit('toggleControls')">
<icon v-if="showingControls" :icon="showingControls ? faAngleUp : faAngleDown" class="toggle"/>
</span>
<label v-if="isMobile.phone" class="text-highlight">
<input type="checkbox" v-model="value"/>
<icon :icon="value ? faAngleUp : faAngleDown" class="toggle"/>
<span>Toggle the song list controls</span>
</label>
</template>
<script lang="ts" setup>
import { faAngleDown, faAngleUp } from '@fortawesome/free-solid-svg-icons'
import isMobile from 'ismobilejs'
import { toRefs } from 'vue'
import { computed } from 'vue'
const props = withDefaults(defineProps<{ showingControls?: boolean }>(), { showingControls: true })
const { showingControls } = toRefs(props)
const props = withDefaults(defineProps<{ modelValue?: boolean }>(), { modelValue: false })
const emit = defineEmits(['update:modelValue'])
const value = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value)
})
</script>
<style lang="scss" scoped>
.toggle {
label {
font-size: 1rem;
display: inline-block;
margin-left: 4px;
}
input, span {
display: none;
}
</style>

View file

@ -47,7 +47,6 @@ export const useSongList = (
const getSongsToPlay = (): Song[] => songList.value.getAllSongsWithSort()
const playAll = (shuffle: boolean) => playbackService.queueAndPlay(getSongsToPlay(), shuffle)
const playSelected = (shuffle: boolean) => playbackService.queueAndPlay(selectedSongs.value, shuffle)
const toggleControls = () => (showingControls.value = !showingControls.value)
const onPressEnter = async (event: KeyboardEvent) => {
if (selectedSongs.value.length === 1) {
@ -121,7 +120,6 @@ export const useSongList = (
onPressEnter,
playAll,
playSelected,
toggleControls,
onScrollBreakpoint,
sort
}