currently playing page + localmusicfetcher fix
This commit is contained in:
parent
4139ab801d
commit
4f8cd4b9ee
12 changed files with 172 additions and 85 deletions
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -58,26 +58,47 @@ class CurrentlyPlayingPage extends StatelessWidget {
|
|||
],
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
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,
|
||||
),
|
||||
const SongCustomizationButtons(),
|
||||
const Spacer(
|
||||
flex: 3,
|
||||
),
|
||||
const TimeProgressIndicator(),
|
||||
const Spacer(
|
||||
flex: 3,
|
||||
flex: 80,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 2.0, right: 2.0, bottom: 10.0),
|
||||
child: SongCustomizationButtons(),
|
||||
),
|
||||
const Spacer(
|
||||
flex: 50,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: TimeProgressIndicator(),
|
||||
),
|
||||
const Spacer(
|
||||
flex: 50,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 2.0),
|
||||
child: PlaybackControl(),
|
||||
),
|
||||
const Spacer(
|
||||
flex: 40,
|
||||
),
|
||||
const PlaybackControl(),
|
||||
const Spacer(),
|
||||
NextIndicator(
|
||||
onTapAction: openQueue,
|
||||
),
|
||||
|
|
|
@ -22,10 +22,14 @@ class AlbumArt extends StatelessWidget {
|
|||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Image(
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Image(
|
||||
image: getAlbumImage(song.albumArtPath),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
|
@ -63,7 +67,6 @@ class AlbumArt extends StatelessWidget {
|
|||
song.artist,
|
||||
style: TEXT_SUBTITLE.copyWith(color: Colors.white70),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -22,11 +22,34 @@ class AlbumBackground extends StatelessWidget {
|
|||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
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: 64.0, sigmaY: 64.0),
|
||||
filter: ImageFilter.blur(sigmaX: 96.0, sigmaY: 96.0),
|
||||
child: Container(
|
||||
child: child,
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
color: Colors.white.withOpacity(0.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -10,9 +10,7 @@ class PlaybackControl extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(
|
||||
return Row(
|
||||
children: const [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
|
@ -33,7 +31,6 @@ class PlaybackControl extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
return Row(
|
||||
children: [
|
||||
Text(msToTimeString(audioStore.currentPositionStream.value)),
|
||||
Container(
|
||||
width: 10,
|
||||
width: 48,
|
||||
child: Text(
|
||||
msToTimeString(audioStore.currentPositionStream.value),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: LinearProgressIndicator(value: audioStore.currentPositionStream.value / duration),
|
||||
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,
|
||||
width: 48,
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(msToTimeString(duration)),
|
||||
),
|
||||
Text(msToTimeString(duration)),
|
||||
],
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue