fixed build issues; song: next/previous; cosmetics
This commit is contained in:
parent
461844e545
commit
cbb8559954
15 changed files with 329 additions and 175 deletions
|
@ -64,4 +64,5 @@ dependencies {
|
|||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||
}
|
||||
|
|
|
@ -3,28 +3,33 @@ import 'package:meta/meta.dart';
|
|||
|
||||
class Song extends Equatable {
|
||||
const Song({
|
||||
@required this.title,
|
||||
@required this.album,
|
||||
@required this.artist,
|
||||
@required this.path,
|
||||
@required this.duration,
|
||||
@required this.blocked,
|
||||
this.discNumber,
|
||||
this.trackNumber,
|
||||
@required this.duration,
|
||||
@required this.path,
|
||||
@required this.title,
|
||||
this.albumArtPath,
|
||||
this.discNumber,
|
||||
this.next,
|
||||
this.previous,
|
||||
this.trackNumber,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String album;
|
||||
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?
|
||||
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
|
||||
List<Object> get props => [title, album, artist];
|
||||
|
|
|
@ -13,4 +13,5 @@ abstract class MusicDataRepository {
|
|||
Future<void> updateDatabase();
|
||||
|
||||
Future<void> setSongBlocked(Song song, bool blocked);
|
||||
Future<void> toggleNextSongLink(Song song);
|
||||
}
|
|
@ -123,4 +123,8 @@ abstract class _MusicDataStore with Store {
|
|||
Future<void> setSongBlocked(Song song, bool blocked) async {
|
||||
await _musicDataRepository.setSongBlocked(song, blocked);
|
||||
}
|
||||
|
||||
Future<void> toggleNextSongLink(Song song) async {
|
||||
await _musicDataRepository.toggleNextSongLink(song);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,6 @@ class NavBar extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _NavBarState extends State<NavBar> {
|
||||
final TextStyle _optionTextStyle = const TextStyle(
|
||||
fontWeight: FontWeight.w300,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
@ -34,27 +30,18 @@ class _NavBarState extends State<NavBar> {
|
|||
backgroundColor: Theme.of(context).primaryColor,
|
||||
currentIndex: widget.currentIndex,
|
||||
onTap: widget.onTap,
|
||||
items: [
|
||||
items: const [
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.home),
|
||||
title: Text(
|
||||
'Home',
|
||||
style: _optionTextStyle,
|
||||
),
|
||||
icon: Icon(Icons.home),
|
||||
label: 'Home',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.library_music),
|
||||
title: Text(
|
||||
'Library',
|
||||
style: _optionTextStyle,
|
||||
),
|
||||
icon: Icon(Icons.library_music),
|
||||
label: 'Library',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: const Icon(Icons.settings),
|
||||
title: Text(
|
||||
'Settings',
|
||||
style: _optionTextStyle,
|
||||
),
|
||||
icon: Icon(Icons.settings),
|
||||
label: 'Settings',
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
@ -20,13 +20,13 @@ class SongCustomizationButtons extends StatelessWidget {
|
|||
final Song song = audioStore.currentSongStream.value;
|
||||
return Row(
|
||||
children: [
|
||||
const IconButton(
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.link,
|
||||
size: 20.0,
|
||||
color: Colors.white10,
|
||||
color: song.next == null ? Colors.white70 : LIGHT1,
|
||||
),
|
||||
onPressed: null,
|
||||
onPressed: () => musicDataStore.toggleNextSongLink(song),
|
||||
),
|
||||
Container(
|
||||
width: 40,
|
||||
|
|
|
@ -40,6 +40,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
int _playbackIndex = -1;
|
||||
int get playbackIndex => _playbackIndex;
|
||||
set playbackIndex(int i) {
|
||||
print(i);
|
||||
if (i != null) {
|
||||
_playbackIndex = i;
|
||||
AudioServiceBackground.setMediaItem(playbackContext[i]);
|
||||
|
@ -176,13 +177,9 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
|||
|
||||
AudioServiceBackground.setQueue(playbackContext);
|
||||
queue = qm.mediaItemsToAudioSource(playbackContext);
|
||||
await audioPlayer.load(queue);
|
||||
|
||||
if (shuffleMode == ShuffleMode.none) {
|
||||
await audioPlayer.seek(const Duration(milliseconds: 0), index: index);
|
||||
}
|
||||
|
||||
audioPlayer.play();
|
||||
final int startIndex = shuffleMode == ShuffleMode.none ? index : 0;
|
||||
await audioPlayer.load(queue, initialIndex: startIndex);
|
||||
}
|
||||
|
||||
void handlePlayerState(PlayerState ps) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:isolate';
|
|||
|
||||
import 'package:moor/isolate.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_provider/path_provider.dart';
|
||||
|
||||
|
@ -47,6 +47,9 @@ class Songs extends Table {
|
|||
BoolColumn get blocked => boolean().withDefault(const Constant(false))();
|
||||
BoolColumn get present => boolean().withDefault(const Constant(true))();
|
||||
|
||||
TextColumn get previous => text().nullable()();
|
||||
TextColumn get next => text().nullable()();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {path};
|
||||
}
|
||||
|
@ -164,6 +167,40 @@ class MoorMusicDataSource extends _$MoorMusicDataSource
|
|||
await (update(songs)..where((tbl) => tbl.path.equals(song.path)))
|
||||
.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() {
|
||||
|
|
|
@ -500,6 +500,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
final int trackNumber;
|
||||
final bool blocked;
|
||||
final bool present;
|
||||
final String previous;
|
||||
final String next;
|
||||
MoorSong(
|
||||
{@required this.title,
|
||||
@required this.albumTitle,
|
||||
|
@ -511,7 +513,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
this.discNumber,
|
||||
this.trackNumber,
|
||||
@required this.blocked,
|
||||
@required this.present});
|
||||
@required this.present,
|
||||
this.previous,
|
||||
this.next});
|
||||
factory MoorSong.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
|
@ -540,6 +544,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}blocked']),
|
||||
present:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']),
|
||||
previous: stringType
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}previous']),
|
||||
next: stringType.mapFromDatabaseResponse(data['${effectivePrefix}next']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -578,6 +585,12 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
if (!nullToAbsent || present != null) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -612,6 +625,10 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
present: present == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: 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']),
|
||||
blocked: serializer.fromJson<bool>(json['blocked']),
|
||||
present: serializer.fromJson<bool>(json['present']),
|
||||
previous: serializer.fromJson<String>(json['previous']),
|
||||
next: serializer.fromJson<String>(json['next']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -647,6 +666,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
'trackNumber': serializer.toJson<int>(trackNumber),
|
||||
'blocked': serializer.toJson<bool>(blocked),
|
||||
'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 trackNumber,
|
||||
bool blocked,
|
||||
bool present}) =>
|
||||
bool present,
|
||||
String previous,
|
||||
String next}) =>
|
||||
MoorSong(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -674,6 +697,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
blocked: blocked ?? this.blocked,
|
||||
present: present ?? this.present,
|
||||
previous: previous ?? this.previous,
|
||||
next: next ?? this.next,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -688,7 +713,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
..write('discNumber: $discNumber, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('blocked: $blocked, ')
|
||||
..write('present: $present')
|
||||
..write('present: $present, ')
|
||||
..write('previous: $previous, ')
|
||||
..write('next: $next')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -712,8 +739,12 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
discNumber.hashCode,
|
||||
$mrjc(
|
||||
trackNumber.hashCode,
|
||||
$mrjc(blocked.hashCode,
|
||||
present.hashCode)))))))))));
|
||||
$mrjc(
|
||||
blocked.hashCode,
|
||||
$mrjc(
|
||||
present.hashCode,
|
||||
$mrjc(previous.hashCode,
|
||||
next.hashCode)))))))))))));
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -728,7 +759,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
other.discNumber == this.discNumber &&
|
||||
other.trackNumber == this.trackNumber &&
|
||||
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> {
|
||||
|
@ -743,6 +776,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
final Value<int> trackNumber;
|
||||
final Value<bool> blocked;
|
||||
final Value<bool> present;
|
||||
final Value<String> previous;
|
||||
final Value<String> next;
|
||||
const SongsCompanion({
|
||||
this.title = const Value.absent(),
|
||||
this.albumTitle = const Value.absent(),
|
||||
|
@ -755,6 +790,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.trackNumber = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
this.previous = const Value.absent(),
|
||||
this.next = const Value.absent(),
|
||||
});
|
||||
SongsCompanion.insert({
|
||||
@required String title,
|
||||
|
@ -768,6 +805,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.trackNumber = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
this.previous = const Value.absent(),
|
||||
this.next = const Value.absent(),
|
||||
}) : title = Value(title),
|
||||
albumTitle = Value(albumTitle),
|
||||
albumId = Value(albumId),
|
||||
|
@ -785,6 +824,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
Expression<int> trackNumber,
|
||||
Expression<bool> blocked,
|
||||
Expression<bool> present,
|
||||
Expression<String> previous,
|
||||
Expression<String> next,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (title != null) 'title': title,
|
||||
|
@ -798,6 +839,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (trackNumber != null) 'track_number': trackNumber,
|
||||
if (blocked != null) 'blocked': blocked,
|
||||
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> trackNumber,
|
||||
Value<bool> blocked,
|
||||
Value<bool> present}) {
|
||||
Value<bool> present,
|
||||
Value<String> previous,
|
||||
Value<String> next}) {
|
||||
return SongsCompanion(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -825,6 +870,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
blocked: blocked ?? this.blocked,
|
||||
present: present ?? this.present,
|
||||
previous: previous ?? this.previous,
|
||||
next: next ?? this.next,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -864,6 +911,12 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (present.present) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -880,7 +933,9 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
..write('discNumber: $discNumber, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('blocked: $blocked, ')
|
||||
..write('present: $present')
|
||||
..write('present: $present, ')
|
||||
..write('previous: $previous, ')
|
||||
..write('next: $next')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -1020,6 +1075,30 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
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
|
||||
List<GeneratedColumn> get $columns => [
|
||||
title,
|
||||
|
@ -1032,7 +1111,9 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
discNumber,
|
||||
trackNumber,
|
||||
blocked,
|
||||
present
|
||||
present,
|
||||
previous,
|
||||
next
|
||||
];
|
||||
@override
|
||||
$SongsTable get asDslTable => this;
|
||||
|
@ -1107,6 +1188,14 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
context.handle(_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ abstract class MusicDataSource {
|
|||
Future<void> insertSong(SongModel songModel);
|
||||
Future<void> insertSongs(List<SongModel> songModels);
|
||||
Future<void> setSongBlocked(SongModel song, bool blocked);
|
||||
Future<void> toggleNextSongLink(SongModel song);
|
||||
|
||||
Future<SongModel> getSongByPath(String path);
|
||||
|
||||
|
|
|
@ -7,40 +7,46 @@ import '../../domain/entities/song.dart';
|
|||
import '../datasources/moor_music_data_source.dart';
|
||||
|
||||
class SongModel extends Song {
|
||||
const SongModel(
|
||||
{@required String title,
|
||||
@required String album,
|
||||
@required this.albumId,
|
||||
@required String artist,
|
||||
@required String path,
|
||||
@required int duration,
|
||||
@required bool blocked,
|
||||
int discNumber,
|
||||
int trackNumber,
|
||||
String albumArtPath})
|
||||
: super(
|
||||
title: title,
|
||||
const SongModel({
|
||||
@required String title,
|
||||
@required String album,
|
||||
@required this.albumId,
|
||||
@required String artist,
|
||||
@required String path,
|
||||
@required int duration,
|
||||
@required bool blocked,
|
||||
String albumArtPath,
|
||||
int discNumber,
|
||||
String next,
|
||||
String previous,
|
||||
int trackNumber,
|
||||
}) : super(
|
||||
album: album,
|
||||
artist: artist,
|
||||
path: path,
|
||||
duration: duration,
|
||||
blocked: blocked,
|
||||
discNumber: discNumber,
|
||||
trackNumber: trackNumber,
|
||||
duration: duration,
|
||||
path: path,
|
||||
title: title,
|
||||
albumArtPath: albumArtPath,
|
||||
discNumber: discNumber,
|
||||
next: next,
|
||||
previous: previous,
|
||||
trackNumber: trackNumber,
|
||||
);
|
||||
|
||||
factory SongModel.fromMoorSong(MoorSong moorSong) => SongModel(
|
||||
title: moorSong.title,
|
||||
artist: moorSong.artist,
|
||||
album: moorSong.albumTitle,
|
||||
albumId: moorSong.albumId,
|
||||
path: moorSong.path,
|
||||
duration: moorSong.duration,
|
||||
artist: moorSong.artist,
|
||||
blocked: moorSong.blocked,
|
||||
discNumber: moorSong.discNumber,
|
||||
trackNumber: moorSong.trackNumber,
|
||||
duration: moorSong.duration,
|
||||
path: moorSong.path,
|
||||
title: moorSong.title,
|
||||
albumArtPath: moorSong.albumArtPath,
|
||||
discNumber: moorSong.discNumber,
|
||||
next: moorSong.next,
|
||||
previous: moorSong.previous,
|
||||
trackNumber: moorSong.trackNumber,
|
||||
);
|
||||
|
||||
factory SongModel.fromSongInfo(SongInfo songInfo) {
|
||||
|
@ -67,7 +73,7 @@ class SongModel extends Song {
|
|||
}
|
||||
|
||||
final String artUri = mediaItem.artUri?.replaceFirst('file://', '');
|
||||
|
||||
|
||||
final dn = mediaItem.extras['discNumber'];
|
||||
int discNumber;
|
||||
final tn = mediaItem.extras['trackNumber'];
|
||||
|
@ -86,16 +92,18 @@ class SongModel extends Song {
|
|||
}
|
||||
|
||||
return SongModel(
|
||||
title: mediaItem.title,
|
||||
album: mediaItem.album,
|
||||
albumId: mediaItem.extras['albumId'] as int,
|
||||
artist: mediaItem.artist,
|
||||
path: mediaItem.id,
|
||||
duration: mediaItem.duration.inMilliseconds,
|
||||
blocked: mediaItem.extras['blocked'] == 'true',
|
||||
discNumber: discNumber,
|
||||
trackNumber: trackNumber,
|
||||
blocked: mediaItem.extras['blocked'] as bool,
|
||||
path: mediaItem.id,
|
||||
title: mediaItem.title,
|
||||
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({
|
||||
String title,
|
||||
String album,
|
||||
String artist,
|
||||
String path,
|
||||
int duration,
|
||||
bool blocked,
|
||||
int discNumber,
|
||||
int trackNumber,
|
||||
String albumArtPath,
|
||||
int albumId,
|
||||
String artist,
|
||||
bool blocked,
|
||||
int duration,
|
||||
String path,
|
||||
String title,
|
||||
String albumArtPath,
|
||||
int discNumber,
|
||||
String next,
|
||||
String previous,
|
||||
int trackNumber,
|
||||
}) =>
|
||||
SongModel(
|
||||
album: album ?? this.album,
|
||||
albumId: albumId ?? this.albumId,
|
||||
artist: artist ?? this.artist,
|
||||
blocked: blocked ?? this.blocked,
|
||||
duration: duration ?? this.duration,
|
||||
path: path ?? this.path,
|
||||
title: title ?? this.title,
|
||||
blocked: blocked ?? this.blocked,
|
||||
discNumber: discNumber ?? this.discNumber,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
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(
|
||||
albumTitle: Value(album),
|
||||
albumId: Value(albumId),
|
||||
artist: Value(artist),
|
||||
title: Value(title),
|
||||
path: Value(path),
|
||||
duration: Value(duration),
|
||||
blocked: Value(blocked),
|
||||
discNumber: Value(discNumber),
|
||||
trackNumber: Value(trackNumber),
|
||||
duration: Value(duration),
|
||||
path: Value(path),
|
||||
title: Value(title),
|
||||
albumArtPath: Value(albumArtPath),
|
||||
discNumber: Value(discNumber),
|
||||
next: Value(next),
|
||||
previous: Value(previous),
|
||||
trackNumber: Value(trackNumber),
|
||||
);
|
||||
|
||||
SongsCompanion toMoorInsert() => SongsCompanion(
|
||||
|
@ -167,15 +181,17 @@ class SongModel extends Song {
|
|||
artUri: 'file://$albumArtPath',
|
||||
extras: {
|
||||
'albumId': albumId,
|
||||
'blocked': blocked.toString(),
|
||||
'blocked': blocked,
|
||||
'discNumber': discNumber,
|
||||
'next': next,
|
||||
'previous': previous,
|
||||
'trackNumber': trackNumber,
|
||||
});
|
||||
|
||||
static List<int> _parseTrackNumber(String trackNumberString) {
|
||||
int discNumber = 1;
|
||||
int trackNumber;
|
||||
|
||||
|
||||
if (trackNumberString == null) {
|
||||
return [null, null];
|
||||
}
|
||||
|
|
|
@ -122,4 +122,9 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
}
|
||||
await musicDataSource.insertSongs(songsToInsert);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> toggleNextSongLink(Song song) async {
|
||||
musicDataSource.toggleNextSongLink(song as SongModel);
|
||||
}
|
||||
}
|
||||
|
|
124
pubspec.lock
124
pubspec.lock
|
@ -7,14 +7,14 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
version: "7.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.39.14"
|
||||
version: "0.39.17"
|
||||
analyzer_plugin:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -35,28 +35,28 @@ packages:
|
|||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.5.0-nullsafety.1"
|
||||
audio_service:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: audio_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.15.0"
|
||||
version: "0.15.2"
|
||||
audio_session:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: audio_session
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.7"
|
||||
version: "0.0.9"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0-nullsafety.1"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -91,7 +91,7 @@ packages:
|
|||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
version: "1.10.2"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -119,14 +119,14 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.1.0-nullsafety.3"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
version: "1.2.0-nullsafety.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -147,21 +147,21 @@ packages:
|
|||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.1.0-nullsafety.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
version: "3.5.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.13"
|
||||
version: "1.15.0-nullsafety.3"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -196,21 +196,21 @@ packages:
|
|||
name: dartz
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.1"
|
||||
version: "0.9.2"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: equatable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.4"
|
||||
version: "1.2.5"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0-nullsafety.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -250,7 +250,7 @@ packages:
|
|||
name: flutter_cache_manager
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "1.4.2"
|
||||
flutter_isolate:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -271,7 +271,7 @@ packages:
|
|||
name: flutter_plugin_android_lifecycle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
version: "1.0.11"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -309,7 +309,7 @@ packages:
|
|||
name: html
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.0+3"
|
||||
version: "0.14.0+4"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -358,14 +358,28 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.0"
|
||||
just_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: just_audio
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
path: "../just_audio/just_audio"
|
||||
relative: true
|
||||
source: path
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -379,14 +393,14 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.8"
|
||||
version: "0.12.10-nullsafety.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.8"
|
||||
version: "1.3.0-nullsafety.3"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -400,21 +414,21 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+2"
|
||||
version: "1.2.1+3"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+1"
|
||||
version: "1.1.1+1"
|
||||
mockito:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mockito
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.1"
|
||||
version: "4.1.2"
|
||||
moor:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -422,13 +436,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -470,14 +477,14 @@ packages:
|
|||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0-nullsafety.1"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.18"
|
||||
version: "1.6.21"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -491,7 +498,7 @@ packages:
|
|||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+3"
|
||||
version: "0.0.4+4"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -512,7 +519,7 @@ packages:
|
|||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.9.2"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -526,7 +533,7 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.3"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -547,7 +554,7 @@ packages:
|
|||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2+1"
|
||||
version: "4.3.2+2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -608,21 +615,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.6"
|
||||
version: "0.9.7+1"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0-nullsafety.2"
|
||||
sqflite:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
version: "1.3.1+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -636,7 +643,14 @@ packages:
|
|||
name: sqlite3
|
||||
url: "https://pub.dartlang.org"
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -650,14 +664,14 @@ packages:
|
|||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.5"
|
||||
version: "1.10.0-nullsafety.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0-nullsafety.1"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -671,7 +685,7 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.1.0-nullsafety.1"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -685,14 +699,14 @@ packages:
|
|||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0-nullsafety.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.17"
|
||||
version: "0.2.19-nullsafety.2"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -706,21 +720,21 @@ packages:
|
|||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0-nullsafety.3"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.2.2"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
version: "2.1.0-nullsafety.3"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -748,7 +762,7 @@ packages:
|
|||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
version: "0.1.2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -757,5 +771,5 @@ packages:
|
|||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=2.9.0 <3.0.0"
|
||||
dart: ">=2.10.0-110 <2.11.0"
|
||||
flutter: ">=1.20.0 <2.0.0"
|
||||
|
|
37
pubspec.yaml
37
pubspec.yaml
|
@ -8,36 +8,33 @@ environment:
|
|||
flutter: ">=1.20.0"
|
||||
|
||||
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_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
|
||||
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
|
||||
provider: ^4.0.4
|
||||
logging: ^0.11.4
|
||||
moor: ^3.0.2
|
||||
moor_ffi: ^0.5.0
|
||||
path:
|
||||
|
||||
mobx: ^1.1.1
|
||||
flutter_mobx: ^1.1.0
|
||||
sqlite3_flutter_libs: ^0.2.0
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: 1.10.2
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
moor_generator: ^3.0.0
|
||||
build_runner: 1.10.1
|
||||
mobx_codegen: ^1.0.3
|
||||
moor_generator: ^3.0.0
|
||||
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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/models/album_model.dart';
|
||||
import 'package:mucke/system/models/song_model.dart';
|
||||
|
|
Loading…
Add table
Reference in a new issue