diff --git a/lib/home/home_groups.dart b/lib/home/home_groups.dart index ab76176..764daf1 100644 --- a/lib/home/home_groups.dart +++ b/lib/home/home_groups.dart @@ -21,6 +21,7 @@ import '../podcasts/podcastlist.dart'; import '../state/audio_state.dart'; import '../state/download_state.dart'; import '../state/podcast_group.dart'; +import '../state/refresh_podcast.dart'; import '../type/episodebrief.dart'; import '../type/play_histroy.dart'; import '../type/podcastlocal.dart'; @@ -493,23 +494,27 @@ class _PodcastPreviewState extends State { return Column( children: [ Expanded( - child: Selector( - selector: (_, worker) => worker.created, - builder: (context, created, child) { - return FutureBuilder>( - future: _getRssItem, - builder: (context, snapshot) { - return (snapshot.hasData) - ? ShowEpisode( - episodes: snapshot.data, - podcastLocal: widget.podcastLocal, - ) - : Padding( - padding: const EdgeInsets.all(5.0), - ); - }, - ); - }), + child: Selector( + selector: (_, worker) => worker.complete, + builder: (_, complete, __) => Selector( + selector: (_, worker) => worker.created, + builder: (context, created, child) { + _getRssItem = _getRssItemTop(widget.podcastLocal); + return FutureBuilder>( + future: _getRssItem, + builder: (context, snapshot) { + return (snapshot.hasData) + ? ShowEpisode( + episodes: snapshot.data, + podcastLocal: widget.podcastLocal, + ) + : Padding( + padding: const EdgeInsets.all(5.0), + ); + }, + ); + }), + ), ), Container( height: 40, diff --git a/lib/playlists/playlist_home.dart b/lib/playlists/playlist_home.dart index 1090cbd..8b648dd 100644 --- a/lib/playlists/playlist_home.dart +++ b/lib/playlists/playlist_home.dart @@ -871,7 +871,9 @@ class __NewPlaylistState extends State<_NewPlaylist> { FlatButton( splashColor: context.accentColor.withAlpha(70), onPressed: () async { - if (context + if (_playlistName == '') { + setState(() => _error = 0); + } else if (context .read() .playlistExisted(_playlistName)) { setState(() => _error = 1); @@ -887,7 +889,7 @@ class __NewPlaylistState extends State<_NewPlaylist> { final recent = await _recent(); playlist = Playlist( _playlistName, - episodeList: [for(var e in recent) e.enclosureUrl], + episodeList: [for (var e in recent) e.enclosureUrl], ); await playlist.getPlaylist(); break; @@ -895,7 +897,7 @@ class __NewPlaylistState extends State<_NewPlaylist> { final random = await _random(); playlist = Playlist( _playlistName, - episodeList: [for(var e in random) e.enclosureUrl], + episodeList: [for (var e in random) e.enclosureUrl], ); await playlist.getPlaylist(); break; @@ -938,14 +940,15 @@ class __NewPlaylistState extends State<_NewPlaylist> { }, ), Container( - alignment: Alignment.centerLeft, - child: (_error == 1) - ? Text( - 'Playlist existed', - style: TextStyle(color: Colors.red[400]), - ) - : Center(), - ), + alignment: Alignment.centerLeft, + child: _error != null + ? Text( + _error == 1 + ? 'Playlist existed' + : 'Playlist name is empty', + style: TextStyle(color: Colors.red[400]), + ) + : Center()), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ diff --git a/lib/podcasts/podcast_detail.dart b/lib/podcasts/podcast_detail.dart index 3dbecf5..ef84317 100644 --- a/lib/podcasts/podcast_detail.dart +++ b/lib/podcasts/podcast_detail.dart @@ -30,6 +30,9 @@ import '../widgets/general_dialog.dart'; import '../widgets/muiliselect_bar.dart'; import 'podcast_settings.dart'; +const KDefaultAvatar = """http://xuanmei.us/assets/default/avatar_small- +170afdc2be97fc6148b283083942d82c101d4c1061f6b28f87c8958b52664af9.jpg"""; + class PodcastDetail extends StatefulWidget { PodcastDetail({Key key, @required this.podcastLocal, this.hide = false}) : super(key: key); @@ -88,6 +91,9 @@ class _PodcastDetailState extends State { bool _selectAfter; bool _loadEpisodes = false; + ///Show podcast info. + bool _showInfo; + @override void initState() { super.initState(); @@ -99,6 +105,7 @@ class _PodcastDetailState extends State { _selectAll = false; _selectAfter = false; _selectBefore = false; + _showInfo = false; Future.delayed(Duration(milliseconds: 200)) .then((value) => setState(() => _loadEpisodes = true)); } @@ -202,16 +209,13 @@ class _PodcastDetailState extends State { Widget _podcastInfo(BuildContext context) { return Container( height: 170, - padding: EdgeInsets.only(top: 40, left: 80, right: 130), + padding: EdgeInsets.only(top: 50, left: 80, right: 130), alignment: Alignment.topLeft, - child: Container( - padding: EdgeInsets.symmetric(vertical: 10), - child: Text( - widget.podcastLocal.title, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: context.textTheme.headline5.copyWith(color: Colors.white), - ), + child: Text( + widget.podcastLocal.title, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: context.textTheme.headline5.copyWith(color: Colors.white), ), ); } @@ -233,28 +237,26 @@ class _PodcastDetailState extends State { errorWidget: (context, url, error) => Center(), imageBuilder: (context, backgroundImageProvider) => Container( - decoration: BoxDecoration( - image: DecorationImage( - image: backgroundImageProvider, - fit: BoxFit.cover)), + // decoration: BoxDecoration( + // image: DecorationImage( + // image: backgroundImageProvider, + // fit: BoxFit.cover)), alignment: Alignment.centerRight, child: Container( - color: Colors.black26, + //color: Colors.black26, padding: EdgeInsets.symmetric(vertical: 5.0), - width: MediaQuery.of(context).size.width, - alignment: Alignment.centerRight, + width: double.infinity, + alignment: Alignment.centerLeft, child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: hosts .map((host) { - final image = host.image == - "http://xuanmei.us/assets/default/avatar_small-" - "170afdc2be97fc6148b283083942d82c101d4c1061f6b28f87c8958b52664af9.jpg" - ? "https://fireside.fm/assets/default/avatar_small" - "-170afdc2be97fc6148b283083942d82c101d4c1061f6b28f87c8958b52664af9.jpg" - : host.image; + final image = + host.image == KDefaultAvatar + ? KDefaultAvatar + : host.image; return Container( padding: EdgeInsets.all(5.0), width: 80.0, @@ -299,11 +301,13 @@ class _PodcastDetailState extends State { Text( host.name, style: TextStyle( - backgroundColor: Colors - .black - .withOpacity(0.5), - color: Colors.white, - ), + fontWeight: + FontWeight.bold + // backgroundColor: Colors + // .black + // .withOpacity(0.5), + //color: Colors.white, + ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.fade, @@ -320,9 +324,8 @@ class _PodcastDetailState extends State { return Center(); } }), - Padding(padding: EdgeInsets.all(10.0)), Container( - padding: EdgeInsets.only(left: 15.0, right: 15.0, bottom: 10.0), + padding: EdgeInsets.fromLTRB(15, 10, 15, 10), alignment: Alignment.topLeft, color: context.scaffoldBackgroundColor, child: AboutPodcast(podcastLocal: widget.podcastLocal), @@ -331,12 +334,12 @@ class _PodcastDetailState extends State { ); } - Widget _customPopupMenu( - {Widget child, - String tooltip, - List> itemBuilder, - Function(int) onSelected, - }) => + Widget _customPopupMenu({ + Widget child, + String tooltip, + List> itemBuilder, + Function(int) onSelected, + }) => Material( key: UniqueKey(), color: Colors.transparent, @@ -708,6 +711,7 @@ class _PodcastDetailState extends State { top: false, child: RefreshIndicator( key: _refreshIndicatorKey, + displacement: context.paddingTop + 40, color: context.accentColor, onRefresh: () async { await _updateRssItem(context, widget.podcastLocal); @@ -765,38 +769,60 @@ class _PodcastDetailState extends State { return FlexibleSpaceBar( background: Stack( children: [ - Container( - margin: EdgeInsets.only( - top: 100 + context.paddingTop), - padding: EdgeInsets.only( - left: 80, right: 20), - color: Colors.white10, - alignment: Alignment.centerLeft, - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - widget.podcastLocal.author ?? - '', - maxLines: 1, - overflow: - TextOverflow.ellipsis, - style: TextStyle( - color: Colors.white)), - if (widget.podcastLocal.provider - .isNotEmpty) + // if (widget.podcastLocal.provider + // .contains('fireside')) + // Positioned.fill( + // child: FutureBuilder( + // future: _getHosts( + // widget.podcastLocal), + // builder: (context, snapshot) { + // if (snapshot.hasData) { + // return CachedNetworkImage( + // imageUrl: + // snapshot.data.item1, + // fit: BoxFit.fill, + // ); + // } else + // return Center(); + // }), + // ), + InkWell( + onTap: () => setState( + () => _showInfo = !_showInfo), + child: Container( + margin: EdgeInsets.only( + top: 100 + context.paddingTop), + padding: EdgeInsets.only( + left: 80, right: 20), + color: Colors.white10, + alignment: Alignment.centerLeft, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ Text( - s.hostedOn(widget - .podcastLocal.provider), - maxLines: 1, - style: TextStyle( - color: Colors.white), - ), - ], + widget.podcastLocal + .author ?? + '', + maxLines: 1, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white)), + if (widget.podcastLocal.provider + .isNotEmpty) + Text( + s.hostedOn(widget + .podcastLocal.provider), + maxLines: 1, + style: TextStyle( + color: Colors.white), + ), + ], + ), ), ), Container( @@ -830,7 +856,9 @@ class _PodcastDetailState extends State { }), ), SliverToBoxAdapter( - child: _hostsList(context, widget.podcastLocal), + child: _showInfo + ? _hostsList(context, widget.podcastLocal) + : SizedBox(height: 10), ), SliverToBoxAdapter( child: _multiSelect @@ -1004,63 +1032,73 @@ class _AboutPodcastState extends State { Widget build(BuildContext context) { return !_load ? Center() - : LayoutBuilder( - builder: (context, size) { - final span = TextSpan(text: _description); - final tp = TextPainter( - text: span, maxLines: 3, textDirection: TextDirection.ltr); - tp.layout(maxWidth: size.maxWidth); - - if (tp.didExceedMaxLines) { - return GestureDetector( - onTap: () { - setState(() => _expand = !_expand); - }, - child: !_expand - ? Column( - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Linkify( - onOpen: (link) { - link.url.launchUrl; - }, - text: _description, - linkStyle: TextStyle( - color: Theme.of(context).accentColor, - decoration: TextDecoration.underline, - textBaseline: TextBaseline.ideographic), - maxLines: 3, - overflow: TextOverflow.ellipsis, - ), - ], - ) - : Linkify( - onOpen: (link) { - link.url.launchUrl; - }, - text: _description, - linkStyle: TextStyle( - color: Theme.of(context).accentColor, - decoration: TextDecoration.underline, - textBaseline: TextBaseline.ideographic), - ), - ); - } else { - return Linkify( - text: _description, - onOpen: (link) { - link.url.launchUrl; - }, - linkStyle: TextStyle( - color: Theme.of(context).accentColor, - decoration: TextDecoration.underline, - textBaseline: TextBaseline.ideographic), - ); - } + : Linkify( + text: _description, + onOpen: (link) { + link.url.launchUrl; }, + linkStyle: TextStyle( + color: Theme.of(context).accentColor, + decoration: TextDecoration.underline, + textBaseline: TextBaseline.ideographic), ); + // LayoutBuilder( + // builder: (context, size) { + // final span = TextSpan(text: _description); + // final tp = TextPainter( + // text: span, maxLines: 3, textDirection: TextDirection.ltr); + // tp.layout(maxWidth: size.maxWidth); + + // if (tp.didExceedMaxLines) { + // return GestureDetector( + // onTap: () { + // setState(() => _expand = !_expand); + // }, + // child: !_expand + // ? Column( + // mainAxisAlignment: MainAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Linkify( + // onOpen: (link) { + // link.url.launchUrl; + // }, + // text: _description, + // linkStyle: TextStyle( + // color: Theme.of(context).accentColor, + // decoration: TextDecoration.underline, + // textBaseline: TextBaseline.ideographic), + // maxLines: 3, + // overflow: TextOverflow.ellipsis, + // ), + // ], + // ) + // : Linkify( + // onOpen: (link) { + // link.url.launchUrl; + // }, + // text: _description, + // linkStyle: TextStyle( + // color: Theme.of(context).accentColor, + // decoration: TextDecoration.underline, + // textBaseline: TextBaseline.ideographic), + // ), + // ); + // } else { + // return Linkify( + // text: _description, + // onOpen: (link) { + // link.url.launchUrl; + // }, + // linkStyle: TextStyle( + // color: Theme.of(context).accentColor, + // decoration: TextDecoration.underline, + // textBaseline: TextBaseline.ideographic), + // ); + // } + // }, + // ); } } diff --git a/lib/widgets/custom_widget.dart b/lib/widgets/custom_widget.dart index 62a97bc..24f2763 100644 --- a/lib/widgets/custom_widget.dart +++ b/lib/widgets/custom_widget.dart @@ -505,7 +505,8 @@ class WavePainter extends CustomPainter { class WaveLoader extends StatefulWidget { final Color color; - WaveLoader({this.color, Key key}) : super(key: key); + final bool animate; + WaveLoader({this.color, this.animate = true, Key key}) : super(key: key); @override _WaveLoaderState createState() => _WaveLoaderState(); } @@ -547,7 +548,8 @@ class _WaveLoaderState extends State @override Widget build(BuildContext context) { return CustomPaint( - painter: WavePainter(_fraction, widget.color ?? Colors.white)); + painter: WavePainter( + widget.animate ? _fraction : 1, widget.color ?? Colors.white)); } } @@ -1300,16 +1302,15 @@ class _SleepTimerPickerState extends State { super.initState(); } - _initTimer(){ + _initTimer() { int h = DateTime.now().hour; int m = DateTime.now().minute; - if(m > 50){ - hour = (h+1) % 24; + if (m > 50) { + hour = (h + 1) % 24; minute = 0; - } - else { + } else { hour = h; - minute = m ~/10 * 10 +10; + minute = m ~/ 10 * 10 + 10; } }