fixed build issues; song: next/previous; cosmetics

This commit is contained in:
Moritz 2020-10-18 12:18:37 +02:00
parent 461844e545
commit cbb8559954
15 changed files with 329 additions and 175 deletions

View file

@ -64,4 +64,5 @@ dependencies {
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1' androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
} }

View file

@ -3,28 +3,33 @@ import 'package:meta/meta.dart';
class Song extends Equatable { class Song extends Equatable {
const Song({ const Song({
@required this.title,
@required this.album, @required this.album,
@required this.artist, @required this.artist,
@required this.path,
@required this.duration,
@required this.blocked, @required this.blocked,
this.discNumber, @required this.duration,
this.trackNumber, @required this.path,
@required this.title,
this.albumArtPath, this.albumArtPath,
this.discNumber,
this.next,
this.previous,
this.trackNumber,
}); });
final String title;
final String album; final String album;
final String artist; final String artist;
final String path;
/// Duration in milliseconds.
final int duration;
final int discNumber;
final int trackNumber;
final String albumArtPath;
/// Is this song blocked in shuffle mode? /// Is this song blocked in shuffle mode?
final bool blocked; final bool blocked;
/// Duration in milliseconds.
final int duration;
final String path;
final String title;
final String albumArtPath;
final int discNumber;
final String next;
final String previous;
final int trackNumber;
@override @override
List<Object> get props => [title, album, artist]; List<Object> get props => [title, album, artist];

View file

@ -13,4 +13,5 @@ abstract class MusicDataRepository {
Future<void> updateDatabase(); Future<void> updateDatabase();
Future<void> setSongBlocked(Song song, bool blocked); Future<void> setSongBlocked(Song song, bool blocked);
Future<void> toggleNextSongLink(Song song);
} }

View file

@ -123,4 +123,8 @@ abstract class _MusicDataStore with Store {
Future<void> setSongBlocked(Song song, bool blocked) async { Future<void> setSongBlocked(Song song, bool blocked) async {
await _musicDataRepository.setSongBlocked(song, blocked); await _musicDataRepository.setSongBlocked(song, blocked);
} }
Future<void> toggleNextSongLink(Song song) async {
await _musicDataRepository.toggleNextSongLink(song);
}
} }

View file

@ -14,10 +14,6 @@ class NavBar extends StatefulWidget {
} }
class _NavBarState extends State<NavBar> { class _NavBarState extends State<NavBar> {
final TextStyle _optionTextStyle = const TextStyle(
fontWeight: FontWeight.w300,
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@ -34,27 +30,18 @@ class _NavBarState extends State<NavBar> {
backgroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).primaryColor,
currentIndex: widget.currentIndex, currentIndex: widget.currentIndex,
onTap: widget.onTap, onTap: widget.onTap,
items: [ items: const [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: const Icon(Icons.home), icon: Icon(Icons.home),
title: Text( label: 'Home',
'Home',
style: _optionTextStyle,
),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: const Icon(Icons.library_music), icon: Icon(Icons.library_music),
title: Text( label: 'Library',
'Library',
style: _optionTextStyle,
),
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: const Icon(Icons.settings), icon: Icon(Icons.settings),
title: Text( label: 'Settings',
'Settings',
style: _optionTextStyle,
),
), ),
], ],
) )

View file

@ -20,13 +20,13 @@ class SongCustomizationButtons extends StatelessWidget {
final Song song = audioStore.currentSongStream.value; final Song song = audioStore.currentSongStream.value;
return Row( return Row(
children: [ children: [
const IconButton( IconButton(
icon: Icon( icon: Icon(
Icons.link, Icons.link,
size: 20.0, size: 20.0,
color: Colors.white10, color: song.next == null ? Colors.white70 : LIGHT1,
), ),
onPressed: null, onPressed: () => musicDataStore.toggleNextSongLink(song),
), ),
Container( Container(
width: 40, width: 40,

View file

@ -40,6 +40,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
int _playbackIndex = -1; int _playbackIndex = -1;
int get playbackIndex => _playbackIndex; int get playbackIndex => _playbackIndex;
set playbackIndex(int i) { set playbackIndex(int i) {
print(i);
if (i != null) { if (i != null) {
_playbackIndex = i; _playbackIndex = i;
AudioServiceBackground.setMediaItem(playbackContext[i]); AudioServiceBackground.setMediaItem(playbackContext[i]);
@ -176,13 +177,9 @@ class AudioPlayerTask extends BackgroundAudioTask {
AudioServiceBackground.setQueue(playbackContext); AudioServiceBackground.setQueue(playbackContext);
queue = qm.mediaItemsToAudioSource(playbackContext); queue = qm.mediaItemsToAudioSource(playbackContext);
await audioPlayer.load(queue);
if (shuffleMode == ShuffleMode.none) {
await audioPlayer.seek(const Duration(milliseconds: 0), index: index);
}
audioPlayer.play(); audioPlayer.play();
final int startIndex = shuffleMode == ShuffleMode.none ? index : 0;
await audioPlayer.load(queue, initialIndex: startIndex);
} }
void handlePlayerState(PlayerState ps) { void handlePlayerState(PlayerState ps) {

View file

@ -3,7 +3,7 @@ import 'dart:isolate';
import 'package:moor/isolate.dart'; import 'package:moor/isolate.dart';
import 'package:moor/moor.dart'; import 'package:moor/moor.dart';
import 'package:moor_ffi/moor_ffi.dart'; import 'package:moor/ffi.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -47,6 +47,9 @@ class Songs extends Table {
BoolColumn get blocked => boolean().withDefault(const Constant(false))(); BoolColumn get blocked => boolean().withDefault(const Constant(false))();
BoolColumn get present => boolean().withDefault(const Constant(true))(); BoolColumn get present => boolean().withDefault(const Constant(true))();
TextColumn get previous => text().nullable()();
TextColumn get next => text().nullable()();
@override @override
Set<Column> get primaryKey => {path}; Set<Column> get primaryKey => {path};
} }
@ -164,6 +167,40 @@ class MoorMusicDataSource extends _$MoorMusicDataSource
await (update(songs)..where((tbl) => tbl.path.equals(song.path))) await (update(songs)..where((tbl) => tbl.path.equals(song.path)))
.write(SongsCompanion(blocked: Value(blocked))); .write(SongsCompanion(blocked: Value(blocked)));
} }
// EXPLORATORY CODE!!!
@override
Future<void> toggleNextSongLink(SongModel song) async {
if (song.next == null) {
final albumSongs = await (select(songs)
..where((tbl) => tbl.albumId.equals(song.albumId))
..orderBy([
(t) => OrderingTerm(expression: t.discNumber),
(t) => OrderingTerm(expression: t.trackNumber)
]))
.get()
.then((moorSongList) => moorSongList
.map((moorSong) => SongModel.fromMoorSong(moorSong))
.toList());
bool current = false;
SongModel nextSong;
for (final s in albumSongs) {
if (current) {
nextSong = s;
break;
}
if (s.path == song.path) {
current = true;
}
}
await (update(songs)..where((tbl) => tbl.path.equals(song.path)))
.write(SongsCompanion(next: Value(nextSong.path)));
} else {
await (update(songs)..where((tbl) => tbl.path.equals(song.path)))
.write(const SongsCompanion(next: Value(null)));
}
}
} }
LazyDatabase _openConnection() { LazyDatabase _openConnection() {

View file

@ -500,6 +500,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
final int trackNumber; final int trackNumber;
final bool blocked; final bool blocked;
final bool present; final bool present;
final String previous;
final String next;
MoorSong( MoorSong(
{@required this.title, {@required this.title,
@required this.albumTitle, @required this.albumTitle,
@ -511,7 +513,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
this.discNumber, this.discNumber,
this.trackNumber, this.trackNumber,
@required this.blocked, @required this.blocked,
@required this.present}); @required this.present,
this.previous,
this.next});
factory MoorSong.fromData(Map<String, dynamic> data, GeneratedDatabase db, factory MoorSong.fromData(Map<String, dynamic> data, GeneratedDatabase db,
{String prefix}) { {String prefix}) {
final effectivePrefix = prefix ?? ''; final effectivePrefix = prefix ?? '';
@ -540,6 +544,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
boolType.mapFromDatabaseResponse(data['${effectivePrefix}blocked']), boolType.mapFromDatabaseResponse(data['${effectivePrefix}blocked']),
present: present:
boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']), boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']),
previous: stringType
.mapFromDatabaseResponse(data['${effectivePrefix}previous']),
next: stringType.mapFromDatabaseResponse(data['${effectivePrefix}next']),
); );
} }
@override @override
@ -578,6 +585,12 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
if (!nullToAbsent || present != null) { if (!nullToAbsent || present != null) {
map['present'] = Variable<bool>(present); map['present'] = Variable<bool>(present);
} }
if (!nullToAbsent || previous != null) {
map['previous'] = Variable<String>(previous);
}
if (!nullToAbsent || next != null) {
map['next'] = Variable<String>(next);
}
return map; return map;
} }
@ -612,6 +625,10 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
present: present == null && nullToAbsent present: present == null && nullToAbsent
? const Value.absent() ? const Value.absent()
: Value(present), : Value(present),
previous: previous == null && nullToAbsent
? const Value.absent()
: Value(previous),
next: next == null && nullToAbsent ? const Value.absent() : Value(next),
); );
} }
@ -630,6 +647,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
trackNumber: serializer.fromJson<int>(json['trackNumber']), trackNumber: serializer.fromJson<int>(json['trackNumber']),
blocked: serializer.fromJson<bool>(json['blocked']), blocked: serializer.fromJson<bool>(json['blocked']),
present: serializer.fromJson<bool>(json['present']), present: serializer.fromJson<bool>(json['present']),
previous: serializer.fromJson<String>(json['previous']),
next: serializer.fromJson<String>(json['next']),
); );
} }
@override @override
@ -647,6 +666,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
'trackNumber': serializer.toJson<int>(trackNumber), 'trackNumber': serializer.toJson<int>(trackNumber),
'blocked': serializer.toJson<bool>(blocked), 'blocked': serializer.toJson<bool>(blocked),
'present': serializer.toJson<bool>(present), 'present': serializer.toJson<bool>(present),
'previous': serializer.toJson<String>(previous),
'next': serializer.toJson<String>(next),
}; };
} }
@ -661,7 +682,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
int discNumber, int discNumber,
int trackNumber, int trackNumber,
bool blocked, bool blocked,
bool present}) => bool present,
String previous,
String next}) =>
MoorSong( MoorSong(
title: title ?? this.title, title: title ?? this.title,
albumTitle: albumTitle ?? this.albumTitle, albumTitle: albumTitle ?? this.albumTitle,
@ -674,6 +697,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
trackNumber: trackNumber ?? this.trackNumber, trackNumber: trackNumber ?? this.trackNumber,
blocked: blocked ?? this.blocked, blocked: blocked ?? this.blocked,
present: present ?? this.present, present: present ?? this.present,
previous: previous ?? this.previous,
next: next ?? this.next,
); );
@override @override
String toString() { String toString() {
@ -688,7 +713,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
..write('discNumber: $discNumber, ') ..write('discNumber: $discNumber, ')
..write('trackNumber: $trackNumber, ') ..write('trackNumber: $trackNumber, ')
..write('blocked: $blocked, ') ..write('blocked: $blocked, ')
..write('present: $present') ..write('present: $present, ')
..write('previous: $previous, ')
..write('next: $next')
..write(')')) ..write(')'))
.toString(); .toString();
} }
@ -712,8 +739,12 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
discNumber.hashCode, discNumber.hashCode,
$mrjc( $mrjc(
trackNumber.hashCode, trackNumber.hashCode,
$mrjc(blocked.hashCode, $mrjc(
present.hashCode))))))))))); blocked.hashCode,
$mrjc(
present.hashCode,
$mrjc(previous.hashCode,
next.hashCode)))))))))))));
@override @override
bool operator ==(dynamic other) => bool operator ==(dynamic other) =>
identical(this, other) || identical(this, other) ||
@ -728,7 +759,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
other.discNumber == this.discNumber && other.discNumber == this.discNumber &&
other.trackNumber == this.trackNumber && other.trackNumber == this.trackNumber &&
other.blocked == this.blocked && other.blocked == this.blocked &&
other.present == this.present); other.present == this.present &&
other.previous == this.previous &&
other.next == this.next);
} }
class SongsCompanion extends UpdateCompanion<MoorSong> { class SongsCompanion extends UpdateCompanion<MoorSong> {
@ -743,6 +776,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
final Value<int> trackNumber; final Value<int> trackNumber;
final Value<bool> blocked; final Value<bool> blocked;
final Value<bool> present; final Value<bool> present;
final Value<String> previous;
final Value<String> next;
const SongsCompanion({ const SongsCompanion({
this.title = const Value.absent(), this.title = const Value.absent(),
this.albumTitle = const Value.absent(), this.albumTitle = const Value.absent(),
@ -755,6 +790,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
this.trackNumber = const Value.absent(), this.trackNumber = const Value.absent(),
this.blocked = const Value.absent(), this.blocked = const Value.absent(),
this.present = const Value.absent(), this.present = const Value.absent(),
this.previous = const Value.absent(),
this.next = const Value.absent(),
}); });
SongsCompanion.insert({ SongsCompanion.insert({
@required String title, @required String title,
@ -768,6 +805,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
this.trackNumber = const Value.absent(), this.trackNumber = const Value.absent(),
this.blocked = const Value.absent(), this.blocked = const Value.absent(),
this.present = const Value.absent(), this.present = const Value.absent(),
this.previous = const Value.absent(),
this.next = const Value.absent(),
}) : title = Value(title), }) : title = Value(title),
albumTitle = Value(albumTitle), albumTitle = Value(albumTitle),
albumId = Value(albumId), albumId = Value(albumId),
@ -785,6 +824,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
Expression<int> trackNumber, Expression<int> trackNumber,
Expression<bool> blocked, Expression<bool> blocked,
Expression<bool> present, Expression<bool> present,
Expression<String> previous,
Expression<String> next,
}) { }) {
return RawValuesInsertable({ return RawValuesInsertable({
if (title != null) 'title': title, if (title != null) 'title': title,
@ -798,6 +839,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
if (trackNumber != null) 'track_number': trackNumber, if (trackNumber != null) 'track_number': trackNumber,
if (blocked != null) 'blocked': blocked, if (blocked != null) 'blocked': blocked,
if (present != null) 'present': present, if (present != null) 'present': present,
if (previous != null) 'previous': previous,
if (next != null) 'next': next,
}); });
} }
@ -812,7 +855,9 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
Value<int> discNumber, Value<int> discNumber,
Value<int> trackNumber, Value<int> trackNumber,
Value<bool> blocked, Value<bool> blocked,
Value<bool> present}) { Value<bool> present,
Value<String> previous,
Value<String> next}) {
return SongsCompanion( return SongsCompanion(
title: title ?? this.title, title: title ?? this.title,
albumTitle: albumTitle ?? this.albumTitle, albumTitle: albumTitle ?? this.albumTitle,
@ -825,6 +870,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
trackNumber: trackNumber ?? this.trackNumber, trackNumber: trackNumber ?? this.trackNumber,
blocked: blocked ?? this.blocked, blocked: blocked ?? this.blocked,
present: present ?? this.present, present: present ?? this.present,
previous: previous ?? this.previous,
next: next ?? this.next,
); );
} }
@ -864,6 +911,12 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
if (present.present) { if (present.present) {
map['present'] = Variable<bool>(present.value); map['present'] = Variable<bool>(present.value);
} }
if (previous.present) {
map['previous'] = Variable<String>(previous.value);
}
if (next.present) {
map['next'] = Variable<String>(next.value);
}
return map; return map;
} }
@ -880,7 +933,9 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
..write('discNumber: $discNumber, ') ..write('discNumber: $discNumber, ')
..write('trackNumber: $trackNumber, ') ..write('trackNumber: $trackNumber, ')
..write('blocked: $blocked, ') ..write('blocked: $blocked, ')
..write('present: $present') ..write('present: $present, ')
..write('previous: $previous, ')
..write('next: $next')
..write(')')) ..write(')'))
.toString(); .toString();
} }
@ -1020,6 +1075,30 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
defaultValue: const Constant(true)); defaultValue: const Constant(true));
} }
final VerificationMeta _previousMeta = const VerificationMeta('previous');
GeneratedTextColumn _previous;
@override
GeneratedTextColumn get previous => _previous ??= _constructPrevious();
GeneratedTextColumn _constructPrevious() {
return GeneratedTextColumn(
'previous',
$tableName,
true,
);
}
final VerificationMeta _nextMeta = const VerificationMeta('next');
GeneratedTextColumn _next;
@override
GeneratedTextColumn get next => _next ??= _constructNext();
GeneratedTextColumn _constructNext() {
return GeneratedTextColumn(
'next',
$tableName,
true,
);
}
@override @override
List<GeneratedColumn> get $columns => [ List<GeneratedColumn> get $columns => [
title, title,
@ -1032,7 +1111,9 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
discNumber, discNumber,
trackNumber, trackNumber,
blocked, blocked,
present present,
previous,
next
]; ];
@override @override
$SongsTable get asDslTable => this; $SongsTable get asDslTable => this;
@ -1107,6 +1188,14 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
context.handle(_presentMeta, context.handle(_presentMeta,
present.isAcceptableOrUnknown(data['present'], _presentMeta)); present.isAcceptableOrUnknown(data['present'], _presentMeta));
} }
if (data.containsKey('previous')) {
context.handle(_previousMeta,
previous.isAcceptableOrUnknown(data['previous'], _previousMeta));
}
if (data.containsKey('next')) {
context.handle(
_nextMeta, next.isAcceptableOrUnknown(data['next'], _nextMeta));
}
return context; return context;
} }

View file

@ -13,6 +13,7 @@ abstract class MusicDataSource {
Future<void> insertSong(SongModel songModel); Future<void> insertSong(SongModel songModel);
Future<void> insertSongs(List<SongModel> songModels); Future<void> insertSongs(List<SongModel> songModels);
Future<void> setSongBlocked(SongModel song, bool blocked); Future<void> setSongBlocked(SongModel song, bool blocked);
Future<void> toggleNextSongLink(SongModel song);
Future<SongModel> getSongByPath(String path); Future<SongModel> getSongByPath(String path);

View file

@ -7,40 +7,46 @@ import '../../domain/entities/song.dart';
import '../datasources/moor_music_data_source.dart'; import '../datasources/moor_music_data_source.dart';
class SongModel extends Song { class SongModel extends Song {
const SongModel( const SongModel({
{@required String title, @required String title,
@required String album, @required String album,
@required this.albumId, @required this.albumId,
@required String artist, @required String artist,
@required String path, @required String path,
@required int duration, @required int duration,
@required bool blocked, @required bool blocked,
int discNumber, String albumArtPath,
int trackNumber, int discNumber,
String albumArtPath}) String next,
: super( String previous,
title: title, int trackNumber,
}) : super(
album: album, album: album,
artist: artist, artist: artist,
path: path,
duration: duration,
blocked: blocked, blocked: blocked,
discNumber: discNumber, duration: duration,
trackNumber: trackNumber, path: path,
title: title,
albumArtPath: albumArtPath, albumArtPath: albumArtPath,
discNumber: discNumber,
next: next,
previous: previous,
trackNumber: trackNumber,
); );
factory SongModel.fromMoorSong(MoorSong moorSong) => SongModel( factory SongModel.fromMoorSong(MoorSong moorSong) => SongModel(
title: moorSong.title,
artist: moorSong.artist,
album: moorSong.albumTitle, album: moorSong.albumTitle,
albumId: moorSong.albumId, albumId: moorSong.albumId,
path: moorSong.path, artist: moorSong.artist,
duration: moorSong.duration,
blocked: moorSong.blocked, blocked: moorSong.blocked,
discNumber: moorSong.discNumber, duration: moorSong.duration,
trackNumber: moorSong.trackNumber, path: moorSong.path,
title: moorSong.title,
albumArtPath: moorSong.albumArtPath, albumArtPath: moorSong.albumArtPath,
discNumber: moorSong.discNumber,
next: moorSong.next,
previous: moorSong.previous,
trackNumber: moorSong.trackNumber,
); );
factory SongModel.fromSongInfo(SongInfo songInfo) { factory SongModel.fromSongInfo(SongInfo songInfo) {
@ -67,7 +73,7 @@ class SongModel extends Song {
} }
final String artUri = mediaItem.artUri?.replaceFirst('file://', ''); final String artUri = mediaItem.artUri?.replaceFirst('file://', '');
final dn = mediaItem.extras['discNumber']; final dn = mediaItem.extras['discNumber'];
int discNumber; int discNumber;
final tn = mediaItem.extras['trackNumber']; final tn = mediaItem.extras['trackNumber'];
@ -86,16 +92,18 @@ class SongModel extends Song {
} }
return SongModel( return SongModel(
title: mediaItem.title,
album: mediaItem.album, album: mediaItem.album,
albumId: mediaItem.extras['albumId'] as int, albumId: mediaItem.extras['albumId'] as int,
artist: mediaItem.artist, artist: mediaItem.artist,
path: mediaItem.id,
duration: mediaItem.duration.inMilliseconds, duration: mediaItem.duration.inMilliseconds,
blocked: mediaItem.extras['blocked'] == 'true', blocked: mediaItem.extras['blocked'] as bool,
discNumber: discNumber, path: mediaItem.id,
trackNumber: trackNumber, title: mediaItem.title,
albumArtPath: artUri, albumArtPath: artUri,
discNumber: discNumber,
next: mediaItem.extras['next'] as String,
previous: mediaItem.extras['previous'] as String,
trackNumber: trackNumber,
); );
} }
@ -107,41 +115,47 @@ class SongModel extends Song {
} }
SongModel copyWith({ SongModel copyWith({
String title,
String album, String album,
String artist,
String path,
int duration,
bool blocked,
int discNumber,
int trackNumber,
String albumArtPath,
int albumId, int albumId,
String artist,
bool blocked,
int duration,
String path,
String title,
String albumArtPath,
int discNumber,
String next,
String previous,
int trackNumber,
}) => }) =>
SongModel( SongModel(
album: album ?? this.album, album: album ?? this.album,
albumId: albumId ?? this.albumId,
artist: artist ?? this.artist, artist: artist ?? this.artist,
blocked: blocked ?? this.blocked,
duration: duration ?? this.duration, duration: duration ?? this.duration,
path: path ?? this.path, path: path ?? this.path,
title: title ?? this.title, title: title ?? this.title,
blocked: blocked ?? this.blocked,
discNumber: discNumber ?? this.discNumber,
trackNumber: trackNumber ?? this.trackNumber,
albumArtPath: albumArtPath ?? this.albumArtPath, albumArtPath: albumArtPath ?? this.albumArtPath,
albumId: albumId ?? this.albumId, discNumber: discNumber ?? this.discNumber,
next: next ?? this.next,
previous: previous ?? this.previous,
trackNumber: trackNumber ?? this.trackNumber,
); );
SongsCompanion toSongsCompanion() => SongsCompanion( SongsCompanion toSongsCompanion() => SongsCompanion(
albumTitle: Value(album), albumTitle: Value(album),
albumId: Value(albumId), albumId: Value(albumId),
artist: Value(artist), artist: Value(artist),
title: Value(title),
path: Value(path),
duration: Value(duration),
blocked: Value(blocked), blocked: Value(blocked),
discNumber: Value(discNumber), duration: Value(duration),
trackNumber: Value(trackNumber), path: Value(path),
title: Value(title),
albumArtPath: Value(albumArtPath), albumArtPath: Value(albumArtPath),
discNumber: Value(discNumber),
next: Value(next),
previous: Value(previous),
trackNumber: Value(trackNumber),
); );
SongsCompanion toMoorInsert() => SongsCompanion( SongsCompanion toMoorInsert() => SongsCompanion(
@ -167,15 +181,17 @@ class SongModel extends Song {
artUri: 'file://$albumArtPath', artUri: 'file://$albumArtPath',
extras: { extras: {
'albumId': albumId, 'albumId': albumId,
'blocked': blocked.toString(), 'blocked': blocked,
'discNumber': discNumber, 'discNumber': discNumber,
'next': next,
'previous': previous,
'trackNumber': trackNumber, 'trackNumber': trackNumber,
}); });
static List<int> _parseTrackNumber(String trackNumberString) { static List<int> _parseTrackNumber(String trackNumberString) {
int discNumber = 1; int discNumber = 1;
int trackNumber; int trackNumber;
if (trackNumberString == null) { if (trackNumberString == null) {
return [null, null]; return [null, null];
} }

View file

@ -122,4 +122,9 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
} }
await musicDataSource.insertSongs(songsToInsert); await musicDataSource.insertSongs(songsToInsert);
} }
@override
Future<void> toggleNextSongLink(Song song) async {
musicDataSource.toggleNextSongLink(song as SongModel);
}
} }

View file

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.0" version: "7.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.39.14" version: "0.39.17"
analyzer_plugin: analyzer_plugin:
dependency: transitive dependency: transitive
description: description:
@ -35,28 +35,28 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.2" version: "2.5.0-nullsafety.1"
audio_service: audio_service:
dependency: "direct main" dependency: "direct main"
description: description:
name: audio_service name: audio_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.15.0" version: "0.15.2"
audio_session: audio_session:
dependency: "direct main" dependency: "direct main"
description: description:
name: audio_session name: audio_session
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.7" version: "0.0.9"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0-nullsafety.1"
build: build:
dependency: transitive dependency: transitive
description: description:
@ -91,7 +91,7 @@ packages:
name: build_runner name: build_runner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.1" version: "1.10.2"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
@ -119,14 +119,14 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0-nullsafety.3"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.3" version: "1.2.0-nullsafety.1"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@ -147,21 +147,21 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.1.0-nullsafety.1"
code_builder: code_builder:
dependency: transitive dependency: transitive
description: description:
name: code_builder name: code_builder
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.4.1" version: "3.5.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.13" version: "1.15.0-nullsafety.3"
convert: convert:
dependency: transitive dependency: transitive
description: description:
@ -196,21 +196,21 @@ packages:
name: dartz name: dartz
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.1" version: "0.9.2"
equatable: equatable:
dependency: "direct main" dependency: "direct main"
description: description:
name: equatable name: equatable
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.4" version: "1.2.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0-nullsafety.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -250,7 +250,7 @@ packages:
name: flutter_cache_manager name: flutter_cache_manager
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.1" version: "1.4.2"
flutter_isolate: flutter_isolate:
dependency: transitive dependency: transitive
description: description:
@ -271,7 +271,7 @@ packages:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.8" version: "1.0.11"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -309,7 +309,7 @@ packages:
name: html name: html
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.14.0+3" version: "0.14.0+4"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -358,14 +358,28 @@ packages:
name: json_annotation name: json_annotation
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.1.0"
just_audio: just_audio:
dependency: "direct main" dependency: "direct main"
description: description:
name: just_audio path: "../just_audio/just_audio"
url: "https://pub.dartlang.org" relative: true
source: hosted source: path
version: "0.4.0" version: "0.5.4+1"
just_audio_platform_interface:
dependency: transitive
description:
path: "../just_audio/just_audio_platform_interface"
relative: true
source: path
version: "1.2.0"
just_audio_web:
dependency: transitive
description:
path: "../just_audio/just_audio_web"
relative: true
source: path
version: "0.1.0"
logging: logging:
dependency: "direct main" dependency: "direct main"
description: description:
@ -379,14 +393,14 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.8" version: "0.12.10-nullsafety.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.3.0-nullsafety.3"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -400,21 +414,21 @@ packages:
name: mobx name: mobx
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1+2" version: "1.2.1+3"
mobx_codegen: mobx_codegen:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: mobx_codegen name: mobx_codegen
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0+1" version: "1.1.1+1"
mockito: mockito:
dependency: "direct main" dependency: "direct main"
description: description:
name: mockito name: mockito
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.1" version: "4.1.2"
moor: moor:
dependency: "direct main" dependency: "direct main"
description: description:
@ -422,13 +436,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.3.1" version: "3.3.1"
moor_ffi:
dependency: "direct main"
description:
name: moor_ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0"
moor_generator: moor_generator:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -470,14 +477,14 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0-nullsafety.1"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.18" version: "1.6.21"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -491,7 +498,7 @@ packages:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+3" version: "0.0.4+4"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -512,7 +519,7 @@ packages:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.9.2"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -526,7 +533,7 @@ packages:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.3"
pool: pool:
dependency: transitive dependency: transitive
description: description:
@ -547,7 +554,7 @@ packages:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.3.2+1" version: "4.3.2+2"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
@ -608,21 +615,21 @@ packages:
name: source_gen name: source_gen
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.6" version: "0.9.7+1"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0-nullsafety.2"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
name: sqflite name: sqflite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1+1"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
@ -636,7 +643,14 @@ packages:
name: sqlite3 name: sqlite3
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.7"
sqlite3_flutter_libs:
dependency: "direct main"
description:
name: sqlite3_flutter_libs
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
sqlparser: sqlparser:
dependency: transitive dependency: transitive
description: description:
@ -650,14 +664,14 @@ packages:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.5" version: "1.10.0-nullsafety.1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0-nullsafety.1"
stream_transform: stream_transform:
dependency: transitive dependency: transitive
description: description:
@ -671,7 +685,7 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0-nullsafety.1"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
@ -685,14 +699,14 @@ packages:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0-nullsafety.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.17" version: "0.2.19-nullsafety.2"
timing: timing:
dependency: transitive dependency: transitive
description: description:
@ -706,21 +720,21 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0-nullsafety.3"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "2.2.2"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.1.0-nullsafety.3"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -748,7 +762,7 @@ packages:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.0" version: "0.1.2"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
@ -757,5 +771,5 @@ packages:
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
sdks: sdks:
dart: ">=2.9.0 <3.0.0" dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.20.0 <2.0.0" flutter: ">=1.20.0 <2.0.0"

