From 122c7c2ae709b28f95d38b04438d6e1c11c5b3b5 Mon Sep 17 00:00:00 2001 From: pato05 Date: Mon, 5 Apr 2021 22:27:54 +0200 Subject: [PATCH] lyrics: allow user to scroll freely --- lib/ui/lyrics.dart | 32 ++- lib/ui/player_screen.dart | 480 +++++++++++++++++++------------------- 2 files changed, 255 insertions(+), 257 deletions(-) diff --git a/lib/ui/lyrics.dart b/lib/ui/lyrics.dart index d63ab3c..d77309a 100644 --- a/lib/ui/lyrics.dart +++ b/lib/ui/lyrics.dart @@ -24,14 +24,15 @@ class _LyricsScreenState extends State { Lyrics lyrics; bool _loading = true; bool _error = false; - int _currentIndex = 0; - int _prevIndex = 0; + int _currentIndex = -1; + int _prevIndex = -1; Timer _timer; ScrollController _controller = ScrollController(); StreamSubscription _mediaItemSub; final double height = 90; bool _freeScroll = false; + bool _animatedScroll = false; Future _load() async { //Already available @@ -59,15 +60,17 @@ class _LyricsScreenState extends State { } } - void _scrollToLyric() { + Future _scrollToLyric() async { //Lyric height, screen height, appbar height double _scrollTo = (height * _currentIndex) - (MediaQuery.of(context).size.height / 2) + (height / 2) + 56; if (0 > _scrollTo) return; - _controller.animateTo(_scrollTo, + _animatedScroll = true; + await _controller.animateTo(_scrollTo, duration: Duration(milliseconds: 250), curve: Curves.ease); + _animatedScroll = false; } @override @@ -82,7 +85,7 @@ class _LyricsScreenState extends State { (l) => l.offset <= AudioService.playbackState.currentPosition); if (_loading) return; //Scroll to current lyric - if (_currentIndex <= 0) return; + if (_currentIndex < 0) return; if (_prevIndex == _currentIndex) return; //Update current lyric index setState(() => null); @@ -149,8 +152,10 @@ class _LyricsScreenState extends State { children: [ //Visualizer if (settings.lyricsVisualizer) - Align( - alignment: Alignment.bottomCenter, + Positioned( + bottom: 0, + left: 0, + right: 0, child: StreamBuilder( stream: playerHelper.visualizerStream, builder: (BuildContext context, AsyncSnapshot snapshot) { @@ -193,17 +198,10 @@ class _LyricsScreenState extends State { ) : NotificationListener( onNotification: (Notification notification) { - if (notification is! ScrollEndNotification) + if (_freeScroll || + notification is! ScrollStartNotification) return false; - if (_freeScroll) return false; - double _currentScroll = _controller.position.pixels; - double _expectedScroll = (height * _currentIndex) - - (MediaQuery.of(context).size.height / 2) + - (height / 2) + - 56; - print( - 'current: $_currentScroll, expected: $_expectedScroll'); - if (_currentScroll != _expectedScroll) + if (!_animatedScroll) setState(() => _freeScroll = true); return false; }, diff --git a/lib/ui/player_screen.dart b/lib/ui/player_screen.dart index 26df621..12d625e 100644 --- a/lib/ui/player_screen.dart +++ b/lib/ui/player_screen.dart @@ -40,7 +40,6 @@ class PlayerScreen extends StatefulWidget { } class _PlayerScreenState extends State { - LinearGradient _bgGradient; StreamSubscription _mediaItemSub; ImageProvider _blurImage; @@ -53,35 +52,51 @@ class _PlayerScreenState extends State { //BG Image if (settings.blurPlayerBackground) setState(() { - _blurImage = NetworkImage(AudioService.currentMediaItem.extras['thumb'] ?? AudioService.currentMediaItem.artUri); + _blurImage = NetworkImage( + AudioService.currentMediaItem.extras['thumb'] ?? + AudioService.currentMediaItem.artUri); }); //Run in isolate - PaletteGenerator palette = await PaletteGenerator.fromImageProvider(CachedNetworkImageProvider(AudioService.currentMediaItem.extras['thumb'] ?? AudioService.currentMediaItem.artUri)); + PaletteGenerator palette = await PaletteGenerator.fromImageProvider( + CachedNetworkImageProvider( + AudioService.currentMediaItem.extras['thumb'] ?? + AudioService.currentMediaItem.artUri)); //Update notification if (settings.blurPlayerBackground) SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: palette.dominantColor.color.withOpacity(0.25), - systemNavigationBarColor: Color.alphaBlend(palette.dominantColor.color.withOpacity(0.25), Theme.of(context).scaffoldBackgroundColor), - systemNavigationBarIconBrightness: ThemeData.estimateBrightnessForColor(palette.dominantColor.color) == Brightness.light ? Brightness.dark : Brightness.light - )); + systemNavigationBarColor: Color.alphaBlend( + palette.dominantColor.color.withOpacity(0.25), + Theme.of(context).scaffoldBackgroundColor), + systemNavigationBarIconBrightness: + ThemeData.estimateBrightnessForColor( + palette.dominantColor.color) == + Brightness.light + ? Brightness.dark + : Brightness.light)); //Color gradient if (!settings.blurPlayerBackground) { SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: palette.dominantColor.color.withOpacity(0.7), - statusBarIconBrightness: ThemeData.estimateBrightnessForColor(palette.dominantColor.color.withOpacity(0.7)) == Brightness.light ? Brightness.dark : Brightness.light - )); + statusBarIconBrightness: ThemeData.estimateBrightnessForColor( + palette.dominantColor.color.withOpacity(0.7)) == + Brightness.light + ? Brightness.dark + : Brightness.light)); setState(() => _bgGradient = LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [palette.dominantColor.color.withOpacity(0.7), Color.fromARGB(0, 0, 0, 0)], - stops: [ - 0.0, - 0.6 - ] - )); + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + palette.dominantColor.color.withOpacity(0.7), + Color.fromARGB(0, 0, 0, 0) + ], + stops: [ + 0.0, + 0.6 + ])); } } @@ -98,13 +113,11 @@ class _PlayerScreenState extends State { @override void dispose() { - if (_mediaItemSub != null) - _mediaItemSub.cancel(); + if (_mediaItemSub != null) _mediaItemSub.cancel(); //Fix bottom buttons SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( - systemNavigationBarColor: settings.themeData.bottomAppBarColor, - statusBarColor: Colors.transparent - )); + systemNavigationBarColor: settings.themeData.bottomAppBarColor, + statusBarColor: Colors.transparent)); super.dispose(); } @@ -114,57 +127,57 @@ class _PlayerScreenState extends State { ScreenUtil.init(context, allowFontScaling: true); return Scaffold( - body: SafeArea( - child: Container( - decoration: BoxDecoration( - gradient: settings.blurPlayerBackground ? null : _bgGradient - ), - child: Stack( - children: [ - if (settings.blurPlayerBackground && _blurImage != null) - ClipRect( - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: _blurImage, - fit: BoxFit.fill, - colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.25), BlendMode.dstATop) - ) + body: SafeArea( + child: Container( + decoration: BoxDecoration( + gradient: + settings.blurPlayerBackground ? null : _bgGradient), + child: Stack( + children: [ + if (settings.blurPlayerBackground && _blurImage != null) + ClipRect( + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: _blurImage, + fit: BoxFit.fill, + colorFilter: ColorFilter.mode( + Colors.black.withOpacity(0.25), + BlendMode.dstATop))), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), + child: Container(color: Colors.transparent), + ), + ), + ), + StreamBuilder( + stream: StreamZip([ + AudioService.playbackStateStream, + AudioService.currentMediaItemStream + ]), + builder: (BuildContext context, AsyncSnapshot snapshot) { + //When disconnected + if (AudioService.currentMediaItem == null) { + playerHelper.startService(); + return Center( + child: CircularProgressIndicator(), + ); + } + + return OrientationBuilder( + builder: (context, orientation) { + //Landscape + if (orientation == Orientation.landscape) { + return PlayerScreenHorizontal(); + } + //Portrait + return PlayerScreenVertical(); + }, + ); + }, ), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: Container(color: Colors.transparent), - ), - ), - ), - StreamBuilder( - stream: StreamZip([AudioService.playbackStateStream, AudioService.currentMediaItemStream]), - builder: (BuildContext context, AsyncSnapshot snapshot) { - - //When disconnected - if (AudioService.currentMediaItem == null) { - playerHelper.startService(); - return Center(child: CircularProgressIndicator(),); - } - - return OrientationBuilder( - builder: (context, orientation) { - //Landscape - if (orientation == Orientation.landscape) { - return PlayerScreenHorizontal(); - } - //Portrait - return PlayerScreenVertical(); - }, - ); - - }, - ), - ], - ) - ) - ) - ); + ], + )))); } } @@ -184,13 +197,13 @@ class _PlayerScreenHorizontalState extends State { Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 8), child: Container( - width: ScreenUtil().setWidth(500), - child: Stack( - children: [ - BigAlbumArt(), - ], - ), + width: ScreenUtil().setWidth(500), + child: Stack( + children: [ + BigAlbumArt(), + ], ), + ), ), //Right side SizedBox( @@ -203,41 +216,40 @@ class _PlayerScreenHorizontalState extends State { padding: EdgeInsets.fromLTRB(8, 16, 8, 0), child: Container( child: PlayerScreenTopRow( - textSize: ScreenUtil().setSp(24), - iconSize: ScreenUtil().setSp(36), - textWidth: ScreenUtil().setWidth(350), - short: true - ), - ) - ), + textSize: ScreenUtil().setSp(24), + iconSize: ScreenUtil().setSp(36), + textWidth: ScreenUtil().setWidth(350), + short: true), + )), Column( mainAxisSize: MainAxisSize.min, children: [ Container( - height: ScreenUtil().setSp(50), - child: AudioService.currentMediaItem.displayTitle.length >= 22 ? - Marquee( - text: AudioService.currentMediaItem.displayTitle, - style: TextStyle( - fontSize: ScreenUtil().setSp(40), - fontWeight: FontWeight.bold - ), - blankSpace: 32.0, - startPadding: 10.0, - accelerationDuration: Duration(seconds: 1), - pauseAfterRound: Duration(seconds: 2), - ): - Text( - AudioService.currentMediaItem.displayTitle, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: ScreenUtil().setSp(40), - fontWeight: FontWeight.bold - ), - ) + height: ScreenUtil().setSp(50), + child: AudioService + .currentMediaItem.displayTitle.length >= + 22 + ? Marquee( + text: AudioService.currentMediaItem.displayTitle, + style: TextStyle( + fontSize: ScreenUtil().setSp(40), + fontWeight: FontWeight.bold), + blankSpace: 32.0, + startPadding: 10.0, + accelerationDuration: Duration(seconds: 1), + pauseAfterRound: Duration(seconds: 2), + ) + : Text( + AudioService.currentMediaItem.displayTitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: ScreenUtil().setSp(40), + fontWeight: FontWeight.bold), + )), + Container( + height: 4, ), - Container(height: 4,), Text( AudioService.currentMediaItem.displaySubtitle ?? '', maxLines: 1, @@ -264,11 +276,13 @@ class _PlayerScreenHorizontalState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( - icon: Icon(Icons.subtitles, size: ScreenUtil().setWidth(32)), + icon: Icon(Icons.subtitles, + size: ScreenUtil().setWidth(32)), onPressed: () { Navigator.of(context).push(MaterialPageRoute( - builder: (context) => LyricsScreen(trackId: AudioService.currentMediaItem.id) - )); + builder: (context) => LyricsScreen( + trackId: + AudioService.currentMediaItem.id))); }, ), QualityInfoWidget(), @@ -276,8 +290,7 @@ class _PlayerScreenHorizontalState extends State { PlayerMenuButton() ], ), - ) - ) + )) ], ), ) @@ -286,8 +299,6 @@ class _PlayerScreenHorizontalState extends State { } } - - //Portrait class PlayerScreenVertical extends StatefulWidget { @override @@ -302,9 +313,8 @@ class _PlayerScreenVerticalState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( - padding: EdgeInsets.fromLTRB(30, 4, 16, 0), - child: PlayerScreenTopRow() - ), + padding: EdgeInsets.fromLTRB(30, 4, 16, 0), + child: PlayerScreenTopRow()), Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 0), child: Container( @@ -321,30 +331,29 @@ class _PlayerScreenVerticalState extends State { mainAxisSize: MainAxisSize.min, children: [ Container( - height: ScreenUtil().setSp(80), - child: AudioService.currentMediaItem.displayTitle.length >= 26 ? - Marquee( - text: AudioService.currentMediaItem.displayTitle, - style: TextStyle( - fontSize: ScreenUtil().setSp(64), - fontWeight: FontWeight.bold - ), - blankSpace: 32.0, - startPadding: 10.0, - accelerationDuration: Duration(seconds: 1), - pauseAfterRound: Duration(seconds: 2), - ): - Text( - AudioService.currentMediaItem.displayTitle, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: ScreenUtil().setSp(64), - fontWeight: FontWeight.bold - ), - ) + height: ScreenUtil().setSp(80), + child: AudioService.currentMediaItem.displayTitle.length >= 26 + ? Marquee( + text: AudioService.currentMediaItem.displayTitle, + style: TextStyle( + fontSize: ScreenUtil().setSp(64), + fontWeight: FontWeight.bold), + blankSpace: 32.0, + startPadding: 10.0, + accelerationDuration: Duration(seconds: 1), + pauseAfterRound: Duration(seconds: 2), + ) + : Text( + AudioService.currentMediaItem.displayTitle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: ScreenUtil().setSp(64), + fontWeight: FontWeight.bold), + )), + Container( + height: 4, ), - Container(height: 4,), Text( AudioService.currentMediaItem.displaySubtitle ?? '', maxLines: 1, @@ -370,13 +379,13 @@ class _PlayerScreenVerticalState extends State { onPressed: () async { //Fix bottom buttons SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( - systemNavigationBarColor: settings.themeData.bottomAppBarColor, - statusBarColor: Colors.transparent - )); + systemNavigationBarColor: + settings.themeData.bottomAppBarColor, + statusBarColor: Colors.transparent)); await Navigator.of(context).push(MaterialPageRoute( - builder: (context) => LyricsScreen(trackId: AudioService.currentMediaItem.id) - )); + builder: (context) => LyricsScreen( + trackId: AudioService.currentMediaItem.id))); updateColor(); }, @@ -398,14 +407,14 @@ class QualityInfoWidget extends StatefulWidget { } class _QualityInfoWidgetState extends State { - String value = ''; StreamSubscription streamSubscription; //Load data from native void _load() async { if (AudioService.currentMediaItem == null) return; - Map data = await DownloadManager.platform.invokeMethod("getStreamInfo", {"id": AudioService.currentMediaItem.id}); + Map data = await DownloadManager.platform.invokeMethod( + "getStreamInfo", {"id": AudioService.currentMediaItem.id}); //N/A if (data == null) { setState(() => value = ''); @@ -418,7 +427,8 @@ class _QualityInfoWidgetState extends State { //Update StreamQualityInfo info = StreamQualityInfo.fromJson(data); setState(() { - value = '${info.format} ${info.bitrate(AudioService.currentMediaItem.duration)}kbps'; + value = + '${info.format} ${info.bitrate(AudioService.currentMediaItem.duration)}kbps'; }); } @@ -426,7 +436,8 @@ class _QualityInfoWidgetState extends State { void initState() { _load(); if (streamSubscription == null) - streamSubscription = AudioService.currentMediaItemStream.listen((event) async { + streamSubscription = + AudioService.currentMediaItemStream.listen((event) async { _load(); }); super.initState(); @@ -434,8 +445,7 @@ class _QualityInfoWidgetState extends State { @override void dispose() { - if (streamSubscription != null) - streamSubscription.cancel(); + if (streamSubscription != null) streamSubscription.cancel(); super.dispose(); } @@ -444,13 +454,13 @@ class _QualityInfoWidgetState extends State { return TextButton( child: Text(value), onPressed: () { - Navigator.of(context).push(MaterialPageRoute(builder: (context) => QualitySettings())); + Navigator.of(context) + .push(MaterialPageRoute(builder: (context) => QualitySettings())); }, ); } } - class PlayerMenuButton extends StatelessWidget { @override Widget build(BuildContext context) { @@ -465,50 +475,37 @@ class PlayerMenuButton extends StatelessWidget { m.defaultTrackMenu(t, options: [m.sleepTimer(), m.wakelock()]); else m.defaultShowEpisodeMenu( - Show.fromJson(jsonDecode(AudioService.currentMediaItem.extras['show'])), - ShowEpisode.fromMediaItem(AudioService.currentMediaItem), - options: [m.sleepTimer(), m.wakelock()] - ); + Show.fromJson( + jsonDecode(AudioService.currentMediaItem.extras['show'])), + ShowEpisode.fromMediaItem(AudioService.currentMediaItem), + options: [m.sleepTimer(), m.wakelock()]); }, ); } } - class RepeatButton extends StatefulWidget { - final double iconSize; - RepeatButton(this.iconSize, {Key key}): super(key: key); + RepeatButton(this.iconSize, {Key key}) : super(key: key); @override _RepeatButtonState createState() => _RepeatButtonState(); } class _RepeatButtonState extends State { - Icon get repeatIcon { switch (playerHelper.repeatType) { case LoopMode.off: - return Icon( - Icons.repeat, - size: widget.iconSize - ); + return Icon(Icons.repeat, size: widget.iconSize); case LoopMode.all: - return Icon( - Icons.repeat, - color: Theme.of(context).primaryColor, - size: widget.iconSize - ); + return Icon(Icons.repeat, + color: Theme.of(context).primaryColor, size: widget.iconSize); case LoopMode.one: - return Icon( - Icons.repeat_one, - color: Theme.of(context).primaryColor, - size: widget.iconSize - ); + return Icon(Icons.repeat_one, + color: Theme.of(context).primaryColor, size: widget.iconSize); } } - @override Widget build(BuildContext context) { return IconButton( @@ -521,20 +518,18 @@ class _RepeatButtonState extends State { } } - class PlaybackControls extends StatefulWidget { - final double iconSize; - PlaybackControls(this.iconSize, {Key key}): super(key: key); + PlaybackControls(this.iconSize, {Key key}) : super(key: key); @override _PlaybackControlsState createState() => _PlaybackControlsState(); } class _PlaybackControlsState extends State { - Icon get libraryIcon { - if (cache.checkTrackFavorite(Track.fromMediaItem(AudioService.currentMediaItem))) { + if (cache.checkTrackFavorite( + Track.fromMediaItem(AudioService.currentMediaItem))) { return Icon(Icons.favorite, size: widget.iconSize * 0.64); } return Icon(Icons.favorite_border, size: widget.iconSize * 0.64); @@ -549,32 +544,37 @@ class _PlaybackControlsState extends State { mainAxisSize: MainAxisSize.max, children: [ IconButton( - icon: Icon(Icons.sentiment_very_dissatisfied, size: ScreenUtil().setWidth(46)), + icon: Icon(Icons.sentiment_very_dissatisfied, + size: ScreenUtil().setWidth(46)), onPressed: () async { await deezerAPI.dislikeTrack(AudioService.currentMediaItem.id); - if (playerHelper.queueIndex < (AudioService.queue??[]).length - 1) { + if (playerHelper.queueIndex < + (AudioService.queue ?? []).length - 1) { AudioService.skipToNext(); } - } - ), + }), PrevNextButton(widget.iconSize, prev: true), PlayPauseButton(widget.iconSize * 1.25), PrevNextButton(widget.iconSize), IconButton( icon: libraryIcon, onPressed: () async { - if (cache.libraryTracks == null) - cache.libraryTracks = []; + if (cache.libraryTracks == null) cache.libraryTracks = []; - if (cache.checkTrackFavorite(Track.fromMediaItem(AudioService.currentMediaItem))) { + if (cache.checkTrackFavorite( + Track.fromMediaItem(AudioService.currentMediaItem))) { //Remove from library - setState(() => cache.libraryTracks.remove(AudioService.currentMediaItem.id)); - await deezerAPI.removeFavorite(AudioService.currentMediaItem.id); + setState(() => cache.libraryTracks + .remove(AudioService.currentMediaItem.id)); + await deezerAPI + .removeFavorite(AudioService.currentMediaItem.id); await cache.save(); } else { //Add - setState(() => cache.libraryTracks.add(AudioService.currentMediaItem.id)); - await deezerAPI.addFavoriteTrack(AudioService.currentMediaItem.id); + setState(() => + cache.libraryTracks.add(AudioService.currentMediaItem.id)); + await deezerAPI + .addFavoriteTrack(AudioService.currentMediaItem.id); await cache.save(); } }, @@ -585,14 +585,12 @@ class _PlaybackControlsState extends State { } } - class BigAlbumArt extends StatefulWidget { @override _BigAlbumArtState createState() => _BigAlbumArtState(); } class _BigAlbumArtState extends State { - PageController _pageController = PageController( initialPage: playerHelper.queueIndex, ); @@ -603,7 +601,8 @@ class _BigAlbumArtState extends State { void initState() { _currentItemSub = AudioService.currentMediaItemStream.listen((event) async { _animationLock = true; - await _pageController.animateToPage(playerHelper.queueIndex, duration: Duration(milliseconds: 300), curve: Curves.easeInOut); + await _pageController.animateToPage(playerHelper.queueIndex, + duration: Duration(milliseconds: 300), curve: Curves.easeInOut); _animationLock = false; }); super.initState(); @@ -611,8 +610,7 @@ class _BigAlbumArtState extends State { @override void dispose() { - if (_currentItemSub != null) - _currentItemSub.cancel(); + if (_currentItemSub != null) _currentItemSub.cancel(); super.dispose(); } @@ -634,7 +632,8 @@ class _BigAlbumArtState extends State { if (_animationLock) return; AudioService.skipToQueueItem(AudioService.queue[index].id); }, - children: List.generate(AudioService.queue.length, (i) => ZoomableImage(url: AudioService.queue[i].artUri)), + children: List.generate(AudioService.queue.length, + (i) => ZoomableImage(url: AudioService.queue[i].artUri)), ), ); } @@ -642,12 +641,12 @@ class _BigAlbumArtState extends State { //Top row containing QueueSource, queue... class PlayerScreenTopRow extends StatelessWidget { - final double textSize; final double iconSize; final double textWidth; final bool short; - PlayerScreenTopRow({this.textSize, this.iconSize, this.textWidth, this.short}); + PlayerScreenTopRow( + {this.textSize, this.iconSize, this.textWidth, this.short}); @override Widget build(BuildContext context) { @@ -657,29 +656,31 @@ class PlayerScreenTopRow extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( - width: this.textWidth??ScreenUtil().setWidth(800), + width: this.textWidth ?? ScreenUtil().setWidth(800), child: Text( - (short??false)?(playerHelper.queueSource.text??''):'Playing from:'.i18n + ' ' + (playerHelper.queueSource?.text??''), + (short ?? false) + ? (playerHelper.queueSource.text ?? '') + : 'Playing from:'.i18n + + ' ' + + (playerHelper.queueSource?.text ?? ''), maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.left, - style: TextStyle(fontSize: this.textSize??ScreenUtil().setSp(38)), + style: TextStyle(fontSize: this.textSize ?? ScreenUtil().setSp(38)), ), ), IconButton( icon: Icon(Icons.menu), - iconSize: this.iconSize??ScreenUtil().setSp(52), - splashRadius: this.iconSize??ScreenUtil().setWidth(52), + iconSize: this.iconSize ?? ScreenUtil().setSp(52), + splashRadius: this.iconSize ?? ScreenUtil().setWidth(52), onPressed: () async { //Fix bottom buttons SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( systemNavigationBarColor: settings.themeData.bottomAppBarColor, - statusBarColor: Colors.transparent - )); + statusBarColor: Colors.transparent)); //Navigate - await Navigator.of(context).push(MaterialPageRoute( - builder: (context) => QueueScreen() - )); + await Navigator.of(context) + .push(MaterialPageRoute(builder: (context) => QueueScreen())); //Fix colors updateColor(); }, @@ -689,22 +690,21 @@ class PlayerScreenTopRow extends StatelessWidget { } } - - class SeekBar extends StatefulWidget { @override _SeekBarState createState() => _SeekBarState(); } class _SeekBarState extends State { - bool _seeking = false; double _pos; double get position { if (_seeking) return _pos; if (AudioService.playbackState == null) return 0.0; - double p = AudioService.playbackState.currentPosition.inMilliseconds.toDouble()??0.0; + double p = + AudioService.playbackState.currentPosition.inMilliseconds.toDouble() ?? + 0.0; if (p > duration) return duration; return p; } @@ -735,15 +735,11 @@ class _SeekBarState extends State { children: [ Text( _timeString(position), - style: TextStyle( - fontSize: ScreenUtil().setSp(35) - ), + style: TextStyle(fontSize: ScreenUtil().setSp(35)), ), Text( _timeString(duration), - style: TextStyle( - fontSize: ScreenUtil().setSp(35) - ), + style: TextStyle(fontSize: ScreenUtil().setSp(35)), ) ], ), @@ -751,7 +747,10 @@ class _SeekBarState extends State { Container( height: 32.0, child: Slider( - focusNode: FocusNode(canRequestFocus: false, skipTraversal: true), // Don't focus on Slider - it doesn't work (and not needed) + focusNode: FocusNode( + canRequestFocus: false, + skipTraversal: + true), // Don't focus on Slider - it doesn't work (and not needed) value: position, max: duration, onChangeStart: (double d) { @@ -787,19 +786,19 @@ class QueueScreen extends StatefulWidget { } class _QueueScreenState extends State { - StreamSubscription _queueSub; @override void initState() { - _queueSub = AudioService.queueStream.listen((event) {setState((){});}); + _queueSub = AudioService.queueStream.listen((event) { + setState(() {}); + }); super.initState(); } @override void dispose() { - if (_queueSub != null) - _queueSub.cancel(); + if (_queueSub != null) _queueSub.cancel(); super.dispose(); } @@ -820,32 +819,33 @@ class _QueueScreenState extends State { ) ], ), - body: ReorderableListView( - onReorder: (int oldIndex, int newIndex) async { + body: ReorderableListView.builder( + onReorder: (int oldIndex, int newIndex) { if (oldIndex == playerHelper.queueIndex) return; - await playerHelper.reorder(oldIndex, newIndex); - setState(() {}); + playerHelper + .reorder(oldIndex, newIndex) + .then((value) => setState(() => null)); }, - children: List.generate(AudioService.queue.length, (int i) { + itemCount: AudioService.queue.length, + itemBuilder: (BuildContext context, int i) { Track t = Track.fromMediaItem(AudioService.queue[i]); return TrackTile( t, - onTap: () async { + onTap: () { pageViewLock = true; - await AudioService.skipToQueueItem(t.id); - Navigator.of(context).pop(); + AudioService.skipToQueueItem(t.id) + .then((value) => Navigator.of(context).pop()); }, key: Key(i.toString()), trailing: IconButton( icon: Icon(Icons.close), - onPressed: () async { - await AudioService.removeQueueItem(t.toMediaItem()); - setState(() {}); + onPressed: () { + AudioService.removeQueueItem(t.toMediaItem()) + .then((value) => setState(() => null)); }, ), ); - }), - ) - ); + }, + )); } -} \ No newline at end of file +}