mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
added support for song track numbers as well as subsorting song lists
with a second sort key. track numbers are also editable via the song edit modal interface.
This commit is contained in:
parent
8c7dae6a32
commit
940cd1a914
7 changed files with 57 additions and 7 deletions
|
@ -133,10 +133,12 @@ class Song extends Model
|
|||
continue;
|
||||
}
|
||||
|
||||
// If we're updating only one song, take into account the title and lyrics.
|
||||
// If we're updating only one song, take into account the title and lyrics
|
||||
// and track number.
|
||||
if (count($ids) === 1) {
|
||||
$song->title = trim($data['title']) ?: $song->title;
|
||||
$song->lyrics = trim($data['lyrics']);
|
||||
$song->track = trim($data['track']);
|
||||
}
|
||||
|
||||
// If "newArtist" is provided, we'll see if such an artist name is found in our database.
|
||||
|
|
|
@ -229,11 +229,19 @@ class Media
|
|||
return;
|
||||
}
|
||||
|
||||
$track = array_get($info, 'comments.track_number', [0])[0];
|
||||
if (preg_match('#(\d+)/#', $track, $matches)) {
|
||||
$track = $matches[1];
|
||||
} elseif ((int) $track) {
|
||||
$track = (int) $track;
|
||||
}
|
||||
|
||||
$props = [
|
||||
'artist' => '',
|
||||
'album' => '',
|
||||
'title' => '',
|
||||
'length' => $info['playtime_seconds'],
|
||||
'track' => $track,
|
||||
'lyrics' => '',
|
||||
'cover' => array_get($info, 'comments.picture', [null])[0],
|
||||
'path' => $file->getPathname(),
|
||||
|
|
|
@ -35,6 +35,7 @@ $factory->define(App\Models\Song::class, function ($faker) {
|
|||
return [
|
||||
'title' => $faker->sentence,
|
||||
'length' => $faker->randomFloat(2, 10, 500),
|
||||
'track' => $faker->randomNumber(),
|
||||
'lyrics' => $faker->paragraph(),
|
||||
'path' => '/tmp/'.uniqid().'.mp3',
|
||||
'mtime' => time(),
|
||||
|
|
|
@ -17,6 +17,7 @@ class CreateSongsTable extends Migration
|
|||
$table->integer('album_id')->unsigned();
|
||||
$table->string('title');
|
||||
$table->float('length');
|
||||
$table->integer('track');
|
||||
$table->text('lyrics');
|
||||
$table->text('path');
|
||||
$table->integer('mtime');
|
||||
|
|
|
@ -280,7 +280,7 @@
|
|||
*
|
||||
* @source https://github.com/vuejs/vue/blob/dev/src/filters/array-filters.js
|
||||
*/
|
||||
Vue.filter('caseInsensitiveOrderBy', (arr, sortKey, reverse) => {
|
||||
Vue.filter('caseInsensitiveOrderBy', (arr, sortKey, reverse, subSortKey) => {
|
||||
if (!sortKey) {
|
||||
return arr;
|
||||
}
|
||||
|
@ -289,17 +289,45 @@
|
|||
|
||||
// sort on a copy to avoid mutating original array
|
||||
return arr.slice().sort((a, b) => {
|
||||
let aSub = subSortKey ? Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, subSortKey) : 0 : 0;
|
||||
let bSub = subSortKey ? Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, subSortKey) : 0 : 0;
|
||||
a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a;
|
||||
b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b;
|
||||
|
||||
if (_.isNumber(a) && _.isNumber(b)) {
|
||||
return a === b ? 0 : a > b ? order : -order;
|
||||
if (a === b) {
|
||||
if (_.isNumber(aSub) && _.isNumber(bSub)) {
|
||||
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
|
||||
} else if (aSub !== undefined && bSub !== undefined) {
|
||||
aSub = aSub.toLowerCase();
|
||||
bSub = bSub.toLowerCase();
|
||||
|
||||
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return a > b ? order : -order;
|
||||
}
|
||||
|
||||
a = a === undefined ? a : a.toLowerCase();
|
||||
b = b === undefined ? b : b.toLowerCase();
|
||||
|
||||
return a === b ? 0 : a > b ? order : -order;
|
||||
if (a === b) {
|
||||
if (_.isNumber(aSub) && _.isNumber(bSub)) {
|
||||
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
|
||||
} else if (aSub !== undefined && bSub !== undefined) {
|
||||
aSub = aSub.toLowerCase();
|
||||
bSub = bSub.toLowerCase();
|
||||
|
||||
return aSub === bSub ? 0 : aSub > bSub ? order : -order;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return a > b ? order : -order;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
:options="albumTypeaheadOptions"
|
||||
:value.sync="formData.albumName"></typeahead>
|
||||
</div>
|
||||
<div class="form-row" v-show="editSingle">
|
||||
<label>Track</label>
|
||||
<input type="text" v-model="formData.track">
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="currentView === 'lyrics' && editSingle">
|
||||
<div class="form-row">
|
||||
|
@ -106,6 +110,7 @@
|
|||
albumName: '',
|
||||
artistName: '',
|
||||
lyrics: '',
|
||||
track: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@ -197,9 +202,11 @@
|
|||
songStore.getInfo(this.songs[0], () => {
|
||||
this.loading = false;
|
||||
this.formData.lyrics = utils.br2nl(this.songs[0].lyrics);
|
||||
this.formData.track = this.songs[0].track;
|
||||
});
|
||||
} else {
|
||||
this.formData.lyrics = utils.br2nl(this.songs[0].lyrics);
|
||||
this.formData.track = this.songs[0].track;
|
||||
}
|
||||
} else {
|
||||
this.formData.albumName = this.inSameAlbum ? this.songs[0].album.name : '';
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<i class="fa fa-angle-down" v-show="sortKey === 'album.artist.name' && order > 0"></i>
|
||||
<i class="fa fa-angle-up" v-show="sortKey === 'album.artist.name' && order < 0"></i>
|
||||
</th>
|
||||
<th @click="sort('album.name')">Album
|
||||
<th @click="sort('album.name', 'track')">Album
|
||||
<i class="fa fa-angle-down" v-show="sortKey === 'album.name' && order > 0"></i>
|
||||
<i class="fa fa-angle-up" v-show="sortKey === 'album.name' && order < 0"></i>
|
||||
</th>
|
||||
|
@ -33,10 +33,11 @@
|
|||
<tbody>
|
||||
<tr
|
||||
v-for="item in items
|
||||
| caseInsensitiveOrderBy sortKey order
|
||||
| caseInsensitiveOrderBy sortKey order subSortKey
|
||||
| filterSongBy q
|
||||
| limitBy numOfItems"
|
||||
is="song-item"
|
||||
data-track="{{ item.track }}"
|
||||
data-song-id="{{ item.id }}"
|
||||
track-by="id"
|
||||
:song="item"
|
||||
|
@ -81,6 +82,7 @@
|
|||
lastSelectedRow: null,
|
||||
q: '', // The filter query
|
||||
sortKey: this.type === 'top-songs' ? 'playCount' : '',
|
||||
subSortKey: 0,
|
||||
order: this.type === 'top-songs' ? -1 : 1,
|
||||
componentCache: {},
|
||||
};
|
||||
|
@ -109,12 +111,13 @@
|
|||
*
|
||||
* @param {String} key The sort key. Can be 'title', 'album', 'artist', or 'fmtLength'
|
||||
*/
|
||||
sort(key) {
|
||||
sort(key, subSortKey) {
|
||||
if (this.sortable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sortKey = key;
|
||||
this.subSortKey = subSortKey ? subSortKey : 0;
|
||||
this.order = 0 - this.order;
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue