diff --git a/lib/home/audioplayer.dart b/lib/home/audioplayer.dart index 54ad9ea..fee9599 100644 --- a/lib/home/audioplayer.dart +++ b/lib/home/audioplayer.dart @@ -449,129 +449,112 @@ class _PlaylistWidgetState extends State { selector: (_, audio) => Tuple2(audio.queue.playlist, audio.queueUpdate), builder: (_, data, __) { - return ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10), - topRight: Radius.circular(10)), - child: AnimatedList( - key: miniPlaylistKey, - shrinkWrap: true, - scrollDirection: Axis.vertical, - initialItemCount: data.item1.length, - itemBuilder: (context, index, animation) => ScaleTransition( - alignment: Alignment.center, - scale: animation, - child: index == 0 || index > data.item1.length - 1 - ? Center() - : Column( - children: [ - Row( - children: [ - Expanded( - child: Material( - color: Colors.transparent, - child: InkWell( - onTap: () { - audio - .episodeLoad(data.item1[index]); - miniPlaylistKey.currentState - .removeItem( - index, - (context, animation) => - Center()); - miniPlaylistKey.currentState - .insertItem(0); - }, - child: Container( - height: 60, - padding: EdgeInsets.symmetric( - horizontal: 20), + var episodesToPlay = data.item1.sublist(1); + return AnimatedList( + key: miniPlaylistKey, + shrinkWrap: true, + scrollDirection: Axis.vertical, + initialItemCount: episodesToPlay.length, + itemBuilder: (context, index, animation) => ScaleTransition( + alignment: Alignment.center, + scale: animation, + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + audio.episodeLoad(data.item1[index]); + miniPlaylistKey.currentState.removeItem( + index, + (context, animation) => Center()); + miniPlaylistKey.currentState.insertItem(0); + }, + child: Container( + height: 60, + padding: + EdgeInsets.symmetric(horizontal: 20), + alignment: Alignment.centerLeft, + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.all(10.0), + child: ClipRRect( + borderRadius: BorderRadius.all( + Radius.circular(15.0)), + child: Container( + height: 30.0, + width: 30.0, + child: Image.file(File( + "${episodesToPlay[index].imagePath}"))), + ), + ), + Expanded( + child: Align( alignment: Alignment.centerLeft, - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: EdgeInsets.all(10.0), - child: ClipRRect( - borderRadius: - BorderRadius.all( - Radius.circular( - 15.0)), - child: Container( - height: 30.0, - width: 30.0, - child: Image.file(File( - "${data.item1[index].imagePath}"))), - ), - ), - Expanded( - child: Align( - alignment: - Alignment.centerLeft, - child: Text( - data.item1[index].title, - maxLines: 1, - overflow: - TextOverflow.ellipsis, - ), - ), - ), - ], + child: Text( + episodesToPlay[index].title, + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ), ), - ), + ], ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20.0), - child: Material( - borderRadius: - BorderRadius.circular(100), - clipBehavior: Clip.hardEdge, - color: context.primaryColor, - child: InkWell( - borderRadius: BorderRadius.all( - Radius.circular(15.0)), - onTap: () async { - await audio - .moveToTop(data.item1[index]); - miniPlaylistKey.currentState - .removeItem( - index, - (context, animation) => Center(), - duration: - Duration(milliseconds: 500), - ); - miniPlaylistKey.currentState - .insertItem( - 1, - duration: Duration( - milliseconds: 200)); - }, - child: SizedBox( - height: 30.0, - width: 30.0, - child: Transform.rotate( - angle: math.pi, - child: Icon( - LineIcons.download_solid, - size: 20.0, - ), - ), - ), - ), - ), - ), - ], + ), ), - Divider(height: 2), - ], + ), ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 20.0), + child: Material( + borderRadius: BorderRadius.circular(100), + clipBehavior: Clip.hardEdge, + color: context.primaryColor, + child: InkWell( + borderRadius: + BorderRadius.all(Radius.circular(15.0)), + onTap: () async { + miniPlaylistKey.currentState.removeItem( + index, + (context, animation) => Center(), + duration: Duration(milliseconds: 50), + ); + var episdoe = + episodesToPlay.removeAt(index); + episodesToPlay.insert(0, episdoe); + miniPlaylistKey.currentState.insertItem(0, + duration: Duration(milliseconds: 200)); + await audio + .moveToTop(data.item1[index + 1]); + }, + child: SizedBox( + height: 30.0, + width: 30.0, + child: Transform.rotate( + angle: math.pi, + child: Icon( + LineIcons.download_solid, + size: 20.0, + ), + ), + ), + ), + ), + ), + ], + ), + Divider(height: 2), + ], ), ), ); diff --git a/lib/state/audio_state.dart b/lib/state/audio_state.dart index ceb2191..5ac21d9 100644 --- a/lib/state/audio_state.dart +++ b/lib/state/audio_state.dart @@ -71,7 +71,7 @@ class AudioPlayerNotifier extends ChangeNotifier { EpisodeBrief _episode; /// Current playlist. - final Playlist _queue = Playlist(); + Playlist _queue; /// Notifier for playlist change. bool _queueUpdate = false; @@ -230,6 +230,7 @@ class AudioPlayerNotifier extends ChangeNotifier { } Future loadPlaylist() async { + _queue = Playlist(); await _queue.getPlaylist(); await _getAutoPlay(); _lastPostion = await positionStorage.getInt(); @@ -519,16 +520,20 @@ class AudioPlayerNotifier extends ChangeNotifier { return index; } - moveToTop(EpisodeBrief episode) async { + Future moveToTop(EpisodeBrief episode) async { await delFromPlaylist(episode); if (playerRunning) { - await addToPlaylistAt(episode, 1); + await AudioService.addQueueItemAt(episode.toMediaItem(), 1); + await _queue.addToPlayListAt(episode, 1, existed: false); } else { - await addToPlaylistAt(episode, 0); + await _queue.addToPlayListAt(episode, 0, existed: false); _lastPostion = 0; positionStorage.saveInt(_lastPostion); } + _queueUpdate = !_queueUpdate; notifyListeners(); + print('moved to top'); + return true; } pauseAduio() async { @@ -652,7 +657,7 @@ class AudioPlayerTask extends BackgroundAudioTask { final List _queue = []; final AudioPlayer _audioPlayer = AudioPlayer(); AudioProcessingState _skipState; - bool _playing = false; + bool _playing; bool _interrupted = false; bool _stopAtEnd; int _cacheMax; @@ -971,7 +976,7 @@ class AudioPlayerTask extends BackgroundAudioTask { systemActions: [MediaAction.seekTo], processingState: processingState ?? AudioServiceBackground.state.processingState, - playing: _playing, + playing: _playing ?? false, position: position, bufferedPosition: bufferedPosition ?? position, speed: _audioPlayer.speed, diff --git a/lib/type/playlist.dart b/lib/type/playlist.dart index 51416cb..9c1fed9 100644 --- a/lib/type/playlist.dart +++ b/lib/type/playlist.dart @@ -38,14 +38,17 @@ class Playlist { } } - addToPlayListAt(EpisodeBrief episodeBrief, int index) async { - if (!_playlist.contains(episodeBrief)) { - _playlist.insert(index, episodeBrief); - await savePlaylist(); + addToPlayListAt(EpisodeBrief episodeBrief, int index, + {bool existed = true}) async { + if (existed) { + _playlist.removeWhere( + (episode) => episode.enclosureUrl == episodeBrief.enclosureUrl); if (episodeBrief.isNew == 1) { await dbHelper.removeEpisodeNewMark(episodeBrief.enclosureUrl); } } + _playlist.insert(index, episodeBrief); + await savePlaylist(); } Future delFromPlaylist(EpisodeBrief episodeBrief) async {