mirror of
https://github.com/koel/koel
synced 2024-09-20 06:11:53 +00:00
implement simple multi disc support (#687)
* add disc field to songs table via migration * add disc field to song model * collect disc information in file sync process * sort song list by disc and track number in album context * check the disc field in file test * remove nullable flag from disc field in add_disc_into_songs migration * fix php code style issues * fix js code style * fix sort usage in song-list * sort songs by inserting into queue by clicking the album/artist item play button (album_id, disc, track) * add disc to sync tags in media model
This commit is contained in:
parent
a98dc2774f
commit
4298774e7f
10 changed files with 53 additions and 5 deletions
|
@ -136,6 +136,7 @@ class File
|
||||||
'title' => basename($this->path, '.'.pathinfo($this->path, PATHINFO_EXTENSION)), // default to be file name
|
'title' => basename($this->path, '.'.pathinfo($this->path, PATHINFO_EXTENSION)), // default to be file name
|
||||||
'length' => $info['playtime_seconds'],
|
'length' => $info['playtime_seconds'],
|
||||||
'track' => (int) $track,
|
'track' => (int) $track,
|
||||||
|
'disc' => (int) array_get($info, 'comments.part_of_a_set.0', 1),
|
||||||
'lyrics' => '',
|
'lyrics' => '',
|
||||||
'cover' => array_get($info, 'comments.picture', [null])[0],
|
'cover' => array_get($info, 'comments.picture', [null])[0],
|
||||||
'path' => $this->path,
|
'path' => $this->path,
|
||||||
|
|
|
@ -24,6 +24,7 @@ use YouTube;
|
||||||
* @property float length
|
* @property float length
|
||||||
* @property string lyrics
|
* @property string lyrics
|
||||||
* @property int track
|
* @property int track
|
||||||
|
* @property int disc
|
||||||
* @property int album_id
|
* @property int album_id
|
||||||
* @property int id
|
* @property int id
|
||||||
* @property int artist_id
|
* @property int artist_id
|
||||||
|
@ -50,6 +51,7 @@ class Song extends Model
|
||||||
'length' => 'float',
|
'length' => 'float',
|
||||||
'mtime' => 'int',
|
'mtime' => 'int',
|
||||||
'track' => 'int',
|
'track' => 'int',
|
||||||
|
'disc' => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Media
|
||||||
'title',
|
'title',
|
||||||
'length',
|
'length',
|
||||||
'track',
|
'track',
|
||||||
|
'disc',
|
||||||
'lyrics',
|
'lyrics',
|
||||||
'cover',
|
'cover',
|
||||||
'mtime',
|
'mtime',
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddDiscIntoSongs extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('songs', function (Blueprint $table) {
|
||||||
|
$table->integer('disc')->after('track')->default(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('songs', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('disc');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { orderBy } from 'lodash'
|
||||||
import { pluralize } from '@/utils'
|
import { pluralize } from '@/utils'
|
||||||
import { queueStore, artistStore, sharedStore } from '@/stores'
|
import { queueStore, artistStore, sharedStore } from '@/stores'
|
||||||
import { playback, download } from '@/services'
|
import { playback, download } from '@/services'
|
||||||
|
@ -72,7 +73,7 @@ export default {
|
||||||
*/
|
*/
|
||||||
play (e) {
|
play (e) {
|
||||||
if (e.metaKey || e.ctrlKey) {
|
if (e.metaKey || e.ctrlKey) {
|
||||||
queueStore.queue(this.album.songs)
|
queueStore.queue(orderBy(this.album.songs, ['disc', 'track']))
|
||||||
} else {
|
} else {
|
||||||
playback.playAllInAlbum(this.album, false)
|
playback.playAllInAlbum(this.album, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { orderBy } from 'lodash'
|
||||||
import { pluralize } from '@/utils'
|
import { pluralize } from '@/utils'
|
||||||
import { artistStore, queueStore, sharedStore } from '@/stores'
|
import { artistStore, queueStore, sharedStore } from '@/stores'
|
||||||
import { playback, download } from '@/services'
|
import { playback, download } from '@/services'
|
||||||
|
@ -68,7 +69,7 @@ export default {
|
||||||
*/
|
*/
|
||||||
play (e) {
|
play (e) {
|
||||||
if (e.metaKey || e.ctrlKey) {
|
if (e.metaKey || e.ctrlKey) {
|
||||||
queueStore.queue(this.artist.songs)
|
queueStore.queue(orderBy(this.artist.songs, ['album_id', 'disc', 'track']))
|
||||||
} else {
|
} else {
|
||||||
playback.playAllByArtist(this.artist, false)
|
playback.playAllByArtist(this.artist, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import isMobile from 'ismobilejs'
|
import isMobile from 'ismobilejs'
|
||||||
import { each } from 'lodash'
|
import { each, orderBy as _orderBy } from 'lodash'
|
||||||
|
|
||||||
import { filterBy, orderBy, event, pluralize, $ } from '@/utils'
|
import { filterBy, orderBy, event, pluralize, $ } from '@/utils'
|
||||||
import { playlistStore, queueStore, songStore, favoriteStore } from '@/stores'
|
import { playlistStore, queueStore, songStore, favoriteStore } from '@/stores'
|
||||||
|
@ -203,9 +203,18 @@ export default {
|
||||||
this.order *= -1
|
this.order *= -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.type === 'album') {
|
||||||
|
this.sortKey = this.sortKey ? this.sortKey : ['song.track']
|
||||||
|
}
|
||||||
|
|
||||||
this.sortingByAlbum = Array.isArray(this.sortKey) && this.sortKey[0] === 'song.album.name'
|
this.sortingByAlbum = Array.isArray(this.sortKey) && this.sortKey[0] === 'song.album.name'
|
||||||
this.sortingByArtist = Array.isArray(this.sortKey) && this.sortKey[0] === 'song.album.artist.name'
|
this.sortingByArtist = Array.isArray(this.sortKey) && this.sortKey[0] === 'song.album.artist.name'
|
||||||
|
|
||||||
this.songRows = orderBy(this.songRows, this.sortKey, this.order)
|
this.songRows = orderBy(this.songRows, this.sortKey, this.order)
|
||||||
|
|
||||||
|
if (this.type === 'album') {
|
||||||
|
this.songRows = _orderBy(this.songRows, 'song.disc')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -418,7 +418,7 @@ export const playback = {
|
||||||
playAllByArtist ({ songs }, shuffled = true) {
|
playAllByArtist ({ songs }, shuffled = true) {
|
||||||
shuffled
|
shuffled
|
||||||
? this.queueAndPlay(songs, true)
|
? this.queueAndPlay(songs, true)
|
||||||
: this.queueAndPlay(orderBy(songs, 'album_id', 'track'))
|
: this.queueAndPlay(orderBy(songs, ['album_id', 'disc', 'track']))
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -430,6 +430,6 @@ export const playback = {
|
||||||
playAllInAlbum ({ songs }, shuffled = true) {
|
playAllInAlbum ({ songs }, shuffled = true) {
|
||||||
shuffled
|
shuffled
|
||||||
? this.queueAndPlay(songs, true)
|
? this.queueAndPlay(songs, true)
|
||||||
: this.queueAndPlay(orderBy(songs, 'track'))
|
: this.queueAndPlay(orderBy(songs, ['disc', 'track']))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ class FileTest extends TestCase
|
||||||
'compilation' => false,
|
'compilation' => false,
|
||||||
'title' => 'Amet',
|
'title' => 'Amet',
|
||||||
'track' => 5,
|
'track' => 5,
|
||||||
|
'disc' => 3,
|
||||||
'lyrics' => "Foo\rbar",
|
'lyrics' => "Foo\rbar",
|
||||||
'cover' => [
|
'cover' => [
|
||||||
'data' => file_get_contents(__DIR__.'/../blobs/cover.png'),
|
'data' => file_get_contents(__DIR__.'/../blobs/cover.png'),
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue