highlighted songs per artist

This commit is contained in:
Moritz Weber 2021-05-04 18:45:57 +02:00
parent caae3bf8dd
commit 5f58570bc2
9 changed files with 115 additions and 5 deletions

View file

@ -41,15 +41,11 @@ class AudioPlayerActor {
void _handlePosition(Duration position, Song song) { void _handlePosition(Duration position, Song song) {
if (song == null || position == null) return; if (song == null || position == null) return;
print('HANDLE POSITION');
final int pos = position.inMilliseconds; final int pos = position.inMilliseconds;
if (pos < song.duration * 0.05) { if (pos < song.duration * 0.05) {
print('COUNT -> TRUE');
_countSongPlayback = true; _countSongPlayback = true;
} else if (pos > song.duration * 0.95 && _countSongPlayback) { } else if (pos > song.duration * 0.95 && _countSongPlayback) {
print('INCREMENT PLAY COUNT: ${song.title}');
_countSongPlayback = false; _countSongPlayback = false;
_incrementPlayCount(song); _incrementPlayCount(song);
} }

View file

@ -9,6 +9,7 @@ abstract class MusicDataInfoRepository {
Stream<List<Song>> get songStream; Stream<List<Song>> get songStream;
Stream<List<Song>> getAlbumSongStream(Album album); Stream<List<Song>> getAlbumSongStream(Album album);
Stream<List<Song>> getArtistSongStream(Artist artist); Stream<List<Song>> getArtistSongStream(Artist artist);
Stream<List<Song>> getArtistHighlightedSongStream(Artist artist);
Stream<List<Album>> get albumStream; Stream<List<Album>> get albumStream;
Stream<List<Album>> getArtistAlbumStream(Artist artist); Stream<List<Album>> getArtistAlbumStream(Artist artist);

View file

@ -9,6 +9,7 @@ import '../state/music_data_store.dart';
import '../theming.dart'; import '../theming.dart';
import '../widgets/artist_albums.dart'; import '../widgets/artist_albums.dart';
import '../widgets/artist_header.dart'; import '../widgets/artist_header.dart';
import '../widgets/artist_highlighted_songs.dart';
import 'album_details_page.dart'; import 'album_details_page.dart';
class ArtistDetailsPage extends StatelessWidget { class ArtistDetailsPage extends StatelessWidget {
@ -40,6 +41,34 @@ class ArtistDetailsPage extends StatelessWidget {
onPressed: () => audioStore.shuffleArtist(artist), onPressed: () => audioStore.shuffleArtist(artist),
), ),
), ),
const Padding(
padding: EdgeInsets.only(
left: HORIZONTAL_PADDING + 2,
right: HORIZONTAL_PADDING + 2,
bottom: 4.0,
),
child: Text(
'Highlights',
style: TEXT_HEADER,
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: HORIZONTAL_PADDING,
vertical: 4.0,
),
child: Container(
height: 1.0,
color: Colors.white10,
),
),
],
),
),
ArtistHighlightedSongs(songs: musicDataStore.artistHighlightedSongStream.value),
SliverList(
delegate: SliverChildListDelegate(
[
const Padding( const Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: HORIZONTAL_PADDING + 2, left: HORIZONTAL_PADDING + 2,

View file

@ -31,6 +31,7 @@ class _ArtistsPageState extends State<ArtistsPage> with AutomaticKeepAliveClient
title: Text(artist.name), title: Text(artist.name),
onTap: () { onTap: () {
musicDataStore.fetchAlbumsFromArtist(artist); musicDataStore.fetchAlbumsFromArtist(artist);
musicDataStore.fetchHighlightedSongsFromArtist(artist);
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute<Widget>( MaterialPageRoute<Widget>(

View file

@ -68,6 +68,9 @@ abstract class _MusicDataStore with Store {
@observable @observable
ObservableStream<List<Album>> artistAlbumStream; ObservableStream<List<Album>> artistAlbumStream;
@observable
ObservableStream<List<Song>> artistHighlightedSongStream;
@observable @observable
bool isUpdatingDatabase = false; bool isUpdatingDatabase = false;
@ -92,12 +95,20 @@ abstract class _MusicDataStore with Store {
_musicDataInfoRepository.getAlbumSongStream(album).asObservable(initialValue: []); _musicDataInfoRepository.getAlbumSongStream(album).asObservable(initialValue: []);
} }
// TODO: das hier ist komplett bescheuert... brauchen einen eigenen Store für die ArtistDetailsPage
@action @action
Future<void> fetchAlbumsFromArtist(Artist artist) async { Future<void> fetchAlbumsFromArtist(Artist artist) async {
artistAlbumStream = artistAlbumStream =
_musicDataInfoRepository.getArtistAlbumStream(artist).asObservable(initialValue: []); _musicDataInfoRepository.getArtistAlbumStream(artist).asObservable(initialValue: []);
} }
@action
Future<void> fetchHighlightedSongsFromArtist(Artist artist) async {
artistHighlightedSongStream = _musicDataInfoRepository
.getArtistHighlightedSongStream(artist)
.asObservable(initialValue: []);
}
Future<void> setSongBlocked(Song song, bool blocked) => _setSongBlocked(song, blocked); Future<void> setSongBlocked(Song song, bool blocked) => _setSongBlocked(song, blocked);
Future<void> toggleNextSongLink(Song song) async { Future<void> toggleNextSongLink(Song song) async {

View file

@ -93,6 +93,23 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
}); });
} }
final _$artistHighlightedSongStreamAtom =
Atom(name: '_MusicDataStore.artistHighlightedSongStream');
@override
ObservableStream<List<Song>> get artistHighlightedSongStream {
_$artistHighlightedSongStreamAtom.reportRead();
return super.artistHighlightedSongStream;
}
@override
set artistHighlightedSongStream(ObservableStream<List<Song>> value) {
_$artistHighlightedSongStreamAtom
.reportWrite(value, super.artistHighlightedSongStream, () {
super.artistHighlightedSongStream = value;
});
}
final _$isUpdatingDatabaseAtom = final _$isUpdatingDatabaseAtom =
Atom(name: '_MusicDataStore.isUpdatingDatabase'); Atom(name: '_MusicDataStore.isUpdatingDatabase');
@ -135,6 +152,15 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
.run(() => super.fetchAlbumsFromArtist(artist)); .run(() => super.fetchAlbumsFromArtist(artist));
} }
final _$fetchHighlightedSongsFromArtistAsyncAction =
AsyncAction('_MusicDataStore.fetchHighlightedSongsFromArtist');
@override
Future<void> fetchHighlightedSongsFromArtist(Artist artist) {
return _$fetchHighlightedSongsFromArtistAsyncAction
.run(() => super.fetchHighlightedSongsFromArtist(artist));
}
@override @override
String toString() { String toString() {
return ''' return '''
@ -143,6 +169,7 @@ albumStream: ${albumStream},
artistStream: ${artistStream}, artistStream: ${artistStream},
albumSongStream: ${albumSongStream}, albumSongStream: ${albumSongStream},
artistAlbumStream: ${artistAlbumStream}, artistAlbumStream: ${artistAlbumStream},
artistHighlightedSongStream: ${artistHighlightedSongStream},
isUpdatingDatabase: ${isUpdatingDatabase}, isUpdatingDatabase: ${isUpdatingDatabase},
sortedArtistAlbums: ${sortedArtistAlbums} sortedArtistAlbums: ${sortedArtistAlbums}
'''; ''';

View file

@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import '../../domain/entities/song.dart';
import 'song_list_tile.dart';
class ArtistHighlightedSongs extends StatelessWidget {
const ArtistHighlightedSongs({Key key, this.songs, this.onTap, this.onTapPlay}) : super(key: key);
final List<Song> songs;
final Function onTap;
final Function onTapPlay;
@override
Widget build(BuildContext context) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(_, int index) {
final Song song = songs[index];
return SongListTile(
song: song
);
},
childCount: songs.length,
),
);
}
}

View file

@ -4,7 +4,7 @@ import '../../domain/entities/song.dart';
import '../utils.dart' as utils; import '../utils.dart' as utils;
class SongListTile extends StatelessWidget { class SongListTile extends StatelessWidget {
const SongListTile({Key key, this.song, this.onTap, this.inAlbum, this.onTapMore}) const SongListTile({Key key, this.song, this.onTap, this.inAlbum = false, this.onTapMore})
: super(key: key); : super(key: key);
final Song song; final Song song;

View file

@ -52,6 +52,13 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
Stream<List<Song>> getArtistSongStream(Artist artist) => Stream<List<Song>> getArtistSongStream(Artist artist) =>
_musicDataSource.getArtistSongStream(artist as ArtistModel); _musicDataSource.getArtistSongStream(artist as ArtistModel);
@override
Stream<List<Song>> getArtistHighlightedSongStream(Artist artist) {
return _musicDataSource
.getArtistSongStream(artist as ArtistModel)
.map((event) => _sortHighlightedSongs(event).take(5).toList());
}
@override @override
Stream<List<Album>> getArtistAlbumStream(Artist artist) => Stream<List<Album>> getArtistAlbumStream(Artist artist) =>
_musicDataSource.getArtistAlbumStream(artist as ArtistModel); _musicDataSource.getArtistAlbumStream(artist as ArtistModel);
@ -137,4 +144,15 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
// TODO: implement resetSkipCount // TODO: implement resetSkipCount
throw UnimplementedError(); throw UnimplementedError();
} }
List<Song> _sortHighlightedSongs(List<Song> songs) {
return songs
..sort(
(a, b) {
final r = -a.likeCount.compareTo(b.likeCount);
if (r != 0) return r;
return -a.playCount.compareTo(b.playCount);
},
);
}
} }