smart list playback
This commit is contained in:
parent
33223d0069
commit
ebc4381216
9 changed files with 140 additions and 68 deletions
|
@ -1,7 +1,6 @@
|
|||
import 'package:mucke/domain/entities/smart_list.dart';
|
||||
|
||||
import '../entities/album.dart';
|
||||
import '../entities/artist.dart';
|
||||
import '../entities/smart_list.dart';
|
||||
import '../entities/song.dart';
|
||||
|
||||
abstract class MusicDataInfoRepository {
|
||||
|
|
20
lib/domain/usecases/play_smart_list.dart
Normal file
20
lib/domain/usecases/play_smart_list.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
import '../entities/smart_list.dart';
|
||||
import '../repositories/music_data_repository.dart';
|
||||
import 'play_songs.dart';
|
||||
|
||||
class PlaySmartList {
|
||||
PlaySmartList(
|
||||
this._musicDataRepository,
|
||||
this._playSongs,
|
||||
);
|
||||
|
||||
final PlaySongs _playSongs;
|
||||
|
||||
final MusicDataRepository _musicDataRepository;
|
||||
|
||||
Future<void> call(SmartList smartList) async {
|
||||
final songs = await _musicDataRepository.getSmartListSongStream(smartList).first;
|
||||
|
||||
_playSongs(songs: songs, initialIndex: 0);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import 'domain/usecases/play.dart';
|
|||
import 'domain/usecases/play_album.dart';
|
||||
import 'domain/usecases/play_artist.dart';
|
||||
import 'domain/usecases/play_next.dart';
|
||||
import 'domain/usecases/play_smart_list.dart';
|
||||
import 'domain/usecases/play_songs.dart';
|
||||
import 'domain/usecases/remove_queue_index.dart';
|
||||
import 'domain/usecases/reset_like_count.dart';
|
||||
|
@ -92,6 +93,7 @@ Future<void> setupGetIt() async {
|
|||
playAlbum: getIt(),
|
||||
playArtist: getIt(),
|
||||
playNext: getIt(),
|
||||
playSmartList: getIt(),
|
||||
playSongs: getIt(),
|
||||
removeQueueIndex: getIt(),
|
||||
seekToIndex: getIt(),
|
||||
|
@ -120,10 +122,12 @@ Future<void> setupGetIt() async {
|
|||
() => SettingsStore(settingsRepository: getIt()),
|
||||
);
|
||||
getIt.registerFactoryParam<SmartListFormStore, SmartList, void>(
|
||||
(SmartList? smartList, _) => SmartListFormStore(settingsRepository: getIt(), smartList: smartList),
|
||||
(SmartList? smartList, _) =>
|
||||
SmartListFormStore(settingsRepository: getIt(), smartList: smartList),
|
||||
);
|
||||
getIt.registerFactoryParam<SmartListPageStore, SmartList, void>(
|
||||
(SmartList? smartList, _) => SmartListPageStore(smartList: smartList!, musicDataInfoRepository: getIt()),
|
||||
(SmartList? smartList, _) =>
|
||||
SmartListPageStore(smartList: smartList!, musicDataInfoRepository: getIt()),
|
||||
);
|
||||
|
||||
// use cases
|
||||
|
@ -183,6 +187,12 @@ Future<void> setupGetIt() async {
|
|||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<PlaySmartList>(
|
||||
() => PlaySmartList(
|
||||
getIt(),
|
||||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<PlayNext>(
|
||||
() => PlayNext(
|
||||
getIt(),
|
||||
|
|
|
@ -161,7 +161,7 @@ class CurrentlyPlayingPage extends StatelessWidget {
|
|||
final song = audioStore.currentSongStream.value;
|
||||
if (song == null)
|
||||
return;
|
||||
// EXPLORATORY
|
||||
// TODO: EXPLORATORY
|
||||
final albums = await musicDataStore.albumStream.first;
|
||||
final album = albums.singleWhere((a) => a.title == song.album);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class _HomePageState extends State<HomePage> {
|
|||
slivers: [
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
const SizedBox(height: 12.0),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: HORIZONTAL_PADDING),
|
||||
child: Highlight(),
|
||||
|
|
|
@ -5,6 +5,7 @@ import '../../domain/entities/artist.dart';
|
|||
import '../../domain/entities/loop_mode.dart';
|
||||
import '../../domain/entities/shuffle_mode.dart';
|
||||
import '../../domain/entities/song.dart';
|
||||
import '../../domain/entities/smart_list.dart';
|
||||
import '../../domain/repositories/audio_player_repository.dart';
|
||||
import '../../domain/usecases/add_to_queue.dart';
|
||||
import '../../domain/usecases/move_queue_item.dart';
|
||||
|
@ -13,6 +14,7 @@ import '../../domain/usecases/play.dart';
|
|||
import '../../domain/usecases/play_album.dart';
|
||||
import '../../domain/usecases/play_artist.dart';
|
||||
import '../../domain/usecases/play_next.dart';
|
||||
import '../../domain/usecases/play_smart_list.dart';
|
||||
import '../../domain/usecases/play_songs.dart';
|
||||
import '../../domain/usecases/remove_queue_index.dart';
|
||||
import '../../domain/usecases/seek_to_index.dart';
|
||||
|
@ -34,6 +36,7 @@ class AudioStore extends _AudioStore with _$AudioStore {
|
|||
required PlayArtist playArtist,
|
||||
required PlayNext playNext,
|
||||
required PlaySongs playSongs,
|
||||
required PlaySmartList playSmartList,
|
||||
required RemoveQueueIndex removeQueueIndex,
|
||||
required SeekToIndex seekToIndex,
|
||||
required SeekToNext seekToNext,
|
||||
|
@ -52,6 +55,7 @@ class AudioStore extends _AudioStore with _$AudioStore {
|
|||
playAlbum,
|
||||
playArtist,
|
||||
playNext,
|
||||
playSmartList,
|
||||
removeQueueIndex,
|
||||
seekToIndex,
|
||||
seekToNext,
|
||||
|
@ -73,6 +77,7 @@ abstract class _AudioStore with Store {
|
|||
this._playAlbum,
|
||||
this._playArtist,
|
||||
this._playNext,
|
||||
this._playSmartList,
|
||||
this._removeQueueIndex,
|
||||
this._seekToIndex,
|
||||
this._seekToNext,
|
||||
|
@ -90,6 +95,7 @@ abstract class _AudioStore with Store {
|
|||
final Play _play;
|
||||
final PlayAlbum _playAlbum;
|
||||
final PlayArtist _playArtist;
|
||||
final PlaySmartList _playSmartList;
|
||||
final PlayNext _playNext;
|
||||
final PlaySongs _playSongs;
|
||||
final RemoveQueueIndex _removeQueueIndex;
|
||||
|
@ -186,6 +192,10 @@ abstract class _AudioStore with Store {
|
|||
_playAlbum(album);
|
||||
}
|
||||
|
||||
Future<void> playSmartList(SmartList smartList) async {
|
||||
_playSmartList(smartList);
|
||||
}
|
||||
|
||||
Future<void> shuffleArtist(Artist artist) async {
|
||||
_playArtist(artist);
|
||||
}
|
||||
|
|
|
@ -32,69 +32,64 @@ class Highlight extends StatelessWidget {
|
|||
),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
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: 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
],
|
||||
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,
|
||||
),
|
||||
iconSize: 48.0,
|
||||
onPressed: () => audioStore.playAlbum(album),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(
|
||||
Icons.play_circle_fill_rounded,
|
||||
size: 48.0,
|
||||
),
|
||||
iconSize: 48.0,
|
||||
onPressed: () => audioStore.playAlbum(album),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,14 +4,17 @@ import 'package:get_it/get_it.dart';
|
|||
|
||||
import '../../domain/entities/smart_list.dart';
|
||||
import '../pages/smart_list_page.dart';
|
||||
import '../state/audio_store.dart';
|
||||
import '../state/navigation_store.dart';
|
||||
import '../state/settings_store.dart';
|
||||
import '../theming.dart';
|
||||
|
||||
class SmartLists extends StatelessWidget {
|
||||
const SmartLists({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AudioStore audioStore = GetIt.I<AudioStore>();
|
||||
final NavigationStore navStore = GetIt.I<NavigationStore>();
|
||||
final SettingsStore settingsStore = GetIt.I<SettingsStore>();
|
||||
|
||||
|
@ -22,14 +25,48 @@ class SmartLists extends StatelessWidget {
|
|||
delegate: SliverChildBuilderDelegate(
|
||||
(_, int index) {
|
||||
final SmartList smartList = smartLists[index];
|
||||
return ListTile(
|
||||
title: Text(smartList.name),
|
||||
return GestureDetector(
|
||||
onTap: () => navStore.push(
|
||||
context,
|
||||
MaterialPageRoute<Widget>(
|
||||
builder: (context) => SmartListPage(smartList: smartList),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: HORIZONTAL_PADDING,
|
||||
vertical: 6.0,
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(4.0), color: Colors.white10),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: HORIZONTAL_PADDING, top: 4.0, bottom: 4.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
smartList.name,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8.0),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(
|
||||
Icons.play_circle_fill_rounded,
|
||||
size: 40.0,
|
||||
),
|
||||
iconSize: 48.0,
|
||||
onPressed: () => audioStore.playSmartList(smartList),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
childCount: smartLists.length,
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:fimber/fimber.dart';
|
||||
import 'package:mucke/domain/entities/smart_list.dart';
|
||||
import 'package:mucke/system/models/smart_list_model.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:string_similarity/string_similarity.dart';
|
||||
|
||||
import '../../domain/entities/album.dart';
|
||||
import '../../domain/entities/artist.dart';
|
||||
import '../../domain/entities/smart_list.dart';
|
||||
import '../../domain/entities/song.dart';
|
||||
import '../../domain/repositories/music_data_repository.dart';
|
||||
import '../datasources/local_music_fetcher.dart';
|
||||
import '../datasources/music_data_source_contract.dart';
|
||||
import '../models/album_model.dart';
|
||||
import '../models/artist_model.dart';
|
||||
import '../models/smart_list_model.dart';
|
||||
import '../models/song_model.dart';
|
||||
|
||||
class MusicDataRepositoryImpl implements MusicDataRepository {
|
||||
|
|
Loading…
Add table
Reference in a new issue