diff --git a/lib/home/audioplayer.dart b/lib/home/audioplayer.dart index dea8be9..71f417d 100644 --- a/lib/home/audioplayer.dart +++ b/lib/home/audioplayer.dart @@ -15,6 +15,7 @@ import '../local_storage/sqflite_localpodcast.dart'; import '../state/audio_state.dart'; import '../type/episodebrief.dart'; import '../type/play_histroy.dart'; +import '../type/playlist.dart'; import '../util/extension_helper.dart'; import '../util/pageroute.dart'; import '../widgets/audiopanel.dart'; @@ -402,202 +403,283 @@ class _PlaylistWidgetState extends State { @override Widget build(BuildContext context) { var audio = Provider.of(context, listen: false); - return Container( - alignment: Alignment.topLeft, - height: 300, - width: double.infinity, - decoration: BoxDecoration( - color: context.accentColor.withAlpha(70), - borderRadius: BorderRadius.circular(10), - ), - child: Column( - children: [ - Expanded( - child: Selector>( - selector: (_, audio) => audio.playlist.episodes, - builder: (_, data, __) { - var episodesToPlay = data.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[index]); - miniPlaylistKey.currentState.removeItem( - index, - (context, animation) => Center()); - }, - 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( + return ClipRRect( + borderRadius: BorderRadius.circular(10), + child: Container( + alignment: Alignment.topLeft, + height: 300, + width: double.infinity, + decoration: BoxDecoration( + color: context.accentColor.withAlpha(70), + borderRadius: BorderRadius.circular(10), + ), + child: Selector>( + selector: (_, audio) => Tuple2(audio.playlist, audio.episode), + builder: (_, data, __) { + var episodes = data.item1.episodes; + return Column( + children: [ + Expanded( + child: data.item1.name == 'Queue' + ? AnimatedList( + key: miniPlaylistKey, + shrinkWrap: true, + scrollDirection: Axis.vertical, + initialItemCount: episodes.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(episodes[index]); + miniPlaylistKey.currentState + .removeItem( + index, + (context, animation) => + Center()); + }, + child: Container( + height: 60, + padding: EdgeInsets.symmetric( + horizontal: 20), alignment: Alignment.centerLeft, - child: Text( - episodesToPlay[index].title, - maxLines: 1, - overflow: TextOverflow.ellipsis, + 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( + "${episodes[index].imagePath}"))), + ), + ), + Expanded( + child: Align( + alignment: + Alignment.centerLeft, + child: Text( + episodes[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 { - var episdoe = - episodesToPlay.removeAt(index); - episodesToPlay.insert(0, episdoe); - miniPlaylistKey.currentState.removeItem( - index, - (context, animation) { - return Center(); - }, - duration: Duration.zero, - ); - miniPlaylistKey.currentState.insertItem(0, - duration: Duration(milliseconds: 100)); - await Future.delayed( - Duration(milliseconds: 100)); - await audio.moveToTop(data[index + 1]); - }, - child: SizedBox( - height: 30.0, - width: 30.0, - child: Transform.rotate( - angle: math.pi, - child: Icon( - LineIcons.download_solid, - size: 20.0, ), ), - ), + 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 { + var episdoe = + episodes.removeAt(index); + episodes.insert(0, episdoe); + miniPlaylistKey.currentState + .removeItem( + index, + (context, animation) { + return Center(); + }, + duration: Duration.zero, + ); + miniPlaylistKey.currentState + .insertItem( + 0, + duration: Duration( + milliseconds: 100)); + await Future.delayed( + Duration(milliseconds: 100)); + await audio.moveToTop( + data.item1.episodes[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: 1), + ], + ), + ), + ) + : ListView.builder( + itemCount: episodes.length, + itemBuilder: (context, index) { + final isPlaying = episodes[index] != null && + episodes[index] == data.item2; + return InkWell( + onTap: () async { + if (!isPlaying) { + await context + .read() + .loadEpisodeFromPlaylist(episodes[index]); + } + }, + child: Container( + color: isPlaying + ? context.accentColor + : Colors.transparent, + 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( + "${episodes[index].imagePath}"))), + ), + ), + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: Text( + episodes[index].title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ), + if (isPlaying) + Container( + height: 20, + width: 20, + margin: EdgeInsets.symmetric( + horizontal: 10), + decoration: BoxDecoration( + shape: BoxShape.circle, + ), + child: WaveLoader( + color: context.primaryColor)), + ], + ), + ), + ); + }, + ), + ), + SizedBox( + height: 60.0, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Text( + data.item1.name == 'Queue' + ? context.s.queue + : '${context.s.homeMenuPlaylist}${'-${data.item1.name}'}', + overflow: TextOverflow.fade, + style: TextStyle( + color: context.accentColor, + fontWeight: FontWeight.bold, + fontSize: 16), + ), + Spacer(), + Material( + borderRadius: BorderRadius.circular(100), + color: context.primaryColor, + child: InkWell( + borderRadius: BorderRadius.all(Radius.circular(15)), + onTap: () { + audio.playNext(); + miniPlaylistKey.currentState.removeItem( + 0, (context, animation) => Container()); + miniPlaylistKey.currentState.insertItem(0); + }, + child: SizedBox( + height: 30, + width: 60, + child: Icon( + Icons.skip_next, + size: 30, + ), + ), + ), + ), + SizedBox(width: 20), + Material( + borderRadius: BorderRadius.circular(100), + color: context.primaryColor, + child: InkWell( + borderRadius: BorderRadius.circular(15.0), + onTap: () { + Navigator.push( + context, + SlideLeftRoute( + page: PlaylistPage( + initPage: InitPage.playlist, + )), + ); + }, + child: SizedBox( + height: 30.0, + width: 30.0, + child: Transform.rotate( + angle: math.pi, + child: Icon( + LineIcons.database_solid, + size: 20.0, ), ), ), - ], + ), ), - Divider(height: 1), ], ), ), - ); - }, - ), - ), - SizedBox( - height: 60.0, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - Text( - context.s.homeMenuPlaylist, - style: TextStyle( - color: context.accentColor, - fontWeight: FontWeight.bold, - fontSize: 16), - ), - Spacer(), - Material( - borderRadius: BorderRadius.circular(100), - color: context.primaryColor, - child: InkWell( - borderRadius: BorderRadius.all(Radius.circular(15)), - onTap: () { - audio.playNext(); - miniPlaylistKey.currentState - .removeItem(0, (context, animation) => Container()); - miniPlaylistKey.currentState.insertItem(0); - }, - child: SizedBox( - height: 30, - width: 60, - child: Icon( - Icons.skip_next, - size: 30, - ), - ), - ), - ), - SizedBox(width: 20), - Material( - borderRadius: BorderRadius.circular(100), - color: context.primaryColor, - child: InkWell( - borderRadius: BorderRadius.circular(15.0), - onTap: () { - Navigator.push( - context, - SlideLeftRoute( - page: PlaylistPage( - initPage: InitPage.playlist, - )), - ); - }, - child: SizedBox( - height: 30.0, - width: 30.0, - child: Transform.rotate( - angle: math.pi, - child: Icon( - LineIcons.database_solid, - size: 20.0, - ), - ), - ), - ), - ), - ], - ), - ), - ), - ], + ), + ], + ); + }, + ), ), ); } diff --git a/lib/local_storage/sqflite_localpodcast.dart b/lib/local_storage/sqflite_localpodcast.dart index adce819..9d5a5b6 100644 --- a/lib/local_storage/sqflite_localpodcast.dart +++ b/lib/local_storage/sqflite_localpodcast.dart @@ -1361,7 +1361,7 @@ class DBHelper { Future removeGroupNewMark(List group) async { var dbClient = await database; - if (group.length > 0) { + if (group.isNotEmpty) { var s = group.map((e) => "'$e'").toList(); await dbClient.transaction((txn) async { await txn.rawUpdate(