View file

@ -8,36 +8,33 @@ environment:
flutter: ">=1.20.0" flutter: ">=1.20.0"
dependencies: dependencies:
flutter:
sdk: flutter
equatable: ^1.1.0
dartz: ^0.9.1
mockito: ^4.1.1
flutter_audio_query: ^0.3.5
audio_service: ^0.15.0 audio_service: ^0.15.0
audio_session: ^0.0.3 audio_session: ^0.0.3
just_audio: ^0.4.0 dartz: ^0.9.1
equatable: ^1.1.0
flutter:
sdk: flutter
flutter_audio_query: ^0.3.5
flutter_mobx: ^1.1.0
get_it: ^4.0.2 get_it: ^4.0.2
just_audio: # ^0.4.0
path: ../just_audio/just_audio
logging: ^0.11.4
mobx: ^1.1.1
mockito: ^4.1.1
moor: ^3.0.2
# moor_ffi: ^0.5.0
path:
path_provider: ^1.6.18 path_provider: ^1.6.18
provider: ^4.0.4 provider: ^4.0.4
logging: ^0.11.4 sqlite3_flutter_libs: ^0.2.0
moor: ^3.0.2
moor_ffi: ^0.5.0
path:
mobx: ^1.1.1
flutter_mobx: ^1.1.0
dev_dependencies: dev_dependencies:
build_runner: 1.10.2
flutter_test: flutter_test:
sdk: flutter sdk: flutter
moor_generator: ^3.0.0
build_runner: 1.10.1
mobx_codegen: ^1.0.3 mobx_codegen: ^1.0.3
moor_generator: ^3.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the

View file

@ -1,5 +1,5 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:moor_ffi/moor_ffi.dart'; import 'package:moor/ffi.dart';
import 'package:mucke/system/datasources/moor_music_data_source.dart'; import 'package:mucke/system/datasources/moor_music_data_source.dart';
import 'package:mucke/system/models/album_model.dart'; import 'package:mucke/system/models/album_model.dart';
import 'package:mucke/system/models/song_model.dart'; import 'package:mucke/system/models/song_model.dart';