Change podcast list page long tap option, long tap See All in homepage to open podcast list.

This commit is contained in:
stonegate 2020-09-19 01:56:07 +08:00
parent b271965009
commit e2ef6ea01b
6 changed files with 129 additions and 110 deletions

View File

@ -11,6 +11,7 @@ import 'package:intl/intl.dart';
import 'package:line_icons/line_icons.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:tsacdop/podcasts/podcastlist.dart';
import 'package:tsacdop/util/general_dialog.dart';
import 'package:tuple/tuple.dart';
@ -166,6 +167,15 @@ class _ScrollPodcastsState extends State<ScrollPodcasts>
);
}
},
onLongPress: () {
if (!import) {
Navigator.push(
context,
SlideLeftRoute(
page: PodcastList()),
);
}
},
borderRadius:
BorderRadius.circular(5),
child: Padding(
@ -317,6 +327,15 @@ class _ScrollPodcastsState extends State<ScrollPodcasts>
);
}
},
onLongPress: () {
if (!import) {
Navigator.push(
context,
SlideLeftRoute(
page: PodcastList()),
);
}
},
borderRadius:
BorderRadius.circular(5),
child: Padding(

View File

@ -127,7 +127,8 @@ class DBHelper {
var dbClient = await database;
List<Map> list = await dbClient
.rawQuery('SELECT episode_count FROM PodcastLocal WHERE id = ?', [id]);
return list.first['episode_count'];
if (list.isNotEmpty) return list.first['episode_count'];
return 0;
}
Future<int> getPodcastUpdateCounts(String id) async {
@ -135,14 +136,16 @@ class DBHelper {
List<Map> list = await dbClient.rawQuery(
'SELECt count(*) as count FROM Episodes WHERE feed_id = ? AND is_new = 1',
[id]);
return list.first['count'];
if (list.isNotEmpty) return list.first['count'];
return 0;
}
Future<int> getSkipSecondsStart(String id) async {
var dbClient = await database;
List<Map> list = await dbClient
.rawQuery('SELECT skip_seconds FROM PodcastLocal WHERE id = ?', [id]);
return list.first['skip_seconds'];
if (list.isNotEmpty) return list.first['skip_seconds'];
return 0;
}
Future<int> saveSkipSecondsStart(String id, int seconds) async {
@ -155,7 +158,8 @@ class DBHelper {
var dbClient = await database;
List<Map> list = await dbClient.rawQuery(
'SELECT skip_seconds_end FROM PodcastLocal WHERE id = ?', [id]);
return list.first['skip_seconds_end'];
if (list.isNotEmpty) return list.first['skip_seconds_end'];
return 0;
}
Future<int> saveSkipSecondsEnd(String id, int seconds) async {
@ -169,7 +173,8 @@ class DBHelper {
var dbClient = await database;
List<Map> list = await dbClient
.rawQuery('SELECT auto_download FROM PodcastLocal WHERE id = ?', [id]);
return list.first['auto_download'] == 1;
if (list.isNotEmpty) return list.first['auto_download'] == 1;
return false;
}
Future<int> saveAutoDownload(String id, {bool boo}) async {
@ -230,7 +235,7 @@ class DBHelper {
var dbClient = await database;
List<Map> list = await dbClient.rawQuery(
'SELECT background_image, hosts FROM PodcastLocal WHERE id = ?', [id]);
if (list.length > 0) {
if (list.isNotEmpty) {
var data = <String>[list.first['background_image'], list.first['hosts']];
return data;
}
@ -316,8 +321,11 @@ class DBHelper {
List<Map> list = await dbClient.rawQuery(
"SELECT SUM(listen_time) FROM PlayHistory WHERE enclosure_url = ?",
[url]);
i = list.first['SUM(listen_time)'];
return i ?? 0;
if (list.isEmpty) {
i = list.first['SUM(listen_time)'];
return i ?? 0;
}
return 0;
}
Future<int> markNotListened(String url) async {

View File

@ -44,6 +44,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
GlobalKey<RefreshIndicatorState>();
final GlobalKey<AudioPanelState> _playerKey = GlobalKey<AudioPanelState>();
final _dbHelper = DBHelper();
/// Episodes total count.
int _episodeCount;
@ -100,8 +101,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
}
Future _updateRssItem(BuildContext context, PodcastLocal podcastLocal) async {
var dbHelper = DBHelper();
final result = await dbHelper.updatePodcastRss(podcastLocal);
final result = await _dbHelper.updatePodcastRss(podcastLocal);
if (result >= 0) {
Fluttertoast.showToast(
msg: context.s.updateEpisodesCount(result),
@ -109,14 +109,14 @@ class _PodcastDetailState extends State<PodcastDetail> {
);
}
if (result > 0) {
var autoDownload = await dbHelper.getAutoDownload(podcastLocal.id);
var autoDownload = await _dbHelper.getAutoDownload(podcastLocal.id);
if (autoDownload) {
var downloader = Provider.of<DownloadState>(context, listen: false);
var result = await Connectivity().checkConnectivity();
var autoDownloadStorage = KeyValueStorage(autoDownloadNetworkKey);
var autoDownloadNetwork = await autoDownloadStorage.getInt();
if (autoDownloadNetwork == 1) {
var episodes = await dbHelper.getNewEpisodes(podcastLocal.id);
var episodes = await _dbHelper.getNewEpisodes(podcastLocal.id);
// For safety
if (episodes.length < 100) {
for (var episode in episodes) {
@ -124,7 +124,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
}
}
} else if (result == ConnectivityResult.wifi) {
var episodes = await dbHelper.getNewEpisodes(podcastLocal.id);
var episodes = await _dbHelper.getNewEpisodes(podcastLocal.id);
//For safety
if (episodes.length < 100) {
for (var episode in episodes) {
@ -144,9 +144,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
Future<List<EpisodeBrief>> _getRssItem(PodcastLocal podcastLocal,
{int count, bool reverse, Filter filter, String query}) async {
var dbHelper = DBHelper();
var episodes = <EpisodeBrief>[];
_episodeCount = await dbHelper.getPodcastCounts(podcastLocal.id);
_episodeCount = await _dbHelper.getPodcastCounts(podcastLocal.id);
var storage = KeyValueStorage(podcastLayoutKey);
var hideListenedStorage = KeyValueStorage(hideListenedKey);
var index = await storage.getInt(defaultValue: 1);
@ -154,7 +153,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
if (_hideListened == null) {
_hideListened = await hideListenedStorage.getBool(defaultValue: false);
}
episodes = await dbHelper.getRssItem(podcastLocal.id, count,
episodes = await _dbHelper.getRssItem(podcastLocal.id, count,
reverse: reverse,
filter: filter,
query: query,
@ -184,6 +183,13 @@ class _PodcastDetailState extends State<PodcastDetail> {
return hideListened;
}
Future<void> _checkPodcast() async {
final exist = await _dbHelper.checkPodcast(widget.podcastLocal.rssUrl);
if (exist == '') {
Navigator.of(context).pop();
}
}
Widget _podcastInfo(BuildContext context) {
return Container(
height: 170,
@ -356,7 +362,10 @@ class _PodcastDetailState extends State<PodcastDetail> {
context,
title: widget.podcastLocal.title,
child: PodcastSetting(podcastLocal: widget.podcastLocal),
).then((value) => setState(() {}));
).then((value) {
_checkPodcast();
setState(() {});
});
break;
}
},

View File

@ -16,7 +16,6 @@ import '../type/podcastlocal.dart';
import '../util/custom_widget.dart';
import '../util/duraiton_picker.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
enum MarkStatus { start, complete, none }
enum RefreshCoverStatus { start, complete, error, none }
@ -390,8 +389,8 @@ class _PodcastSettingState extends State<PodcastSetting> {
),
FlatButton(
splashColor: Colors.red.withAlpha(70),
onPressed: () {
groupList.removePodcast(widget.podcastLocal.id);
onPressed: () async {
await groupList.removePodcast(widget.podcastLocal.id);
Navigator.of(context).pop();
},
child:

View File

@ -12,8 +12,10 @@ import '../local_storage/sqflite_localpodcast.dart';
import '../state/podcast_group.dart';
import '../type/podcastlocal.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../util/pageroute.dart';
import 'podcast_detail.dart';
import 'podcast_settings.dart';
class AboutPodcast extends StatefulWidget {
final PodcastLocal podcastLocal;
@ -76,10 +78,9 @@ class _AboutPodcastState extends State<AboutPodcast> {
!_load
? Center()
: _description != null ? Html(data: _description) : Center(),
(widget.podcastLocal.author != null)
? Text(widget.podcastLocal.author,
style: TextStyle(color: Colors.blue))
: Center(),
if (widget.podcastLocal.author != null)
Text(widget.podcastLocal.author,
style: TextStyle(color: Colors.blue))
],
),
),
@ -93,7 +94,7 @@ class PodcastList extends StatefulWidget {
}
class _PodcastListState extends State<PodcastList> {
Future<List<PodcastLocal>> getPodcastLocal() async {
Future<List<PodcastLocal>> _getPodcastLocal() async {
var dbHelper = DBHelper();
var podcastList = await dbHelper.getPodcastLocalAll();
return podcastList;
@ -101,11 +102,11 @@ class _PodcastListState extends State<PodcastList> {
@override
Widget build(BuildContext context) {
var _width = MediaQuery.of(context).size.width;
final width = context.width;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
systemNavigationBarColor: Theme.of(context).primaryColor,
systemNavigationBarColor: context.primaryColor,
systemNavigationBarIconBrightness:
Theme.of(context).accentColorBrightness,
),
@ -116,13 +117,12 @@ class _PodcastListState extends State<PodcastList> {
),
body: SafeArea(
child: Container(
color: Theme.of(context).primaryColor,
color: context.primaryColor,
child: FutureBuilder<List<PodcastLocal>>(
future: getPodcastLocal(),
future: _getPodcastLocal(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(10.0),
@ -144,62 +144,40 @@ class _PodcastListState extends State<PodcastList> {
)),
);
},
onLongPress: () {
showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel:
MaterialLocalizations.of(context)
.modalBarrierDismissLabel,
barrierColor: Colors.black54,
transitionDuration:
const Duration(milliseconds: 200),
pageBuilder: (context, animaiton,
secondaryAnimation) =>
AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarIconBrightness:
Brightness.light,
systemNavigationBarColor:
Theme.of(context)
.brightness ==
Brightness.light
? Color.fromRGBO(
113, 113, 113, 1)
: Color.fromRGBO(
15, 15, 15, 1),
),
child: AboutPodcast(
podcastLocal:
snapshot.data[index]),
));
onLongPress: () async {
generalSheet(
context,
title: snapshot.data[index].title,
child: PodcastSetting(
podcastLocal: snapshot.data[index]),
).then((value) {
if (mounted) setState(() {});
});
},
child: Container(
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
SizedBox(
height: 10.0,
),
ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(_width / 8)),
borderRadius:
BorderRadius.circular(width / 8),
child: Container(
height: _width / 4,
width: _width / 4,
height: width / 4,
width: width / 4,
child: Image.file(File(
"${snapshot.data[index].imagePath}")),
),
),
Container(
padding: EdgeInsets.all(4.0),
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
snapshot.data[index].title,
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.bodyText1,
style: context.textTheme.bodyText1,
maxLines: 2,
),
),
@ -215,7 +193,12 @@ class _PodcastListState extends State<PodcastList> {
],
);
}
return Text('NoData');
return Center(
child: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator()),
);
},
),
),

View File

@ -33,45 +33,46 @@ Future generalDialog(BuildContext context,
Future generalSheet(BuildContext context, {Widget child, String title}) async =>
await showModalBottomSheet(
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0)),
),
elevation: 2,
context: context,
builder: (context) {
return SafeArea(
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 10.0, bottom: 2.0),
child: Container(
height: 4,
width: 25,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2.0),
color: context.primaryColorDark),
),
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0)),
),
elevation: 2,
context: context,
builder: (context) {
return SafeArea(
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 10.0, bottom: 2.0),
child: Container(
height: 4,
width: 25,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2.0),
color: context.primaryColorDark),
),
Padding(
padding: EdgeInsets.only(
left: 50, right: 50, top: 6.0, bottom: 15),
child: Text(
title,
style: context.textTheme.headline6,
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.clip,
),
),
Padding(
padding: EdgeInsets.only(
left: 50, right: 50, top: 6.0, bottom: 15),
child: Text(
title,
style: context.textTheme.headline6,
textAlign: TextAlign.center,
maxLines: 1,
overflow: TextOverflow.clip,
),
Divider(height: 1),
child,
],
),
),
Divider(height: 1),
child,
],
),
);
});
),
);
},
);