mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
parent
4eab978bb0
commit
e068a4ca8c
22 changed files with 813 additions and 85 deletions
53
app/Console/Commands/CollectTagsCommand.php
Normal file
53
app/Console/Commands/CollectTagsCommand.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Song;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CollectTagsCommand extends Command
|
||||
{
|
||||
protected $signature = 'koel:tags:collect {tag*}';
|
||||
protected $description = 'Collect additional tags from existing songs';
|
||||
|
||||
private const ALL_TAGS = [
|
||||
'title',
|
||||
'album',
|
||||
'artist',
|
||||
'albumartist',
|
||||
'track',
|
||||
'disc',
|
||||
'year',
|
||||
'genre',
|
||||
'lyrics',
|
||||
'cover',
|
||||
];
|
||||
|
||||
private const COLLECTABLE_TAGS = ['year', 'genre'];
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$tags = collect($this->argument('tag'))->unique();
|
||||
|
||||
if ($tags->diff(self::COLLECTABLE_TAGS)->isNotEmpty()) {
|
||||
$this->error(
|
||||
sprintf(
|
||||
'Invalid tag(s): %s. Allowed tags are: %s.',
|
||||
$tags->diff(self::COLLECTABLE_TAGS)->join(', '),
|
||||
implode(', ', self::COLLECTABLE_TAGS)
|
||||
)
|
||||
);
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
Song::withoutSyncingToSearch(function () use ($tags): void {
|
||||
$this->call('koel:sync', [
|
||||
'--force' => true,
|
||||
'--ignore' => collect(self::ALL_TAGS)->diff($tags)->all(),
|
||||
]);
|
||||
});
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ class SyncCommand extends Command
|
|||
{
|
||||
protected $signature = 'koel:sync
|
||||
{record? : A single watch record. Consult Wiki for more info.}
|
||||
{--ignore= : The comma-separated tags to ignore (exclude) from syncing}
|
||||
{--ignore=* : The comma-separated tags to ignore (exclude) from syncing}
|
||||
{--force : Force re-syncing even unchanged files}';
|
||||
|
||||
protected $description = 'Sync songs found in configured directory against the database.';
|
||||
|
@ -59,7 +59,11 @@ class SyncCommand extends Command
|
|||
// The tags to ignore from syncing.
|
||||
// Notice that this is only meaningful for existing records.
|
||||
// New records will have every applicable field synced in.
|
||||
$ignores = $this->option('ignore') ? explode(',', $this->option('ignore')) : [];
|
||||
$ignores = collect($this->option('ignore'))->sort()->values()->all();
|
||||
|
||||
if ($ignores) {
|
||||
$this->components->info('Ignoring tag(s): ' . implode(', ', $ignores));
|
||||
}
|
||||
|
||||
$results = $this->mediaSyncService->sync($ignores, $this->option('force'));
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ class SongResource extends JsonResource
|
|||
'play_count' => (int) $this->song->play_count,
|
||||
'track' => $this->song->track,
|
||||
'disc' => $this->song->disc,
|
||||
'genre' => $this->song->genre,
|
||||
'year' => $this->song->year,
|
||||
'created_at' => $this->song->created_at,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ use Laravel\Scout\Searchable;
|
|||
* @property int $track
|
||||
* @property int $disc
|
||||
* @property int $album_id
|
||||
* @property int|null $year
|
||||
* @property string $genre
|
||||
* @property string $id
|
||||
* @property int $artist_id
|
||||
* @property int $mtime
|
||||
|
|
|
@ -90,7 +90,7 @@ class FileSynchronizer
|
|||
$albumArtist = Arr::get($info, 'albumartist') ? Artist::getOrCreate($info['albumartist']) : $artist;
|
||||
$album = Arr::get($info, 'album') ? Album::getOrCreate($albumArtist, $info['album']) : $this->song->album;
|
||||
|
||||
if (!$album->has_cover) {
|
||||
if (!in_array('cover', $ignores, true) && !$album->has_cover) {
|
||||
$this->tryGenerateAlbumCover($album, Arr::get($info, 'cover', []));
|
||||
}
|
||||
|
||||
|
|
|
@ -76,9 +76,13 @@ class SongService
|
|||
$maybeSetAlbum();
|
||||
}
|
||||
|
||||
$song->title = $data->title ?? $song->title; // Empty string still has effects
|
||||
$song->lyrics = $data->lyrics ?? $song->lyrics; // Empty string still has effects
|
||||
// For string attributes like title, lyrics, and genre, we use "??" because empty strings still have effects
|
||||
$song->title = $data->title ?? $song->title;
|
||||
$song->lyrics = $data->lyrics ?? $song->lyrics;
|
||||
$song->genre = $data->genre ?? $song->genre;
|
||||
|
||||
$song->track = $data->track ?: $song->track;
|
||||
$song->year = $data->year ?: $song->year;
|
||||
$song->disc = $data->disc ?: $song->disc;
|
||||
|
||||
$song->push();
|
||||
|
|
|
@ -42,6 +42,8 @@ final class SmartPlaylistRule implements Arrayable
|
|||
private const MODEL_LENGTH = 'length';
|
||||
private const MODEL_DATE_ADDED = 'created_at';
|
||||
private const MODEL_DATE_MODIFIED = 'updated_at';
|
||||
private const MODEL_GENRE = 'genre';
|
||||
private const MODEL_YEAR = 'year';
|
||||
|
||||
private const VALID_MODELS = [
|
||||
self::MODEL_TITLE,
|
||||
|
@ -52,13 +54,13 @@ final class SmartPlaylistRule implements Arrayable
|
|||
self::MODEL_LENGTH,
|
||||
self::MODEL_DATE_ADDED,
|
||||
self::MODEL_DATE_MODIFIED,
|
||||
self::MODEL_GENRE,
|
||||
self::MODEL_YEAR,
|
||||
];
|
||||
|
||||
private const MODEL_COLUMN_MAP = [
|
||||
self::MODEL_TITLE => 'songs.title',
|
||||
self::MODEL_ALBUM_NAME => 'albums.name',
|
||||
self::MODEL_ARTIST_NAME => 'artists.name',
|
||||
self::MODEL_LENGTH => 'songs.length',
|
||||
self::MODEL_DATE_ADDED => 'songs.created_at',
|
||||
self::MODEL_DATE_MODIFIED => 'songs.updated_at',
|
||||
];
|
||||
|
|
|
@ -17,6 +17,8 @@ final class SongScanInformation implements Arrayable
|
|||
public ?string $albumArtistName,
|
||||
public ?int $track,
|
||||
public ?int $disc,
|
||||
public ?int $year,
|
||||
public ?string $genre,
|
||||
public ?string $lyrics,
|
||||
public ?float $length,
|
||||
public ?array $cover,
|
||||
|
@ -65,15 +67,17 @@ final class SongScanInformation implements Arrayable
|
|||
albumArtistName: html_entity_decode($albumArtistName),
|
||||
track: (int) self::getTag($tags, ['track', 'tracknumber', 'track_number']),
|
||||
disc: (int) self::getTag($tags, ['discnumber', 'part_of_a_set'], 1),
|
||||
year: (int) self::getTag($tags, 'year') ?: null,
|
||||
genre: self::getTag($tags, 'genre'),
|
||||
lyrics: $lyrics,
|
||||
length: (float) Arr::get($info, 'playtime_seconds'),
|
||||
cover: $cover,
|
||||
path: $path,
|
||||
mTime: Helper::getModifiedTime($path),
|
||||
mTime: Helper::getModifiedTime($path)
|
||||
);
|
||||
}
|
||||
|
||||
private static function getTag(array $arr, string | array $keys, $default = ''): mixed
|
||||
private static function getTag(array $arr, string|array $keys, $default = ''): mixed
|
||||
{
|
||||
$keys = Arr::wrap($keys);
|
||||
|
||||
|
@ -98,6 +102,8 @@ final class SongScanInformation implements Arrayable
|
|||
'albumartist' => $this->albumArtistName,
|
||||
'track' => $this->track,
|
||||
'disc' => $this->disc,
|
||||
'year' => $this->year,
|
||||
'genre' => $this->genre,
|
||||
'lyrics' => $this->lyrics,
|
||||
'length' => $this->length,
|
||||
'cover' => $this->cover,
|
||||
|
|
|
@ -14,6 +14,8 @@ final class SongUpdateData implements Arrayable
|
|||
public ?string $albumArtistName,
|
||||
public ?int $track,
|
||||
public ?int $disc,
|
||||
public ?string $genre,
|
||||
public ?int $year,
|
||||
public ?string $lyrics,
|
||||
) {
|
||||
$this->albumArtistName = $this->albumArtistName ?: $this->artistName;
|
||||
|
@ -28,6 +30,8 @@ final class SongUpdateData implements Arrayable
|
|||
albumArtistName: $request->input('data.album_artist_name'),
|
||||
track: (int) $request->input('data.track'),
|
||||
disc: (int) $request->input('data.disc'),
|
||||
genre: $request->input('data.genre'),
|
||||
year: (int) $request->input('data.year') ?: null,
|
||||
lyrics: $request->input('data.lyrics'),
|
||||
);
|
||||
}
|
||||
|
@ -39,6 +43,8 @@ final class SongUpdateData implements Arrayable
|
|||
?string $albumArtistName,
|
||||
?int $track,
|
||||
?int $disc,
|
||||
?string $genre,
|
||||
?int $year,
|
||||
?string $lyrics
|
||||
): self {
|
||||
return new self(
|
||||
|
@ -48,6 +54,8 @@ final class SongUpdateData implements Arrayable
|
|||
$albumArtistName,
|
||||
$track,
|
||||
$disc,
|
||||
$genre,
|
||||
$year,
|
||||
$lyrics,
|
||||
);
|
||||
}
|
||||
|
@ -62,6 +70,8 @@ final class SongUpdateData implements Arrayable
|
|||
'album_artist' => $this->albumArtistName,
|
||||
'track' => $this->track,
|
||||
'disc' => $this->disc,
|
||||
'genre' => $this->genre,
|
||||
'year' => $this->year,
|
||||
'lyrics' => $this->lyrics,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -22,8 +22,11 @@ class SongFactory extends Factory
|
|||
'title' => $this->faker->sentence,
|
||||
'length' => $this->faker->randomFloat(2, 10, 500),
|
||||
'track' => random_int(1, 20),
|
||||
'disc' => random_int(1, 5),
|
||||
'lyrics' => $this->faker->paragraph(),
|
||||
'path' => '/tmp/' . uniqid() . '.mp3',
|
||||
'genre' => $this->faker->randomElement(['Rock', 'Pop', 'Jazz', 'Classical', 'Metal', 'Hip Hop', 'Rap']),
|
||||
'year' => $this->faker->year(),
|
||||
'mtime' => time(),
|
||||
];
|
||||
}
|
||||
|
|
16
database/migrations/2022_09_21_084050_more_tags.php
Normal file
16
database/migrations/2022_09_21_084050_more_tags.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('songs', static function (Blueprint $table): void {
|
||||
$table->year('year')->nullable();
|
||||
$table->string('genre')->default('');
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
import { Faker, faker } from '@faker-js/faker'
|
||||
import { genres } from '@/config'
|
||||
|
||||
const generate = (partOfCompilation = false): Song => {
|
||||
const artistId = faker.datatype.number({ min: 3 })
|
||||
|
@ -18,6 +19,8 @@ const generate = (partOfCompilation = false): Song => {
|
|||
length: faker.datatype.number(),
|
||||
track: faker.datatype.number(),
|
||||
disc: faker.datatype.number({ min: 1, max: 2 }),
|
||||
genre: faker.random.arrayElement(genres),
|
||||
year: faker.random.arrayElement([null, 1990, 2000, 2011, 2022]),
|
||||
lyrics: faker.lorem.paragraph(),
|
||||
play_count: faker.datatype.number(),
|
||||
liked: faker.datatype.boolean(),
|
||||
|
|
|
@ -39,7 +39,8 @@ new class extends UnitTestCase {
|
|||
title: 'Rocket to Heaven',
|
||||
artist_name: 'Led Zeppelin',
|
||||
album_name: 'IV',
|
||||
album_cover: 'http://localhost/album.jpg'
|
||||
album_cover: 'http://localhost/album.jpg',
|
||||
genre: 'Rock'
|
||||
}))
|
||||
|
||||
expect(html()).toMatchSnapshot()
|
||||
|
@ -50,6 +51,8 @@ new class extends UnitTestCase {
|
|||
await fireEvent.update(getByTestId('album-input'), 'Back in Black')
|
||||
await fireEvent.update(getByTestId('disc-input'), '1')
|
||||
await fireEvent.update(getByTestId('track-input'), '10')
|
||||
await fireEvent.update(getByTestId('genre-input'), 'Rock & Roll')
|
||||
await fireEvent.update(getByTestId('year-input'), '1971')
|
||||
await fireEvent.update(getByTestId('lyrics-input'), 'I\'m gonna make him an offer he can\'t refuse')
|
||||
|
||||
await fireEvent.click(getByRole('button', { name: 'Update' }))
|
||||
|
@ -61,7 +64,9 @@ new class extends UnitTestCase {
|
|||
album_artist_name: 'AC/DC',
|
||||
lyrics: 'I\'m gonna make him an offer he can\'t refuse',
|
||||
track: 10,
|
||||
disc: 1
|
||||
disc: 1,
|
||||
genre: 'Rock & Roll',
|
||||
year: 1971
|
||||
})
|
||||
|
||||
expect(alertMock).toHaveBeenCalledWith('Updated 1 song.')
|
||||
|
@ -84,6 +89,8 @@ new class extends UnitTestCase {
|
|||
await fireEvent.update(getByTestId('album-input'), 'Back in Black')
|
||||
await fireEvent.update(getByTestId('disc-input'), '1')
|
||||
await fireEvent.update(getByTestId('track-input'), '10')
|
||||
await fireEvent.update(getByTestId('year-input'), '1990')
|
||||
await fireEvent.update(getByTestId('genre-input'), 'Pop')
|
||||
|
||||
await fireEvent.click(getByRole('button', { name: 'Update' }))
|
||||
|
||||
|
@ -92,7 +99,9 @@ new class extends UnitTestCase {
|
|||
artist_name: 'AC/DC',
|
||||
album_artist_name: 'AC/DC',
|
||||
track: 10,
|
||||
disc: 1
|
||||
disc: 1,
|
||||
genre: 'Pop',
|
||||
year: 1990
|
||||
})
|
||||
|
||||
expect(alertMock).toHaveBeenCalledWith('Updated 3 songs.')
|
||||
|
|
|
@ -70,16 +70,28 @@
|
|||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label>
|
||||
Artist
|
||||
<input
|
||||
v-model="formData.artist_name"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="artist-input"
|
||||
name="artist"
|
||||
type="text"
|
||||
>
|
||||
</label>
|
||||
<div class="cols">
|
||||
<label>
|
||||
Artist
|
||||
<input
|
||||
v-model="formData.artist_name"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="artist-input"
|
||||
name="artist"
|
||||
type="text"
|
||||
>
|
||||
</label>
|
||||
<label>
|
||||
Album Artist
|
||||
<input
|
||||
v-model="formData.album_artist_name"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="albumArtist-input"
|
||||
name="album_artist"
|
||||
type="text"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
|
@ -96,46 +108,58 @@
|
|||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label>
|
||||
Album Artist
|
||||
<input
|
||||
v-model="formData.album_artist_name"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="albumArtist-input"
|
||||
name="album_artist"
|
||||
type="text"
|
||||
>
|
||||
</label>
|
||||
<div class="cols">
|
||||
<label>
|
||||
Track
|
||||
<input
|
||||
v-model="formData.track"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="track-input"
|
||||
min="1"
|
||||
name="track"
|
||||
type="number"
|
||||
>
|
||||
</label>
|
||||
<label>
|
||||
Disc
|
||||
<input
|
||||
v-model="formData.disc"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="disc-input"
|
||||
min="1"
|
||||
name="disc"
|
||||
type="number"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="cols">
|
||||
<div>
|
||||
<label>
|
||||
Track
|
||||
<input
|
||||
v-model="formData.track"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="track-input"
|
||||
min="1"
|
||||
name="track"
|
||||
type="number"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
Disc
|
||||
<input
|
||||
v-model="formData.disc"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="disc-input"
|
||||
min="1"
|
||||
name="disc"
|
||||
type="number"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
Genre
|
||||
<input
|
||||
v-model="formData.genre"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="genre-input"
|
||||
name="genre"
|
||||
type="text"
|
||||
list="genres"
|
||||
>
|
||||
<datalist id="genres">
|
||||
<option v-for="genre in genres" :key="genre" :value="genre"/>
|
||||
</datalist>
|
||||
</label>
|
||||
<label>
|
||||
Year
|
||||
<input
|
||||
v-model="formData.year"
|
||||
:placeholder="inputPlaceholder"
|
||||
data-testid="year-input"
|
||||
name="year"
|
||||
type="number"
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -175,6 +199,7 @@ import { isEqual } from 'lodash'
|
|||
import { defaultCover, eventBus, pluralize, requireInjection } from '@/utils'
|
||||
import { songStore, SongUpdateData } from '@/stores'
|
||||
import { DialogBoxKey, EditSongFormInitialTabKey, MessageToasterKey, SongsKey } from '@/symbols'
|
||||
import { genres } from '@/config'
|
||||
|
||||
import Btn from '@/components/ui/Btn.vue'
|
||||
import SoundBars from '@/components/ui/SoundBars.vue'
|
||||
|
@ -199,7 +224,9 @@ const formData = reactive<SongUpdateData>({
|
|||
album_artist_name: '',
|
||||
lyrics: '',
|
||||
track: null,
|
||||
disc: null
|
||||
disc: null,
|
||||
year: null,
|
||||
genre: ''
|
||||
})
|
||||
|
||||
const initialFormData = {}
|
||||
|
@ -261,6 +288,9 @@ const open = async () => {
|
|||
formData.disc = allSongsShareSameValue('disc') ? firstSong.disc : null
|
||||
formData.disc = formData.disc || null // if 0, just don't show it
|
||||
|
||||
formData.year = allSongsShareSameValue('year') ? firstSong.year : null
|
||||
formData.genre = allSongsShareSameValue('genre') ? firstSong.genre : ''
|
||||
|
||||
if (!editingOnlyOneSong.value) {
|
||||
delete formData.title
|
||||
delete formData.lyrics
|
||||
|
@ -330,7 +360,7 @@ form {
|
|||
place-content: space-between;
|
||||
gap: 1rem;
|
||||
|
||||
> div {
|
||||
> * {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,207 @@ exports[`edits a single song 1`] = `
|
|||
<div class="panes" data-v-210b4214="">
|
||||
<div id="editSongPanelDetails" aria-labelledby="editSongTabDetails" role="tabpanel" tabindex="0" data-v-210b4214="">
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Title <input data-testid="title-input" name="title" title="Title" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Artist <input placeholder="" data-testid="artist-input" name="artist" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album <input placeholder="" data-testid="album-input" name="album" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album Artist <input placeholder="" data-testid="albumArtist-input" name="album_artist" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214="">
|
||||
<div data-v-210b4214=""><label data-v-210b4214=""> Track <input placeholder="" data-testid="track-input" min="1" name="track" type="number" data-v-210b4214=""></label></div>
|
||||
<div data-v-210b4214=""><label data-v-210b4214=""> Disc <input placeholder="" data-testid="disc-input" min="1" name="disc" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Artist <input placeholder="" data-testid="artist-input" name="artist" type="text" data-v-210b4214=""></label><label data-v-210b4214=""> Album Artist <input placeholder="" data-testid="albumArtist-input" name="album_artist" type="text" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album <input placeholder="" data-testid="album-input" name="album" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Track <input placeholder="" data-testid="track-input" min="1" name="track" type="number" data-v-210b4214=""></label><label data-v-210b4214=""> Disc <input placeholder="" data-testid="disc-input" min="1" name="disc" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Genre <input placeholder="" data-testid="genre-input" name="genre" type="text" list="genres" data-v-210b4214=""><datalist id="genres" data-v-210b4214="">
|
||||
<option value="Blues" data-v-210b4214=""></option>
|
||||
<option value="Classic Rock" data-v-210b4214=""></option>
|
||||
<option value="Country" data-v-210b4214=""></option>
|
||||
<option value="Dance" data-v-210b4214=""></option>
|
||||
<option value="Disco" data-v-210b4214=""></option>
|
||||
<option value="Funk" data-v-210b4214=""></option>
|
||||
<option value="Grunge" data-v-210b4214=""></option>
|
||||
<option value="Hip-Hop" data-v-210b4214=""></option>
|
||||
<option value="Jazz" data-v-210b4214=""></option>
|
||||
<option value="Metal" data-v-210b4214=""></option>
|
||||
<option value="New Age" data-v-210b4214=""></option>
|
||||
<option value="Oldies" data-v-210b4214=""></option>
|
||||
<option value="Other" data-v-210b4214=""></option>
|
||||
<option value="Pop" data-v-210b4214=""></option>
|
||||
<option value="R&B" data-v-210b4214=""></option>
|
||||
<option value="Rap" data-v-210b4214=""></option>
|
||||
<option value="Reggae" data-v-210b4214=""></option>
|
||||
<option value="Rock" data-v-210b4214=""></option>
|
||||
<option value="Techno" data-v-210b4214=""></option>
|
||||
<option value="Industrial" data-v-210b4214=""></option>
|
||||
<option value="Alternative" data-v-210b4214=""></option>
|
||||
<option value="Ska" data-v-210b4214=""></option>
|
||||
<option value="Death Metal" data-v-210b4214=""></option>
|
||||
<option value="Pranks" data-v-210b4214=""></option>
|
||||
<option value="Soundtrack" data-v-210b4214=""></option>
|
||||
<option value="Euro-Techno" data-v-210b4214=""></option>
|
||||
<option value="Ambient" data-v-210b4214=""></option>
|
||||
<option value="Trip-Hop" data-v-210b4214=""></option>
|
||||
<option value="Vocal" data-v-210b4214=""></option>
|
||||
<option value="Jazz & Funk" data-v-210b4214=""></option>
|
||||
<option value="Fusion" data-v-210b4214=""></option>
|
||||
<option value="Trance" data-v-210b4214=""></option>
|
||||
<option value="Classical" data-v-210b4214=""></option>
|
||||
<option value="Instrumental" data-v-210b4214=""></option>
|
||||
<option value="Acid" data-v-210b4214=""></option>
|
||||
<option value="House" data-v-210b4214=""></option>
|
||||
<option value="Game" data-v-210b4214=""></option>
|
||||
<option value="Sound Clip" data-v-210b4214=""></option>
|
||||
<option value="Gospel" data-v-210b4214=""></option>
|
||||
<option value="Noise" data-v-210b4214=""></option>
|
||||
<option value="Alternative Rock" data-v-210b4214=""></option>
|
||||
<option value="Bass" data-v-210b4214=""></option>
|
||||
<option value="Punk" data-v-210b4214=""></option>
|
||||
<option value="Space" data-v-210b4214=""></option>
|
||||
<option value="Meditative" data-v-210b4214=""></option>
|
||||
<option value="Instrumental Pop" data-v-210b4214=""></option>
|
||||
<option value="Instrumental Rock" data-v-210b4214=""></option>
|
||||
<option value="Ethnic" data-v-210b4214=""></option>
|
||||
<option value="Gothic" data-v-210b4214=""></option>
|
||||
<option value="Darkwave" data-v-210b4214=""></option>
|
||||
<option value="Techno-Industrial" data-v-210b4214=""></option>
|
||||
<option value="Electronic" data-v-210b4214=""></option>
|
||||
<option value="Pop-Folk" data-v-210b4214=""></option>
|
||||
<option value="Eurodance" data-v-210b4214=""></option>
|
||||
<option value="Dream" data-v-210b4214=""></option>
|
||||
<option value="Southern Rock" data-v-210b4214=""></option>
|
||||
<option value="Comedy" data-v-210b4214=""></option>
|
||||
<option value="Cult" data-v-210b4214=""></option>
|
||||
<option value="Gangsta" data-v-210b4214=""></option>
|
||||
<option value="Top 40" data-v-210b4214=""></option>
|
||||
<option value="Christian Rap" data-v-210b4214=""></option>
|
||||
<option value="Pop/Funk" data-v-210b4214=""></option>
|
||||
<option value="Jungle" data-v-210b4214=""></option>
|
||||
<option value="Native US" data-v-210b4214=""></option>
|
||||
<option value="Cabaret" data-v-210b4214=""></option>
|
||||
<option value="New Wave" data-v-210b4214=""></option>
|
||||
<option value="Psychedelic" data-v-210b4214=""></option>
|
||||
<option value="Rave" data-v-210b4214=""></option>
|
||||
<option value="Showtunes" data-v-210b4214=""></option>
|
||||
<option value="Trailer" data-v-210b4214=""></option>
|
||||
<option value="Lo-Fi" data-v-210b4214=""></option>
|
||||
<option value="Tribal" data-v-210b4214=""></option>
|
||||
<option value="Acid Punk" data-v-210b4214=""></option>
|
||||
<option value="Acid Jazz" data-v-210b4214=""></option>
|
||||
<option value="Polka" data-v-210b4214=""></option>
|
||||
<option value="Retro" data-v-210b4214=""></option>
|
||||
<option value="Musical" data-v-210b4214=""></option>
|
||||
<option value="Rock & Roll" data-v-210b4214=""></option>
|
||||
<option value="Hard Rock" data-v-210b4214=""></option>
|
||||
<option value="Folk" data-v-210b4214=""></option>
|
||||
<option value="Folk-Rock" data-v-210b4214=""></option>
|
||||
<option value="National Folk" data-v-210b4214=""></option>
|
||||
<option value="Swing" data-v-210b4214=""></option>
|
||||
<option value="Fast Fusion" data-v-210b4214=""></option>
|
||||
<option value="Bebob" data-v-210b4214=""></option>
|
||||
<option value="Latin" data-v-210b4214=""></option>
|
||||
<option value="Revival" data-v-210b4214=""></option>
|
||||
<option value="Celtic" data-v-210b4214=""></option>
|
||||
<option value="Bluegrass" data-v-210b4214=""></option>
|
||||
<option value="Avantgarde" data-v-210b4214=""></option>
|
||||
<option value="Gothic Rock" data-v-210b4214=""></option>
|
||||
<option value="Progressive Rock" data-v-210b4214=""></option>
|
||||
<option value="Psychedelic Rock" data-v-210b4214=""></option>
|
||||
<option value="Symphonic Rock" data-v-210b4214=""></option>
|
||||
<option value="Slow Rock" data-v-210b4214=""></option>
|
||||
<option value="Big Band" data-v-210b4214=""></option>
|
||||
<option value="Chorus" data-v-210b4214=""></option>
|
||||
<option value="Easy Listening" data-v-210b4214=""></option>
|
||||
<option value="Acoustic" data-v-210b4214=""></option>
|
||||
<option value="Humour" data-v-210b4214=""></option>
|
||||
<option value="Speech" data-v-210b4214=""></option>
|
||||
<option value="Chanson" data-v-210b4214=""></option>
|
||||
<option value="Opera" data-v-210b4214=""></option>
|
||||
<option value="Chamber Music" data-v-210b4214=""></option>
|
||||
<option value="Sonata" data-v-210b4214=""></option>
|
||||
<option value="Symphony" data-v-210b4214=""></option>
|
||||
<option value="Booty Bass" data-v-210b4214=""></option>
|
||||
<option value="Primus" data-v-210b4214=""></option>
|
||||
<option value="Porn Groove" data-v-210b4214=""></option>
|
||||
<option value="Satire" data-v-210b4214=""></option>
|
||||
<option value="Slow Jam" data-v-210b4214=""></option>
|
||||
<option value="Club" data-v-210b4214=""></option>
|
||||
<option value="Tango" data-v-210b4214=""></option>
|
||||
<option value="Samba" data-v-210b4214=""></option>
|
||||
<option value="Folklore" data-v-210b4214=""></option>
|
||||
<option value="Ballad" data-v-210b4214=""></option>
|
||||
<option value="Power Ballad" data-v-210b4214=""></option>
|
||||
<option value="Rhythmic Soul" data-v-210b4214=""></option>
|
||||
<option value="Freestyle" data-v-210b4214=""></option>
|
||||
<option value="Duet" data-v-210b4214=""></option>
|
||||
<option value="Punk Rock" data-v-210b4214=""></option>
|
||||
<option value="Drum Solo" data-v-210b4214=""></option>
|
||||
<option value="A cappella" data-v-210b4214=""></option>
|
||||
<option value="Euro-House" data-v-210b4214=""></option>
|
||||
<option value="Dance Hall" data-v-210b4214=""></option>
|
||||
<option value="Goa" data-v-210b4214=""></option>
|
||||
<option value="Drum & Bass" data-v-210b4214=""></option>
|
||||
<option value="Club-House" data-v-210b4214=""></option>
|
||||
<option value="Hardcore Techno" data-v-210b4214=""></option>
|
||||
<option value="Terror" data-v-210b4214=""></option>
|
||||
<option value="Indie" data-v-210b4214=""></option>
|
||||
<option value="BritPop" data-v-210b4214=""></option>
|
||||
<option value="Negerpunk" data-v-210b4214=""></option>
|
||||
<option value="Polsk Punk" data-v-210b4214=""></option>
|
||||
<option value="Beat" data-v-210b4214=""></option>
|
||||
<option value="Christian Gangsta Rap" data-v-210b4214=""></option>
|
||||
<option value="Heavy Metal" data-v-210b4214=""></option>
|
||||
<option value="Black Metal" data-v-210b4214=""></option>
|
||||
<option value="Crossover" data-v-210b4214=""></option>
|
||||
<option value="Contemporary Christian" data-v-210b4214=""></option>
|
||||
<option value="Christian Rock" data-v-210b4214=""></option>
|
||||
<option value="Merengue" data-v-210b4214=""></option>
|
||||
<option value="Salsa" data-v-210b4214=""></option>
|
||||
<option value="Thrash Metal" data-v-210b4214=""></option>
|
||||
<option value="Anime" data-v-210b4214=""></option>
|
||||
<option value="JPop" data-v-210b4214=""></option>
|
||||
<option value="SynthPop" data-v-210b4214=""></option>
|
||||
<option value="Abstract" data-v-210b4214=""></option>
|
||||
<option value="Art Rock" data-v-210b4214=""></option>
|
||||
<option value="Baroque" data-v-210b4214=""></option>
|
||||
<option value="Bhangra" data-v-210b4214=""></option>
|
||||
<option value="Big beat" data-v-210b4214=""></option>
|
||||
<option value="Breakbeat" data-v-210b4214=""></option>
|
||||
<option value="Chillout" data-v-210b4214=""></option>
|
||||
<option value="Downtempo" data-v-210b4214=""></option>
|
||||
<option value="Dub" data-v-210b4214=""></option>
|
||||
<option value="EBM" data-v-210b4214=""></option>
|
||||
<option value="Eclectic" data-v-210b4214=""></option>
|
||||
<option value="Electro" data-v-210b4214=""></option>
|
||||
<option value="Electroclash" data-v-210b4214=""></option>
|
||||
<option value="Emo" data-v-210b4214=""></option>
|
||||
<option value="Experimental" data-v-210b4214=""></option>
|
||||
<option value="Garage" data-v-210b4214=""></option>
|
||||
<option value="Global" data-v-210b4214=""></option>
|
||||
<option value="IDM" data-v-210b4214=""></option>
|
||||
<option value="Illbient" data-v-210b4214=""></option>
|
||||
<option value="Industro-Goth" data-v-210b4214=""></option>
|
||||
<option value="Jam Band" data-v-210b4214=""></option>
|
||||
<option value="Krautrock" data-v-210b4214=""></option>
|
||||
<option value="Leftfield" data-v-210b4214=""></option>
|
||||
<option value="Lounge" data-v-210b4214=""></option>
|
||||
<option value="Math Rock" data-v-210b4214=""></option>
|
||||
<option value="New Romantic" data-v-210b4214=""></option>
|
||||
<option value="Nu-Breakz" data-v-210b4214=""></option>
|
||||
<option value="Post-Punk" data-v-210b4214=""></option>
|
||||
<option value="Post-Rock" data-v-210b4214=""></option>
|
||||
<option value="Psytrance" data-v-210b4214=""></option>
|
||||
<option value="Shoegaze" data-v-210b4214=""></option>
|
||||
<option value="Space Rock" data-v-210b4214=""></option>
|
||||
<option value="Trop Rock" data-v-210b4214=""></option>
|
||||
<option value="World Music" data-v-210b4214=""></option>
|
||||
<option value="Neoclassical" data-v-210b4214=""></option>
|
||||
<option value="Audiobook" data-v-210b4214=""></option>
|
||||
<option value="Audio Theatre" data-v-210b4214=""></option>
|
||||
<option value="Neue Deutsche Welle" data-v-210b4214=""></option>
|
||||
<option value="Podcast" data-v-210b4214=""></option>
|
||||
<option value="Indie-Rock" data-v-210b4214=""></option>
|
||||
<option value="G-Funk" data-v-210b4214=""></option>
|
||||
<option value="Dubstep" data-v-210b4214=""></option>
|
||||
<option value="Garage Rock" data-v-210b4214=""></option>
|
||||
<option value="Psybient" data-v-210b4214=""></option>
|
||||
</datalist></label><label data-v-210b4214=""> Year <input placeholder="" data-testid="year-input" name="year" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="editSongPanelLyrics" aria-labelledby="editSongTabLyrics" role="tabpanel" tabindex="0" data-v-210b4214="" style="display: none;">
|
||||
|
@ -52,14 +245,207 @@ exports[`edits multiple songs 1`] = `
|
|||
<div class="panes" data-v-210b4214="">
|
||||
<div id="editSongPanelDetails" aria-labelledby="editSongTabDetails" role="tabpanel" tabindex="0" data-v-210b4214="">
|
||||
<!--v-if-->
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Artist <input placeholder="Leave unchanged" data-testid="artist-input" name="artist" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album <input placeholder="Leave unchanged" data-testid="album-input" name="album" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album Artist <input placeholder="Leave unchanged" data-testid="albumArtist-input" name="album_artist" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214="">
|
||||
<div data-v-210b4214=""><label data-v-210b4214=""> Track <input placeholder="Leave unchanged" data-testid="track-input" min="1" name="track" type="number" data-v-210b4214=""></label></div>
|
||||
<div data-v-210b4214=""><label data-v-210b4214=""> Disc <input placeholder="Leave unchanged" data-testid="disc-input" min="1" name="disc" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Artist <input placeholder="Leave unchanged" data-testid="artist-input" name="artist" type="text" data-v-210b4214=""></label><label data-v-210b4214=""> Album Artist <input placeholder="Leave unchanged" data-testid="albumArtist-input" name="album_artist" type="text" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="form-row" data-v-210b4214=""><label data-v-210b4214=""> Album <input placeholder="Leave unchanged" data-testid="album-input" name="album" type="text" data-v-210b4214=""></label></div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Track <input placeholder="Leave unchanged" data-testid="track-input" min="1" name="track" type="number" data-v-210b4214=""></label><label data-v-210b4214=""> Disc <input placeholder="Leave unchanged" data-testid="disc-input" min="1" name="disc" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
<div class="form-row" data-v-210b4214="">
|
||||
<div class="cols" data-v-210b4214=""><label data-v-210b4214=""> Genre <input placeholder="Leave unchanged" data-testid="genre-input" name="genre" type="text" list="genres" data-v-210b4214=""><datalist id="genres" data-v-210b4214="">
|
||||
<option value="Blues" data-v-210b4214=""></option>
|
||||
<option value="Classic Rock" data-v-210b4214=""></option>
|
||||
<option value="Country" data-v-210b4214=""></option>
|
||||
<option value="Dance" data-v-210b4214=""></option>
|
||||
<option value="Disco" data-v-210b4214=""></option>
|
||||
<option value="Funk" data-v-210b4214=""></option>
|
||||
<option value="Grunge" data-v-210b4214=""></option>
|
||||
<option value="Hip-Hop" data-v-210b4214=""></option>
|
||||
<option value="Jazz" data-v-210b4214=""></option>
|
||||
<option value="Metal" data-v-210b4214=""></option>
|
||||
<option value="New Age" data-v-210b4214=""></option>
|
||||
<option value="Oldies" data-v-210b4214=""></option>
|
||||
<option value="Other" data-v-210b4214=""></option>
|
||||
<option value="Pop" data-v-210b4214=""></option>
|
||||
<option value="R&B" data-v-210b4214=""></option>
|
||||
<option value="Rap" data-v-210b4214=""></option>
|
||||
<option value="Reggae" data-v-210b4214=""></option>
|
||||
<option value="Rock" data-v-210b4214=""></option>
|
||||
<option value="Techno" data-v-210b4214=""></option>
|
||||
<option value="Industrial" data-v-210b4214=""></option>
|
||||
<option value="Alternative" data-v-210b4214=""></option>
|
||||
<option value="Ska" data-v-210b4214=""></option>
|
||||
<option value="Death Metal" data-v-210b4214=""></option>
|
||||
<option value="Pranks" data-v-210b4214=""></option>
|
||||
<option value="Soundtrack" data-v-210b4214=""></option>
|
||||
<option value="Euro-Techno" data-v-210b4214=""></option>
|
||||
<option value="Ambient" data-v-210b4214=""></option>
|
||||
<option value="Trip-Hop" data-v-210b4214=""></option>
|
||||
<option value="Vocal" data-v-210b4214=""></option>
|
||||
<option value="Jazz & Funk" data-v-210b4214=""></option>
|
||||
<option value="Fusion" data-v-210b4214=""></option>
|
||||
<option value="Trance" data-v-210b4214=""></option>
|
||||
<option value="Classical" data-v-210b4214=""></option>
|
||||
<option value="Instrumental" data-v-210b4214=""></option>
|
||||
<option value="Acid" data-v-210b4214=""></option>
|
||||
<option value="House" data-v-210b4214=""></option>
|
||||
<option value="Game" data-v-210b4214=""></option>
|
||||
<option value="Sound Clip" data-v-210b4214=""></option>
|
||||
<option value="Gospel" data-v-210b4214=""></option>
|
||||
<option value="Noise" data-v-210b4214=""></option>
|
||||
<option value="Alternative Rock" data-v-210b4214=""></option>
|
||||
<option value="Bass" data-v-210b4214=""></option>
|
||||
<option value="Punk" data-v-210b4214=""></option>
|
||||
<option value="Space" data-v-210b4214=""></option>
|
||||
<option value="Meditative" data-v-210b4214=""></option>
|
||||
<option value="Instrumental Pop" data-v-210b4214=""></option>
|
||||
<option value="Instrumental Rock" data-v-210b4214=""></option>
|
||||
<option value="Ethnic" data-v-210b4214=""></option>
|
||||
<option value="Gothic" data-v-210b4214=""></option>
|
||||
<option value="Darkwave" data-v-210b4214=""></option>
|
||||
<option value="Techno-Industrial" data-v-210b4214=""></option>
|
||||
<option value="Electronic" data-v-210b4214=""></option>
|
||||
<option value="Pop-Folk" data-v-210b4214=""></option>
|
||||
<option value="Eurodance" data-v-210b4214=""></option>
|
||||
<option value="Dream" data-v-210b4214=""></option>
|
||||
<option value="Southern Rock" data-v-210b4214=""></option>
|
||||
<option value="Comedy" data-v-210b4214=""></option>
|
||||
<option value="Cult" data-v-210b4214=""></option>
|
||||
<option value="Gangsta" data-v-210b4214=""></option>
|
||||
<option value="Top 40" data-v-210b4214=""></option>
|
||||
<option value="Christian Rap" data-v-210b4214=""></option>
|
||||
<option value="Pop/Funk" data-v-210b4214=""></option>
|
||||
<option value="Jungle" data-v-210b4214=""></option>
|
||||
<option value="Native US" data-v-210b4214=""></option>
|
||||
<option value="Cabaret" data-v-210b4214=""></option>
|
||||
<option value="New Wave" data-v-210b4214=""></option>
|
||||
<option value="Psychedelic" data-v-210b4214=""></option>
|
||||
<option value="Rave" data-v-210b4214=""></option>
|
||||
<option value="Showtunes" data-v-210b4214=""></option>
|
||||
<option value="Trailer" data-v-210b4214=""></option>
|
||||
<option value="Lo-Fi" data-v-210b4214=""></option>
|
||||
<option value="Tribal" data-v-210b4214=""></option>
|
||||
<option value="Acid Punk" data-v-210b4214=""></option>
|
||||
<option value="Acid Jazz" data-v-210b4214=""></option>
|
||||
<option value="Polka" data-v-210b4214=""></option>
|
||||
<option value="Retro" data-v-210b4214=""></option>
|
||||
<option value="Musical" data-v-210b4214=""></option>
|
||||
<option value="Rock & Roll" data-v-210b4214=""></option>
|
||||
<option value="Hard Rock" data-v-210b4214=""></option>
|
||||
<option value="Folk" data-v-210b4214=""></option>
|
||||
<option value="Folk-Rock" data-v-210b4214=""></option>
|
||||
<option value="National Folk" data-v-210b4214=""></option>
|
||||
<option value="Swing" data-v-210b4214=""></option>
|
||||
<option value="Fast Fusion" data-v-210b4214=""></option>
|
||||
<option value="Bebob" data-v-210b4214=""></option>
|
||||
<option value="Latin" data-v-210b4214=""></option>
|
||||
<option value="Revival" data-v-210b4214=""></option>
|
||||
<option value="Celtic" data-v-210b4214=""></option>
|
||||
<option value="Bluegrass" data-v-210b4214=""></option>
|
||||
<option value="Avantgarde" data-v-210b4214=""></option>
|
||||
<option value="Gothic Rock" data-v-210b4214=""></option>
|
||||
<option value="Progressive Rock" data-v-210b4214=""></option>
|
||||
<option value="Psychedelic Rock" data-v-210b4214=""></option>
|
||||
<option value="Symphonic Rock" data-v-210b4214=""></option>
|
||||
<option value="Slow Rock" data-v-210b4214=""></option>
|
||||
<option value="Big Band" data-v-210b4214=""></option>
|
||||
<option value="Chorus" data-v-210b4214=""></option>
|
||||
<option value="Easy Listening" data-v-210b4214=""></option>
|
||||
<option value="Acoustic" data-v-210b4214=""></option>
|
||||
<option value="Humour" data-v-210b4214=""></option>
|
||||
<option value="Speech" data-v-210b4214=""></option>
|
||||
<option value="Chanson" data-v-210b4214=""></option>
|
||||
<option value="Opera" data-v-210b4214=""></option>
|
||||
<option value="Chamber Music" data-v-210b4214=""></option>
|
||||
<option value="Sonata" data-v-210b4214=""></option>
|
||||
<option value="Symphony" data-v-210b4214=""></option>
|
||||
<option value="Booty Bass" data-v-210b4214=""></option>
|
||||
<option value="Primus" data-v-210b4214=""></option>
|
||||
<option value="Porn Groove" data-v-210b4214=""></option>
|
||||
<option value="Satire" data-v-210b4214=""></option>
|
||||
<option value="Slow Jam" data-v-210b4214=""></option>
|
||||
<option value="Club" data-v-210b4214=""></option>
|
||||
<option value="Tango" data-v-210b4214=""></option>
|
||||
<option value="Samba" data-v-210b4214=""></option>
|
||||
<option value="Folklore" data-v-210b4214=""></option>
|
||||
<option value="Ballad" data-v-210b4214=""></option>
|
||||
<option value="Power Ballad" data-v-210b4214=""></option>
|
||||
<option value="Rhythmic Soul" data-v-210b4214=""></option>
|
||||
<option value="Freestyle" data-v-210b4214=""></option>
|
||||
<option value="Duet" data-v-210b4214=""></option>
|
||||
<option value="Punk Rock" data-v-210b4214=""></option>
|
||||
<option value="Drum Solo" data-v-210b4214=""></option>
|
||||
<option value="A cappella" data-v-210b4214=""></option>
|
||||
<option value="Euro-House" data-v-210b4214=""></option>
|
||||
<option value="Dance Hall" data-v-210b4214=""></option>
|
||||
<option value="Goa" data-v-210b4214=""></option>
|
||||
<option value="Drum & Bass" data-v-210b4214=""></option>
|
||||
<option value="Club-House" data-v-210b4214=""></option>
|
||||
<option value="Hardcore Techno" data-v-210b4214=""></option>
|
||||
<option value="Terror" data-v-210b4214=""></option>
|
||||
<option value="Indie" data-v-210b4214=""></option>
|
||||
<option value="BritPop" data-v-210b4214=""></option>
|
||||
<option value="Negerpunk" data-v-210b4214=""></option>
|
||||
<option value="Polsk Punk" data-v-210b4214=""></option>
|
||||
<option value="Beat" data-v-210b4214=""></option>
|
||||
<option value="Christian Gangsta Rap" data-v-210b4214=""></option>
|
||||
<option value="Heavy Metal" data-v-210b4214=""></option>
|
||||
<option value="Black Metal" data-v-210b4214=""></option>
|
||||
<option value="Crossover" data-v-210b4214=""></option>
|
||||
<option value="Contemporary Christian" data-v-210b4214=""></option>
|
||||
<option value="Christian Rock" data-v-210b4214=""></option>
|
||||
<option value="Merengue" data-v-210b4214=""></option>
|
||||
<option value="Salsa" data-v-210b4214=""></option>
|
||||
<option value="Thrash Metal" data-v-210b4214=""></option>
|
||||
<option value="Anime" data-v-210b4214=""></option>
|
||||
<option value="JPop" data-v-210b4214=""></option>
|
||||
<option value="SynthPop" data-v-210b4214=""></option>
|
||||
<option value="Abstract" data-v-210b4214=""></option>
|
||||
<option value="Art Rock" data-v-210b4214=""></option>
|
||||
<option value="Baroque" data-v-210b4214=""></option>
|
||||
<option value="Bhangra" data-v-210b4214=""></option>
|
||||
<option value="Big beat" data-v-210b4214=""></option>
|
||||
<option value="Breakbeat" data-v-210b4214=""></option>
|
||||
<option value="Chillout" data-v-210b4214=""></option>
|
||||
<option value="Downtempo" data-v-210b4214=""></option>
|
||||
<option value="Dub" data-v-210b4214=""></option>
|
||||
<option value="EBM" data-v-210b4214=""></option>
|
||||
<option value="Eclectic" data-v-210b4214=""></option>
|
||||
<option value="Electro" data-v-210b4214=""></option>
|
||||
<option value="Electroclash" data-v-210b4214=""></option>
|
||||
<option value="Emo" data-v-210b4214=""></option>
|
||||
<option value="Experimental" data-v-210b4214=""></option>
|
||||
<option value="Garage" data-v-210b4214=""></option>
|
||||
<option value="Global" data-v-210b4214=""></option>
|
||||
<option value="IDM" data-v-210b4214=""></option>
|
||||
<option value="Illbient" data-v-210b4214=""></option>
|
||||
<option value="Industro-Goth" data-v-210b4214=""></option>
|
||||
<option value="Jam Band" data-v-210b4214=""></option>
|
||||
<option value="Krautrock" data-v-210b4214=""></option>
|
||||
<option value="Leftfield" data-v-210b4214=""></option>
|
||||
<option value="Lounge" data-v-210b4214=""></option>
|
||||
<option value="Math Rock" data-v-210b4214=""></option>
|
||||
<option value="New Romantic" data-v-210b4214=""></option>
|
||||
<option value="Nu-Breakz" data-v-210b4214=""></option>
|
||||
<option value="Post-Punk" data-v-210b4214=""></option>
|
||||
<option value="Post-Rock" data-v-210b4214=""></option>
|
||||
<option value="Psytrance" data-v-210b4214=""></option>
|
||||
<option value="Shoegaze" data-v-210b4214=""></option>
|
||||
<option value="Space Rock" data-v-210b4214=""></option>
|
||||
<option value="Trop Rock" data-v-210b4214=""></option>
|
||||
<option value="World Music" data-v-210b4214=""></option>
|
||||
<option value="Neoclassical" data-v-210b4214=""></option>
|
||||
<option value="Audiobook" data-v-210b4214=""></option>
|
||||
<option value="Audio Theatre" data-v-210b4214=""></option>
|
||||
<option value="Neue Deutsche Welle" data-v-210b4214=""></option>
|
||||
<option value="Podcast" data-v-210b4214=""></option>
|
||||
<option value="Indie-Rock" data-v-210b4214=""></option>
|
||||
<option value="G-Funk" data-v-210b4214=""></option>
|
||||
<option value="Dubstep" data-v-210b4214=""></option>
|
||||
<option value="Garage Rock" data-v-210b4214=""></option>
|
||||
<option value="Psybient" data-v-210b4214=""></option>
|
||||
</datalist></label><label data-v-210b4214=""> Year <input placeholder="Leave unchanged" data-testid="year-input" name="year" type="number" data-v-210b4214=""></label></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--v-if-->
|
||||
|
|
193
resources/assets/js/config/genres.ts
Normal file
193
resources/assets/js/config/genres.ts
Normal file
|
@ -0,0 +1,193 @@
|
|||
export const genres = [
|
||||
'Blues',
|
||||
'Classic Rock',
|
||||
'Country',
|
||||
'Dance',
|
||||
'Disco',
|
||||
'Funk',
|
||||
'Grunge',
|
||||
'Hip-Hop',
|
||||
'Jazz',
|
||||
'Metal',
|
||||
'New Age',
|
||||
'Oldies',
|
||||
'Other',
|
||||
'Pop',
|
||||
'R&B',
|
||||
'Rap',
|
||||
'Reggae',
|
||||
'Rock',
|
||||
'Techno',
|
||||
'Industrial',
|
||||
'Alternative',
|
||||
'Ska',
|
||||
'Death Metal',
|
||||
'Pranks',
|
||||
'Soundtrack',
|
||||
'Euro-Techno',
|
||||
'Ambient',
|
||||
'Trip-Hop',
|
||||
'Vocal',
|
||||
'Jazz & Funk',
|
||||
'Fusion',
|
||||
'Trance',
|
||||
'Classical',
|
||||
'Instrumental',
|
||||
'Acid',
|
||||
'House',
|
||||
'Game',
|
||||
'Sound Clip',
|
||||
'Gospel',
|
||||
'Noise',
|
||||
'Alternative Rock',
|
||||
'Bass',
|
||||
'Punk',
|
||||
'Space',
|
||||
'Meditative',
|
||||
'Instrumental Pop',
|
||||
'Instrumental Rock',
|
||||
'Ethnic',
|
||||
'Gothic',
|
||||
'Darkwave',
|
||||
'Techno-Industrial',
|
||||
'Electronic',
|
||||
'Pop-Folk',
|
||||
'Eurodance',
|
||||
'Dream',
|
||||
'Southern Rock',
|
||||
'Comedy',
|
||||
'Cult',
|
||||
'Gangsta',
|
||||
'Top 40',
|
||||
'Christian Rap',
|
||||
'Pop/Funk',
|
||||
'Jungle',
|
||||
'Native US',
|
||||
'Cabaret',
|
||||
'New Wave',
|
||||
'Psychedelic',
|
||||
'Rave',
|
||||
'Showtunes',
|
||||
'Trailer',
|
||||
'Lo-Fi',
|
||||
'Tribal',
|
||||
'Acid Punk',
|
||||
'Acid Jazz',
|
||||
'Polka',
|
||||
'Retro',
|
||||
'Musical',
|
||||
'Rock & Roll',
|
||||
'Hard Rock',
|
||||
'Folk',
|
||||
'Folk-Rock',
|
||||
'National Folk',
|
||||
'Swing',
|
||||
'Fast Fusion',
|
||||
'Bebob',
|
||||
'Latin',
|
||||
'Revival',
|
||||
'Celtic',
|
||||
'Bluegrass',
|
||||
'Avantgarde',
|
||||
'Gothic Rock',
|
||||
'Progressive Rock',
|
||||
'Psychedelic Rock',
|
||||
'Symphonic Rock',
|
||||
'Slow Rock',
|
||||
'Big Band',
|
||||
'Chorus',
|
||||
'Easy Listening',
|
||||
'Acoustic',
|
||||
'Humour',
|
||||
'Speech',
|
||||
'Chanson',
|
||||
'Opera',
|
||||
'Chamber Music',
|
||||
'Sonata',
|
||||
'Symphony',
|
||||
'Booty Bass',
|
||||
'Primus',
|
||||
'Porn Groove',
|
||||
'Satire',
|
||||
'Slow Jam',
|
||||
'Club',
|
||||
'Tango',
|
||||
'Samba',
|
||||
'Folklore',
|
||||
'Ballad',
|
||||
'Power Ballad',
|
||||
'Rhythmic Soul',
|
||||
'Freestyle',
|
||||
'Duet',
|
||||
'Punk Rock',
|
||||
'Drum Solo',
|
||||
'A cappella',
|
||||
'Euro-House',
|
||||
'Dance Hall',
|
||||
'Goa',
|
||||
'Drum & Bass',
|
||||
'Club-House',
|
||||
'Hardcore Techno',
|
||||
'Terror',
|
||||
'Indie',
|
||||
'BritPop',
|
||||
'Negerpunk',
|
||||
'Polsk Punk',
|
||||
'Beat',
|
||||
'Christian Gangsta Rap',
|
||||
'Heavy Metal',
|
||||
'Black Metal',
|
||||
'Crossover',
|
||||
'Contemporary Christian',
|
||||
'Christian Rock',
|
||||
'Merengue',
|
||||
'Salsa',
|
||||
'Thrash Metal',
|
||||
'Anime',
|
||||
'JPop',
|
||||
'SynthPop',
|
||||
'Abstract',
|
||||
'Art Rock',
|
||||
'Baroque',
|
||||
'Bhangra',
|
||||
'Big beat',
|
||||
'Breakbeat',
|
||||
'Chillout',
|
||||
'Downtempo',
|
||||
'Dub',
|
||||
'EBM',
|
||||
'Eclectic',
|
||||
'Electro',
|
||||
'Electroclash',
|
||||
'Emo',
|
||||
'Experimental',
|
||||
'Garage',
|
||||
'Global',
|
||||
'IDM',
|
||||
'Illbient',
|
||||
'Industro-Goth',
|
||||
'Jam Band',
|
||||
'Krautrock',
|
||||
'Leftfield',
|
||||
'Lounge',
|
||||
'Math Rock',
|
||||
'New Romantic',
|
||||
'Nu-Breakz',
|
||||
'Post-Punk',
|
||||
'Post-Rock',
|
||||
'Psytrance',
|
||||
'Shoegaze',
|
||||
'Space Rock',
|
||||
'Trop Rock',
|
||||
'World Music',
|
||||
'Neoclassical',
|
||||
'Audiobook',
|
||||
'Audio Theatre',
|
||||
'Neue Deutsche Welle',
|
||||
'Podcast',
|
||||
'Indie-Rock',
|
||||
'G-Funk',
|
||||
'Dubstep',
|
||||
'Garage Rock',
|
||||
'Psybient'
|
||||
]
|
|
@ -1,3 +1,4 @@
|
|||
export * from './events'
|
||||
export * from './upload.types'
|
||||
export * from './acceptedMediaTypes'
|
||||
export * from './genres'
|
||||
|
|
|
@ -11,16 +11,15 @@ const models: SmartPlaylistModel[] = [
|
|||
name: 'artist.name',
|
||||
type: 'text',
|
||||
label: 'Artist'
|
||||
// }, {
|
||||
// name: 'genre',
|
||||
// type: 'text',
|
||||
// label: 'Genre'
|
||||
}, {
|
||||
// name: 'bit_rate',
|
||||
// type: 'number',
|
||||
// label: 'Bit Rate',
|
||||
// unit: 'kbps'
|
||||
// }, {
|
||||
name: 'genre',
|
||||
type: 'text',
|
||||
label: 'Genre'
|
||||
}, {
|
||||
name: 'year',
|
||||
type: 'number',
|
||||
label: 'Year'
|
||||
}, {
|
||||
name: 'interactions.play_count',
|
||||
type: 'number',
|
||||
label: 'Plays'
|
||||
|
|
|
@ -14,6 +14,8 @@ export type SongUpdateData = {
|
|||
track?: number | null
|
||||
disc?: number | null
|
||||
lyrics?: string
|
||||
year?: number | null
|
||||
genre?: string
|
||||
}
|
||||
|
||||
export interface SongUpdateResult {
|
||||
|
|
4
resources/assets/js/types.d.ts
vendored
4
resources/assets/js/types.d.ts
vendored
|
@ -152,6 +152,8 @@ interface Song {
|
|||
readonly length: number
|
||||
track: number | null
|
||||
disc: number | null
|
||||
genre: string
|
||||
year: number | null
|
||||
lyrics: string
|
||||
play_count_registered?: boolean
|
||||
preloaded?: boolean
|
||||
|
@ -170,7 +172,7 @@ interface SmartPlaylistRuleGroup {
|
|||
}
|
||||
|
||||
interface SmartPlaylistModel {
|
||||
name: 'title' | 'length' | 'created_at' | 'updated_at' | 'album.name' | 'artist.name' | 'interactions.play_count' | 'interactions.updated_at'
|
||||
name: 'title' | 'length' | 'created_at' | 'updated_at' | 'album.name' | 'artist.name' | 'interactions.play_count' | 'interactions.updated_at' | 'genre' | 'year'
|
||||
type: 'text' | 'number' | 'date'
|
||||
label: string
|
||||
unit?: 'seconds' | 'days'
|
||||
|
|
|
@ -125,7 +125,6 @@ em {
|
|||
|
||||
label {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
|
||||
&.small {
|
||||
|
|
|
@ -24,6 +24,8 @@ class SongTest extends TestCase
|
|||
'liked',
|
||||
'play_count',
|
||||
'track',
|
||||
'genre',
|
||||
'year',
|
||||
'disc',
|
||||
'created_at',
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue