Minor change.

This commit is contained in:
stonega 2020-10-30 20:35:02 +08:00
parent fe36c06a38
commit e2aa75ee02
43 changed files with 234 additions and 494 deletions

View File

@ -1,7 +1,6 @@
[![Tsacdop Banner][]][google play]
[![github action][]][github action link]
[![Build Status - Cirrus][]][build status]
[![GitHub Release][]][github release - recent]
[![Github Downloads][]][github release - recent]
[![Localizely][]][localizely - website]

View File

@ -45,9 +45,8 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.stonegate.tsacdop"
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -16,8 +16,8 @@ import '../state/audio_state.dart';
import '../state/setting_state.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../util/audiopanel.dart';
import '../util/custom_widget.dart';
import '../widgets/audiopanel.dart';
import '../widgets/custom_widget.dart';
import '../util/extension_helper.dart';
import 'episode_download.dart';

View File

@ -8,15 +8,15 @@ import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import '../local_storage/key_value_storage.dart';
import '../local_storage/key_value_storage.dart';
import '../state/audio_state.dart';
import '../state/download_state.dart';
import '../type/episode_task.dart';
import '../type/episodebrief.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../widgets/custom_widget.dart';
import '../widgets/general_dialog.dart';
class DownloadButton extends StatefulWidget {
final EpisodeBrief episode;

View File

@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:line_icons/line_icons.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
const String version = '0.5.0';

View File

@ -15,11 +15,11 @@ import '../local_storage/sqflite_localpodcast.dart';
import '../state/audio_state.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../util/audiopanel.dart';
import '../util/custom_slider.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/pageroute.dart';
import '../widgets/audiopanel.dart';
import '../widgets/custom_slider.dart';
import '../widgets/custom_widget.dart';
import 'playlist.dart';
final List<BoxShadow> _customShadow = [

View File

@ -4,12 +4,11 @@ import 'dart:io';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:feature_discovery/feature_discovery.dart';
import 'package:flutter/material.dart' hide NestedScrollView;
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart';
import 'package:tsacdop/podcasts/podcast_detail.dart';
import 'package:tsacdop/util/pageroute.dart';
import 'package:tuple/tuple.dart';
import '../local_storage/key_value_storage.dart';
@ -21,12 +20,13 @@ import '../state/refresh_podcast.dart';
import '../state/setting_state.dart';
import '../type/episodebrief.dart';
import '../type/playlist.dart';
import '../util/audiopanel.dart';
import '../util/custom_popupmenu.dart';
import '../util/custom_widget.dart';
import '../util/episodegrid.dart';
import '../util/extension_helper.dart';
import '../util/muiliselect_bar.dart';
import '../widgets/audiopanel.dart';
import '../widgets/custom_popupmenu.dart';
import '../widgets/custom_widget.dart';
import '../widgets/episodegrid.dart';
import '../widgets/feature_discovery.dart';
import '../widgets/muiliselect_bar.dart';
import 'audioplayer.dart';
import 'download_list.dart';
import 'home_groups.dart';
@ -35,13 +35,6 @@ import 'import_ompl.dart';
import 'playlist.dart';
import 'search_podcast.dart';
const String addFeature = 'addFeature';
const String menuFeature = 'menuFeature';
const String playlistFeature = 'playlistFeature';
const String longTapFeature = 'longTapFeature';
const String groupsFeature = 'groupsFeature';
const String podcastFeature = 'podcastFeature';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
@ -67,24 +60,24 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
@override
void initState() {
super.initState();
_controller = TabController(length: 3, vsync: this);
FeatureDiscovery.isDisplayed(context, addFeature).then((value) {
if (!value) {
WidgetsBinding.instance.addPostFrameCallback((_) {
FeatureDiscovery.discoverFeatures(
context,
const <String>{
addFeature,
menuFeature,
playlistFeature,
groupsFeature,
podcastFeature,
},
);
});
}
// FeatureDiscovery.hasPreviouslyCompleted(context, addFeature).then((value) {
// if (!value) {
SchedulerBinding.instance.addPostFrameCallback((_) {
FeatureDiscovery.discoverFeatures(
context,
const <String>{
addFeature,
menuFeature,
playlistFeature,
//groupsFeature,
//podcastFeature,
},
);
});
// }
// });
super.initState();
}
@override
@ -144,58 +137,21 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
DescribedFeatureOverlay(
featureDiscoveryOverlay(
context,
featureId: addFeature,
tapTarget:
Icon(Icons.add_circle_outline),
title: Text(s.featureDiscoverySearch),
title: s.featureDiscoverySearch,
backgroundColor: Colors.cyan[600],
overflowMode: feature1OverflowMode,
onDismiss: () {
return Future.value(true);
},
description: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(s.featureDiscoverySearchDes),
FlatButton(
color: Colors.cyan[500],
padding:
const EdgeInsets.all(0),
child: Text(s.understood,
style: context
.textTheme.button
.copyWith(
color:
Colors.white)),
onPressed: () async =>
FeatureDiscovery
.completeCurrentStep(
context),
),
FlatButton(
color: Colors.cyan[500],
padding:
const EdgeInsets.all(0),
child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color:
Colors.white)),
onPressed: () =>
FeatureDiscovery.dismissAll(
context),
),
],
),
buttonColor: Colors.cyan[500],
description:
s.featureDiscoverySearchDes,
child: IconButton(
tooltip: s.add,
splashRadius: 25,
icon: const Icon(
Icons.add_circle_outline),
icon:
Icon(Icons.add_circle_outline),
onPressed: () async {
await showSearch<int>(
context: context,
@ -225,49 +181,14 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
height: 30,
),
),
DescribedFeatureOverlay(
featureDiscoveryOverlay(context,
featureId: menuFeature,
tapTarget: Icon(Icons.more_vert),
backgroundColor: Colors.cyan[500],
onDismiss: () => Future.value(true),
title: Text(s.featureDiscoveryOMPL),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: <Widget>[
Text(s.featureDiscoveryOMPLDes),
FlatButton(
color: Colors.cyan[600],
padding: EdgeInsets.zero,
child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color: Colors
.white)),
onPressed: () async =>
FeatureDiscovery
.completeCurrentStep(
context),
),
FlatButton(
color: Colors.cyan[600],
padding:
const EdgeInsets.all(0),
child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color: Colors
.white)),
onPressed: () =>
FeatureDiscovery
.dismissAll(context),
),
],
),
buttonColor: Colors.cyan[600],
title: s.featureDiscoveryOMPL,
description:
s.featureDiscoveryOMPLDes,
child: PopupMenu()),
],
),
@ -276,68 +197,11 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
],
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return DescribedFeatureOverlay(
featureId: groupsFeature,
tapTarget: Center(
child: Text(
s.featureDiscoveryPodcast,
textAlign: TextAlign.center,
)),
backgroundColor: Colors.cyan[500],
enablePulsingAnimation: false,
onDismiss: () => Future.value(true),
title: Text(s.featureDiscoveryPodcastTitle),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(s.featureDiscoveryPodcastDes),
Row(
children: [
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color: Colors.white)),
onPressed: () async =>
FeatureDiscovery
.completeCurrentStep(
context),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 5)),
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.dismiss,
style: context
.textTheme.button
.copyWith(
color: Colors.white)),
onPressed: () =>
FeatureDiscovery.dismissAll(
context),
),
],
),
],
),
child: SizedBox(
height: height,
width: width,
child: ScrollPodcasts(),
),
);
},
childCount: 1,
SliverToBoxAdapter(
child: SizedBox(
height: height,
width: width,
child: ScrollPodcasts(),
),
),
SliverPersistentHeader(
@ -368,57 +232,7 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
controller: _controller,
children: <Widget>[
NestedScrollViewInnerScrollPositionKeyWidget(
Key('tab0'),
DescribedFeatureOverlay(
featureId: podcastFeature,
tapTarget: Text(s.featureDiscoveryEpisode,
textAlign: TextAlign.center),
backgroundColor: Colors.cyan[500],
enablePulsingAnimation: false,
onDismiss: () => Future.value(true),
title: Text(s.featureDiscoveryEpisodeTitle),
description: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(s.featureDiscoveryEpisodeDes),
Row(
children: [
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color: Colors.white)),
onPressed: () async =>
FeatureDiscovery
.completeCurrentStep(
context),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 5)),
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(
color: Colors.white)),
onPressed: () =>
FeatureDiscovery.dismissAll(
context),
),
],
),
],
),
child: _RecentUpdate())),
Key('tab0'), _RecentUpdate()),
NestedScrollViewInnerScrollPositionKeyWidget(
Key('tab1'), _MyFavorite()),
NestedScrollViewInnerScrollPositionKeyWidget(
@ -469,39 +283,13 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
children: <Widget>[
_tabBar,
Spacer(),
DescribedFeatureOverlay(
featureDiscoveryOverlay(context,
featureId: playlistFeature,
tapTarget: Icon(Icons.playlist_play),
backgroundColor: Colors.cyan[500],
title: Text(s.featureDiscoveryPlaylist),
onDismiss: () => Future.value(true),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(s.featureDiscoveryPlaylistDes),
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () async =>
FeatureDiscovery.completeCurrentStep(context),
),
FlatButton(
color: Colors.cyan[600],
padding: const EdgeInsets.all(0),
child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () => FeatureDiscovery.dismissAll(context),
),
],
),
title: s.featureDiscoveryPlaylist,
description: s.featureDiscoveryPlaylistDes,
buttonColor: Colors.cyan[600],
child: _PlaylistButton()),
],
),
@ -895,20 +683,6 @@ class _RecentUpdateState extends State<_RecentUpdate>
}),
)
: Center();
// Material(
// color: Colors.transparent,
// child: IconButton(
// tooltip: s.addNewEpisodeTooltip,
// icon: SizedBox(
// height: 15,
// width: 20,
// child: CustomPaint(
// painter: AddToPlaylistPainter(
// context.textColor,
// context.textColor,
// ))),
// onPressed: () {}),
// );
});
}

