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/album.dart';
|
||||||
import '../entities/artist.dart';
|
import '../entities/artist.dart';
|
||||||
|
import '../entities/smart_list.dart';
|
||||||
import '../entities/song.dart';
|
import '../entities/song.dart';
|
||||||
|
|
||||||
abstract class MusicDataInfoRepository {
|
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_album.dart';
|
||||||
import 'domain/usecases/play_artist.dart';
|
import 'domain/usecases/play_artist.dart';
|
||||||
import 'domain/usecases/play_next.dart';
|
import 'domain/usecases/play_next.dart';
|
||||||
|
import 'domain/usecases/play_smart_list.dart';
|
||||||
import 'domain/usecases/play_songs.dart';
|
import 'domain/usecases/play_songs.dart';
|
||||||
import 'domain/usecases/remove_queue_index.dart';
|
import 'domain/usecases/remove_queue_index.dart';
|
||||||
import 'domain/usecases/reset_like_count.dart';
|
import 'domain/usecases/reset_like_count.dart';
|
||||||
|
@ -92,6 +93,7 @@ Future<void> setupGetIt() async {
|
||||||
playAlbum: getIt(),
|
playAlbum: getIt(),
|
||||||
playArtist: getIt(),
|
playArtist: getIt(),
|
||||||
playNext: getIt(),
|
playNext: getIt(),
|
||||||
|
playSmartList: getIt(),
|
||||||
playSongs: getIt(),
|
playSongs: getIt(),
|
||||||
removeQueueIndex: getIt(),
|
removeQueueIndex: getIt(),
|
||||||
seekToIndex: getIt(),
|
seekToIndex: getIt(),
|
||||||
|
@ -120,10 +122,12 @@ Future<void> setupGetIt() async {
|
||||||
() => SettingsStore(settingsRepository: getIt()),
|
() => SettingsStore(settingsRepository: getIt()),
|
||||||
);
|
);
|
||||||
getIt.registerFactoryParam<SmartListFormStore, SmartList, void>(
|
getIt.registerFactoryParam<SmartListFormStore, SmartList, void>(
|
||||||
(SmartList? smartList, _) => SmartListFormStore(settingsRepository: getIt(), smartList: smartList),
|
(SmartList? smartList, _) =>
|
||||||
|
SmartListFormStore(settingsRepository: getIt(), smartList: smartList),
|
||||||
);
|
);
|
||||||
getIt.registerFactoryParam<SmartListPageStore, SmartList, void>(
|
getIt.registerFactoryParam<SmartListPageStore, SmartList, void>(
|
||||||
(SmartList? smartList, _) => SmartListPageStore(smartList: smartList!, musicDataInfoRepository: getIt()),
|
(SmartList? smartList, _) =>
|
||||||
|
SmartListPageStore(smartList: smartList!, musicDataInfoRepository: getIt()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// use cases
|
// use cases
|
||||||
|
@ -183,6 +187,12 @@ Future<void> setupGetIt() async {
|
||||||
getIt(),
|
getIt(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
getIt.registerLazySingleton<PlaySmartList>(
|
||||||
|
() => PlaySmartList(
|
||||||
|
getIt(),
|
||||||
|
getIt(),
|
||||||
|
),
|
||||||
|
);
|
||||||
getIt.registerLazySingleton<PlayNext>(
|
getIt.registerLazySingleton<PlayNext>(
|
||||||
() => PlayNext(
|
() => PlayNext(
|
||||||
getIt(),
|
getIt(),
|
||||||
|
|
|
@ -161,7 +161,7 @@ class CurrentlyPlayingPage extends StatelessWidget {
|
||||||
final song = audioStore.currentSongStream.value;
|
final song = audioStore.currentSongStream.value;
|
||||||
if (song == null)
|
if (song == null)
|
||||||
return;
|
return;
|
||||||
// EXPLORATORY
|
// TODO: EXPLORATORY
|
||||||
final albums = await musicDataStore.albumStream.first;
|
final albums = await musicDataStore.albumStream.first;
|
||||||
final album = albums.singleWhere((a) => a.title == song.album);
|
final album = albums.singleWhere((a) => a.title == song.album);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ class _HomePageState extends State<HomePage> {
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverList(
|
SliverList(
|
||||||
delegate: SliverChildListDelegate([
|
delegate: SliverChildListDelegate([
|
||||||
|
const SizedBox(height: 12.0),
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: HORIZONTAL_PADDING),
|
padding: EdgeInsets.symmetric(horizontal: HORIZONTAL_PADDING),
|
||||||
child: Highlight(),
|
child: Highlight(),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import '../../domain/entities/artist.dart';
|
||||||
import '../../domain/entities/loop_mode.dart';
|
import '../../domain/entities/loop_mode.dart';
|
||||||
import '../../domain/entities/shuffle_mode.dart';
|
import '../../domain/entities/shuffle_mode.dart';
|
||||||
import '../../domain/entities/song.dart';
|
import '../../domain/entities/song.dart';
|
||||||
|
import '../../domain/entities/smart_list.dart';
|
||||||
import '../../domain/repositories/audio_player_repository.dart';
|
import '../../domain/repositories/audio_player_repository.dart';
|
||||||
import '../../domain/usecases/add_to_queue.dart';
|
import '../../domain/usecases/add_to_queue.dart';
|
||||||
import '../../domain/usecases/move_queue_item.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_album.dart';
|
||||||
import '../../domain/usecases/play_artist.dart';
|
import '../../domain/usecases/play_artist.dart';
|
||||||
import '../../domain/usecases/play_next.dart';
|
import '../../domain/usecases/play_next.dart';
|
||||||
|
import '../../domain/usecases/play_smart_list.dart';
|
||||||
import '../../domain/usecases/play_songs.dart';
|
import '../../domain/usecases/play_songs.dart';
|
||||||
import '../../domain/usecases/remove_queue_index.dart';
|
import '../../domain/usecases/remove_queue_index.dart';
|
||||||
import '../../domain/usecases/seek_to_index.dart';
|
import '../../domain/usecases/seek_to_index.dart';
|
||||||
|
@ -34,6 +36,7 @@ class AudioStore extends _AudioStore with _$AudioStore {
|
||||||
required PlayArtist playArtist,
|
required PlayArtist playArtist,
|
||||||
required PlayNext playNext,
|
required PlayNext playNext,
|
||||||
required PlaySongs playSongs,
|
required PlaySongs playSongs,
|
||||||
|
required PlaySmartList playSmartList,
|
||||||
required RemoveQueueIndex removeQueueIndex,
|
required RemoveQueueIndex removeQueueIndex,
|
||||||
required SeekToIndex seekToIndex,
|
required SeekToIndex seekToIndex,
|
||||||
required SeekToNext seekToNext,
|
required SeekToNext seekToNext,
|
||||||
|
@ -52,6 +55,7 @@ class AudioStore extends _AudioStore with _$AudioStore {
|
||||||
playAlbum,
|
playAlbum,
|
||||||
playArtist,
|
playArtist,
|
||||||
playNext,
|
playNext,
|
||||||
|
playSmartList,
|
||||||
removeQueueIndex,
|
removeQueueIndex,
|
||||||
seekToIndex,
|
seekToIndex,
|
||||||
seekToNext,
|
seekToNext,
|
||||||
|
@ -73,6 +77,7 @@ abstract class _AudioStore with Store {
|
||||||
this._playAlbum,
|
this._playAlbum,
|
||||||
this._playArtist,
|
this._playArtist,
|
||||||
this._playNext,
|
this._playNext,
|
||||||
|
this._playSmartList,
|
||||||
this._removeQueueIndex,
|
this._removeQueueIndex,
|
||||||
this._seekToIndex,
|
this._seekToIndex,
|
||||||
this._seekToNext,
|
this._seekToNext,
|
||||||
|
@ -90,6 +95,7 @@ abstract class _AudioStore with Store {
|
||||||
final Play _play;
|
final Play _play;
|
||||||
final PlayAlbum _playAlbum;
|
final PlayAlbum _playAlbum;
|
||||||
final PlayArtist _playArtist;
|
final PlayArtist _playArtist;
|
||||||
|
final PlaySmartList _playSmartList;
|
||||||
final PlayNext _playNext;
|
final PlayNext _playNext;
|
||||||
final PlaySongs _playSongs;
|
final PlaySongs _playSongs;
|
||||||
final RemoveQueueIndex _removeQueueIndex;
|
final RemoveQueueIndex _removeQueueIndex;
|
||||||
|
@ -186,6 +192,10 @@ abstract class _AudioStore with Store {
|
||||||
_playAlbum(album);
|
_playAlbum(album);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> playSmartList(SmartList smartList) async {
|
||||||
|
_playSmartList(smartList);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> shuffleArtist(Artist artist) async {
|
Future<void> shuffleArtist(Artist artist) async {
|
||||||
_playArtist(artist);
|
_playArtist(artist);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,7 @@ class Highlight extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Column(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -94,8 +91,6 @@ class Highlight extends StatelessWidget {
|
||||||
onPressed: () => audioStore.playAlbum(album),
|
onPressed: () => audioStore.playAlbum(album),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,14 +4,17 @@ import 'package:get_it/get_it.dart';
|
||||||
|
|
||||||
import '../../domain/entities/smart_list.dart';
|
import '../../domain/entities/smart_list.dart';
|
||||||
import '../pages/smart_list_page.dart';
|
import '../pages/smart_list_page.dart';
|
||||||
|
import '../state/audio_store.dart';
|
||||||
import '../state/navigation_store.dart';
|
import '../state/navigation_store.dart';
|
||||||
import '../state/settings_store.dart';
|
import '../state/settings_store.dart';
|
||||||
|
import '../theming.dart';
|
||||||
|
|
||||||
class SmartLists extends StatelessWidget {
|
class SmartLists extends StatelessWidget {
|
||||||
const SmartLists({Key? key}) : super(key: key);
|
const SmartLists({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final AudioStore audioStore = GetIt.I<AudioStore>();
|
||||||
final NavigationStore navStore = GetIt.I<NavigationStore>();
|
final NavigationStore navStore = GetIt.I<NavigationStore>();
|
||||||
final SettingsStore settingsStore = GetIt.I<SettingsStore>();
|
final SettingsStore settingsStore = GetIt.I<SettingsStore>();
|
||||||
|
|
||||||
|
@ -22,14 +25,48 @@ class SmartLists extends StatelessWidget {
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(_, int index) {
|
(_, int index) {
|
||||||
final SmartList smartList = smartLists[index];
|
final SmartList smartList = smartLists[index];
|
||||||
return ListTile(
|
return GestureDetector(
|
||||||
title: Text(smartList.name),
|
|
||||||
onTap: () => navStore.push(
|
onTap: () => navStore.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute<Widget>(
|
MaterialPageRoute<Widget>(
|
||||||
builder: (context) => SmartListPage(smartList: smartList),
|
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,
|
childCount: smartLists.length,
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:fimber/fimber.dart';
|
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:rxdart/rxdart.dart';
|
||||||
import 'package:string_similarity/string_similarity.dart';
|
import 'package:string_similarity/string_similarity.dart';
|
||||||
|
|
||||||
import '../../domain/entities/album.dart';
|
import '../../domain/entities/album.dart';
|
||||||
import '../../domain/entities/artist.dart';
|
import '../../domain/entities/artist.dart';
|
||||||
|
import '../../domain/entities/smart_list.dart';
|
||||||
import '../../domain/entities/song.dart';
|
import '../../domain/entities/song.dart';
|
||||||
import '../../domain/repositories/music_data_repository.dart';
|
import '../../domain/repositories/music_data_repository.dart';
|
||||||
import '../datasources/local_music_fetcher.dart';
|
import '../datasources/local_music_fetcher.dart';
|
||||||
import '../datasources/music_data_source_contract.dart';
|
import '../datasources/music_data_source_contract.dart';
|
||||||
import '../models/album_model.dart';
|
import '../models/album_model.dart';
|
||||||
import '../models/artist_model.dart';
|
import '../models/artist_model.dart';
|
||||||
|
import '../models/smart_list_model.dart';
|
||||||
import '../models/song_model.dart';
|
import '../models/song_model.dart';
|
||||||
|
|
||||||
class MusicDataRepositoryImpl implements MusicDataRepository {
|
class MusicDataRepositoryImpl implements MusicDataRepository {
|
||||||
|
|
Loading…
Add table
Reference in a new issue