play count, song blocking
This commit is contained in:
parent
0bece0df29
commit
caae3bf8dd
8 changed files with 167 additions and 6 deletions
|
@ -2,26 +2,60 @@ import '../entities/song.dart';
|
|||
import '../repositories/audio_player_repository.dart';
|
||||
import '../repositories/music_data_repository.dart';
|
||||
import '../usecases/handle_playback_state.dart';
|
||||
import '../usecases/increment_play_count.dart';
|
||||
import '../usecases/set_current_song.dart';
|
||||
|
||||
class AudioPlayerActor {
|
||||
AudioPlayerActor(this._audioPlayerRepository, this._musicDataInfoRepository, this._handlePlaybackEvent, this._setCurrentSong) {
|
||||
AudioPlayerActor(
|
||||
this._audioPlayerRepository,
|
||||
this._musicDataInfoRepository,
|
||||
this._handlePlaybackEvent,
|
||||
this._incrementPlayCount,
|
||||
this._setCurrentSong,
|
||||
) {
|
||||
_audioPlayerRepository.currentSongStream.listen(_handleCurrentSong);
|
||||
_audioPlayerRepository.playbackEventStream.listen(_handlePlaybackEvent);
|
||||
_audioPlayerRepository.positionStream
|
||||
.listen((duration) => _handlePosition(duration, _currentSong));
|
||||
|
||||
_musicDataInfoRepository.songUpdateStream.listen(_handleSongUpdate);
|
||||
}
|
||||
|
||||
// TODO: is this against a previous design choice? only direct "read" access to repos?
|
||||
// Should this actor only listen to AudioPlayer events? --> move song update to new actor?
|
||||
final AudioPlayerRepository _audioPlayerRepository;
|
||||
final MusicDataInfoRepository _musicDataInfoRepository;
|
||||
|
||||
final HandlePlaybackEvent _handlePlaybackEvent;
|
||||
final IncrementPlayCount _incrementPlayCount;
|
||||
final SetCurrentSong _setCurrentSong;
|
||||
|
||||
void _handleCurrentSong(Song song) => _setCurrentSong(song);
|
||||
Song _currentSong;
|
||||
bool _countSongPlayback = false;
|
||||
|
||||
Future<void> _handleCurrentSong(Song song) async {
|
||||
_currentSong = song;
|
||||
return _setCurrentSong(song);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleSongUpdate(Map<String, Song> songs) {
|
||||
_audioPlayerRepository.updateSongs(songs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,16 @@ abstract class MusicDataInfoRepository {
|
|||
|
||||
abstract class MusicDataRepository extends MusicDataInfoRepository {
|
||||
Future<void> updateDatabase();
|
||||
|
||||
Future<void> setSongBlocked(Song song, bool blocked);
|
||||
|
||||
Future<void> incrementSkipCount(Song song);
|
||||
Future<void> resetSkipCount(Song song);
|
||||
|
||||
Future<void> incrementLikeCount(Song song);
|
||||
Future<void> decrementLikeCount(Song song);
|
||||
Future<void> resetLikeCount(Song song);
|
||||
|
||||
Future<void> incrementPlayCount(Song song);
|
||||
Future<void> resetPlayCount(Song song);
|
||||
}
|
12
lib/domain/usecases/increment_play_count.dart
Normal file
12
lib/domain/usecases/increment_play_count.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
import '../entities/song.dart';
|
||||
import '../repositories/music_data_repository.dart';
|
||||
|
||||
class IncrementPlayCount {
|
||||
IncrementPlayCount(this._musicDataRepository);
|
||||
|
||||
final MusicDataRepository _musicDataRepository;
|
||||
|
||||
Future<void> call(Song song) async {
|
||||
await _musicDataRepository.incrementPlayCount(song);
|
||||
}
|
||||
}
|
12
lib/domain/usecases/set_song_blocked.dart
Normal file
12
lib/domain/usecases/set_song_blocked.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
import '../entities/song.dart';
|
||||
import '../repositories/music_data_repository.dart';
|
||||
|
||||
class SetSongBlocked {
|
||||
SetSongBlocked(this._musicDataRepository);
|
||||
|
||||
final MusicDataRepository _musicDataRepository;
|
||||
|
||||
Future<void> call(Song song, bool blocked) async {
|
||||
await _musicDataRepository.setSongBlocked(song, blocked);
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import 'domain/repositories/platform_integration_repository.dart';
|
|||
import 'domain/repositories/settings_repository.dart';
|
||||
import 'domain/usecases/add_to_queue.dart';
|
||||
import 'domain/usecases/handle_playback_state.dart';
|
||||
import 'domain/usecases/increment_play_count.dart';
|
||||
import 'domain/usecases/inrement_like_count.dart';
|
||||
import 'domain/usecases/move_queue_item.dart';
|
||||
import 'domain/usecases/pause.dart';
|
||||
|
@ -29,6 +30,7 @@ import 'domain/usecases/seek_to_previous.dart';
|
|||
import 'domain/usecases/set_current_song.dart';
|
||||
import 'domain/usecases/set_loop_mode.dart';
|
||||
import 'domain/usecases/set_shuffle_mode.dart';
|
||||
import 'domain/usecases/set_song_blocked.dart';
|
||||
import 'domain/usecases/shuffle_all.dart';
|
||||
import 'domain/usecases/update_database.dart';
|
||||
import 'presentation/state/audio_store.dart';
|
||||
|
@ -64,6 +66,7 @@ Future<void> setupGetIt() async {
|
|||
settingsRepository: getIt(),
|
||||
musicDataModifierRepository: getIt(),
|
||||
incrementLikeCount: getIt(),
|
||||
setSongBlocked: getIt(),
|
||||
updateDatabase: getIt(),
|
||||
);
|
||||
return musicDataStore;
|
||||
|
@ -118,6 +121,11 @@ Future<void> setupGetIt() async {
|
|||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<IncrementPlayCount>(
|
||||
() => IncrementPlayCount(
|
||||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<MoveQueueItem>(
|
||||
() => MoveQueueItem(
|
||||
getIt(),
|
||||
|
@ -207,6 +215,11 @@ Future<void> setupGetIt() async {
|
|||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<SetSongBlocked>(
|
||||
() => SetSongBlocked(
|
||||
getIt(),
|
||||
),
|
||||
);
|
||||
getIt.registerLazySingleton<ShuffleAll>(
|
||||
() => ShuffleAll(
|
||||
getIt(),
|
||||
|
@ -325,6 +338,7 @@ Future<void> setupGetIt() async {
|
|||
getIt(),
|
||||
getIt(),
|
||||
getIt(),
|
||||
getIt(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mucke/presentation/widgets/song_info.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../domain/entities/album.dart';
|
||||
|
@ -168,6 +169,35 @@ class AlbumDetailsPage extends StatelessWidget {
|
|||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Show song info'),
|
||||
leading: const Icon(Icons.info),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return SimpleDialog(
|
||||
backgroundColor: DARK3,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(HORIZONTAL_PADDING),
|
||||
child: SongInfo(song),
|
||||
),
|
||||
SimpleDialogOption(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text(
|
||||
'Close',
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ import '../../domain/repositories/music_data_modifier_repository.dart';
|
|||
import '../../domain/repositories/music_data_repository.dart';
|
||||
import '../../domain/repositories/settings_repository.dart';
|
||||
import '../../domain/usecases/inrement_like_count.dart';
|
||||
import '../../domain/usecases/set_song_blocked.dart';
|
||||
import '../../domain/usecases/update_database.dart';
|
||||
|
||||
part 'music_data_store.g.dart';
|
||||
|
@ -19,12 +20,14 @@ class MusicDataStore extends _MusicDataStore with _$MusicDataStore {
|
|||
@required SettingsRepository settingsRepository,
|
||||
@required UpdateDatabase updateDatabase,
|
||||
@required IncrementLikeCount incrementLikeCount,
|
||||
@required SetSongBlocked setSongBlocked,
|
||||
}) : super(
|
||||
musicDataInfoRepository,
|
||||
settingsRepository,
|
||||
musicDataModifierRepository,
|
||||
updateDatabase,
|
||||
incrementLikeCount,
|
||||
setSongBlocked,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -35,6 +38,7 @@ abstract class _MusicDataStore with Store {
|
|||
this._musicDataModifierRepository,
|
||||
this._updateDatabase,
|
||||
this._incrementLikeCount,
|
||||
this._setSongBlocked,
|
||||
) {
|
||||
songStream = _musicDataInfoRepository.songStream.asObservable(initialValue: []);
|
||||
albumStream = _musicDataInfoRepository.albumStream.asObservable(initialValue: []);
|
||||
|
@ -42,6 +46,7 @@ abstract class _MusicDataStore with Store {
|
|||
}
|
||||
|
||||
final IncrementLikeCount _incrementLikeCount;
|
||||
final SetSongBlocked _setSongBlocked;
|
||||
final UpdateDatabase _updateDatabase;
|
||||
|
||||
final MusicDataInfoRepository _musicDataInfoRepository;
|
||||
|
@ -93,9 +98,7 @@ abstract class _MusicDataStore with Store {
|
|||
_musicDataInfoRepository.getArtistAlbumStream(artist).asObservable(initialValue: []);
|
||||
}
|
||||
|
||||
Future<void> setSongBlocked(Song song, bool blocked) async {
|
||||
await _musicDataModifierRepository.setSongBlocked(song, blocked);
|
||||
}
|
||||
Future<void> setSongBlocked(Song song, bool blocked) => _setSongBlocked(song, blocked);
|
||||
|
||||
Future<void> toggleNextSongLink(Song song) async {
|
||||
await _musicDataModifierRepository.toggleNextSongLink(song);
|
||||
|
|
|
@ -91,4 +91,50 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
Future<void> _updateSongs(List<SongModel> songs) async {
|
||||
await _musicDataSource.insertSongs(songs);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setSongBlocked(Song song, bool blocked) async {
|
||||
if (song.blocked != blocked) {
|
||||
final newSong = (song as SongModel).copyWith(blocked: blocked);
|
||||
_songUpdateSubject.add({song.path: newSong});
|
||||
_musicDataSource.setSongBlocked(song as SongModel, blocked);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> decrementLikeCount(Song song) {
|
||||
// TODO: implement decrementLikeCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> incrementPlayCount(Song song) async {
|
||||
final newSong = (song as SongModel).copyWith(playCount: song.playCount + 1);
|
||||
_songUpdateSubject.add({song.path: newSong});
|
||||
_musicDataSource.incrementPlayCount(song as SongModel);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> incrementSkipCount(Song song) {
|
||||
// TODO: implement incrementSkipCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> resetLikeCount(Song song) {
|
||||
// TODO: implement resetLikeCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> resetPlayCount(Song song) {
|
||||
// TODO: implement resetPlayCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> resetSkipCount(Song song) {
|
||||
// TODO: implement resetSkipCount
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue