currently playing page + localmusicfetcher fix

This commit is contained in:
Moritz Weber 2020-12-10 20:55:37 +01:00
parent 4139ab801d
commit 4f8cd4b9ee
12 changed files with 172 additions and 85 deletions

View file

@ -1,17 +1,14 @@
import 'dart:ui';
import 'package:audio_service/audio_service.dart';
import 'package:device_info/device_info.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
import 'package:get_it/get_it.dart';
import 'package:moor/isolate.dart';
import 'package:moor/moor.dart';
import 'package:mucke/system/audio/audio_handler.dart';
import 'domain/repositories/audio_repository.dart';
import 'domain/repositories/music_data_repository.dart';
import 'presentation/state/audio_store.dart';
import 'presentation/state/music_data_store.dart';
import 'presentation/state/navigation_store.dart';
import 'system/audio/audio_handler.dart';
import 'system/audio/audio_manager.dart';
import 'system/audio/audio_manager_contract.dart';
import 'system/datasources/local_music_fetcher.dart';
@ -71,6 +68,7 @@ Future<void> setupGetIt() async {
getIt.registerLazySingleton<LocalMusicFetcher>(
() => LocalMusicFetcherImpl(
getIt(),
getIt(),
),
);
getIt.registerLazySingleton<AudioManager>(() => AudioManagerImpl(getIt()));
@ -86,4 +84,6 @@ Future<void> setupGetIt() async {
// external
getIt.registerLazySingleton<FlutterAudioQuery>(() => FlutterAudioQuery());
getIt.registerLazySingleton<DeviceInfoPlugin>(() => DeviceInfoPlugin());
}

View file

@ -12,7 +12,6 @@ import 'presentation/pages/library_page.dart';
import 'presentation/pages/settings_page.dart';
import 'presentation/state/navigation_store.dart';
import 'presentation/theming.dart';
// import 'presentation/widgets/audio_service_widget.dart';
import 'presentation/widgets/injection_widget.dart';
import 'presentation/widgets/navbar.dart';

View file

@ -58,26 +58,47 @@ class CurrentlyPlayingPage extends StatelessWidget {
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: AlbumArt(
song: song,
const Spacer(
flex: 1,
),
Expanded(
flex: 1000,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 0.0,
),
child: AlbumArt(
song: song,
),
),
),
),
const Spacer(
flex: 4,
flex: 80,
),
const Padding(
padding: EdgeInsets.only(left: 2.0, right: 2.0, bottom: 10.0),
child: SongCustomizationButtons(),
),
const SongCustomizationButtons(),
const Spacer(
flex: 3,
flex: 50,
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: TimeProgressIndicator(),
),
const TimeProgressIndicator(),
const Spacer(
flex: 3,
flex: 50,
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 2.0),
child: PlaybackControl(),
),
const Spacer(
flex: 40,
),
const PlaybackControl(),
const Spacer(),
NextIndicator(
onTapAction: openQueue,
),

View file

@ -22,9 +22,13 @@ class AlbumArt extends StatelessWidget {
),
child: Stack(
children: [
Image(
image: getAlbumImage(song.albumArtPath),
fit: BoxFit.cover,
Container(
width: double.infinity,
height: double.infinity,
child: Image(
image: getAlbumImage(song.albumArtPath),
fit: BoxFit.cover,
),
),
Positioned(
bottom: 0,
@ -63,7 +67,6 @@ class AlbumArt extends StatelessWidget {
song.artist,
style: TEXT_SUBTITLE.copyWith(color: Colors.white70),
),
],
),
),

View file

@ -22,11 +22,34 @@ class AlbumBackground extends StatelessWidget {
fit: BoxFit.cover,
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 64.0, sigmaY: 64.0),
child: Container(
child: child,
color: Colors.black.withOpacity(0.2),
child: Container(
height: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0x55000000),
Color(0x22FFFFFF),
Color(0x22FFFFFF),
Color(0x88000000),
Color(0xBB000000),
],
stops: [
0.0,
0.1,
0.5,
0.65,
1.0,
],
),
),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 96.0, sigmaY: 96.0),
child: Container(
child: child,
color: Colors.white.withOpacity(0.0),
),
),
),
);

View file

@ -22,7 +22,7 @@ class NextIndicator extends StatelessWidget {
return GestureDetector(
onTap: () => onTapAction(context),
child: Padding(
padding: const EdgeInsets.all(10.0),
padding: const EdgeInsets.only(top: 4.0, bottom: 8.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,

View file

@ -10,30 +10,27 @@ class PlaybackControl extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: const [
IconButton(
icon: Icon(
Icons.repeat,
size: 20.0,
color: Colors.white10,
),
onPressed: null,
return Row(
children: const [
IconButton(
icon: Icon(
Icons.repeat,
size: 20.0,
color: Colors.white10,
),
PreviousButton(iconSize: 32.0),
PlayPauseButton(
circle: true,
iconSize: 52.0,
),
NextButton(iconSize: 32.0),
ShuffleButton(
iconSize: 20.0,
),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
onPressed: null,
),
PreviousButton(iconSize: 32.0),
PlayPauseButton(
circle: true,
iconSize: 52.0,
),
NextButton(iconSize: 32.0),
ShuffleButton(
iconSize: 20.0,
),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
);
}
}

View file

@ -25,14 +25,13 @@ class SongCustomizationButtons extends StatelessWidget {
IconButton(
icon: Icon(
Icons.link,
size: 20.0,
// size: 20.0,
color: song.next == null ? Colors.white70 : LIGHT1,
),
iconSize: 20.0,
onPressed: () => musicDataStore.toggleNextSongLink(song),
),
Container(
width: 40,
),
const Spacer(),
const IconButton(
icon: Icon(
Icons.favorite,
@ -41,17 +40,14 @@ class SongCustomizationButtons extends StatelessWidget {
),
onPressed: null,
),
Container(
width: 40,
),
const Spacer(),
IconButton(
icon: Icon(
Icons.remove_circle_outline,
size: 20.0,
color: isBlocked ? RASPBERRY : Colors.white70,
),
onPressed: () =>
musicDataStore.setSongBlocked(song, !isBlocked),
onPressed: () => musicDataStore.setSongBlocked(song, !isBlocked),
),
],
mainAxisAlignment: MainAxisAlignment.center,

View file

@ -16,27 +16,44 @@ class TimeProgressIndicator extends StatelessWidget {
builder: (BuildContext context) {
final int duration = audioStore.currentSong?.duration ?? 1000;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
Text(msToTimeString(audioStore.currentPositionStream.value)),
Container(
width: 10,
return Row(
children: [
Container(
width: 48,
child: Text(
msToTimeString(audioStore.currentPositionStream.value),
),
Expanded(
child: Container(
child: LinearProgressIndicator(value: audioStore.currentPositionStream.value / duration),
height: 3.0,
),
Expanded(
child: Container(
width: double.infinity,
height: 3.0,
decoration: const BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.all(Radius.circular(2)),
),
alignment: Alignment.centerLeft,
child: FractionallySizedBox(
widthFactor:
audioStore.currentPositionStream.value / duration,
heightFactor: 1.0,
child: Container(
height: double.infinity,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(2)),
),
),
),
),
Container(
width: 10,
),
Text(msToTimeString(duration)),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
),
),
Container(
width: 48,
alignment: Alignment.centerRight,
child: Text(msToTimeString(duration)),
),
],
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
);
},
);

View file

@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'dart:ui';
import 'package:device_info/device_info.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
import '../models/album_model.dart';
@ -9,14 +10,22 @@ import '../models/song_model.dart';
import 'local_music_fetcher_contract.dart';
class LocalMusicFetcherImpl implements LocalMusicFetcher {
LocalMusicFetcherImpl(this.flutterAudioQuery);
LocalMusicFetcherImpl(this._flutterAudioQuery, this._deviceInfo);
final FlutterAudioQuery flutterAudioQuery;
final FlutterAudioQuery _flutterAudioQuery;
// CODESMELL: should probably encapsulate the deviceinfoplugin
final DeviceInfoPlugin _deviceInfo;
AndroidDeviceInfo _androidDeviceInfo;
Future<AndroidDeviceInfo> get androidDeviceInfo async {
_androidDeviceInfo ??= await _deviceInfo.androidInfo;
return _androidDeviceInfo;
}
@override
Future<List<ArtistModel>> getArtists() async {
final List<ArtistInfo> artistInfoList =
await flutterAudioQuery.getArtists();
await _flutterAudioQuery.getArtists();
return artistInfoList
.map((ArtistInfo artistInfo) => ArtistModel.fromArtistInfo(artistInfo))
.toSet()
@ -25,7 +34,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher {
@override
Future<List<AlbumModel>> getAlbums() async {
final List<AlbumInfo> albumInfoList = await flutterAudioQuery.getAlbums();
final List<AlbumInfo> albumInfoList = await _flutterAudioQuery.getAlbums();
return albumInfoList
.map((AlbumInfo albumInfo) => AlbumModel.fromAlbumInfo(albumInfo))
.toList();
@ -33,7 +42,7 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher {
@override
Future<List<SongModel>> getSongs() async {
final List<SongInfo> songInfoList = await flutterAudioQuery.getSongs();
final List<SongInfo> songInfoList = await _flutterAudioQuery.getSongs();
return songInfoList
.where((songInfo) => songInfo.isMusic)
.map((SongInfo songInfo) => SongModel.fromSongInfo(songInfo))
@ -42,7 +51,14 @@ class LocalMusicFetcherImpl implements LocalMusicFetcher {
@override
Future<Uint8List> getAlbumArtwork(int id) async {
return flutterAudioQuery.getArtwork(
type: ResourceType.ALBUM, id: id.toString(), size: const Size(500.0, 500.0));
final info = await androidDeviceInfo;
if (info.version.sdkInt >= 29) {
return _flutterAudioQuery.getArtwork(
type: ResourceType.ALBUM,
id: id.toString(),
size: const Size(500.0, 500.0),
);
}
return Uint8List(0);
}
}

View file

@ -199,6 +199,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.2"
device_info:
dependency: "direct main"
description:
name: device_info
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
device_info_platform_interface:
dependency: transitive
description:
name: device_info_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
equatable:
dependency: "direct main"
description:

View file

@ -14,6 +14,7 @@ dependencies:
ref: one-isolate
audio_session: ^0.0.3
dartz: ^0.9.1
device_info: ^1.0.0
equatable: ^1.1.0
flutter:
sdk: flutter