Cached image performace, background audio bug
This commit is contained in:
parent
ed087bc583
commit
7df500bc9c
|
@ -61,7 +61,7 @@ class DeezerAPI {
|
||||||
'gateway_input': gatewayInput
|
'gateway_input': gatewayInput
|
||||||
},
|
},
|
||||||
data: jsonEncode(params??{}),
|
data: jsonEncode(params??{}),
|
||||||
options: Options(responseType: ResponseType.json, sendTimeout: 7000, receiveTimeout: 7000)
|
options: Options(responseType: ResponseType.json, sendTimeout: 5000, receiveTimeout: 5000)
|
||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -545,8 +545,15 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
source = 'Stream';
|
source = 'Stream';
|
||||||
}
|
}
|
||||||
//Calculate
|
//Calculate
|
||||||
int bitrate = ((size / 125) / duration.inSeconds).floor();
|
return '$format ${_bitrateString(size, duration.inSeconds)} ($source)';
|
||||||
return '$format ${bitrate}kbps ($source)';
|
}
|
||||||
|
|
||||||
|
String _bitrateString(int size, int duration) {
|
||||||
|
int bitrate = ((size / 125) / duration).floor();
|
||||||
|
//Prettify
|
||||||
|
if (bitrate > 315 && bitrate < 325) return '320kbps';
|
||||||
|
if (bitrate > 125 && bitrate < 135) return '128kbps';
|
||||||
|
return '${bitrate}kbps';
|
||||||
}
|
}
|
||||||
|
|
||||||
//Magic number to string, source: https://en.wikipedia.org/wiki/List_of_file_signatures
|
//Magic number to string, source: https://en.wikipedia.org/wiki/List_of_file_signatures
|
||||||
|
@ -564,17 +571,15 @@ class AudioPlayerTask extends BackgroundAudioTask {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onTaskRemoved() async {
|
void onTaskRemoved() async {
|
||||||
await _saveQueue();
|
await onStop();
|
||||||
onStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future onStop() async {
|
Future onStop() async {
|
||||||
await _saveQueue();
|
_audioPlayer.stop();
|
||||||
|
|
||||||
if (_playing != null) _audioPlayer.stop();
|
|
||||||
if (_playerStateSub != null) _playerStateSub.cancel();
|
if (_playerStateSub != null) _playerStateSub.cancel();
|
||||||
if (_eventSub != null) _eventSub.cancel();
|
if (_eventSub != null) _eventSub.cancel();
|
||||||
|
await _saveQueue();
|
||||||
|
|
||||||
await super.onStop();
|
await super.onStop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,7 @@ class _CachedImageState extends State<CachedImage> {
|
||||||
ImageProvider _image = AssetImage('assets/cover.jpg');
|
ImageProvider _image = AssetImage('assets/cover.jpg');
|
||||||
double _opacity = 0.0;
|
double _opacity = 0.0;
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
|
String _prevUrl;
|
||||||
|
|
||||||
Future<ImageProvider> _getImage() async {
|
Future<ImageProvider> _getImage() async {
|
||||||
//Image already path
|
//Image already path
|
||||||
|
@ -146,6 +147,7 @@ class _CachedImageState extends State<CachedImage> {
|
||||||
_image = image;
|
_image = image;
|
||||||
_opacity = 1.0;
|
_opacity = 1.0;
|
||||||
});
|
});
|
||||||
|
_prevUrl = widget.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -162,6 +164,7 @@ class _CachedImageState extends State<CachedImage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(CachedImage oldWidget) {
|
void didUpdateWidget(CachedImage oldWidget) {
|
||||||
|
if (_prevUrl == widget.url) return;
|
||||||
_load();
|
_load();
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,99 +126,108 @@ class _HomePageScreenState extends State<HomePageScreen> {
|
||||||
return ErrorScreen();
|
return ErrorScreen();
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
...List.generate(_homePage.sections.length, (i) {
|
children: List.generate(_homePage.sections.length, (i) {
|
||||||
HomePageSection section = _homePage.sections[i];
|
HomePageSection section = _homePage.sections[i];
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
child: Text(
|
child: Text(
|
||||||
section.title,
|
section.title,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(fontSize: 24.0),
|
style: TextStyle(fontSize: 24.0),
|
||||||
),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0)
|
|
||||||
),
|
|
||||||
SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: Row(
|
|
||||||
children: List<Widget>.generate(section.items.length, (i) {
|
|
||||||
HomePageItem item = section.items[i];
|
|
||||||
|
|
||||||
switch (item.type) {
|
|
||||||
case HomePageItemType.SMARTTRACKLIST:
|
|
||||||
return SmartTrackListTile(
|
|
||||||
item.value,
|
|
||||||
onTap: () {
|
|
||||||
playerHelper.playFromSmartTrackList(item.value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
case HomePageItemType.ALBUM:
|
|
||||||
return AlbumCard(
|
|
||||||
item.value,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (context) => AlbumDetails(item.value)
|
|
||||||
));
|
|
||||||
},
|
|
||||||
onHold: () {
|
|
||||||
MenuSheet m = MenuSheet(context);
|
|
||||||
m.defaultAlbumMenu(item.value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
case HomePageItemType.ARTIST:
|
|
||||||
return ArtistTile(
|
|
||||||
item.value,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (context) => ArtistDetails(item.value)
|
|
||||||
));
|
|
||||||
},
|
|
||||||
onHold: () {
|
|
||||||
MenuSheet m = MenuSheet(context);
|
|
||||||
m.defaultArtistMenu(item.value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
case HomePageItemType.PLAYLIST:
|
|
||||||
return PlaylistCardTile(
|
|
||||||
item.value,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (context) => PlaylistDetails(item.value)
|
|
||||||
));
|
|
||||||
},
|
|
||||||
onHold: () {
|
|
||||||
MenuSheet m = MenuSheet(context);
|
|
||||||
m.defaultPlaylistMenu(item.value);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
case HomePageItemType.CHANNEL:
|
|
||||||
return ChannelTile(
|
|
||||||
item.value,
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (context) => Scaffold(
|
|
||||||
appBar: AppBar(title: Text(item.value.title.toString()),),
|
|
||||||
body: HomePageScreen(channel: item.value,),
|
|
||||||
)
|
|
||||||
));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Container(height: 0, width: 0);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0)
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
children: List.generate(section.items.length, (i) {
|
||||||
|
HomePageItem item = section.items[i];
|
||||||
|
return HomePageItemWidget(item);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
Container(height: 16.0,)
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
})
|
}),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HomePageItemWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
HomePageItem item;
|
||||||
|
HomePageItemWidget(this.item);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
switch (item.type) {
|
||||||
|
case HomePageItemType.SMARTTRACKLIST:
|
||||||
|
return SmartTrackListTile(
|
||||||
|
item.value,
|
||||||
|
onTap: () {
|
||||||
|
playerHelper.playFromSmartTrackList(item.value);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
case HomePageItemType.ALBUM:
|
||||||
|
return AlbumCard(
|
||||||
|
item.value,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (context) => AlbumDetails(item.value)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
onHold: () {
|
||||||
|
MenuSheet m = MenuSheet(context);
|
||||||
|
m.defaultAlbumMenu(item.value);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
case HomePageItemType.ARTIST:
|
||||||
|
return ArtistTile(
|
||||||
|
item.value,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (context) => ArtistDetails(item.value)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
onHold: () {
|
||||||
|
MenuSheet m = MenuSheet(context);
|
||||||
|
m.defaultArtistMenu(item.value);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
case HomePageItemType.PLAYLIST:
|
||||||
|
return PlaylistCardTile(
|
||||||
|
item.value,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (context) => PlaylistDetails(item.value)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
onHold: () {
|
||||||
|
MenuSheet m = MenuSheet(context);
|
||||||
|
m.defaultPlaylistMenu(item.value);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
case HomePageItemType.CHANNEL:
|
||||||
|
return ChannelTile(
|
||||||
|
item.value,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (context) => Scaffold(
|
||||||
|
appBar: AppBar(title: Text(item.value.title.toString()),),
|
||||||
|
body: HomePageScreen(channel: item.value,),
|
||||||
|
)
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Container(height: 0, width: 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,229 +27,231 @@ class _PlayerScreenState extends State<PlayerScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: StreamBuilder(
|
body: SafeArea(
|
||||||
stream: AudioService.playbackStateStream,
|
child: StreamBuilder(
|
||||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
stream: AudioService.playbackStateStream,
|
||||||
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
|
||||||
//Disable lyrics when skipping songs, loading
|
//Disable lyrics when skipping songs, loading
|
||||||
PlaybackState s = snapshot.data;
|
PlaybackState s = snapshot.data;
|
||||||
if (s != null && s.processingState != AudioProcessingState.ready && s.processingState != AudioProcessingState.buffering) _lyrics = false;
|
if (s != null && s.processingState != AudioProcessingState.ready && s.processingState != AudioProcessingState.buffering) _lyrics = false;
|
||||||
|
|
||||||
return OrientationBuilder(
|
return OrientationBuilder(
|
||||||
builder: (context, orientation) {
|
builder: (context, orientation) {
|
||||||
//Landscape
|
//Landscape
|
||||||
if (orientation == Orientation.landscape) {
|
if (orientation == Orientation.landscape) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.fromLTRB(16, 32, 16, 8),
|
padding: EdgeInsets.fromLTRB(16, 0, 16, 8),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 320,
|
width: 320,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
CachedImage(
|
CachedImage(
|
||||||
url: AudioService.currentMediaItem.artUri,
|
url: AudioService.currentMediaItem.artUri,
|
||||||
),
|
|
||||||
if (_lyrics) LyricsWidget(
|
|
||||||
artUri: AudioService.currentMediaItem.artUri,
|
|
||||||
trackId: AudioService.currentMediaItem.id,
|
|
||||||
lyrics: Track.fromMediaItem(AudioService.currentMediaItem).lyrics,
|
|
||||||
height: 320.0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width / 2 - 32,
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(8, 42, 8, 0),
|
|
||||||
child: Container(
|
|
||||||
width: 300,
|
|
||||||
child: PlayerScreenTopRow(),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
Text(
|
|
||||||
AudioService.currentMediaItem.displayTitle,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.clip,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24.0,
|
|
||||||
fontWeight: FontWeight.bold
|
|
||||||
),
|
),
|
||||||
|
if (_lyrics) LyricsWidget(
|
||||||
|
artUri: AudioService.currentMediaItem.artUri,
|
||||||
|
trackId: AudioService.currentMediaItem.id,
|
||||||
|
lyrics: Track.fromMediaItem(AudioService.currentMediaItem).lyrics,
|
||||||
|
height: 320.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 2 - 32,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(8, 16, 8, 0),
|
||||||
|
child: Container(
|
||||||
|
width: 300,
|
||||||
|
child: PlayerScreenTopRow(),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
AudioService.currentMediaItem.displayTitle,
|
||||||
|
maxLines: 1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.clip,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(height: 4,),
|
||||||
|
Text(
|
||||||
|
AudioService.currentMediaItem.displaySubtitle,
|
||||||
|
maxLines: 1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.clip,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 320,
|
||||||
|
child: SeekBar(),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 320,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: <Widget>[
|
||||||
|
PrevNextButton(iconSize, prev: true,),
|
||||||
|
PlayPauseButton(iconSize),
|
||||||
|
PrevNextButton(iconSize)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Container(height: 4,),
|
),
|
||||||
Text(
|
Padding(
|
||||||
AudioService.currentMediaItem.displaySubtitle,
|
padding: EdgeInsets.fromLTRB(8, 0, 8, 16),
|
||||||
maxLines: 1,
|
child: Container(
|
||||||
textAlign: TextAlign.center,
|
width: 300,
|
||||||
overflow: TextOverflow.clip,
|
child: Row(
|
||||||
style: TextStyle(
|
mainAxisSize: MainAxisSize.max,
|
||||||
fontSize: 18.0,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
color: Theme.of(context).primaryColor,
|
children: <Widget>[
|
||||||
),
|
IconButton(
|
||||||
|
icon: Icon(Icons.subtitles),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() => _lyrics = !_lyrics);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
AudioService.currentMediaItem.extras['qualityString']
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.more_vert),
|
||||||
|
onPressed: () {
|
||||||
|
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
||||||
|
MenuSheet m = MenuSheet(context);
|
||||||
|
m.defaultTrackMenu(t);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Portrait
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(28, 16, 28, 0),
|
||||||
|
child: PlayerScreenTopRow()
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
|
||||||
|
child: Container(
|
||||||
|
height: 360,
|
||||||
|
child: Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
CachedImage(
|
||||||
|
url: AudioService.currentMediaItem.artUri,
|
||||||
|
),
|
||||||
|
if (_lyrics) LyricsWidget(
|
||||||
|
artUri: AudioService.currentMediaItem.artUri,
|
||||||
|
trackId: AudioService.currentMediaItem.id,
|
||||||
|
lyrics: Track.fromMediaItem(AudioService.currentMediaItem).lyrics,
|
||||||
|
height: 360.0,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Container(
|
)
|
||||||
width: 320,
|
),
|
||||||
child: SeekBar(),
|
Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
AudioService.currentMediaItem.displayTitle,
|
||||||
|
maxLines: 1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
overflow: TextOverflow.clip,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24.0,
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
),
|
),
|
||||||
Container(
|
),
|
||||||
width: 320,
|
Container(height: 4,),
|
||||||
child: Row(
|
Text(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
AudioService.currentMediaItem.displaySubtitle,
|
||||||
mainAxisSize: MainAxisSize.max,
|
maxLines: 1,
|
||||||
children: <Widget>[
|
textAlign: TextAlign.center,
|
||||||
PrevNextButton(iconSize, prev: true,),
|
overflow: TextOverflow.clip,
|
||||||
PlayPauseButton(iconSize),
|
style: TextStyle(
|
||||||
PrevNextButton(iconSize)
|
fontSize: 18.0,
|
||||||
],
|
color: Theme.of(context).primaryColor,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: EdgeInsets.fromLTRB(8, 0, 8, 16),
|
],
|
||||||
child: Container(
|
),
|
||||||
width: 300,
|
SeekBar(),
|
||||||
child: Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
IconButton(
|
PrevNextButton(iconSize, prev: true,),
|
||||||
icon: Icon(Icons.subtitles),
|
PlayPauseButton(iconSize),
|
||||||
onPressed: () {
|
PrevNextButton(iconSize)
|
||||||
setState(() => _lyrics = !_lyrics);
|
],
|
||||||
},
|
),
|
||||||
),
|
//Container(height: 8.0,),
|
||||||
Text(
|
Padding(
|
||||||
AudioService.currentMediaItem.extras['qualityString']
|
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
|
||||||
),
|
child: Row(
|
||||||
IconButton(
|
mainAxisSize: MainAxisSize.max,
|
||||||
icon: Icon(Icons.more_vert),
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
onPressed: () {
|
children: <Widget>[
|
||||||
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
IconButton(
|
||||||
MenuSheet m = MenuSheet(context);
|
icon: Icon(Icons.subtitles),
|
||||||
m.defaultTrackMenu(t);
|
onPressed: () {
|
||||||
},
|
setState(() => _lyrics = !_lyrics);
|
||||||
)
|
},
|
||||||
],
|
),
|
||||||
),
|
Text(
|
||||||
)
|
AudioService.currentMediaItem.extras['qualityString']
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.more_vert),
|
||||||
|
onPressed: () {
|
||||||
|
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
||||||
|
MenuSheet m = MenuSheet(context);
|
||||||
|
m.defaultTrackMenu(t);
|
||||||
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
//Portrait
|
},
|
||||||
return Column(
|
);
|
||||||
mainAxisSize: MainAxisSize.max,
|
},
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
),
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(28, 28, 28, 0),
|
|
||||||
child: PlayerScreenTopRow()
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(16, 8, 16, 8),
|
|
||||||
child: Container(
|
|
||||||
height: 360,
|
|
||||||
child: Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
CachedImage(
|
|
||||||
url: AudioService.currentMediaItem.artUri,
|
|
||||||
),
|
|
||||||
if (_lyrics) LyricsWidget(
|
|
||||||
artUri: AudioService.currentMediaItem.artUri,
|
|
||||||
trackId: AudioService.currentMediaItem.id,
|
|
||||||
lyrics: Track.fromMediaItem(AudioService.currentMediaItem).lyrics,
|
|
||||||
height: 360.0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
Text(
|
|
||||||
AudioService.currentMediaItem.displayTitle,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.clip,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24.0,
|
|
||||||
fontWeight: FontWeight.bold
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(height: 4,),
|
|
||||||
Text(
|
|
||||||
AudioService.currentMediaItem.displaySubtitle,
|
|
||||||
maxLines: 1,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
overflow: TextOverflow.clip,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18.0,
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SeekBar(),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children: <Widget>[
|
|
||||||
PrevNextButton(iconSize, prev: true,),
|
|
||||||
PlayPauseButton(iconSize),
|
|
||||||
PrevNextButton(iconSize)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
//Container(height: 8.0,),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.subtitles),
|
|
||||||
onPressed: () {
|
|
||||||
setState(() => _lyrics = !_lyrics);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
AudioService.currentMediaItem.extras['qualityString']
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(Icons.more_vert),
|
|
||||||
onPressed: () {
|
|
||||||
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
|
|
||||||
MenuSheet m = MenuSheet(context);
|
|
||||||
m.defaultTrackMenu(t);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,8 @@ class PlaylistCardTile extends StatelessWidget {
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(fontSize: 16.0),
|
style: TextStyle(fontSize: 16.0),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
Container(height: 8.0,)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -272,7 +273,8 @@ class SmartTrackListTile extends StatelessWidget {
|
||||||
fontSize: 16.0
|
fontSize: 16.0
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
Container(height: 8.0,)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -315,7 +317,8 @@ class AlbumCard extends StatelessWidget {
|
||||||
fontSize: 16.0
|
fontSize: 16.0
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
Container(height: 8.0,)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -350,9 +353,9 @@ class ChannelTile extends StatelessWidget {
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18.0,
|
fontSize: 18.0,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: _textColor()
|
color: _textColor()
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 0.1.0
|
version: 0.1.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
|
|
Loading…
Reference in New Issue