View File

@ -24,10 +24,10 @@ import '../state/podcast_group.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../type/podcastlocal.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../util/pageroute.dart';
import '../widgets/custom_widget.dart';
import '../widgets/general_dialog.dart';
class ScrollPodcasts extends StatefulWidget {
@override

View File

@ -11,8 +11,8 @@ import '../state/audio_state.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../type/playlist.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
enum InitPage { playlist, history }

View File

@ -7,8 +7,8 @@ import '../service/search_api.dart';
import '../state/search_state.dart';
import '../type/search_api/search_genre.dart';
import '../type/search_api/searchpodcast.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
import 'search_podcast.dart';
class DiscoveryPage extends StatefulWidget {

View File

@ -16,8 +16,8 @@ import '../state/podcast_group.dart';
import '../state/search_state.dart';
import '../type/search_api/searchepisodes.dart';
import '../type/search_api/searchpodcast.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
import 'pocast_discovery.dart';
class MyHomePageDelegate extends SearchDelegate<int> {

View File

@ -91,7 +91,7 @@ class DBHelper {
list = await dbClient.rawQuery(
"""SELECT id, title, imageUrl, rssUrl, primaryColor, author, imagePath , provider,
link ,update_count, episode_count FROM PodcastLocal WHERE id = ? AND
never_update = 1""", [s]);
never_update = 0""", [s]);
} else {
list = await dbClient.rawQuery(
"""SELECT id, title, imageUrl, rssUrl, primaryColor, author, imagePath , provider,

View File

@ -67,7 +67,9 @@ class MyApp extends StatelessWidget {
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
home: setting.showIntro ? SlideIntro(goto: Goto.home) : Home(),
home: setting.showIntro
? SlideIntro(goto: Goto.home)
: FeatureDiscovery(child: Home()),
),
);
},

View File

@ -22,12 +22,12 @@ import '../state/download_state.dart';
import '../type/episodebrief.dart';
import '../type/fireside_data.dart';
import '../type/podcastlocal.dart';
import '../util/audiopanel.dart';
import '../util/custom_widget.dart';
import '../util/episodegrid.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../util/muiliselect_bar.dart';
import '../widgets/audiopanel.dart';
import '../widgets/custom_widget.dart';
import '../widgets/episodegrid.dart';
import '../widgets/general_dialog.dart';
import '../widgets/muiliselect_bar.dart';
import 'podcast_settings.dart';
class PodcastDetail extends StatefulWidget {
@ -363,8 +363,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
width: 30,
height: 30,
decoration: BoxDecoration(
color: widget.podcastLocal
.backgroudColor(context)
color: widget.podcastLocal.primaryColor
.colorizedark()
.withOpacity(0.6),
shape: BoxShape.circle,
),

View File

@ -11,9 +11,9 @@ import 'package:provider/provider.dart';
import '../local_storage/sqflite_localpodcast.dart';
import '../state/podcast_group.dart';
import '../type/podcastlocal.dart';
import '../util/duraiton_picker.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../widgets/duraiton_picker.dart';
import '../widgets/general_dialog.dart';
class PodcastGroupList extends StatefulWidget {
final PodcastGroup group;

View File

@ -9,18 +9,15 @@ import 'package:line_icons/line_icons.dart';
import 'package:provider/provider.dart';
import '../state/podcast_group.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../util/pageroute.dart';
import '../widgets/custom_widget.dart';
import '../widgets/feature_discovery.dart';
import '../widgets/general_dialog.dart';
import 'custom_tabview.dart';
import 'podcast_group.dart';
import 'podcastlist.dart';
const String addGroupFeature = 'addGroupFeature';
const String configureGroup = 'configureFeature';
const String configurePodcast = 'configurePodcast';
class PodcastManage extends StatefulWidget {
@override
_PodcastManageState createState() => _PodcastManageState();
@ -67,16 +64,9 @@ class _PodcastManageState extends State<PodcastManage>
_controller.stop();
}
});
FeatureDiscovery.isDisplayed(context, addGroupFeature).then((value) {
if (!value) {
WidgetsBinding.instance.addPostFrameCallback((_) {
FeatureDiscovery.discoverFeatures(context, const <String>{
addGroupFeature,
configureGroup,
configurePodcast
});
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
FeatureDiscovery.discoverFeatures(context,
const <String>{addGroupFeature, configureGroup, configurePodcast});
});
}
@ -96,46 +86,19 @@ class _PodcastManageState extends State<PodcastManage>
} else if (_fraction > 0) {
_controller.reverse();
}
return DescribedFeatureOverlay(
return featureDiscoveryOverlay(
context,
featureId: configureGroup,
tapTarget: Icon(Icons.menu),
title: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: Text(s.featureDiscoveryEditGroup),
),
overflowMode: OverflowMode.clipContent,
title: s.featureDiscoveryEditGroup,
backgroundColor: Colors.cyan[600],
onDismiss: () => Future.value(true),
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(s.featureDiscoveryEditGroupDes),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () async =>
FeatureDiscovery.completeCurrentStep(context),
),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () => FeatureDiscovery.dismissAll(context),
),
],
),
description: s.featureDiscoveryEditGroupDes,
buttonColor: Colors.cyan[500],
child: Transform(
alignment: FractionalOffset(0.5, 0.5),
transform: Matrix4.rotationY(math.pi * _fraction),
alignment: FractionalOffset.center,
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(math.pi * _fraction),
child: InkWell(
onTap: () async {
if (_fraction == 0) {
@ -206,41 +169,16 @@ class _PodcastManageState extends State<PodcastManage>
title: Text(context.s.groups(2)),
leading: CustomBackButton(),
actions: <Widget>[
DescribedFeatureOverlay(
featureDiscoveryOverlay(
context,
featureId: addGroupFeature,
tapTarget: Icon(Icons.add),
title: Text(s.featureDiscoveryGroup),
overflowMode: OverflowMode.clipContent,
title: s.featureDiscoveryGroup,
backgroundColor: Colors.cyan[600],
onDismiss: () => Future.value(true),
description: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(s.featureDiscoveryGroupDes),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(context.s.understood,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () async =>
FeatureDiscovery.completeCurrentStep(context),
),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(context.s.dismiss,
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white)),
onPressed: () => FeatureDiscovery.dismissAll(context),
),
],
),
description: s.featureDiscoveryGroupDes,
buttonColor: Colors.cyan[500],
child: IconButton(
splashRadius: 25,
onPressed: () => showGeneralDialog(
context: context,
barrierDismissible: true,
@ -288,39 +226,14 @@ class _PodcastManageState extends State<PodcastManage>
)),
),
pageBuilder: (context, index) =>
DescribedFeatureOverlay(
featureDiscoveryOverlay(
context,
featureId: configurePodcast,
tapTarget: Text(s.podcast(1)),
title: Text(s.featureDiscoveryGroupPodcast),
overflowMode: OverflowMode.clipContent,
onDismiss: () => Future.value(true),
enablePulsingAnimation: false,
title: s.featureDiscoveryGroupPodcast,
backgroundColor: Colors.cyan[600],
description: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(s.featureDiscoveryGroupPodcastDes),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(context.s.understood,
style: context.textTheme.button
.copyWith(color: Colors.white)),
onPressed: () async =>
FeatureDiscovery.completeCurrentStep(
context),
),
FlatButton(
color: Colors.cyan[500],
padding: const EdgeInsets.all(0),
child: Text(context.s.dismiss,
style: context.textTheme.button
.copyWith(color: Colors.white)),
onPressed: () =>
FeatureDiscovery.dismissAll(context),
),
],
),
buttonColor: Colors.cyan[500],
description: s.featureDiscoveryGroupPodcastDes,
child: Container(
key: ValueKey<String>(_groups[index].name),
child:
@ -525,9 +438,8 @@ class _OrderMenu extends StatelessWidget {
Widget build(BuildContext context) {
final s = context.s;
return PopupMenuButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 1,
tooltip: s.menu,
itemBuilder: (context) => [
PopupMenuItem(
@ -589,13 +501,11 @@ class _AddGroupState extends State<AddGroup> {
: Color.fromRGBO(5, 5, 5, 1),
),
child: AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 1,
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
titlePadding:
const EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 20),
actionsPadding: EdgeInsets.all(0),
contentPadding: EdgeInsets.symmetric(horizontal: 20),
titlePadding: EdgeInsets.all(20),
actionsPadding: EdgeInsets.zero,
actions: <Widget>[
FlatButton(
splashColor: context.accentColor.withAlpha(70),
@ -630,12 +540,12 @@ class _AddGroupState extends State<AddGroup> {
hintStyle: TextStyle(fontSize: 18),
filled: true,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor, width: 2.0),
borderSide:
BorderSide(color: context.accentColor, width: 2.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor, width: 2.0),
borderSide:
BorderSide(color: context.accentColor, width: 2.0),
),
),
cursorRadius: Radius.circular(2),

View File

@ -13,9 +13,9 @@ import '../local_storage/sqflite_localpodcast.dart';
import '../state/podcast_group.dart';
import '../type/play_histroy.dart';
import '../type/podcastlocal.dart';
import '../util/custom_widget.dart';
import '../util/duraiton_picker.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
import '../widgets/duraiton_picker.dart';
enum MarkStatus { start, complete, none }
enum RefreshCoverStatus { start, complete, error, none }

View File

@ -11,10 +11,10 @@ import 'package:provider/provider.dart';
import '../local_storage/sqflite_localpodcast.dart';
import '../state/podcast_group.dart';
import '../type/podcastlocal.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../util/pageroute.dart';
import '../widgets/custom_widget.dart';
import '../widgets/general_dialog.dart';
import 'podcast_detail.dart';
import 'podcast_settings.dart';

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'package:confetti/confetti.dart';
import 'package:device_info/device_info.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/gestures.dart';
@ -10,7 +11,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:line_icons/line_icons.dart';
import 'package:confetti/confetti.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
@ -23,8 +23,8 @@ import '../service/opml_build.dart';
import '../state/podcast_group.dart';
import '../state/setting_state.dart';
import '../type/settings_backup.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
class DataBackup extends StatefulWidget {
@override

View File

@ -11,8 +11,8 @@ import 'package:provider/provider.dart';
import '../local_storage/sqflite_localpodcast.dart';
import '../state/download_state.dart';
import '../type/episodebrief.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
class DownloadsManage extends StatefulWidget {
@override

View File

@ -15,8 +15,8 @@ import '../state/podcast_group.dart';
import '../type/play_histroy.dart';
import '../type/search_api/searchpodcast.dart';
import '../type/sub_history.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
class PlayedHistory extends StatefulWidget {
@override

View File

@ -5,10 +5,10 @@ import 'package:provider/provider.dart';
import '../local_storage/key_value_storage.dart';
import '../service/search_api.dart';
import '../state/audio_state.dart';
import '../util/custom_dropdown.dart';
import '../util/custom_widget.dart';
import '../util/episodegrid.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_dropdown.dart';
import '../widgets/custom_widget.dart';
import '../widgets/episodegrid.dart';
import 'popup_menu.dart';
class LayoutSetting extends StatefulWidget {

View File

@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
import 'licenses.dart';
class Libries extends StatelessWidget {

View File

@ -10,10 +10,10 @@ import '../home/audioplayer.dart';
import '../local_storage/key_value_storage.dart';
import '../state/audio_state.dart';
import '../state/setting_state.dart';
import '../util/custom_dropdown.dart';
import '../util/custom_time_picker.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_dropdown.dart';
import '../widgets/custom_time_picker.dart';
import '../widgets/custom_widget.dart';
const List kSecondsToSelect = [5, 10, 15, 20, 25, 30, 45, 60];
const List<double> kSpeedToSelect = [

View File

@ -4,8 +4,8 @@ import 'package:flutter/services.dart';
import 'package:line_icons/line_icons.dart';
import '../local_storage/key_value_storage.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_widget.dart';
class PopupMenuSetting extends StatefulWidget {
const PopupMenuSetting({Key key}) : super(key: key);

View File

@ -4,12 +4,11 @@ import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:line_icons/line_icons.dart';
import '../home/home.dart';
import '../intro_slider/app_intro.dart';
import '../podcasts/podcast_manage.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../widgets/custom_widget.dart';
import '../widgets/feature_discovery.dart';
import '../widgets/general_dialog.dart';
import 'data_backup.dart';
import 'history.dart';
import 'languages.dart';
@ -219,7 +218,7 @@ class _SettingsState extends State<Settings> {
),
ListTile(
onTap: () {
FeatureDiscovery.clearPreferences(context, const <String>{
FeatureDiscovery.clearPreferences(context, <String>{
addFeature,
menuFeature,
playlistFeature,

View File

@ -7,10 +7,10 @@ import 'package:provider/provider.dart';
import '../local_storage/key_value_storage.dart';
import '../settings/downloads_manage.dart';
import '../state/setting_state.dart';
import '../util/custom_dropdown.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../widgets/custom_dropdown.dart';
import '../widgets/custom_widget.dart';
import '../widgets/general_dialog.dart';
class StorageSetting extends StatefulWidget {
@override

View File

@ -4,9 +4,9 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import '../state/setting_state.dart';
import '../util/custom_dropdown.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../widgets/custom_dropdown.dart';
import '../widgets/custom_widget.dart';
class SyncingSetting extends StatelessWidget {
@override

View File

@ -3,9 +3,9 @@ import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import '../state/setting_state.dart';
import '../util/custom_widget.dart';
import '../util/extension_helper.dart';
import '../util/general_dialog.dart';
import '../widgets/custom_widget.dart';
import '../widgets/general_dialog.dart';
class ThemeSetting extends StatelessWidget {
@override

View File

@ -21,7 +21,7 @@ void callbackDispatcher() {
if (Platform.isAndroid) {
Workmanager.executeTask((task, inputData) async {
var dbHelper = DBHelper();
var podcastList = await dbHelper.getPodcastLocalAll(updateOnly: false);
var podcastList = await dbHelper.getPodcastLocalAll(updateOnly: true);
//lastWork is a indicator for if the app was opened since last backgroundwork
//if the app wes opend,then the old marked new episode would be marked not new.
var lastWorkStorage = KeyValueStorage(lastWorkKey);
@ -107,6 +107,26 @@ class SettingState extends ChangeNotifier {
await _getRealDark();
}
@override
void addListener(VoidCallback listener) {
super.addListener(listener);
_getLocale();
_getAutoUpdate();
_getDownloadUsingData();
_getSleepTimerData();
_getPlayerSeconds();
_getShowNotesFonts();
_getUpdateInterval().then((value) async {
if (_initUpdateTag == 0) {
setWorkManager(24);
} else if (_autoUpdate && _initialShowIntor < 3) {
await cancelWork();
setWorkManager(_initUpdateTag);
await saveShowIntro(3);
}
});
}
Locale _locale;
/// Load locale.
@ -301,26 +321,6 @@ class SettingState extends ChangeNotifier {
_saveShowNotesFonts();
}
@override
void addListener(VoidCallback listener) {
super.addListener(listener);
_getLocale();
_getAutoUpdate();
_getDownloadUsingData();
_getSleepTimerData();
_getPlayerSeconds();
_getShowNotesFonts();
_getUpdateInterval().then((value) async {
if (_initUpdateTag == 0) {
setWorkManager(24);
} else if (_autoUpdate && _initialShowIntor == 1) {
await cancelWork();
setWorkManager(_initUpdateTag);
await saveShowIntro(2);
}
});
}
Future _getTheme() async {
var mode = await themeStorage.getInt();
_theme = ThemeMode.values[mode];
@ -358,7 +358,7 @@ class SettingState extends ChangeNotifier {
Future _getShowIntro() async {
_initialShowIntor = await introStorage.getInt();
_showIntro = _initialShowIntor == 0 ? true : false;
_showIntro = _initialShowIntor == 0;
}
Future _getRealDark() async {
@ -616,7 +616,7 @@ class SettingState extends ChangeNotifier {
if (_autoUpdate) {
await cancelWork();
setWorkManager(_initUpdateTag);
await saveShowIntro(2);
await saveShowIntro(3);
}
});
}

View File

@ -2,7 +2,7 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'extension_helper.dart';
import '../util/extension_helper.dart';
enum SlideDirection { up, down }

View File

@ -3,8 +3,8 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import '../type/episodebrief.dart';
import '../util/extension_helper.dart';
import 'episodegrid.dart';
import 'extension_helper.dart';
const kTwoPi = math.pi * 2;
const kPi = math.pi;

View File

@ -22,11 +22,11 @@ import '../state/download_state.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../type/podcastlocal.dart';
import '../util/extension_helper.dart';
import '../util/open_container.dart';
import '../util/pageroute.dart';
import 'custom_widget.dart';
import 'extension_helper.dart';
import 'general_dialog.dart';
import 'open_container.dart';
import 'pageroute.dart';
enum Layout { three, two, one }

View File

@ -0,0 +1,57 @@
import 'package:feature_discovery/feature_discovery.dart';
import 'package:flutter/material.dart';
import '../util/extension_helper.dart';
const String addFeature = 'addFeature';
const String menuFeature = 'menuFeature';
const String playlistFeature = 'playlistFeature';
const String longTapFeature = 'longTapFeature';
const String groupsFeature = 'groupsFeature';
const String podcastFeature = 'podcastFeature';
const String addGroupFeature = 'addGroupFeature';
const String configureGroup = 'configureFeature';
const String configurePodcast = 'configurePodcast';
Widget featureDiscoveryOverlay(BuildContext context,
{String featureId,
Color buttonColor,
Color backgroundColor,
Widget child,
Widget tapTarget,
String title,
String description}) {
final s = context.s;
return DescribedFeatureOverlay(
featureId: featureId,
tapTarget: tapTarget,
title: Text(title),
backgroundColor: backgroundColor,
overflowMode: OverflowMode.clipContent,
onDismiss: () {
return Future.value(true);
},
description: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(description),
FlatButton(
color: buttonColor,
padding: EdgeInsets.zero,
child: Text(s.understood,
style: context.textTheme.button.copyWith(color: Colors.white)),
onPressed: () async =>
FeatureDiscovery.completeCurrentStep(context),
),
FlatButton(
color: buttonColor,
padding: EdgeInsets.zero,
child: Text(s.dismiss,
style: context.textTheme.button.copyWith(color: Colors.white)),
onPressed: () => FeatureDiscovery.dismissAll(context),
),
],
),
child: child);
}

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'extension_helper.dart';
import '../util/extension_helper.dart';
Future generalDialog(BuildContext context,
{Widget title, Widget content, List<Widget> actions}) async =>

View File

@ -10,8 +10,8 @@ import '../state/audio_state.dart';
import '../state/download_state.dart';
import '../type/episodebrief.dart';
import '../type/play_histroy.dart';
import '../util/extension_helper.dart';
import 'custom_widget.dart';
import 'extension_helper.dart';
import 'general_dialog.dart';
class MultiSelectMenuBar extends StatefulWidget {

View File

@ -12,8 +12,8 @@ dependencies:
flutter_localizations:
sdk: flutter
auto_animated: ^2.1.0
audio_session: ^0.0.8
cached_network_image: ^2.3.2+1
audio_session: ^0.0.9
cached_network_image: ^2.3.3
color_thief_flutter: ^1.0.2
confetti: ^0.5.4+1
cookie_jar: ^1.0.1
@ -27,10 +27,10 @@ dependencies:
extended_nested_scroll_view: ^1.0.1
effective_dart: ^1.2.4
equatable: ^1.2.5
feature_discovery: ^0.10.0
file_picker: ^2.0.7
feature_discovery: ^0.12.1
file_picker: ^2.0.11
flutter_html: ^0.11.1
flutter_downloader: ^1.5.1
flutter_downloader: ^1.5.2
fluttertoast: ^4.0.0
flutter_isolate: ^1.0.0+14
flutter_linkify: ^3.1.3
@ -38,24 +38,24 @@ dependencies:
flare_flutter: ^2.0.6
fl_chart: ^0.12.0
marquee: ^1.6.1
google_fonts: ^1.1.0
google_fonts: ^1.1.1
image: ^2.1.18
intl: ^0.16.1
json_serializable: ^3.5.0
json_annotation: ^3.1.0
path_provider: ^1.6.18
path_provider: ^1.6.22
permission_handler: ^5.0.1
provider: ^4.3.2
rxdart: ^0.24.1
sqflite: ^1.3.1+1
sqflite: ^1.3.2+1
shared_preferences: ^0.5.12
tuple: ^1.0.3
url_launcher: ^5.7.2
url_launcher: ^5.7.8
uuid: ^2.2.2
xml: ^4.2.0
workmanager: ^0.2.3
wc_flutter_share: ^0.2.2
audio_service: ^0.15.1
audio_service: ^0.15.2
just_audio:
git:
url: https://github.com/stonega/just_audio.git