mirror of
https://github.com/janishutz/MusicPlayer.git
synced 2026-09-10 14:25:24 +02:00
fix: crash, design for playlists
crash was caused by indices not updating correctly
This commit is contained in:
@@ -4,8 +4,15 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="playlist-main">
|
||||
<h1>Playlists</h1>
|
||||
<UserPlaylists />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.playlist-main {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
};
|
||||
|
||||
const song: ComputedRef<Song> = computed( () => {
|
||||
if ( queueIdx.value >= 0 ) {
|
||||
if ( queueIdx.value >= 0 && queue.value.length > queueIdx.value ) {
|
||||
return queue.value[ queueIdx.value ]!;
|
||||
} else {
|
||||
return {
|
||||
|
||||
@@ -69,37 +69,46 @@
|
||||
<template>
|
||||
<div class="playlists">
|
||||
<AddPlaylist v-model="showAddPlaylist" @add-playlist="addPlaylist" />
|
||||
<div v-if="checkingStatus">
|
||||
<div v-if="checkingStatus" class="playlist-wrapper">
|
||||
Loading{{ '.'.repeat( dots ) }}
|
||||
</div>
|
||||
<div v-else-if="playlists.length === 0">
|
||||
<div v-else-if="playlists.length === 0" class="playlist-wrapper">
|
||||
No playlists
|
||||
<button @click="openAddPlaylistPopup">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
Add one
|
||||
</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<button @click="openAddPlaylistPopup">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
Add Playlist
|
||||
</button>
|
||||
<button @click="savePlaylists">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
Save Changes
|
||||
</button>
|
||||
<button @click="loadPlaylists">
|
||||
<i class="fa-solid fa-rotate"></i>
|
||||
Undo unsaved changes
|
||||
</button>
|
||||
<div v-for="(playlist, index) in playlists" :key="index">
|
||||
<input v-if="editingPlaylists[ index ]" v-model="playlist.name" type="text">
|
||||
<h2 v-else @click="() => selectPlaylist( index )">
|
||||
{{ playlist.name }}
|
||||
</h2>
|
||||
<i class="fa-solid fa-pen-to-square" @click="() => togglePlaylistEditing( index )"></i>
|
||||
<i class="fa-solid fa-trash" @click="() => removePlaylist( index )"></i>
|
||||
<div v-else class="playlist-wrapper">
|
||||
<div class="playlist-actions">
|
||||
<button @click="openAddPlaylistPopup">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
Add Playlist
|
||||
</button>
|
||||
<button @click="savePlaylists">
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
Save Changes
|
||||
</button>
|
||||
<button @click="loadPlaylists">
|
||||
<i class="fa-solid fa-rotate"></i>
|
||||
Undo unsaved changes
|
||||
</button>
|
||||
</div>
|
||||
<div class="playlist-container">
|
||||
<div v-for="(playlist, index) in playlists" :key="index" class="playlist">
|
||||
<i class="fa-solid fa-circle-play" @click="() => selectPlaylist( index )"></i>
|
||||
<input v-if="editingPlaylists[ index ]" v-model="playlist.name" type="text">
|
||||
<h2 v-else @click="() => selectPlaylist( index )">
|
||||
{{ playlist.name }}
|
||||
</h2>
|
||||
<i class="fa-solid fa-pen-to-square" @click="() => togglePlaylistEditing( index )"></i>
|
||||
<i class="fa-solid fa-trash" @click="() => removePlaylist( index )"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '@/scss/components/playlists.scss';
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
.playlists {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
>.playlist-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
>.playlist-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
overflow-x: scroll;
|
||||
|
||||
>.playlist {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
height: 3rem;
|
||||
|
||||
>h2, >input {
|
||||
margin: 0;
|
||||
margin-right: auto;
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
cursor: pointer;
|
||||
}
|
||||
>input {
|
||||
margin-right: auto;
|
||||
margin-left: 10px;
|
||||
width: 50%;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
>.fa-circle-play {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
>.fa-solid {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
&.moving {
|
||||
position: fixed;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
>i {
|
||||
|
||||
@@ -43,7 +43,12 @@ const connect = (): Promise<void> => {
|
||||
currentQueueIdx.value = data.state.index;
|
||||
isPlaying.value = data.state.playing;
|
||||
startTime.value = data.state.start;
|
||||
playbackTime.value = data.state.offset;
|
||||
|
||||
if ( data.playlist.length === 0 )
|
||||
playbackTime.value = 0;
|
||||
else
|
||||
playbackTime.value = data.state.offset;
|
||||
|
||||
playbackOffset.value = data.state.offset;
|
||||
playbackProgress.value = data.state.offset / ( data.playlist[ data.state.index ]?.duration ?? -1 );
|
||||
resolve();
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
}, 250 );
|
||||
} );
|
||||
const song: ComputedRef<Song> = computed( () => {
|
||||
if ( currentQueueIdx.value >= 0 )
|
||||
if ( currentQueueIdx.value >= 0 && currentQueue.value.length > currentQueueIdx.value )
|
||||
return currentQueue.value[currentQueueIdx.value]!;
|
||||
else
|
||||
return {
|
||||
@@ -68,7 +68,7 @@
|
||||
<ProgressBar v-model="playbackProgress" :disallow-move="true" />
|
||||
<div class="time">
|
||||
<p class="current">
|
||||
{{ beautifyTime( playbackTime ) }}
|
||||
{{ beautifyTime( song.duration >= 0 ? playbackTime : -1 ) }}
|
||||
</p>
|
||||
<p class="duration">
|
||||
{{ beautifyTime( song.duration ) }}
|
||||
|
||||
Reference in New Issue
Block a user