album of the day
This commit is contained in:
parent
7e21135bfe
commit
3fd97c882f
15 changed files with 394 additions and 86 deletions
|
@ -46,7 +46,7 @@ linter:
|
|||
# the Dart Lint rules page to make maintenance easier
|
||||
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
|
||||
- always_declare_return_types
|
||||
- always_put_control_body_on_new_line
|
||||
# - always_put_control_body_on_new_line
|
||||
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
|
||||
- always_require_non_null_named_parameters
|
||||
##### - always_specify_types
|
||||
|
|
|
@ -13,6 +13,8 @@ abstract class MusicDataInfoRepository {
|
|||
|
||||
Stream<List<Album>> get albumStream;
|
||||
Stream<List<Album>> getArtistAlbumStream(Artist artist);
|
||||
// TODO: make this a stream? or call everytime on home screen?
|
||||
Future<Album?> getAlbumOfDay();
|
||||
|
||||
Stream<List<Artist>> get artistStream;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,9 @@ abstract class _MusicDataStore with Store {
|
|||
@observable
|
||||
bool isUpdatingDatabase = false;
|
||||
|
||||
@observable
|
||||
late ObservableFuture<Album?> albumOfDay = _musicDataInfoRepository.getAlbumOfDay().asObservable();
|
||||
|
||||
@action
|
||||
Future<void> updateDatabase() async {
|
||||
isUpdatingDatabase = true;
|
||||
|
|
|
@ -70,6 +70,21 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
|
|||
});
|
||||
}
|
||||
|
||||
final _$albumOfDayAtom = Atom(name: '_MusicDataStore.albumOfDay');
|
||||
|
||||
@override
|
||||
ObservableFuture<Album?> get albumOfDay {
|
||||
_$albumOfDayAtom.reportRead();
|
||||
return super.albumOfDay;
|
||||
}
|
||||
|
||||
@override
|
||||
set albumOfDay(ObservableFuture<Album?> value) {
|
||||
_$albumOfDayAtom.reportWrite(value, super.albumOfDay, () {
|
||||
super.albumOfDay = value;
|
||||
});
|
||||
}
|
||||
|
||||
final _$updateDatabaseAsyncAction =
|
||||
AsyncAction('_MusicDataStore.updateDatabase');
|
||||
|
||||
|
@ -84,7 +99,8 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
|
|||
songStream: ${songStream},
|
||||
albumStream: ${albumStream},
|
||||
artistStream: ${artistStream},
|
||||
isUpdatingDatabase: ${isUpdatingDatabase}
|
||||
isUpdatingDatabase: ${isUpdatingDatabase},
|
||||
albumOfDay: ${albumOfDay}
|
||||
''';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,78 +1,90 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
import '../../domain/entities/album.dart';
|
||||
import '../state/music_data_store.dart';
|
||||
import '../theming.dart';
|
||||
import '../utils.dart';
|
||||
|
||||
class Highlight extends StatelessWidget {
|
||||
const Highlight({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 10,
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(1.0),
|
||||
),
|
||||
child: const Image(
|
||||
image: AssetImage('assets/no_cover.png'),
|
||||
fit: BoxFit.cover,
|
||||
final MusicDataStore store = GetIt.I<MusicDataStore>();
|
||||
|
||||
return Observer(
|
||||
builder: (context) {
|
||||
final Album? album = store.albumOfDay.value;
|
||||
if (album == null) return Container();
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 10,
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(1.0),
|
||||
),
|
||||
child: Image(
|
||||
image: getAlbumImage(album.albumArtPath),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 23,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Album of the Day'.toUpperCase(),
|
||||
style: TEXT_SMALL_HEADLINE,
|
||||
),
|
||||
Container(height: 6.0),
|
||||
Text(
|
||||
'All Our Gods Have Abandoned Us',
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const Text(
|
||||
'Architects',
|
||||
style: TEXT_SMALL_SUBTITLE,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
Expanded(
|
||||
flex: 23,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Album of the Day'.toUpperCase(),
|
||||
style: TEXT_SMALL_HEADLINE,
|
||||
),
|
||||
Container(height: 6.0),
|
||||
Text(
|
||||
album.title,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
album.artist,
|
||||
style: TEXT_SMALL_SUBTITLE,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(
|
||||
Icons.play_circle_fill_rounded,
|
||||
size: 48.0,
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(
|
||||
Icons.play_circle_fill_rounded,
|
||||
size: 48.0,
|
||||
),
|
||||
iconSize: 48.0,
|
||||
onPressed: () {},
|
||||
),
|
||||
iconSize: 48.0,
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import '../music_data_source_contract.dart';
|
|||
|
||||
part 'music_data_dao.g.dart';
|
||||
|
||||
@UseDao(tables: [Albums, Artists, Songs])
|
||||
@UseDao(tables: [Albums, Artists, Songs, MoorAlbumOfDay])
|
||||
class MusicDataDao extends DatabaseAccessor<MoorDatabase>
|
||||
with _$MusicDataDaoMixin
|
||||
implements MusicDataSource {
|
||||
|
@ -97,8 +97,8 @@ class MusicDataDao extends DatabaseAccessor<MoorDatabase>
|
|||
@override
|
||||
Future<SongModel> getSongByPath(String path) async {
|
||||
return (select(songs)..where((t) => t.path.equals(path))).getSingle().then(
|
||||
(moorSong) => SongModel.fromMoor(moorSong),
|
||||
);
|
||||
(moorSong) => SongModel.fromMoor(moorSong),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -270,4 +270,36 @@ class MusicDataDao extends DatabaseAccessor<MoorDatabase>
|
|||
await (update(songs)..where((tbl) => tbl.path.equals(songModel.path)))
|
||||
.write(songModel.toSongsCompanion());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AlbumOfDay?> getAlbumOfDay() async {
|
||||
final query = select(moorAlbumOfDay)
|
||||
.join([innerJoin(albums, albums.id.equalsExp(moorAlbumOfDay.albumId))]);
|
||||
|
||||
return (query..limit(1)).getSingleOrNull().then(
|
||||
(result) {
|
||||
if (result == null)
|
||||
return null;
|
||||
return AlbumOfDay(
|
||||
AlbumModel.fromMoor(result.readTable(albums)),
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
result.readTable(moorAlbumOfDay).milliSecSinceEpoch,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setAlbumOfDay(AlbumOfDay albumOfDay) async {
|
||||
transaction(() async {
|
||||
await delete(moorAlbumOfDay).go();
|
||||
into(moorAlbumOfDay).insert(
|
||||
MoorAlbumOfDayCompanion(
|
||||
albumId: Value(albumOfDay.albumModel.id),
|
||||
milliSecSinceEpoch: Value(albumOfDay.date.millisecondsSinceEpoch),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,4 +10,5 @@ mixin _$MusicDataDaoMixin on DatabaseAccessor<MoorDatabase> {
|
|||
$AlbumsTable get albums => attachedDatabase.albums;
|
||||
$ArtistsTable get artists => attachedDatabase.artists;
|
||||
$SongsTable get songs => attachedDatabase.songs;
|
||||
$MoorAlbumOfDayTable get moorAlbumOfDay => attachedDatabase.moorAlbumOfDay;
|
||||
}
|
||||
|
|
|
@ -114,17 +114,19 @@ class PersistentStateDao extends DatabaseAccessor<MoorDatabase>
|
|||
|
||||
@override
|
||||
Future<int> get currentIndex async {
|
||||
return select(persistentIndex).getSingle().then((event) => event.index ?? 0);
|
||||
return (select(persistentIndex)..limit(1)).getSingleOrNull().then((event) => event?.index ?? 0);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setCurrentIndex(int index) async {
|
||||
await delete(persistentIndex).go();
|
||||
into(persistentIndex).insert(PersistentIndexCompanion(index: Value(index)));
|
||||
transaction(() async {
|
||||
await delete(persistentIndex).go();
|
||||
into(persistentIndex).insert(PersistentIndexCompanion(index: Value(index)));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoopMode> get loopMode {
|
||||
Future<LoopMode> get loopMode async {
|
||||
return select(persistentLoopMode).getSingle().then((event) => event.loopMode.toLoopMode());
|
||||
}
|
||||
|
||||
|
|
|
@ -104,6 +104,14 @@ class LibraryFolders extends Table {
|
|||
TextColumn get path => text()();
|
||||
}
|
||||
|
||||
class MoorAlbumOfDay extends Table {
|
||||
IntColumn get albumId => integer()();
|
||||
IntColumn get milliSecSinceEpoch => integer()();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {albumId};
|
||||
}
|
||||
|
||||
@UseMoor(
|
||||
tables: [
|
||||
Albums,
|
||||
|
@ -116,6 +124,7 @@ class LibraryFolders extends Table {
|
|||
PersistentLoopMode,
|
||||
PersistentShuffleMode,
|
||||
Songs,
|
||||
MoorAlbumOfDay,
|
||||
],
|
||||
daos: [
|
||||
PersistentStateDao,
|
||||
|
|
|
@ -2555,6 +2555,202 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
}
|
||||
}
|
||||
|
||||
class MoorAlbumOfDayData extends DataClass
|
||||
implements Insertable<MoorAlbumOfDayData> {
|
||||
final int albumId;
|
||||
final int milliSecSinceEpoch;
|
||||
MoorAlbumOfDayData({required this.albumId, required this.milliSecSinceEpoch});
|
||||
factory MoorAlbumOfDayData.fromData(
|
||||
Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String? prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
return MoorAlbumOfDayData(
|
||||
albumId: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}album_id'])!,
|
||||
milliSecSinceEpoch: const IntType().mapFromDatabaseResponse(
|
||||
data['${effectivePrefix}milli_sec_since_epoch'])!,
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['album_id'] = Variable<int>(albumId);
|
||||
map['milli_sec_since_epoch'] = Variable<int>(milliSecSinceEpoch);
|
||||
return map;
|
||||
}
|
||||
|
||||
MoorAlbumOfDayCompanion toCompanion(bool nullToAbsent) {
|
||||
return MoorAlbumOfDayCompanion(
|
||||
albumId: Value(albumId),
|
||||
milliSecSinceEpoch: Value(milliSecSinceEpoch),
|
||||
);
|
||||
}
|
||||
|
||||
factory MoorAlbumOfDayData.fromJson(Map<String, dynamic> json,
|
||||
{ValueSerializer? serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return MoorAlbumOfDayData(
|
||||
albumId: serializer.fromJson<int>(json['albumId']),
|
||||
milliSecSinceEpoch: serializer.fromJson<int>(json['milliSecSinceEpoch']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= moorRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'albumId': serializer.toJson<int>(albumId),
|
||||
'milliSecSinceEpoch': serializer.toJson<int>(milliSecSinceEpoch),
|
||||
};
|
||||
}
|
||||
|
||||
MoorAlbumOfDayData copyWith({int? albumId, int? milliSecSinceEpoch}) =>
|
||||
MoorAlbumOfDayData(
|
||||
albumId: albumId ?? this.albumId,
|
||||
milliSecSinceEpoch: milliSecSinceEpoch ?? this.milliSecSinceEpoch,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('MoorAlbumOfDayData(')
|
||||
..write('albumId: $albumId, ')
|
||||
..write('milliSecSinceEpoch: $milliSecSinceEpoch')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
$mrjf($mrjc(albumId.hashCode, milliSecSinceEpoch.hashCode));
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is MoorAlbumOfDayData &&
|
||||
other.albumId == this.albumId &&
|
||||
other.milliSecSinceEpoch == this.milliSecSinceEpoch);
|
||||
}
|
||||
|
||||
class MoorAlbumOfDayCompanion extends UpdateCompanion<MoorAlbumOfDayData> {
|
||||
final Value<int> albumId;
|
||||
final Value<int> milliSecSinceEpoch;
|
||||
const MoorAlbumOfDayCompanion({
|
||||
this.albumId = const Value.absent(),
|
||||
this.milliSecSinceEpoch = const Value.absent(),
|
||||
});
|
||||
MoorAlbumOfDayCompanion.insert({
|
||||
this.albumId = const Value.absent(),
|
||||
required int milliSecSinceEpoch,
|
||||
}) : milliSecSinceEpoch = Value(milliSecSinceEpoch);
|
||||
static Insertable<MoorAlbumOfDayData> custom({
|
||||
Expression<int>? albumId,
|
||||
Expression<int>? milliSecSinceEpoch,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (albumId != null) 'album_id': albumId,
|
||||
if (milliSecSinceEpoch != null)
|
||||
'milli_sec_since_epoch': milliSecSinceEpoch,
|
||||
});
|
||||
}
|
||||
|
||||
MoorAlbumOfDayCompanion copyWith(
|
||||
{Value<int>? albumId, Value<int>? milliSecSinceEpoch}) {
|
||||
return MoorAlbumOfDayCompanion(
|
||||
albumId: albumId ?? this.albumId,
|
||||
milliSecSinceEpoch: milliSecSinceEpoch ?? this.milliSecSinceEpoch,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (albumId.present) {
|
||||
map['album_id'] = Variable<int>(albumId.value);
|
||||
}
|
||||
if (milliSecSinceEpoch.present) {
|
||||
map['milli_sec_since_epoch'] = Variable<int>(milliSecSinceEpoch.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('MoorAlbumOfDayCompanion(')
|
||||
..write('albumId: $albumId, ')
|
||||
..write('milliSecSinceEpoch: $milliSecSinceEpoch')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class $MoorAlbumOfDayTable extends MoorAlbumOfDay
|
||||
with TableInfo<$MoorAlbumOfDayTable, MoorAlbumOfDayData> {
|
||||
final GeneratedDatabase _db;
|
||||
final String? _alias;
|
||||
$MoorAlbumOfDayTable(this._db, [this._alias]);
|
||||
final VerificationMeta _albumIdMeta = const VerificationMeta('albumId');
|
||||
@override
|
||||
late final GeneratedIntColumn albumId = _constructAlbumId();
|
||||
GeneratedIntColumn _constructAlbumId() {
|
||||
return GeneratedIntColumn(
|
||||
'album_id',
|
||||
$tableName,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
final VerificationMeta _milliSecSinceEpochMeta =
|
||||
const VerificationMeta('milliSecSinceEpoch');
|
||||
@override
|
||||
late final GeneratedIntColumn milliSecSinceEpoch =
|
||||
_constructMilliSecSinceEpoch();
|
||||
GeneratedIntColumn _constructMilliSecSinceEpoch() {
|
||||
return GeneratedIntColumn(
|
||||
'milli_sec_since_epoch',
|
||||
$tableName,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [albumId, milliSecSinceEpoch];
|
||||
@override
|
||||
$MoorAlbumOfDayTable get asDslTable => this;
|
||||
@override
|
||||
String get $tableName => _alias ?? 'moor_album_of_day';
|
||||
@override
|
||||
final String actualTableName = 'moor_album_of_day';
|
||||
@override
|
||||
VerificationContext validateIntegrity(Insertable<MoorAlbumOfDayData> instance,
|
||||
{bool isInserting = false}) {
|
||||
final context = VerificationContext();
|
||||
final data = instance.toColumns(true);
|
||||
if (data.containsKey('album_id')) {
|
||||
context.handle(_albumIdMeta,
|
||||
albumId.isAcceptableOrUnknown(data['album_id']!, _albumIdMeta));
|
||||
}
|
||||
if (data.containsKey('milli_sec_since_epoch')) {
|
||||
context.handle(
|
||||
_milliSecSinceEpochMeta,
|
||||
milliSecSinceEpoch.isAcceptableOrUnknown(
|
||||
data['milli_sec_since_epoch']!, _milliSecSinceEpochMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_milliSecSinceEpochMeta);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {albumId};
|
||||
@override
|
||||
MoorAlbumOfDayData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
return MoorAlbumOfDayData.fromData(data, _db,
|
||||
prefix: tablePrefix != null ? '$tablePrefix.' : null);
|
||||
}
|
||||
|
||||
@override
|
||||
$MoorAlbumOfDayTable createAlias(String alias) {
|
||||
return $MoorAlbumOfDayTable(_db, alias);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$MoorDatabase extends GeneratedDatabase {
|
||||
_$MoorDatabase(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
|
||||
_$MoorDatabase.connect(DatabaseConnection c) : super.connect(c);
|
||||
|
@ -2573,6 +2769,7 @@ abstract class _$MoorDatabase extends GeneratedDatabase {
|
|||
late final $PersistentShuffleModeTable persistentShuffleMode =
|
||||
$PersistentShuffleModeTable(this);
|
||||
late final $SongsTable songs = $SongsTable(this);
|
||||
late final $MoorAlbumOfDayTable moorAlbumOfDay = $MoorAlbumOfDayTable(this);
|
||||
late final PersistentStateDao persistentStateDao =
|
||||
PersistentStateDao(this as MoorDatabase);
|
||||
late final SettingsDao settingsDao = SettingsDao(this as MoorDatabase);
|
||||
|
@ -2590,6 +2787,7 @@ abstract class _$MoorDatabase extends GeneratedDatabase {
|
|||
persistentIndex,
|
||||
persistentLoopMode,
|
||||
persistentShuffleMode,
|
||||
songs
|
||||
songs,
|
||||
moorAlbumOfDay
|
||||
];
|
||||
}
|
||||
|
|
|
@ -39,4 +39,8 @@ abstract class MusicDataSource {
|
|||
Future<int> insertArtist(ArtistModel artistModel);
|
||||
Future<void> insertArtists(List<ArtistModel> artistModels);
|
||||
Future<void> deleteAllArtists();
|
||||
|
||||
// TODO: is this the right place? maybe persistent state?
|
||||
Future<void> setAlbumOfDay(AlbumOfDay albumOfDay);
|
||||
Future<AlbumOfDay?> getAlbumOfDay();
|
||||
}
|
||||
|
|
|
@ -84,3 +84,10 @@ class AlbumModel extends Album {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AlbumOfDay {
|
||||
AlbumOfDay(this.albumModel, this.date);
|
||||
|
||||
final AlbumModel albumModel;
|
||||
final DateTime date;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:fimber/fimber.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
|
@ -198,4 +200,24 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
return -a.pubYear!.compareTo(b.pubYear!);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Album?> getAlbumOfDay() async {
|
||||
final storedAlbum = await _musicDataSource.getAlbumOfDay();
|
||||
if (storedAlbum == null || !_isAlbumValid(storedAlbum)) {
|
||||
final albums = await _musicDataSource.getAlbums();
|
||||
if (albums.isNotEmpty) {
|
||||
final rng = Random();
|
||||
final index = rng.nextInt(albums.length);
|
||||
_musicDataSource.setAlbumOfDay(AlbumOfDay(albums[index], DateTime.now()));
|
||||
return albums[index];
|
||||
}
|
||||
} else {
|
||||
return storedAlbum.albumModel;
|
||||
}
|
||||
}
|
||||
|
||||
bool _isAlbumValid(AlbumOfDay albumOfDay) {
|
||||
return albumOfDay.date.difference(DateTime.now()).inDays < 1;
|
||||
}
|
||||
}
|
||||
|
|
20
pubspec.lock
20
pubspec.lock
|
@ -270,9 +270,9 @@ packages:
|
|||
flutter_mobx:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
path: "../mobx.dart/flutter_mobx"
|
||||
relative: true
|
||||
source: path
|
||||
version: "2.0.0"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
|
@ -420,16 +420,16 @@ packages:
|
|||
mobx:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
path: "../mobx.dart/mobx"
|
||||
relative: true
|
||||
source: path
|
||||
version: "2.0.1+1"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
path: "../mobx.dart/mobx_codegen"
|
||||
relative: true
|
||||
source: path
|
||||
version: "2.0.1+3"
|
||||
mockito:
|
||||
dependency: "direct dev"
|
||||
|
|
12
pubspec.yaml
12
pubspec.yaml
|
@ -22,12 +22,12 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_fimber: ^0.6.3
|
||||
flutter_fimber_filelogger: ^2.0.0
|
||||
flutter_mobx: ^2.0.0
|
||||
# path: ../mobx.dart/flutter_mobx
|
||||
flutter_mobx: # ^2.0.0
|
||||
path: ../mobx.dart/flutter_mobx
|
||||
get_it: ^7.1.3
|
||||
just_audio: ^0.7.5
|
||||
mobx: ^2.0.1
|
||||
# path: ../mobx.dart/mobx
|
||||
mobx: # ^2.0.1
|
||||
path: ../mobx.dart/mobx
|
||||
moor: ^4.3.2
|
||||
path: ^1.8.0
|
||||
path_provider: ^2.0.2
|
||||
|
@ -39,8 +39,8 @@ dev_dependencies:
|
|||
build_runner: ^2.0.4
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
mobx_codegen: ^2.0.1+3
|
||||
# path: ../mobx.dart/mobx_codegen
|
||||
mobx_codegen: #^2.0.1+3
|
||||
path: ../mobx.dart/mobx_codegen
|
||||
mockito: ^5.0.10
|
||||
moor_generator: ^4.3.1
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue