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) {
if (song == null || position == null) return;
print('HANDLE POSITION');
final int pos = position.inMilliseconds;
if (pos < song.duration * 0.05) {
print('COUNT -> TRUE');
_countSongPlayback = true;
} else if (pos > song.duration * 0.95 && _countSongPlayback) {
print('INCREMENT PLAY COUNT: ${song.title}');
_countSongPlayback = false;
_incrementPlayCount(song);
}

View file

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

View file

@ -9,6 +9,7 @@ import '../state/music_data_store.dart';
import '../theming.dart';
import '../widgets/artist_albums.dart';
import '../widgets/artist_header.dart';
import '../widgets/artist_highlighted_songs.dart';
import 'album_details_page.dart';
class ArtistDetailsPage extends StatelessWidget {
@ -40,6 +41,34 @@ class ArtistDetailsPage extends StatelessWidget {
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(
padding: EdgeInsets.only(
left: HORIZONTAL_PADDING + 2,

View file

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

View file

@ -68,6 +68,9 @@ abstract class _MusicDataStore with Store {
@observable
ObservableStream<List<Album>> artistAlbumStream;
@observable
ObservableStream<List<Song>> artistHighlightedSongStream;
@observable
bool isUpdatingDatabase = false;
@ -92,12 +95,20 @@ abstract class _MusicDataStore with Store {
_musicDataInfoRepository.getAlbumSongStream(album).asObservable(initialValue: []);
}
// TODO: das hier ist komplett bescheuert... brauchen einen eigenen Store für die ArtistDetailsPage
@action
Future<void> fetchAlbumsFromArtist(Artist artist) async {
artistAlbumStream =
_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> 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 =
Atom(name: '_MusicDataStore.isUpdatingDatabase');
@ -135,6 +152,15 @@ mixin _$MusicDataStore on _MusicDataStore, Store {
.run(() => super.fetchAlbumsFromArtist(artist));
}
final _$fetchHighlightedSongsFromArtistAsyncAction =
AsyncAction('_MusicDataStore.fetchHighlightedSongsFromArtist');
@override
Future<void> fetchHighlightedSongsFromArtist(Artist artist) {
return _$fetchHighlightedSongsFromArtistAsyncAction
.run(() => super.fetchHighlightedSongsFromArtist(artist));
}
@override
String toString() {
return '''
@ -143,6 +169,7 @@ albumStream: ${albumStream},
artistStream: ${artistStream},
albumSongStream: ${albumSongStream},
artistAlbumStream: ${artistAlbumStream},
artistHighlightedSongStream: ${artistHighlightedSongStream},
isUpdatingDatabase: ${isUpdatingDatabase},
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;
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);
final Song song;

View file

@ -52,6 +52,13 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
Stream<List<Song>> getArtistSongStream(Artist artist) =>
_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
Stream<List<Album>> getArtistAlbumStream(Artist artist) =>
_musicDataSource.getArtistAlbumStream(artist as ArtistModel);
@ -137,4 +144,15 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
// TODO: implement resetSkipCount
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);
},
);
}
}