mirror of
https://github.com/stonega/tsacdop
synced 2025-02-18 04:20:37 +01:00
modified: lib/class/settingstate.dart
modified: lib/episodes/episodedetail.dart modified: lib/home/appbar/about.dart modified: lib/home/appbar/addpodcast.dart modified: lib/home/appbar/importompl.dart modified: lib/home/appbar/popupmenu.dart modified: lib/home/audio_player.dart modified: lib/home/audiopanel.dart modified: lib/home/homescroll.dart modified: lib/home/hometab.dart modified: lib/local_storage/key_value_storage.dart modified: lib/main.dart modified: lib/podcasts/podcastdetail.dart modified: lib/podcasts/podcastgroup.dart modified: lib/podcasts/podcastlist.dart modified: lib/podcasts/podcastmanage.dart modified: lib/util/episodegrid.dart
This commit is contained in:
parent
9d4bbc895a
commit
7ba0552717
@ -1,13 +1,30 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
//two types podcast update, backhome nedd to back to default grooup.
|
||||
enum Update {backhome, justupdate}
|
||||
class SettingState extends ChangeNotifier{
|
||||
Update _subscribeupdate;
|
||||
Update get subscribeupdate => _subscribeupdate;
|
||||
set subscribeUpdate(Update s){
|
||||
_subscribeupdate = s;
|
||||
import 'package:tsacdop/local_storage/key_value_storage.dart';
|
||||
|
||||
class SettingState extends ChangeNotifier {
|
||||
KeyValueStorage storage = KeyValueStorage('themes');
|
||||
int _theme;
|
||||
|
||||
int get theme => _theme;
|
||||
void setTheme(int theme) {
|
||||
_theme = theme;
|
||||
notifyListeners();
|
||||
_saveTheme(theme);
|
||||
}
|
||||
|
||||
@override
|
||||
void addListener(VoidCallback listener) {
|
||||
super.addListener(listener);
|
||||
_getTheme();
|
||||
}
|
||||
|
||||
_getTheme() async {
|
||||
_theme = await storage.getTheme();
|
||||
}
|
||||
|
||||
_saveTheme(theme) async {
|
||||
await storage.saveTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@ -15,8 +16,7 @@ import 'episodedownload.dart';
|
||||
class EpisodeDetail extends StatefulWidget {
|
||||
final EpisodeBrief episodeItem;
|
||||
final String heroTag;
|
||||
EpisodeDetail({this.episodeItem, this.heroTag, Key key})
|
||||
: super(key: key);
|
||||
EpisodeDetail({this.episodeItem, this.heroTag, Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_EpisodeDetailState createState() => _EpisodeDetailState();
|
||||
@ -53,16 +53,21 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey[100],
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
appBar: AppBar(
|
||||
title: Text(widget.episodeItem.feedTitle),
|
||||
elevation: 0.0,
|
||||
centerTitle: true,
|
||||
backgroundColor: Colors.grey[100],
|
||||
),
|
||||
body: Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@ -87,7 +92,9 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
height: 30.0,
|
||||
child: Text(
|
||||
'Published ' +
|
||||
DateFormat.yMMMd().format( DateTime.fromMillisecondsSinceEpoch(widget.episodeItem.pubDate)),
|
||||
DateFormat.yMMMd().format(
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
widget.episodeItem.pubDate)),
|
||||
style: TextStyle(color: Colors.blue[500])),
|
||||
),
|
||||
Container(
|
||||
@ -117,7 +124,8 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
(widget.episodeItem.duration).toString() + 'mins',
|
||||
(widget.episodeItem.duration).toString() +
|
||||
'mins',
|
||||
style: textstyle),
|
||||
),
|
||||
Container(
|
||||
@ -130,7 +138,8 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
((widget.episodeItem.enclosureLength) ~/ 1000000)
|
||||
((widget.episodeItem.enclosureLength) ~/
|
||||
1000000)
|
||||
.toString() +
|
||||
'MB',
|
||||
style: textstyle),
|
||||
@ -168,6 +177,8 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -175,8 +186,7 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||
class MenuBar extends StatefulWidget {
|
||||
final EpisodeBrief episodeItem;
|
||||
final String heroTag;
|
||||
MenuBar({this.episodeItem, this.heroTag, Key key})
|
||||
: super(key: key);
|
||||
MenuBar({this.episodeItem, this.heroTag, Key key}) : super(key: key);
|
||||
@override
|
||||
_MenuBarState createState() => _MenuBarState();
|
||||
}
|
||||
@ -227,7 +237,7 @@ class _MenuBarState extends State<MenuBar> {
|
||||
return Container(
|
||||
height: 50.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
child: Row(
|
||||
@ -249,9 +259,9 @@ class _MenuBarState extends State<MenuBar> {
|
||||
child: Container(
|
||||
height: 30.0,
|
||||
width: 30.0,
|
||||
color: Colors.white,
|
||||
child: Image.file(File(
|
||||
"${widget.episodeItem.imagePath}")),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child:
|
||||
Image.file(File("${widget.episodeItem.imagePath}")),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -276,8 +286,7 @@ class _MenuBarState extends State<MenuBar> {
|
||||
],
|
||||
),
|
||||
DownloadButton(episodeBrief: widget.episodeItem),
|
||||
_buttonOnMenu(Icon(Icons.playlist_add, color: Colors.grey[700]),
|
||||
() {
|
||||
_buttonOnMenu(Icon(Icons.playlist_add, color: Colors.grey[700]), () {
|
||||
Fluttertoast.showToast(
|
||||
msg: 'Not support yet',
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
@ -303,13 +312,13 @@ class _MenuBarState extends State<MenuBar> {
|
||||
children: <Widget>[
|
||||
Text('Play Now',
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
color: Theme.of(context).accentColor,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
)),
|
||||
Icon(
|
||||
Icons.play_arrow,
|
||||
color: Colors.blue,
|
||||
color: Theme.of(context).accentColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -320,8 +329,8 @@ class _MenuBarState extends State<MenuBar> {
|
||||
audioplay.audioState == AudioState.play)
|
||||
? Container(
|
||||
padding: EdgeInsets.only(right: 30),
|
||||
child: SizedBox(
|
||||
width: 20, height: 15, child: WaveLoader()))
|
||||
child:
|
||||
SizedBox(width: 20, height: 15, child: WaveLoader()))
|
||||
: Container(
|
||||
padding: EdgeInsets.only(right: 30),
|
||||
child: SizedBox(
|
||||
|
@ -1,31 +1,37 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AboutApp extends StatelessWidget {
|
||||
TextSpan buildTextSpan() {
|
||||
return TextSpan(children: [
|
||||
TextSpan(text: 'Tsacdop\n',style: TextStyle(fontSize: 20)),
|
||||
TextSpan(text: 'Tsacdop\n', style: TextStyle(fontSize: 20)),
|
||||
TextSpan(
|
||||
text:
|
||||
'Tsacdop is a podcast client developed by flutter, is a simple, easy-use player.\n'),
|
||||
TextSpan(
|
||||
text:
|
||||
'Github https://github.com/stonga/tsacdop .\n'),
|
||||
TextSpan(text: 'Github https://github.com/stonga/tsacdop .\n'),
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.grey[100],
|
||||
title: Text('Tsacdop'),
|
||||
centerTitle: true,
|
||||
elevation: 0,
|
||||
),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text.rich(buildTextSpan()),
|
||||
));
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -34,16 +34,15 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
Widget build(BuildContext context) {
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.grey[100],
|
||||
statusBarColor: Colors.green,
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
backgroundColor: Colors.grey[100],
|
||||
brightness: Brightness.light,
|
||||
leading: IconButton(
|
||||
tooltip: 'Add',
|
||||
icon: const Icon(Icons.add_circle_outline),
|
||||
@ -64,6 +63,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
),
|
||||
body: Home(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -84,6 +84,9 @@ class _MyHomePageDelegate extends SearchDelegate<int> {
|
||||
return searchResult.results;
|
||||
}
|
||||
|
||||
@override
|
||||
ThemeData appBarTheme(BuildContext context) => Theme.of(context);
|
||||
|
||||
@override
|
||||
Widget buildLeading(BuildContext context) {
|
||||
return IconButton(
|
||||
@ -327,7 +330,7 @@ class _SearchResultState extends State<SearchResult> {
|
||||
? !_adding
|
||||
? OutlineButton(
|
||||
child: Text('Subscribe',
|
||||
style: TextStyle(color: Colors.blue)),
|
||||
style: TextStyle(color: Theme.of(context).accentColor)),
|
||||
onPressed: () {
|
||||
importOmpl.rssTitle = widget.onlinePodcast.title;
|
||||
savePodcast(widget.onlinePodcast.rss);
|
||||
@ -351,7 +354,7 @@ class _SearchResultState extends State<SearchResult> {
|
||||
? Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
color: Theme.of(context).primaryColorDark,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(15.0),
|
||||
bottomLeft: Radius.circular(15.0),
|
||||
|
@ -7,7 +7,7 @@ class Import extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<ImportOmpl>(
|
||||
builder: (context, importOmpl, _) => Container(
|
||||
color: Colors.grey[300],
|
||||
color: Theme.of(context).primaryColorDark,
|
||||
child: importOmpl.importState == ImportState.start
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tsacdop/class/podcast_group.dart';
|
||||
import 'package:tsacdop/class/settingstate.dart';
|
||||
import 'package:xml/xml.dart' as xml;
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -47,6 +48,7 @@ class PopupMenu extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
ImportOmpl importOmpl = Provider.of<ImportOmpl>(context, listen: false);
|
||||
GroupList groupList = Provider.of<GroupList>(context, listen: false);
|
||||
SettingState setting = Provider.of<SettingState>(context);
|
||||
_refreshAll() async {
|
||||
var dbHelper = DBHelper();
|
||||
List<PodcastLocal> podcastList = await dbHelper.getPodcastLocalAll();
|
||||
@ -113,8 +115,7 @@ class PopupMenu extends StatelessWidget {
|
||||
await Future.delayed(Duration(seconds: 5));
|
||||
importOmpl.importState = ImportState.stop;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
importOmpl.importState = ImportState.error;
|
||||
|
||||
Fluttertoast.showToast(
|
||||
@ -144,8 +145,9 @@ class PopupMenu extends StatelessWidget {
|
||||
for (int i = 0; i < total.length; i++) {
|
||||
if (total[i].xmlUrl != null) {
|
||||
importOmpl.rssTitle = total[i].text;
|
||||
try{await saveOmpl(total[i].xmlUrl);}
|
||||
catch (e){
|
||||
try {
|
||||
await saveOmpl(total[i].xmlUrl);
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
print(total[i].text);
|
||||
@ -183,17 +185,23 @@ class PopupMenu extends StatelessWidget {
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 3,
|
||||
child: setting.theme != 2 ? Text('Night Mode') : Text('Light Mode'),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 4,
|
||||
child: Text('About'),
|
||||
),
|
||||
],
|
||||
onSelected: (value) {
|
||||
if (value == 3) {
|
||||
if (value == 4) {
|
||||
Navigator.push(
|
||||
context, MaterialPageRoute(builder: (context) => AboutApp()));
|
||||
} else if (value == 2) {
|
||||
_getFilePath();
|
||||
} else if (value == 1) {
|
||||
_refreshAll();
|
||||
} else if (value == 3) {
|
||||
setting.theme != 2 ? setting.setTheme(2) : setting.setTheme(1);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -65,9 +65,10 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
_remoteAudioLoading = true;
|
||||
Provider.of<AudioPlay>(context, listen: false).audioState = AudioState.load;
|
||||
|
||||
if (_backgroundAudioPlaying == true)
|
||||
{ _backgroundAudio?.pause();
|
||||
AudioSystem.instance.stopBackgroundDisplay();}
|
||||
if (_backgroundAudioPlaying == true) {
|
||||
_backgroundAudio?.pause();
|
||||
AudioSystem.instance.stopBackgroundDisplay();
|
||||
}
|
||||
_backgroundAudio?.dispose();
|
||||
_backgroundAudio = Audio.loadFromRemoteUrl(url,
|
||||
onDuration: (double durationSeconds) {
|
||||
@ -118,9 +119,10 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
_remoteAudioLoading = true;
|
||||
ByteData audio = getAudio(path);
|
||||
Provider.of<AudioPlay>(context, listen: false).audioState = AudioState.load;
|
||||
if (_backgroundAudioPlaying == true)
|
||||
{_backgroundAudio?.pause();
|
||||
AudioSystem.instance.stopBackgroundDisplay();}
|
||||
if (_backgroundAudioPlaying == true) {
|
||||
_backgroundAudio?.pause();
|
||||
AudioSystem.instance.stopBackgroundDisplay();
|
||||
}
|
||||
_backgroundAudio?.dispose();
|
||||
_backgroundAudio = Audio.loadFromByteData(audio,
|
||||
onDuration: (double durationSeconds) {
|
||||
@ -192,11 +194,6 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
setState(() {
|
||||
this.url = url;
|
||||
episode = Provider.of<AudioPlay>(context).episode;
|
||||
var color = json.decode(episode?.primaryColor);
|
||||
(color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
_backgroundAudioPlaying = true;
|
||||
_isLoading = true;
|
||||
_getFile(url).then((result) {
|
||||
@ -270,11 +267,10 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
'playnow', likeButtonId, 'ic_stat_play_circle_filled');
|
||||
|
||||
Future<void> _setNotification() async {
|
||||
final Uint8List imageBytes =
|
||||
File('${episode.imagePath}').readAsBytesSync();
|
||||
final Uint8List imageBytes = File('${episode.imagePath}').readAsBytesSync();
|
||||
AudioSystem.instance.setMetadata(AudioMetadata(
|
||||
title: episode.title,
|
||||
artist:episode.feedTitle,
|
||||
artist: episode.feedTitle,
|
||||
album: episode.feedTitle,
|
||||
genre: "Podcast",
|
||||
durationSeconds: _backgroundAudioDurationSeconds,
|
||||
@ -309,8 +305,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
Provider.of<AudioPlay>(context, listen: false).audioState =
|
||||
AudioState.play;
|
||||
});
|
||||
final Uint8List imageBytes =
|
||||
File('${episode.imagePath}').readAsBytesSync();
|
||||
final Uint8List imageBytes = File('${episode.imagePath}').readAsBytesSync();
|
||||
AudioSystem.instance.setMetadata(AudioMetadata(
|
||||
title: episode.title,
|
||||
artist: episode.feedTitle,
|
||||
@ -383,9 +378,9 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
AudioSystem.instance.setPlaybackState(true, forwardposition);
|
||||
}
|
||||
|
||||
Widget _expandedPanel() => Container(
|
||||
Widget _expandedPanel(BuildContext context) => Container(
|
||||
height: 300,
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@ -459,7 +454,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
color: const Color(0xFFFF0000)))
|
||||
: Text(
|
||||
_remoteAudioLoading ? 'Buffring...' : '',
|
||||
style: TextStyle(color: Colors.blue),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).accentColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -474,6 +470,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
height: 100,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
@ -484,7 +481,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
: null,
|
||||
iconSize: 32.0,
|
||||
icon: Icon(Icons.replay_10),
|
||||
color: Colors.black),
|
||||
color: Theme.of(context).tabBarTheme.labelColor),
|
||||
),
|
||||
_backgroundAudioPlaying
|
||||
? Material(
|
||||
@ -498,7 +495,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
: null,
|
||||
iconSize: 40.0,
|
||||
icon: Icon(Icons.pause_circle_filled),
|
||||
color: Colors.black),
|
||||
color:
|
||||
Theme.of(context).tabBarTheme.labelColor),
|
||||
)
|
||||
: Material(
|
||||
color: Colors.transparent,
|
||||
@ -511,7 +509,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
},
|
||||
iconSize: 40.0,
|
||||
icon: Icon(Icons.play_circle_filled),
|
||||
color: Colors.black),
|
||||
color:
|
||||
Theme.of(context).tabBarTheme.labelColor),
|
||||
),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
@ -522,7 +521,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
: null,
|
||||
iconSize: 32.0,
|
||||
icon: Icon(Icons.forward_30),
|
||||
color: Colors.black),
|
||||
color: Theme.of(context).tabBarTheme.labelColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -533,7 +532,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0),
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
child: Row(
|
||||
@ -547,10 +546,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
child: Container(
|
||||
height: 30.0,
|
||||
width: 30.0,
|
||||
color: Colors.white,
|
||||
child: Image.file(
|
||||
File("${episode.imagePath}"))
|
||||
),
|
||||
child: Image.file(File("${episode.imagePath}"))),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -565,17 +561,31 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
))
|
||||
]),
|
||||
);
|
||||
Widget _miniPanel(double width) => Container(
|
||||
Widget _miniPanel(double width, BuildContext context) {
|
||||
var color = json.decode(episode?.primaryColor);
|
||||
if (color) {
|
||||
if (Theme.of(context).brightness == Brightness.light) {
|
||||
_c = (color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
} else {
|
||||
_c = (color[0] < 50 && color[1] < 50 && color[2] < 50)
|
||||
? Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
}
|
||||
}
|
||||
return Container(
|
||||
height: 60,
|
||||
color: Colors.grey[100],
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
color: Theme.of(context).primaryColor,
|
||||
child:
|
||||
Column(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
|
||||
SizedBox(
|
||||
height: 2,
|
||||
child: LinearProgressIndicator(
|
||||
value: _seekSliderValue,
|
||||
backgroundColor: Colors.grey[100],
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(_c),
|
||||
)),
|
||||
Expanded(
|
||||
@ -603,8 +613,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
startPadding: 30.0,
|
||||
accelerationDuration: Duration(seconds: 1),
|
||||
accelerationCurve: Curves.linear,
|
||||
decelerationDuration:
|
||||
Duration(milliseconds: 500),
|
||||
decelerationDuration: Duration(milliseconds: 500),
|
||||
decelerationCurve: Curves.easeOut,
|
||||
)
|
||||
: Text(
|
||||
@ -622,7 +631,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
child: _remoteAudioLoading
|
||||
? Text(
|
||||
'Buffring...',
|
||||
style: TextStyle(color: Colors.blue),
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).accentColor),
|
||||
)
|
||||
: Row(
|
||||
children: <Widget>[
|
||||
@ -658,7 +668,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
: null,
|
||||
iconSize: 25.0,
|
||||
icon: Icon(Icons.pause_circle_filled),
|
||||
color: Colors.black),
|
||||
color:
|
||||
Theme.of(context).tabBarTheme.labelColor),
|
||||
)
|
||||
: Material(
|
||||
color: Colors.transparent,
|
||||
@ -670,7 +681,8 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
},
|
||||
iconSize: 25.0,
|
||||
icon: Icon(Icons.play_circle_filled),
|
||||
color: Colors.black),
|
||||
color:
|
||||
Theme.of(context).tabBarTheme.labelColor),
|
||||
),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
@ -680,7 +692,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
: null,
|
||||
iconSize: 25.0,
|
||||
icon: Icon(Icons.forward_30),
|
||||
color: Colors.black),
|
||||
color: Theme.of(context).tabBarTheme.labelColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -691,12 +703,16 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double _width = MediaQuery.of(context).size.width;
|
||||
|
||||
return !_isLoading
|
||||
? Center()
|
||||
: AudioPanel(
|
||||
miniPanel: _miniPanel(_width), expandedPanel: _expandedPanel());
|
||||
miniPanel: _miniPanel(_width, context),
|
||||
expandedPanel: _expandedPanel(context));
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class _AudioPanelState extends State<AudioPanel>
|
||||
child: GestureDetector(
|
||||
onTap: () => _backToMini(),
|
||||
child: Container(
|
||||
color: Colors.white.withOpacity(0.5),
|
||||
color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -64,7 +64,7 @@ class _AudioPanelState extends State<AudioPanel>
|
||||
: (_animation.value <= minSize) ? minSize : _animation.value,
|
||||
child: _animation.value < minSize + 30
|
||||
? Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: Opacity(
|
||||
opacity: _animation.value > minSize
|
||||
? (minSize + 30 - _animation.value) / 40
|
||||
@ -75,7 +75,7 @@ class _AudioPanelState extends State<AudioPanel>
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: SingleChildScrollView(
|
||||
child: Opacity(
|
||||
opacity: _animation.value < (maxSize - 50)
|
||||
|
@ -87,9 +87,10 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
||||
EdgeInsets.symmetric(horizontal: 15.0),
|
||||
child: Text(
|
||||
groups[_groupIndex].name,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.red[300]),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
.copyWith(color: Colors.red[300]),
|
||||
)),
|
||||
Spacer(),
|
||||
Container(
|
||||
@ -106,19 +107,22 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
||||
child: Container(
|
||||
height: 30,
|
||||
padding: EdgeInsets.all(5.0),
|
||||
child: Text('See All',
|
||||
style: TextStyle(
|
||||
color: Colors.red[300],
|
||||
fontWeight: FontWeight.bold,
|
||||
child: Text(
|
||||
'See All',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.accentColor),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white10,
|
||||
// color: Colors.white10,
|
||||
height: 70,
|
||||
width: _width,
|
||||
alignment: Alignment.centerLeft,
|
||||
@ -153,14 +157,15 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
|
||||
height: (_width - 20) / 3 + 40,
|
||||
margin: EdgeInsets.only(left: 10, right: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
),
|
||||
child: TabBarView(
|
||||
children: groups[_groupIndex]
|
||||
.podcasts
|
||||
.map<Widget>((PodcastLocal podcastLocal) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: Colors.grey[100]),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor),
|
||||
margin: EdgeInsets.symmetric(horizontal: 5.0),
|
||||
key: ObjectKey(podcastLocal.title),
|
||||
child: PodcastPreview(
|
||||
@ -193,18 +198,21 @@ class _PodcastPreviewState extends State<PodcastPreview> {
|
||||
}
|
||||
|
||||
Color _c;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Widget build(BuildContext context) {
|
||||
var color = json.decode(widget.podcastLocal.primaryColor);
|
||||
if (Theme.of(context).brightness == Brightness.light) {
|
||||
(color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
} else {
|
||||
(color[0] < 50 && color[1] < 50 && color[2] < 50)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
@ -294,10 +302,18 @@ class ShowEpisode extends StatelessWidget {
|
||||
(BuildContext context, int index) {
|
||||
Color _c;
|
||||
var color = json.decode(podcast[index].primaryColor);
|
||||
|
||||
if (Theme.of(context).brightness == Brightness.light) {
|
||||
(color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
} else {
|
||||
(color[0] < 50 && color[1] < 50 && color[2] < 50)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
}
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
@ -315,12 +331,12 @@ class ShowEpisode extends StatelessWidget {
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
border: Border.all(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
width: 3.0,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
blurRadius: 1.0,
|
||||
spreadRadius: 0.5,
|
||||
),
|
||||
|
@ -12,11 +12,16 @@ class MainTab extends StatefulWidget {
|
||||
|
||||
class _MainTabState extends State<MainTab> with TickerProviderStateMixin {
|
||||
TabController _controller;
|
||||
Decoration getIndicator() {
|
||||
return const UnderlineTabIndicator(
|
||||
borderSide: BorderSide(color: Colors.red, width: 2),
|
||||
insets: EdgeInsets.only(left:10.0,right: 10.0, top:10.0,)
|
||||
);}
|
||||
Decoration getIndicator(BuildContext context) {
|
||||
return UnderlineTabIndicator(
|
||||
borderSide: BorderSide(color: Theme.of(context).accentColor, width: 2),
|
||||
insets: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
right: 10.0,
|
||||
top: 10.0,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -41,16 +46,22 @@ class _MainTabState extends State<MainTab> with TickerProviderStateMixin {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: TabBar(
|
||||
isScrollable: true,
|
||||
labelPadding:
|
||||
EdgeInsets.all(10.0),
|
||||
labelPadding: EdgeInsets.all(10.0),
|
||||
controller: _controller,
|
||||
labelColor: Colors.red,
|
||||
unselectedLabelColor: Colors.black,
|
||||
indicator: getIndicator(),
|
||||
indicator: getIndicator(context),
|
||||
tabs: <Widget>[
|
||||
Text('Recent Update',style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
Text('Favorites',style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
Text('Downloads',style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
Text(
|
||||
'Recent Update',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'Favorites',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'Downloads',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -96,7 +107,13 @@ class _RecentUpdateState extends State<RecentUpdate> {
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) print(snapshot.error);
|
||||
return (snapshot.hasData)
|
||||
? EpisodeGrid(podcast: snapshot.data, showDownload: false, showFavorite: false, showNumber: false, heroTag: 'recent',)
|
||||
? EpisodeGrid(
|
||||
podcast: snapshot.data,
|
||||
showDownload: false,
|
||||
showFavorite: false,
|
||||
showNumber: false,
|
||||
heroTag: 'recent',
|
||||
)
|
||||
: Center(child: CircularProgressIndicator());
|
||||
},
|
||||
);
|
||||
@ -111,7 +128,7 @@ class MyFavorite extends StatefulWidget {
|
||||
class _MyFavoriteState extends State<MyFavorite> {
|
||||
Future<List<EpisodeBrief>> _getLikedRssItem() async {
|
||||
var dbHelper = DBHelper();
|
||||
List<EpisodeBrief> episodes =await dbHelper.getLikedRssItem();
|
||||
List<EpisodeBrief> episodes = await dbHelper.getLikedRssItem();
|
||||
return episodes;
|
||||
}
|
||||
|
||||
@ -122,23 +139,28 @@ class _MyFavoriteState extends State<MyFavorite> {
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) print(snapshot.error);
|
||||
return (snapshot.hasData)
|
||||
? EpisodeGrid(podcast: snapshot.data, showDownload: false, showFavorite: false, showNumber: false, heroTag: 'favorite',)
|
||||
? EpisodeGrid(
|
||||
podcast: snapshot.data,
|
||||
showDownload: false,
|
||||
showFavorite: false,
|
||||
showNumber: false,
|
||||
heroTag: 'favorite',
|
||||
)
|
||||
: Center(child: CircularProgressIndicator());
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyDownload extends StatefulWidget {
|
||||
class MyDownload extends StatefulWidget {
|
||||
@override
|
||||
_MyDownloadState createState() => _MyDownloadState();
|
||||
}
|
||||
|
||||
|
||||
class _MyDownloadState extends State<MyDownload> {
|
||||
Future<List<EpisodeBrief>> _getDownloadedRssItem() async {
|
||||
var dbHelper = DBHelper();
|
||||
List<EpisodeBrief> episodes =await dbHelper.getDownloadedRssItem();
|
||||
List<EpisodeBrief> episodes = await dbHelper.getDownloadedRssItem();
|
||||
return episodes;
|
||||
}
|
||||
|
||||
@ -149,10 +171,15 @@ class _MyDownloadState extends State<MyDownload> {
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) print(snapshot.error);
|
||||
return (snapshot.hasData)
|
||||
? EpisodeGrid(podcast: snapshot.data, showDownload: true, showFavorite: false, showNumber: false, heroTag: 'download',)
|
||||
? EpisodeGrid(
|
||||
podcast: snapshot.data,
|
||||
showDownload: true,
|
||||
showFavorite: false,
|
||||
showNumber: false,
|
||||
heroTag: 'download',
|
||||
)
|
||||
: Center(child: CircularProgressIndicator());
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,4 +31,15 @@ class KeyValueStorage {
|
||||
json.encode(
|
||||
{'groups': groupList.map((group) => group.toJson()).toList()}));
|
||||
}
|
||||
|
||||
Future<bool> saveTheme(int setting) async{
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
return prefs.setInt(key, setting);
|
||||
}
|
||||
|
||||
Future<int> getTheme() async{
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
if(prefs.getInt(key) == null) await prefs.setInt(key, 0);
|
||||
return prefs.getInt(key);
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,35 @@ void main() async {
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
SystemUiOverlayStyle(statusBarColor: Colors.grey[100]));
|
||||
var theme = Provider.of<SettingState>(context).theme;
|
||||
return MaterialApp(
|
||||
themeMode: theme == 0
|
||||
? ThemeMode.system
|
||||
: theme == 1 ? ThemeMode.dark : ThemeMode.light,
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'TsacDop',
|
||||
theme: ThemeData(
|
||||
primaryColor: Colors.white,
|
||||
accentColorBrightness: Brightness.dark,
|
||||
primaryColor: Colors.grey[100],
|
||||
accentColor: Colors.blue[400],
|
||||
primaryColorLight: Colors.white,
|
||||
primaryColorDark: Colors.grey[300],
|
||||
dialogBackgroundColor: Colors.white,
|
||||
backgroundColor: Colors.grey[100],
|
||||
appBarTheme: AppBarTheme(
|
||||
color: Colors.grey[100],
|
||||
elevation: 0,
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
headline1: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
|
||||
bodyText2: TextStyle(fontSize: 15.0, fontWeight: FontWeight.normal),
|
||||
),
|
||||
tabBarTheme: TabBarTheme(
|
||||
labelColor: Colors.black,
|
||||
unselectedLabelColor: Colors.grey[400],
|
||||
),
|
||||
),
|
||||
darkTheme: ThemeData.dark(),
|
||||
home: MyHomePage(),
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:tsacdop/class/podcastlocal.dart';
|
||||
@ -21,8 +22,8 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
Future _updateRssItem(PodcastLocal podcastLocal) async {
|
||||
var dbHelper = DBHelper();
|
||||
final result = await dbHelper.updatePodcastRss(podcastLocal);
|
||||
result == 0 ?
|
||||
Fluttertoast.showToast(
|
||||
result == 0
|
||||
? Fluttertoast.showToast(
|
||||
msg: 'No Update',
|
||||
gravity: ToastGravity.TOP,
|
||||
)
|
||||
@ -30,24 +31,30 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
msg: 'Updated $result Episodes',
|
||||
gravity: ToastGravity.TOP,
|
||||
);
|
||||
if(mounted) setState(() {});
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
Future<List<EpisodeBrief>> _getRssItem(PodcastLocal podcastLocal) async {
|
||||
print(podcastLocal.id);
|
||||
var dbHelper = DBHelper();
|
||||
List<EpisodeBrief> episodes = await
|
||||
dbHelper.getRssItem(podcastLocal.id);
|
||||
List<EpisodeBrief> episodes = await dbHelper.getRssItem(podcastLocal.id);
|
||||
return episodes;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.podcastLocal.title,),
|
||||
elevation: 0.0,
|
||||
backgroundColor: Colors.grey[100],
|
||||
title: Text(
|
||||
widget.podcastLocal.title,
|
||||
),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
@ -59,10 +66,18 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) print(snapshot.error);
|
||||
return (snapshot.hasData)
|
||||
? EpisodeGrid(podcast: snapshot.data, showDownload: true, showFavorite: true, showNumber: true, heroTag: 'podcast',)
|
||||
? EpisodeGrid(
|
||||
podcast: snapshot.data,
|
||||
showDownload: true,
|
||||
showFavorite: true,
|
||||
showNumber: true,
|
||||
heroTag: 'podcast',
|
||||
)
|
||||
: Center(child: CircularProgressIndicator());
|
||||
},
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tsacdop/class/podcast_group.dart';
|
||||
@ -38,12 +39,13 @@ class _PodcastGroupListState extends State<PodcastGroupList> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [BoxShadow(
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey[700],
|
||||
blurRadius: 5,
|
||||
offset: Offset(1, 1),
|
||||
),]
|
||||
),
|
||||
]),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'Save',
|
||||
@ -68,10 +70,10 @@ class _PodcastGroupListState extends State<PodcastGroupList> {
|
||||
Widget build(BuildContext context) {
|
||||
return widget.group.podcastList.length == 0
|
||||
? Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
)
|
||||
: Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
ReorderableListView(
|
||||
@ -89,7 +91,8 @@ class _PodcastGroupListState extends State<PodcastGroupList> {
|
||||
children: widget.group.podcasts
|
||||
.map<Widget>((PodcastLocal podcastLocal) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: Colors.grey[100]),
|
||||
decoration:
|
||||
BoxDecoration(color: Theme.of(context).primaryColor),
|
||||
key: ObjectKey(podcastLocal.title),
|
||||
child: PodcastCard(
|
||||
podcastLocal: podcastLocal,
|
||||
@ -147,10 +150,17 @@ class _PodcastCardState extends State<PodcastCard> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var color = json.decode(widget.podcastLocal.primaryColor);
|
||||
if (Theme.of(context).brightness == Brightness.light) {
|
||||
(color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
} else {
|
||||
(color[0] < 50 && color[1] < 50 && color[2] < 50)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
}
|
||||
double _width = MediaQuery.of(context).size.width;
|
||||
var _groupList = Provider.of<GroupList>(context);
|
||||
_belongGroups = _groupList.getPodcastGroup(widget.podcastLocal.id);
|
||||
@ -219,6 +229,12 @@ class _PodcastCardState extends State<PodcastCard> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
child: AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
systemNavigationBarColor:
|
||||
Colors.black.withOpacity(0.5),
|
||||
statusBarColor: Colors.red,
|
||||
),
|
||||
child: AlertDialog(
|
||||
elevation: 2.0,
|
||||
title: Text('Remove confirm'),
|
||||
@ -231,7 +247,8 @@ class _PodcastCardState extends State<PodcastCard> {
|
||||
),
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
_groupList.removePodcast(widget.podcastLocal.id);
|
||||
_groupList
|
||||
.removePodcast(widget.podcastLocal.id);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
@ -240,6 +257,7 @@ class _PodcastCardState extends State<PodcastCard> {
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
},
|
||||
),
|
||||
@ -251,10 +269,12 @@ class _PodcastCardState extends State<PodcastCard> {
|
||||
: Container(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Colors.grey[300]),
|
||||
top: BorderSide(color: Colors.grey[300]))),
|
||||
bottom: BorderSide(
|
||||
color: Theme.of(context).primaryColorDark),
|
||||
top: BorderSide(
|
||||
color: Theme.of(context).primaryColorDark))),
|
||||
height: 50,
|
||||
child: _addGroup
|
||||
? Row(
|
||||
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tsacdop/class/podcast_group.dart';
|
||||
@ -52,7 +53,6 @@ class _AboutPodcastState extends State<AboutPodcast> {
|
||||
_groupList.removePodcast(widget.podcastLocal.id);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
color: Colors.grey[200],
|
||||
textColor: Colors.red,
|
||||
child: Text(
|
||||
'UNSUBSCRIBE',
|
||||
@ -83,7 +83,6 @@ class PodcastList extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _PodcastListState extends State<PodcastList> {
|
||||
|
||||
Future<List<PodcastLocal>> getPodcastLocal() async {
|
||||
var dbHelper = DBHelper();
|
||||
var podcastList = await dbHelper.getPodcastLocalAll();
|
||||
@ -93,15 +92,20 @@ class _PodcastListState extends State<PodcastList> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double _width = MediaQuery.of(context).size.width;
|
||||
return Scaffold(
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Podcasts'),
|
||||
centerTitle: true,
|
||||
backgroundColor: Colors.grey[100],
|
||||
elevation: 0,
|
||||
),
|
||||
body: Container(
|
||||
color: Colors.grey[100],
|
||||
color: Theme.of(context).primaryColor,
|
||||
child: FutureBuilder<List<PodcastLocal>>(
|
||||
future: getPodcastLocal(),
|
||||
builder: (context, snapshot) {
|
||||
@ -112,7 +116,8 @@ class _PodcastListState extends State<PodcastList> {
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
sliver: SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
gridDelegate:
|
||||
SliverGridDelegateWithFixedCrossAxisCount(
|
||||
childAspectRatio: 0.8,
|
||||
crossAxisCount: 3,
|
||||
),
|
||||
@ -131,7 +136,8 @@ class _PodcastListState extends State<PodcastList> {
|
||||
onLongPress: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AboutPodcast(
|
||||
builder: (BuildContext context) =>
|
||||
AboutPodcast(
|
||||
podcastLocal: snapshot.data[index]),
|
||||
).then((_) => setState(() {}));
|
||||
},
|
||||
@ -158,10 +164,7 @@ class _PodcastListState extends State<PodcastList> {
|
||||
child: Text(
|
||||
snapshot.data[index].title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
),
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
@ -181,21 +184,8 @@ class _PodcastListState extends State<PodcastList> {
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Podcast extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.grey[100],
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
title: Text('Podcasts'),
|
||||
),
|
||||
body: Container(child: PodcastList()),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tsacdop/class/podcast_group.dart';
|
||||
import 'package:tsacdop/podcasts/podcastgroup.dart';
|
||||
@ -26,13 +27,23 @@ class _PodcastManageState extends State<PodcastManage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
|
||||
systemNavigationBarColor: Theme.of(context).primaryColor,
|
||||
statusBarColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
backgroundColor: Colors.grey[100],
|
||||
title: Text('Groups'),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AddGroup()),
|
||||
icon: Icon(Icons.add)),
|
||||
OrderMenu(),
|
||||
],
|
||||
),
|
||||
@ -47,17 +58,13 @@ class _PodcastManageState extends State<PodcastManage> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Container(
|
||||
Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: TabBar(
|
||||
labelColor: Colors.black,
|
||||
unselectedLabelColor: Colors.grey[500],
|
||||
// labelColor: Colors.black,
|
||||
// unselectedLabelColor: Colors.grey[500],
|
||||
labelPadding: EdgeInsets.all(5.0),
|
||||
indicator: getIndicator(),
|
||||
isScrollable: true,
|
||||
@ -65,13 +72,16 @@ class _PodcastManageState extends State<PodcastManage> {
|
||||
return Tab(
|
||||
child: Container(
|
||||
height: 30.0,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10.0),
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[300],
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(15)),
|
||||
color: Theme.of(context).brightness ==
|
||||
Brightness.light
|
||||
? Theme.of(context).primaryColorDark
|
||||
: Colors.grey[800],
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(15)),
|
||||
),
|
||||
child: Text(
|
||||
group.name,
|
||||
@ -80,18 +90,6 @@ class _PodcastManageState extends State<PodcastManage> {
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: IconButton(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
AddGroup()),
|
||||
icon: Icon(Icons.add)),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: TabBarView(
|
||||
@ -106,6 +104,8 @@ class _PodcastManageState extends State<PodcastManage> {
|
||||
],
|
||||
));
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -166,7 +166,12 @@ class _AddGroupState extends State<AddGroup> {
|
||||
Widget build(BuildContext context) {
|
||||
var groupList = Provider.of<GroupList>(context);
|
||||
List list = groupList.groups.map((e) => e.name).toList();
|
||||
return AlertDialog(
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.black.withOpacity(0.5),
|
||||
statusBarColor: Colors.red,
|
||||
),
|
||||
child: AlertDialog(
|
||||
elevation: 1,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 20),
|
||||
titlePadding: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 20),
|
||||
@ -176,7 +181,7 @@ class _AddGroupState extends State<AddGroup> {
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: Text(
|
||||
'CANCEL',
|
||||
style: TextStyle(color: Colors.grey[700]),
|
||||
style: TextStyle(color: Colors.grey[600]),
|
||||
),
|
||||
),
|
||||
FlatButton(
|
||||
@ -202,7 +207,7 @@ class _AddGroupState extends State<AddGroup> {
|
||||
hintStyle: TextStyle(fontSize: 18),
|
||||
filled: true,
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white, width: 2.0),
|
||||
borderSide: BorderSide(color: Colors.blue, width: 2.0),
|
||||
),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.blue, width: 2.0),
|
||||
@ -227,6 +232,7 @@ class _AddGroupState extends State<AddGroup> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -45,10 +45,17 @@ class EpisodeGrid extends StatelessWidget {
|
||||
(BuildContext context, int index) {
|
||||
Color _c;
|
||||
var color = json.decode(podcast[index].primaryColor);
|
||||
if (Theme.of(context).brightness == Brightness.light) {
|
||||
(color[0] > 200 && color[1] > 200 && color[2] > 200)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
} else {
|
||||
(color[0] < 50 && color[1] < 50 && color[2] < 50)
|
||||
? _c = Color.fromRGBO(
|
||||
(255 - color[0]), 255 - color[1], 255 - color[2], 1.0)
|
||||
: _c = Color.fromRGBO(color[0], color[1], color[2], 1.0);
|
||||
}
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
@ -67,13 +74,16 @@ class EpisodeGrid extends StatelessWidget {
|
||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
border: Border.all(
|
||||
color: Colors.grey[100],
|
||||
color:
|
||||
Theme.of(context).brightness == Brightness.light
|
||||
? Theme.of(context).primaryColor
|
||||
: Theme.of(context).scaffoldBackgroundColor,
|
||||
width: 3.0,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey[100],
|
||||
blurRadius: 1.0,
|
||||
color: Theme.of(context).primaryColor,
|
||||
blurRadius: 0.5,
|
||||
spreadRadius: 0.5,
|
||||
),
|
||||
]),
|
||||
|
Loading…
x
Reference in New Issue
Block a user