preparation for song blocking
This commit is contained in:
parent
ce8b2be1fe
commit
43e68bbdf6
27 changed files with 227 additions and 255 deletions
|
@ -8,6 +8,7 @@ class Song extends Equatable {
|
|||
@required this.artist,
|
||||
@required this.path,
|
||||
@required this.duration,
|
||||
@required this.blocked,
|
||||
this.trackNumber,
|
||||
this.albumArtPath,
|
||||
});
|
||||
|
@ -20,6 +21,8 @@ class Song extends Equatable {
|
|||
final int duration;
|
||||
final int trackNumber;
|
||||
final String albumArtPath;
|
||||
/// Is this song blocked in shuffle mode?
|
||||
final bool blocked;
|
||||
|
||||
@override
|
||||
List<Object> get props => [title, album, artist];
|
||||
|
|
|
@ -11,4 +11,6 @@ abstract class MusicDataRepository {
|
|||
Future<Either<Failure, List<Album>>> getAlbums();
|
||||
Future<Either<Failure, List<Artist>>> getArtists();
|
||||
Future<void> updateDatabase();
|
||||
|
||||
Future<void> setSongBlocked(Song song, bool blocked);
|
||||
}
|
|
@ -30,7 +30,6 @@ Future<void> setupGetIt() async {
|
|||
final musicDataStore = MusicDataStore(
|
||||
musicDataRepository: getIt(),
|
||||
);
|
||||
musicDataStore.init();
|
||||
return musicDataStore;
|
||||
},
|
||||
);
|
||||
|
@ -39,14 +38,12 @@ Future<void> setupGetIt() async {
|
|||
final audioStore = AudioStore(
|
||||
audioRepository: getIt(),
|
||||
);
|
||||
audioStore.init();
|
||||
return audioStore;
|
||||
},
|
||||
);
|
||||
getIt.registerFactory<NavigationStore>(
|
||||
() {
|
||||
final navigationStore = NavigationStore();
|
||||
navigationStore.init();
|
||||
return navigationStore;
|
||||
},
|
||||
);
|
||||
|
|
|
@ -4,10 +4,10 @@ import 'package:provider/provider.dart';
|
|||
|
||||
import '../../domain/entities/song.dart';
|
||||
import '../state/audio_store.dart';
|
||||
import '../theming.dart';
|
||||
import '../widgets/album_art.dart';
|
||||
import '../widgets/next_indicator.dart';
|
||||
import '../widgets/playback_control.dart';
|
||||
import '../widgets/song_customization_buttons.dart';
|
||||
import '../widgets/time_progress_indicator.dart';
|
||||
import 'queue_page.dart';
|
||||
|
||||
|
@ -64,30 +64,7 @@ class CurrentlyPlayingPage extends StatelessWidget {
|
|||
const Spacer(
|
||||
flex: 4,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.link,
|
||||
size: 20.0,
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
),
|
||||
const Icon(
|
||||
Icons.favorite,
|
||||
size: 20.0,
|
||||
color: RASPBERRY,
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
),
|
||||
const Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 20.0,
|
||||
),
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
const SongCustomizationButtons(),
|
||||
const Spacer(
|
||||
flex: 3,
|
||||
),
|
||||
|
|
|
@ -14,11 +14,28 @@ class AudioStore extends _AudioStore with _$AudioStore {
|
|||
}
|
||||
|
||||
abstract class _AudioStore with Store {
|
||||
_AudioStore(this._audioRepository);
|
||||
_AudioStore(this._audioRepository) {
|
||||
currentSong = _audioRepository.currentSongStream.asObservable();
|
||||
|
||||
currentPositionStream =
|
||||
_audioRepository.currentPositionStream.asObservable(initialValue: 0);
|
||||
|
||||
queueStream = _audioRepository.queueStream.asObservable(initialValue: []);
|
||||
|
||||
queueIndexStream = _audioRepository.queueIndexStream.asObservable();
|
||||
|
||||
shuffleModeStream = _audioRepository.shuffleModeStream
|
||||
.asObservable(initialValue: ShuffleMode.none);
|
||||
|
||||
_disposers.add(autorun((_) {
|
||||
updateSong(currentSong.value);
|
||||
}));
|
||||
|
||||
playbackStateStream = _audioRepository.playbackStateStream.asObservable();
|
||||
}
|
||||
|
||||
final AudioRepository _audioRepository;
|
||||
|
||||
bool _initialized = false;
|
||||
final List<ReactionDisposer> _disposers = [];
|
||||
|
||||
// TODO: naming and usage confusing!
|
||||
|
@ -42,31 +59,6 @@ abstract class _AudioStore with Store {
|
|||
@observable
|
||||
ObservableStream<ShuffleMode> shuffleModeStream;
|
||||
|
||||
@action
|
||||
void init() {
|
||||
if (!_initialized) {
|
||||
print('AudioStore.init');
|
||||
currentSong = _audioRepository.currentSongStream.asObservable();
|
||||
|
||||
currentPositionStream =
|
||||
_audioRepository.currentPositionStream.asObservable(initialValue: 0);
|
||||
|
||||
queueStream = _audioRepository.queueStream.asObservable(initialValue: []);
|
||||
|
||||
queueIndexStream = _audioRepository.queueIndexStream.asObservable();
|
||||
|
||||
shuffleModeStream = _audioRepository.shuffleModeStream.asObservable(initialValue: ShuffleMode.none);
|
||||
|
||||
_disposers.add(autorun((_) {
|
||||
updateSong(currentSong.value);
|
||||
}));
|
||||
|
||||
playbackStateStream = _audioRepository.playbackStateStream.asObservable();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
print('AudioStore.dispose');
|
||||
for (final ReactionDisposer d in _disposers) {
|
||||
|
|
|
@ -159,19 +159,6 @@ mixin _$AudioStore on _AudioStore, Store {
|
|||
return _$updateSongAsyncAction.run(() => super.updateSong(streamValue));
|
||||
}
|
||||
|
||||
final _$_AudioStoreActionController = ActionController(name: '_AudioStore');
|
||||
|
||||
@override
|
||||
void init() {
|
||||
final _$actionInfo =
|
||||
_$_AudioStoreActionController.startAction(name: '_AudioStore.init');
|
||||
try {
|
||||
return super.init();
|
||||
} finally {
|
||||
_$_AudioStoreActionController.endAction(_$actionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''
|
||||
|
|
|
@ -14,12 +14,14 @@ class MusicDataStore extends _MusicDataStore with _$MusicDataStore {
|
|||
}
|
||||
|
||||
abstract class _MusicDataStore with Store {
|
||||
_MusicDataStore(this._musicDataRepository);
|
||||
_MusicDataStore(this._musicDataRepository) {
|
||||
fetchArtists();
|
||||
fetchAlbums();
|
||||
fetchSongs();
|
||||
}
|
||||
|
||||
final MusicDataRepository _musicDataRepository;
|
||||
|
||||
bool _initialized = false;
|
||||
|
||||
@observable
|
||||
ObservableList<Artist> artists = <Artist>[].asObservable();
|
||||
@observable
|
||||
|
@ -41,18 +43,6 @@ abstract class _MusicDataStore with Store {
|
|||
@observable
|
||||
ObservableList<Song> albumSongs = <Song>[].asObservable();
|
||||
|
||||
@action
|
||||
void init() {
|
||||
if (!_initialized) {
|
||||
print('MusicDataStore.init');
|
||||
fetchArtists();
|
||||
fetchAlbums();
|
||||
fetchSongs();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> updateDatabase() async {
|
||||
isUpdatingDatabase = true;
|
||||
|
@ -122,4 +112,8 @@ abstract class _MusicDataStore with Store {
|
|||
(songList) => albumSongs.addAll(songList),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setSongBlocked(Song song, bool blocked) async {
|
||||
await _musicDataRepository.setSongBlocked(song, blocked);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,20 +169,6 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
|
|||
.run(() => super.fetchSongsFromAlbum(album));
|
||||
}
|
||||
|
||||
final _$_MusicDataStoreActionController =
|
||||
ActionController(name: '_MusicDataStore');
|
||||
|
||||
@override
|
||||
void init() {
|
||||
final _$actionInfo = _$_MusicDataStoreActionController.startAction(
|
||||
name: '_MusicDataStore.init');
|
||||
try {
|
||||
return super.init();
|
||||
} finally {
|
||||
_$_MusicDataStoreActionController.endAction(_$actionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''
|
||||
|
|
|
@ -9,18 +9,8 @@ class NavigationStore extends _NavigationStore with _$NavigationStore {
|
|||
abstract class _NavigationStore with Store {
|
||||
_NavigationStore();
|
||||
|
||||
bool _initialized = false;
|
||||
|
||||
@observable int navIndex = 1;
|
||||
|
||||
@action
|
||||
void init() {
|
||||
if (!_initialized) {
|
||||
print('NavigationStore.init');
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
void setNavIndex(int i) {
|
||||
navIndex = i;
|
||||
|
|
|
@ -27,17 +27,6 @@ mixin _$NavigationStore on _NavigationStore, Store {
|
|||
final _$_NavigationStoreActionController =
|
||||
ActionController(name: '_NavigationStore');
|
||||
|
||||
@override
|
||||
void init() {
|
||||
final _$actionInfo = _$_NavigationStoreActionController.startAction(
|
||||
name: '_NavigationStore.init');
|
||||
try {
|
||||
return super.init();
|
||||
} finally {
|
||||
_$_NavigationStoreActionController.endAction(_$actionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void setNavIndex(int i) {
|
||||
final _$actionInfo = _$_NavigationStoreActionController.startAction(
|
||||
|
|
|
@ -16,41 +16,44 @@ class ShuffleButton extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (BuildContext context) {
|
||||
switch (audioStore.shuffleModeStream.value) {
|
||||
case ShuffleMode.none:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.shuffle,
|
||||
color: Colors.white24,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.standard);
|
||||
},
|
||||
);
|
||||
case ShuffleMode.standard:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.shuffle,
|
||||
color: Colors.white,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.none);
|
||||
},
|
||||
);
|
||||
default:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.shuffle,
|
||||
color: Colors.blue,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.none);
|
||||
},
|
||||
);
|
||||
if (audioStore.shuffleModeStream != null) {
|
||||
switch (audioStore.shuffleModeStream.value) {
|
||||
case ShuffleMode.none:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.shuffle,
|
||||
color: Colors.white24,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.standard);
|
||||
},
|
||||
);
|
||||
case ShuffleMode.standard:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.shuffle,
|
||||
color: Colors.white,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.plus);
|
||||
},
|
||||
);
|
||||
case ShuffleMode.plus:
|
||||
return IconButton(
|
||||
icon: const Icon(
|
||||
Icons.fingerprint,
|
||||
color: Colors.white,
|
||||
),
|
||||
iconSize: iconSize,
|
||||
onPressed: () {
|
||||
audioStore.setShuffleMode(ShuffleMode.none);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
48
lib/presentation/widgets/song_customization_buttons.dart
Normal file
48
lib/presentation/widgets/song_customization_buttons.dart
Normal file
|
@ -0,0 +1,48 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../state/audio_store.dart';
|
||||
import '../state/music_data_store.dart';
|
||||
import '../theming.dart';
|
||||
|
||||
class SongCustomizationButtons extends StatelessWidget {
|
||||
const SongCustomizationButtons({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final MusicDataStore musicDataStore = Provider.of<MusicDataStore>(context);
|
||||
final AudioStore audioStore = Provider.of<AudioStore>(context);
|
||||
|
||||
return Observer(
|
||||
builder: (BuildContext context) => Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.link,
|
||||
size: 20.0,
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
),
|
||||
const Icon(
|
||||
Icons.favorite,
|
||||
size: 20.0,
|
||||
color: RASPBERRY,
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.remove_circle_outline,
|
||||
size: 20.0,
|
||||
color: audioStore.song.blocked ? Colors.red : Colors.white70,
|
||||
),
|
||||
onPressed: () => musicDataStore.setSongBlocked(audioStore.song, !audioStore.song.blocked),
|
||||
),
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -105,6 +105,7 @@ class AudioManagerImpl implements AudioManager {
|
|||
|
||||
@override
|
||||
Future<void> play() async {
|
||||
await _startAudioService();
|
||||
await AudioService.play();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,13 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
await super.onStop();
|
||||
}
|
||||
|
||||
// @override
|
||||
// Future<void> onClose() async {
|
||||
// audioPlayer.stop();
|
||||
// AudioServiceBackground.setState(controls: null, processingState: null, playing: false);
|
||||
// AudioServiceBackground.setMediaItem(null);
|
||||
// }
|
||||
|
||||
@override
|
||||
Future<void> onPlay() async {
|
||||
audioPlayer.play();
|
||||
|
@ -152,7 +159,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
|
||||
Future<void> playPlaylist(List<MediaItem> mediaItems, int index) async {
|
||||
final permutation =
|
||||
qm.generatePermutation(shuffleMode, mediaItems.length, index);
|
||||
qm.generatePermutation(shuffleMode, mediaItems, index);
|
||||
playbackContext = qm.getPermutatedSongs(mediaItems, permutation);
|
||||
originalPlaybackContext = mediaItems;
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ class Albums extends Table {
|
|||
TextColumn get artist => text()();
|
||||
TextColumn get albumArtPath => text().nullable()();
|
||||
IntColumn get year => integer().nullable()();
|
||||
BoolColumn get present => boolean().withDefault(const Constant(true))();
|
||||
}
|
||||
|
||||
@DataClassName('MoorSong')
|
||||
|
@ -44,7 +43,7 @@ class Songs extends Table {
|
|||
IntColumn get duration => integer().nullable()();
|
||||
TextColumn get albumArtPath => text().nullable()();
|
||||
IntColumn get trackNumber => integer().nullable()();
|
||||
BoolColumn get present => boolean().withDefault(const Constant(true))();
|
||||
BoolColumn get blocked => boolean().withDefault(const Constant(false))();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {path};
|
||||
|
|
|
@ -161,20 +161,17 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
final String artist;
|
||||
final String albumArtPath;
|
||||
final int year;
|
||||
final bool present;
|
||||
MoorAlbum(
|
||||
{@required this.id,
|
||||
@required this.title,
|
||||
@required this.artist,
|
||||
this.albumArtPath,
|
||||
this.year,
|
||||
@required this.present});
|
||||
this.year});
|
||||
factory MoorAlbum.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
final intType = db.typeSystem.forDartType<int>();
|
||||
final stringType = db.typeSystem.forDartType<String>();
|
||||
final boolType = db.typeSystem.forDartType<bool>();
|
||||
return MoorAlbum(
|
||||
id: intType.mapFromDatabaseResponse(data['${effectivePrefix}id']),
|
||||
title:
|
||||
|
@ -184,8 +181,6 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
albumArtPath: stringType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}album_art_path']),
|
||||
year: intType.mapFromDatabaseResponse(data['${effectivePrefix}year']),
|
||||
present:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -206,9 +201,6 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
if (!nullToAbsent || year != null) {
|
||||
map['year'] = Variable<int>(year);
|
||||
}
|
||||
if (!nullToAbsent || present != null) {
|
||||
map['present'] = Variable<bool>(present);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -223,9 +215,6 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
? const Value.absent()
|
||||
: Value(albumArtPath),
|
||||
year: year == null && nullToAbsent ? const Value.absent() : Value(year),
|
||||
present: present == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(present),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -238,7 +227,6 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
artist: serializer.fromJson<String>(json['artist']),
|
||||
albumArtPath: serializer.fromJson<String>(json['albumArtPath']),
|
||||
year: serializer.fromJson<int>(json['year']),
|
||||
present: serializer.fromJson<bool>(json['present']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -250,7 +238,6 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
'artist': serializer.toJson<String>(artist),
|
||||
'albumArtPath': serializer.toJson<String>(albumArtPath),
|
||||
'year': serializer.toJson<int>(year),
|
||||
'present': serializer.toJson<bool>(present),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -259,15 +246,13 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
String title,
|
||||
String artist,
|
||||
String albumArtPath,
|
||||
int year,
|
||||
bool present}) =>
|
||||
int year}) =>
|
||||
MoorAlbum(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
artist: artist ?? this.artist,
|
||||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
year: year ?? this.year,
|
||||
present: present ?? this.present,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -276,8 +261,7 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
..write('title: $title, ')
|
||||
..write('artist: $artist, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('year: $year, ')
|
||||
..write('present: $present')
|
||||
..write('year: $year')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -288,9 +272,7 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
$mrjc(
|
||||
title.hashCode,
|
||||
$mrjc(
|
||||
artist.hashCode,
|
||||
$mrjc(albumArtPath.hashCode,
|
||||
$mrjc(year.hashCode, present.hashCode))))));
|
||||
artist.hashCode, $mrjc(albumArtPath.hashCode, year.hashCode)))));
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -299,8 +281,7 @@ class MoorAlbum extends DataClass implements Insertable<MoorAlbum> {
|
|||
other.title == this.title &&
|
||||
other.artist == this.artist &&
|
||||
other.albumArtPath == this.albumArtPath &&
|
||||
other.year == this.year &&
|
||||
other.present == this.present);
|
||||
other.year == this.year);
|
||||
}
|
||||
|
||||
class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
||||
|
@ -309,14 +290,12 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
final Value<String> artist;
|
||||
final Value<String> albumArtPath;
|
||||
final Value<int> year;
|
||||
final Value<bool> present;
|
||||
const AlbumsCompanion({
|
||||
this.id = const Value.absent(),
|
||||
this.title = const Value.absent(),
|
||||
this.artist = const Value.absent(),
|
||||
this.albumArtPath = const Value.absent(),
|
||||
this.year = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
});
|
||||
AlbumsCompanion.insert({
|
||||
this.id = const Value.absent(),
|
||||
|
@ -324,7 +303,6 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
@required String artist,
|
||||
this.albumArtPath = const Value.absent(),
|
||||
this.year = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
}) : title = Value(title),
|
||||
artist = Value(artist);
|
||||
static Insertable<MoorAlbum> custom({
|
||||
|
@ -333,7 +311,6 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
Expression<String> artist,
|
||||
Expression<String> albumArtPath,
|
||||
Expression<int> year,
|
||||
Expression<bool> present,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (id != null) 'id': id,
|
||||
|
@ -341,7 +318,6 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
if (artist != null) 'artist': artist,
|
||||
if (albumArtPath != null) 'album_art_path': albumArtPath,
|
||||
if (year != null) 'year': year,
|
||||
if (present != null) 'present': present,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -350,15 +326,13 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
Value<String> title,
|
||||
Value<String> artist,
|
||||
Value<String> albumArtPath,
|
||||
Value<int> year,
|
||||
Value<bool> present}) {
|
||||
Value<int> year}) {
|
||||
return AlbumsCompanion(
|
||||
id: id ?? this.id,
|
||||
title: title ?? this.title,
|
||||
artist: artist ?? this.artist,
|
||||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
year: year ?? this.year,
|
||||
present: present ?? this.present,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -380,9 +354,6 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
if (year.present) {
|
||||
map['year'] = Variable<int>(year.value);
|
||||
}
|
||||
if (present.present) {
|
||||
map['present'] = Variable<bool>(present.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -393,8 +364,7 @@ class AlbumsCompanion extends UpdateCompanion<MoorAlbum> {
|
|||
..write('title: $title, ')
|
||||
..write('artist: $artist, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('year: $year, ')
|
||||
..write('present: $present')
|
||||
..write('year: $year')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -463,18 +433,8 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, MoorAlbum> {
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _presentMeta = const VerificationMeta('present');
|
||||
GeneratedBoolColumn _present;
|
||||
@override
|
||||
GeneratedBoolColumn get present => _present ??= _constructPresent();
|
||||
GeneratedBoolColumn _constructPresent() {
|
||||
return GeneratedBoolColumn('present', $tableName, false,
|
||||
defaultValue: const Constant(true));
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns =>
|
||||
[id, title, artist, albumArtPath, year, present];
|
||||
List<GeneratedColumn> get $columns => [id, title, artist, albumArtPath, year];
|
||||
@override
|
||||
$AlbumsTable get asDslTable => this;
|
||||
@override
|
||||
|
@ -511,10 +471,6 @@ class $AlbumsTable extends Albums with TableInfo<$AlbumsTable, MoorAlbum> {
|
|||
context.handle(
|
||||
_yearMeta, year.isAcceptableOrUnknown(data['year'], _yearMeta));
|
||||
}
|
||||
if (data.containsKey('present')) {
|
||||
context.handle(_presentMeta,
|
||||
present.isAcceptableOrUnknown(data['present'], _presentMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -541,7 +497,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
final int duration;
|
||||
final String albumArtPath;
|
||||
final int trackNumber;
|
||||
final bool present;
|
||||
final bool blocked;
|
||||
MoorSong(
|
||||
{@required this.title,
|
||||
@required this.albumTitle,
|
||||
|
@ -551,7 +507,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
this.duration,
|
||||
this.albumArtPath,
|
||||
this.trackNumber,
|
||||
@required this.present});
|
||||
@required this.blocked});
|
||||
factory MoorSong.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
|
@ -574,8 +530,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
.mapFromDatabaseResponse(data['${effectivePrefix}album_art_path']),
|
||||
trackNumber: intType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}track_number']),
|
||||
present:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']),
|
||||
blocked:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}blocked']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -605,8 +561,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
if (!nullToAbsent || trackNumber != null) {
|
||||
map['track_number'] = Variable<int>(trackNumber);
|
||||
}
|
||||
if (!nullToAbsent || present != null) {
|
||||
map['present'] = Variable<bool>(present);
|
||||
if (!nullToAbsent || blocked != null) {
|
||||
map['blocked'] = Variable<bool>(blocked);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -633,9 +589,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
trackNumber: trackNumber == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(trackNumber),
|
||||
present: present == null && nullToAbsent
|
||||
blocked: blocked == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(present),
|
||||
: Value(blocked),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -651,7 +607,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
duration: serializer.fromJson<int>(json['duration']),
|
||||
albumArtPath: serializer.fromJson<String>(json['albumArtPath']),
|
||||
trackNumber: serializer.fromJson<int>(json['trackNumber']),
|
||||
present: serializer.fromJson<bool>(json['present']),
|
||||
blocked: serializer.fromJson<bool>(json['blocked']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -666,7 +622,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
'duration': serializer.toJson<int>(duration),
|
||||
'albumArtPath': serializer.toJson<String>(albumArtPath),
|
||||
'trackNumber': serializer.toJson<int>(trackNumber),
|
||||
'present': serializer.toJson<bool>(present),
|
||||
'blocked': serializer.toJson<bool>(blocked),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -679,7 +635,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
int duration,
|
||||
String albumArtPath,
|
||||
int trackNumber,
|
||||
bool present}) =>
|
||||
bool blocked}) =>
|
||||
MoorSong(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -689,7 +645,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
duration: duration ?? this.duration,
|
||||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
present: present ?? this.present,
|
||||
blocked: blocked ?? this.blocked,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -702,7 +658,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
..write('duration: $duration, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('present: $present')
|
||||
..write('blocked: $blocked')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -723,7 +679,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
$mrjc(
|
||||
albumArtPath.hashCode,
|
||||
$mrjc(trackNumber.hashCode,
|
||||
present.hashCode)))))))));
|
||||
blocked.hashCode)))))))));
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -736,7 +692,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
other.duration == this.duration &&
|
||||
other.albumArtPath == this.albumArtPath &&
|
||||
other.trackNumber == this.trackNumber &&
|
||||
other.present == this.present);
|
||||
other.blocked == this.blocked);
|
||||
}
|
||||
|
||||
class SongsCompanion extends UpdateCompanion<MoorSong> {
|
||||
|
@ -748,7 +704,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
final Value<int> duration;
|
||||
final Value<String> albumArtPath;
|
||||
final Value<int> trackNumber;
|
||||
final Value<bool> present;
|
||||
final Value<bool> blocked;
|
||||
const SongsCompanion({
|
||||
this.title = const Value.absent(),
|
||||
this.albumTitle = const Value.absent(),
|
||||
|
@ -758,7 +714,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.duration = const Value.absent(),
|
||||
this.albumArtPath = const Value.absent(),
|
||||
this.trackNumber = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
});
|
||||
SongsCompanion.insert({
|
||||
@required String title,
|
||||
|
@ -769,7 +725,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.duration = const Value.absent(),
|
||||
this.albumArtPath = const Value.absent(),
|
||||
this.trackNumber = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
}) : title = Value(title),
|
||||
albumTitle = Value(albumTitle),
|
||||
albumId = Value(albumId),
|
||||
|
@ -784,7 +740,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
Expression<int> duration,
|
||||
Expression<String> albumArtPath,
|
||||
Expression<int> trackNumber,
|
||||
Expression<bool> present,
|
||||
Expression<bool> blocked,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (title != null) 'title': title,
|
||||
|
@ -795,7 +751,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (duration != null) 'duration': duration,
|
||||
if (albumArtPath != null) 'album_art_path': albumArtPath,
|
||||
if (trackNumber != null) 'track_number': trackNumber,
|
||||
if (present != null) 'present': present,
|
||||
if (blocked != null) 'blocked': blocked,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -808,7 +764,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
Value<int> duration,
|
||||
Value<String> albumArtPath,
|
||||
Value<int> trackNumber,
|
||||
Value<bool> present}) {
|
||||
Value<bool> blocked}) {
|
||||
return SongsCompanion(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -818,7 +774,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
duration: duration ?? this.duration,
|
||||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
present: present ?? this.present,
|
||||
blocked: blocked ?? this.blocked,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -849,8 +805,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (trackNumber.present) {
|
||||
map['track_number'] = Variable<int>(trackNumber.value);
|
||||
}
|
||||
if (present.present) {
|
||||
map['present'] = Variable<bool>(present.value);
|
||||
if (blocked.present) {
|
||||
map['blocked'] = Variable<bool>(blocked.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -866,7 +822,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
..write('duration: $duration, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('present: $present')
|
||||
..write('blocked: $blocked')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -976,13 +932,13 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _presentMeta = const VerificationMeta('present');
|
||||
GeneratedBoolColumn _present;
|
||||
final VerificationMeta _blockedMeta = const VerificationMeta('blocked');
|
||||
GeneratedBoolColumn _blocked;
|
||||
@override
|
||||
GeneratedBoolColumn get present => _present ??= _constructPresent();
|
||||
GeneratedBoolColumn _constructPresent() {
|
||||
return GeneratedBoolColumn('present', $tableName, false,
|
||||
defaultValue: const Constant(true));
|
||||
GeneratedBoolColumn get blocked => _blocked ??= _constructBlocked();
|
||||
GeneratedBoolColumn _constructBlocked() {
|
||||
return GeneratedBoolColumn('blocked', $tableName, false,
|
||||
defaultValue: const Constant(false));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -995,7 +951,7 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
duration,
|
||||
albumArtPath,
|
||||
trackNumber,
|
||||
present
|
||||
blocked
|
||||
];
|
||||
@override
|
||||
$SongsTable get asDslTable => this;
|
||||
|
@ -1056,9 +1012,9 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
trackNumber.isAcceptableOrUnknown(
|
||||
data['track_number'], _trackNumberMeta));
|
||||
}
|
||||
if (data.containsKey('present')) {
|
||||
context.handle(_presentMeta,
|
||||
present.isAcceptableOrUnknown(data['present'], _presentMeta));
|
||||
if (data.containsKey('blocked')) {
|
||||
context.handle(_blockedMeta,
|
||||
blocked.isAcceptableOrUnknown(data['blocked'], _blockedMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,10 @@ class QueueManager {
|
|||
|
||||
// TODO: test
|
||||
List<int> generatePermutation(
|
||||
ShuffleMode shuffleMode, int length, int startIndex) {
|
||||
ShuffleMode shuffleMode, List<MediaItem> mediaItems, int startIndex) {
|
||||
// permutation[i] = j; => song j is on the i-th position in the permutated list
|
||||
List<int> permutation;
|
||||
final int length = mediaItems.length;
|
||||
|
||||
switch (shuffleMode) {
|
||||
case ShuffleMode.none:
|
||||
|
@ -39,7 +40,7 @@ class QueueManager {
|
|||
permutation = [startIndex] + tmp;
|
||||
break;
|
||||
case ShuffleMode.plus:
|
||||
break;
|
||||
permutation = generatePlusPermutation(mediaItems, startIndex);
|
||||
}
|
||||
|
||||
return permutation;
|
||||
|
@ -57,4 +58,15 @@ class QueueManager {
|
|||
.map((MediaItem m) => AudioSource.uri(Uri.file(m.id)))
|
||||
.toList());
|
||||
}
|
||||
|
||||
List<int> generatePlusPermutation(
|
||||
List<MediaItem> mediaItems, int startIndex) {
|
||||
final List<int> indices = [];
|
||||
for (var i = 0; i < mediaItems.length; i++) {
|
||||
if (!(mediaItems[i].extras['blocked'] as bool)) {
|
||||
indices.add(i);
|
||||
}
|
||||
}
|
||||
return [startIndex] + indices..removeAt(startIndex)..shuffle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ class SongModel extends Song {
|
|||
@required String artist,
|
||||
@required String path,
|
||||
@required int duration,
|
||||
@required bool blocked,
|
||||
int trackNumber,
|
||||
String albumArtPath})
|
||||
: super(
|
||||
|
@ -22,6 +23,7 @@ class SongModel extends Song {
|
|||
artist: artist,
|
||||
path: path,
|
||||
duration: duration,
|
||||
blocked: blocked,
|
||||
trackNumber: trackNumber,
|
||||
albumArtPath: albumArtPath,
|
||||
);
|
||||
|
@ -33,8 +35,9 @@ class SongModel extends Song {
|
|||
albumId: moorSong.albumId,
|
||||
path: moorSong.path,
|
||||
duration: moorSong.duration,
|
||||
albumArtPath: moorSong.albumArtPath,
|
||||
blocked: moorSong.blocked,
|
||||
trackNumber: moorSong.trackNumber,
|
||||
albumArtPath: moorSong.albumArtPath,
|
||||
);
|
||||
|
||||
factory SongModel.fromSongInfo(SongInfo songInfo) {
|
||||
|
@ -47,6 +50,7 @@ class SongModel extends Song {
|
|||
albumId: int.parse(songInfo.albumId),
|
||||
path: songInfo.filePath,
|
||||
duration: duration == null ? null : int.parse(duration),
|
||||
blocked: false,
|
||||
albumArtPath: songInfo.albumArtwork,
|
||||
trackNumber: _parseTrackNumber(songInfo.track),
|
||||
);
|
||||
|
@ -74,6 +78,7 @@ class SongModel extends Song {
|
|||
artist: mediaItem.artist,
|
||||
path: mediaItem.id,
|
||||
duration: mediaItem.duration.inMilliseconds,
|
||||
blocked: mediaItem.extras['blocked'] == 'true',
|
||||
albumArtPath: artUri,
|
||||
trackNumber: trackNumber,
|
||||
);
|
||||
|
@ -92,6 +97,7 @@ class SongModel extends Song {
|
|||
String artist,
|
||||
String path,
|
||||
int duration,
|
||||
bool blocked,
|
||||
int trackNumber,
|
||||
String albumArtPath,
|
||||
int albumId,
|
||||
|
@ -102,6 +108,7 @@ class SongModel extends Song {
|
|||
duration: duration ?? this.duration,
|
||||
path: path ?? this.path,
|
||||
title: title ?? this.title,
|
||||
blocked: blocked ?? this.blocked,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
albumId: albumId ?? this.albumId,
|
||||
|
@ -114,6 +121,7 @@ class SongModel extends Song {
|
|||
title: Value(title),
|
||||
path: Value(path),
|
||||
duration: Value(duration),
|
||||
blocked: Value(blocked),
|
||||
albumArtPath: Value(albumArtPath),
|
||||
trackNumber: Value(trackNumber),
|
||||
);
|
||||
|
@ -127,6 +135,7 @@ class SongModel extends Song {
|
|||
artUri: 'file://$albumArtPath',
|
||||
extras: {
|
||||
'albumId': albumId,
|
||||
'blocked': blocked.toString(),
|
||||
'trackNumber': trackNumber,
|
||||
});
|
||||
|
||||
|
|
|
@ -74,4 +74,10 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
await musicDataSource.insertSong(songToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setSongBlocked(Song song, bool blocked) {
|
||||
// TODO: implement setSongBlocked
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,14 +42,14 @@ packages:
|
|||
name: audio_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.0"
|
||||
version: "0.15.0"
|
||||
audio_session:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: audio_session
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.3"
|
||||
version: "0.0.7"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -17,7 +17,7 @@ dependencies:
|
|||
|
||||
flutter_audio_query: ^0.3.5
|
||||
|
||||
audio_service: ^0.14.0
|
||||
audio_service: ^0.15.0
|
||||
audio_session: ^0.0.3
|
||||
just_audio: ^0.4.0
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ void main() {
|
|||
artist: ARTIST_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
);
|
||||
|
|
|
@ -66,7 +66,6 @@ void main() {
|
|||
title: ALBUM_TITLE_1,
|
||||
albumArtPath: ALBUM_ART_PATH_1,
|
||||
year: YEAR_1,
|
||||
present: PRESENT_1,
|
||||
);
|
||||
|
||||
const expected = AlbumModel(
|
||||
|
@ -92,7 +91,6 @@ void main() {
|
|||
artist: ARTIST_1,
|
||||
title: ALBUM_TITLE_1,
|
||||
year: YEAR_1,
|
||||
present: PRESENT_1,
|
||||
);
|
||||
|
||||
const expected = AlbumModel(
|
||||
|
@ -117,7 +115,6 @@ void main() {
|
|||
artist: ARTIST_1,
|
||||
title: ALBUM_TITLE_1,
|
||||
albumArtPath: ALBUM_ART_PATH_1,
|
||||
present: PRESENT_1,
|
||||
);
|
||||
|
||||
const expected = AlbumModel(
|
||||
|
|
|
@ -19,6 +19,7 @@ void main() {
|
|||
artist: ARTIST_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
);
|
||||
|
@ -43,6 +44,7 @@ void main() {
|
|||
title: Value(SONG_TITLE_3),
|
||||
path: Value(PATH_3),
|
||||
duration: Value(DURATION_3),
|
||||
blocked: Value(BLOCKED_3),
|
||||
albumArtPath: Value(ALBUM_ART_PATH_3),
|
||||
trackNumber: Value(TRACKNUMBER_3),
|
||||
);
|
||||
|
@ -54,6 +56,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -86,6 +89,7 @@ void main() {
|
|||
extras: {
|
||||
'albumId': ALBUM_ID_3,
|
||||
'trackNumber': TRACKNUMBER_3,
|
||||
'blocked': BLOCKED_3
|
||||
});
|
||||
|
||||
const songModel = SongModel(
|
||||
|
@ -95,6 +99,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -126,7 +131,7 @@ void main() {
|
|||
duration: DURATION_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
present: PRESENT_3,
|
||||
blocked: BLOCKED_3,
|
||||
);
|
||||
|
||||
const expected = SongModel(
|
||||
|
@ -136,6 +141,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -163,7 +169,7 @@ void main() {
|
|||
});
|
||||
|
||||
test(
|
||||
'should create SongModel from AlbumInfo',
|
||||
'should create SongModel from SongInfo',
|
||||
() async {
|
||||
// arrange
|
||||
const expected = SongModel(
|
||||
|
@ -173,6 +179,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: false,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -199,6 +206,7 @@ void main() {
|
|||
extras: {
|
||||
'albumId': ALBUM_ID_3,
|
||||
'trackNumber': TRACKNUMBER_3,
|
||||
'blocked': BLOCKED_3,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -209,6 +217,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -244,6 +253,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -260,6 +270,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
@ -281,6 +292,7 @@ void main() {
|
|||
title: SONG_TITLE_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
);
|
||||
|
|
|
@ -41,6 +41,7 @@ List<SongModel> setupSongList() => [
|
|||
artist: ARTIST_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
),
|
||||
|
@ -51,6 +52,7 @@ List<SongModel> setupSongList() => [
|
|||
artist: ARTIST_4,
|
||||
path: PATH_4,
|
||||
duration: DURATION_4,
|
||||
blocked: BLOCKED_4,
|
||||
trackNumber: TRACKNUMBER_4,
|
||||
albumArtPath: ALBUM_ART_PATH_4,
|
||||
),
|
||||
|
|
|
@ -127,6 +127,7 @@ List<SongModel> setupSongList() => [
|
|||
artist: ARTIST_3,
|
||||
path: PATH_3,
|
||||
duration: DURATION_3,
|
||||
blocked: BLOCKED_3,
|
||||
trackNumber: TRACKNUMBER_3,
|
||||
albumArtPath: ALBUM_ART_PATH_3,
|
||||
),
|
||||
|
@ -137,6 +138,7 @@ List<SongModel> setupSongList() => [
|
|||
artist: ARTIST_4,
|
||||
path: PATH_4,
|
||||
duration: DURATION_4,
|
||||
blocked: BLOCKED_4,
|
||||
trackNumber: TRACKNUMBER_4,
|
||||
albumArtPath: ALBUM_ART_PATH_4,
|
||||
),
|
||||
|
|
|
@ -26,7 +26,7 @@ const String PATH_3 = '/music/parkwaydrive/bottom_feeder.mp3';
|
|||
const int DURATION_3 = 180000;
|
||||
const String ALBUM_ART_PATH_3 = '/music/parkwaydrive/ire.jpg';
|
||||
const int TRACKNUMBER_3 = 7;
|
||||
const bool PRESENT_3 = true;
|
||||
const bool BLOCKED_3 = false;
|
||||
|
||||
const String SONG_TITLE_4 = 'Black Flame';
|
||||
const String ALBUM_TITLE_4 = 'Black Flame';
|
||||
|
@ -36,4 +36,4 @@ const String PATH_4 = '/music/burytomorrow/blackflame.mp3';
|
|||
const int DURATION_4 = 240000;
|
||||
const String ALBUM_ART_PATH_4 = '/music/parkwaydrive/blackflame.jpg';
|
||||
const int TRACKNUMBER_4 = 3;
|
||||
const bool PRESENT_4 = false;
|
||||
const bool BLOCKED_4 = false;
|
Loading…
Add table
Reference in a new issue