parent
0a0e0a45f5
commit
5dc490f83f
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -126,7 +126,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
bool _stopOnComplete = false;
|
bool _stopOnComplete = false;
|
||||||
Timer _stopTimer;
|
Timer _stopTimer;
|
||||||
int _timeLeft = 0;
|
int _timeLeft = 0;
|
||||||
bool _showStopWatch = false;
|
bool _startSleepTimer = false;
|
||||||
double _switchValue = 0;
|
double _switchValue = 0;
|
||||||
bool _autoPlay = true;
|
bool _autoPlay = true;
|
||||||
DateTime _current;
|
DateTime _current;
|
||||||
|
@ -144,7 +144,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
bool get queueUpdate => _queueUpdate;
|
bool get queueUpdate => _queueUpdate;
|
||||||
EpisodeBrief get episode => _episode;
|
EpisodeBrief get episode => _episode;
|
||||||
bool get stopOnComplete => _stopOnComplete;
|
bool get stopOnComplete => _stopOnComplete;
|
||||||
bool get showStopWatch => _showStopWatch;
|
bool get startSleepTimer => _startSleepTimer;
|
||||||
bool get autoPlay => _autoPlay;
|
bool get autoPlay => _autoPlay;
|
||||||
int get timeLeft => _timeLeft;
|
int get timeLeft => _timeLeft;
|
||||||
double get switchValue => _switchValue;
|
double get switchValue => _switchValue;
|
||||||
|
@ -165,8 +165,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
_queueUpdate = false;
|
_queueUpdate = false;
|
||||||
await AudioService.connect();
|
await AudioService.connect();
|
||||||
bool running = await AudioService.running;
|
bool running = await AudioService.running;
|
||||||
if (running) {
|
if (running) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPlaylist() async {
|
loadPlaylist() async {
|
||||||
|
@ -217,13 +216,13 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
await AudioService.connect();
|
await AudioService.connect();
|
||||||
}
|
}
|
||||||
await AudioService.start(
|
await AudioService.start(
|
||||||
backgroundTaskEntrypoint: _audioPlayerTaskEntrypoint,
|
backgroundTaskEntrypoint: _audioPlayerTaskEntrypoint,
|
||||||
androidNotificationChannelName: 'Tsacdop',
|
androidNotificationChannelName: 'Tsacdop',
|
||||||
notificationColor: 0xFF4d91be,
|
notificationColor: 0xFF4d91be,
|
||||||
androidNotificationIcon: 'drawable/ic_notification',
|
androidNotificationIcon: 'drawable/ic_notification',
|
||||||
enableQueue: true,
|
enableQueue: true,
|
||||||
androidStopOnRemoveTask: true,
|
androidStopOnRemoveTask: true,
|
||||||
androidStopForegroundOnPause: true);
|
);
|
||||||
_playerRunning = true;
|
_playerRunning = true;
|
||||||
if (_autoPlay) {
|
if (_autoPlay) {
|
||||||
await Future.forEach(_queue.playlist, (episode) async {
|
await Future.forEach(_queue.playlist, (episode) async {
|
||||||
|
@ -312,7 +311,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
if (_audioState == BasicPlaybackState.stopped) {
|
if (_audioState == BasicPlaybackState.stopped || _playerRunning == false) {
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -325,6 +324,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
_seekSliderValue = 0;
|
_seekSliderValue = 0;
|
||||||
_episode = _queue.playlist.first;
|
_episode = _queue.playlist.first;
|
||||||
_playerRunning = true;
|
_playerRunning = true;
|
||||||
|
_queueUpdate = !_queueUpdate;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_startAudioService(_lastPostion ?? 0);
|
_startAudioService(_lastPostion ?? 0);
|
||||||
}
|
}
|
||||||
|
@ -397,9 +397,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
int pos = _backgroundAudioPosition + s * 1000;
|
int pos = _backgroundAudioPosition + s * 1000;
|
||||||
AudioService.seekTo(pos);
|
AudioService.seekTo(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
seekTo(int position) async{
|
seekTo(int position) async {
|
||||||
if (_audioState != BasicPlaybackState.connecting &&
|
if (_audioState != BasicPlaybackState.connecting &&
|
||||||
_audioState != BasicPlaybackState.none)
|
_audioState != BasicPlaybackState.none)
|
||||||
await AudioService.seekTo(position);
|
await AudioService.seekTo(position);
|
||||||
}
|
}
|
||||||
|
@ -417,9 +417,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set sleep time
|
//Set sleep timer
|
||||||
sleepTimer(int mins) {
|
sleepTimer(int mins) {
|
||||||
_showStopWatch = true;
|
_startSleepTimer= true;
|
||||||
_switchValue = 1;
|
_switchValue = 1;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
_timeLeft = mins * 60;
|
_timeLeft = mins * 60;
|
||||||
|
@ -432,12 +432,14 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_stopTimer = Timer(Duration(minutes: mins), () {
|
_stopTimer = Timer(Duration(minutes: mins), () {
|
||||||
_stopOnComplete = false;
|
_stopOnComplete = false;
|
||||||
_showStopWatch = false;
|
_startSleepTimer= false;
|
||||||
_switchValue = 0;
|
_switchValue = 0;
|
||||||
|
_playerRunning = false;
|
||||||
|
notifyListeners();
|
||||||
AudioService.stop();
|
AudioService.stop();
|
||||||
notifyListeners();
|
AudioService.disconnect();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +447,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
|
||||||
cancelTimer() {
|
cancelTimer() {
|
||||||
_stopTimer.cancel();
|
_stopTimer.cancel();
|
||||||
_timeLeft = 0;
|
_timeLeft = 0;
|
||||||
_showStopWatch = false;
|
_startSleepTimer= false;
|
||||||
_switchValue = 0;
|
_switchValue = 0;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,16 @@ import 'package:flutter_linkify/flutter_linkify.dart';
|
||||||
import 'package:tsacdop/class/audiostate.dart';
|
import 'package:tsacdop/class/audiostate.dart';
|
||||||
import 'package:tsacdop/class/episodebrief.dart';
|
import 'package:tsacdop/class/episodebrief.dart';
|
||||||
import 'package:tsacdop/local_storage/sqflite_localpodcast.dart';
|
import 'package:tsacdop/local_storage/sqflite_localpodcast.dart';
|
||||||
|
import 'package:tsacdop/util/context_extension.dart';
|
||||||
import 'episodedownload.dart';
|
import 'episodedownload.dart';
|
||||||
|
|
||||||
class EpisodeDetail extends StatefulWidget {
|
class EpisodeDetail extends StatefulWidget {
|
||||||
final EpisodeBrief episodeItem;
|
final EpisodeBrief episodeItem;
|
||||||
final String heroTag;
|
final String heroTag;
|
||||||
final bool hide;
|
final bool hide;
|
||||||
EpisodeDetail({this.episodeItem, this.heroTag = '',this.hide = false, Key key}) : super(key: key);
|
EpisodeDetail(
|
||||||
|
{this.episodeItem, this.heroTag = '', this.hide = false, Key key})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_EpisodeDetailState createState() => _EpisodeDetailState();
|
_EpisodeDetailState createState() => _EpisodeDetailState();
|
||||||
|
@ -38,7 +41,8 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||||
Future getSDescription(String url) async {
|
Future getSDescription(String url) async {
|
||||||
var dbHelper = DBHelper();
|
var dbHelper = DBHelper();
|
||||||
_description = (await dbHelper.getDescription(url))
|
_description = (await dbHelper.getDescription(url))
|
||||||
.replaceAll(RegExp(r'\s?<p>(<br>)?</p>\s?'), '').replaceAll('\r', '');
|
.replaceAll(RegExp(r'\s?<p>(<br>)?</p>\s?'), '')
|
||||||
|
.replaceAll('\r', '');
|
||||||
if (mounted)
|
if (mounted)
|
||||||
setState(() {
|
setState(() {
|
||||||
_loaddes = true;
|
_loaddes = true;
|
||||||
|
@ -93,7 +97,7 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
// title: Text(widget.episodeItem.feedTitle),
|
// title: Text(widget.episodeItem.feedTitle),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: Stack(
|
body: Stack(
|
||||||
|
@ -197,13 +201,12 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||||
padding: EdgeInsets.only(top: 5.0),
|
padding: EdgeInsets.only(top: 5.0),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
//physics: AlwaysScrollableScrollPhysics(),
|
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
child: _loaddes
|
child: _loaddes
|
||||||
? (_description.contains('<'))
|
? (_description.contains('<'))
|
||||||
? Html(
|
? Html(
|
||||||
padding:
|
padding: EdgeInsets.only(
|
||||||
EdgeInsets.only(left: 20.0, right: 20, bottom: 10),
|
left: 20.0, right: 20, bottom: 10),
|
||||||
defaultTextStyle: TextStyle(height: 1.8),
|
defaultTextStyle: TextStyle(height: 1.8),
|
||||||
data: _description,
|
data: _description,
|
||||||
linkStyle: TextStyle(
|
linkStyle: TextStyle(
|
||||||
|
@ -215,24 +218,48 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||||
},
|
},
|
||||||
useRichText: true,
|
useRichText: true,
|
||||||
)
|
)
|
||||||
: Container(
|
: _description.length > 0
|
||||||
padding:
|
? Container(
|
||||||
EdgeInsets.only(left: 20.0, right: 20.0, bottom: 10.0),
|
padding: EdgeInsets.only(
|
||||||
alignment: Alignment.topLeft,
|
left: 20.0,
|
||||||
child: SelectableLinkify(
|
right: 20.0,
|
||||||
onOpen: (link) {
|
bottom: 10.0),
|
||||||
_launchUrl(link.url);
|
alignment: Alignment.topLeft,
|
||||||
},
|
child: SelectableLinkify(
|
||||||
text: _description,
|
onOpen: (link) {
|
||||||
style: TextStyle(
|
_launchUrl(link.url);
|
||||||
height: 1.8,
|
},
|
||||||
),
|
text: _description,
|
||||||
linkStyle: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).accentColor,
|
height: 1.8,
|
||||||
decoration: TextDecoration.underline,
|
),
|
||||||
),
|
linkStyle: TextStyle(
|
||||||
),
|
color:
|
||||||
)
|
Theme.of(context).accentColor,
|
||||||
|
decoration:
|
||||||
|
TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
height: context.width,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Image(
|
||||||
|
image: AssetImage(
|
||||||
|
'assets/shownote.png'),
|
||||||
|
height: 100.0,
|
||||||
|
),
|
||||||
|
Padding(padding: EdgeInsets.all(5.0)),
|
||||||
|
Text(
|
||||||
|
'Still no shownote received\n for this episode.', textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(color: context.textTheme.bodyText1.color.withOpacity(0.5))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
: Center(),
|
: Center(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -259,10 +286,9 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: MenuBar(
|
child: MenuBar(
|
||||||
episodeItem: widget.episodeItem,
|
episodeItem: widget.episodeItem,
|
||||||
heroTag: widget.heroTag,
|
heroTag: widget.heroTag,
|
||||||
hide: widget.hide
|
hide: widget.hide),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -279,7 +305,8 @@ class MenuBar extends StatefulWidget {
|
||||||
final EpisodeBrief episodeItem;
|
final EpisodeBrief episodeItem;
|
||||||
final String heroTag;
|
final String heroTag;
|
||||||
final bool hide;
|
final bool hide;
|
||||||
MenuBar({this.episodeItem, this.heroTag, this.hide, Key key}) : super(key: key);
|
MenuBar({this.episodeItem, this.heroTag, this.hide, Key key})
|
||||||
|
: super(key: key);
|
||||||
@override
|
@override
|
||||||
_MenuBarState createState() => _MenuBarState();
|
_MenuBarState createState() => _MenuBarState();
|
||||||
}
|
}
|
||||||
|
@ -349,10 +376,11 @@ class _MenuBarState extends State<MenuBar> {
|
||||||
height: 30.0,
|
height: 30.0,
|
||||||
width: 30.0,
|
width: 30.0,
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
child: widget.hide ? Center() :
|
child: widget.hide
|
||||||
CircleAvatar(
|
? Center()
|
||||||
backgroundImage:
|
: CircleAvatar(
|
||||||
FileImage(File("${widget.episodeItem.imagePath}"))),
|
backgroundImage:
|
||||||
|
FileImage(File("${widget.episodeItem.imagePath}"))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -72,20 +72,19 @@ class AboutApp extends StatelessWidget {
|
||||||
image: AssetImage('assets/logo.png'),
|
image: AssetImage('assets/logo.png'),
|
||||||
height: 80,
|
height: 80,
|
||||||
),
|
),
|
||||||
Text('Version: 0.1.5'),
|
Text('Version: 0.1.6'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 50),
|
padding: EdgeInsets.symmetric(horizontal: 50),
|
||||||
height: 50,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Tsacdop is a podcast player developed in flutter, a simple, beautiful, and easy-use application.',
|
'Tsacdop is a podcast player developed in flutter, a simply beautiful, and friendly app.',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(5.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
||||||
|
@ -113,7 +112,7 @@ class AboutApp extends StatelessWidget {
|
||||||
'https://twitter.com/shimenmen'),
|
'https://twitter.com/shimenmen'),
|
||||||
_listItem(
|
_listItem(
|
||||||
context,
|
context,
|
||||||
'Stone Gate',
|
'Medium',
|
||||||
LineIcons.medium,
|
LineIcons.medium,
|
||||||
'https://medium.com/@stonegate'),
|
'https://medium.com/@stonegate'),
|
||||||
],
|
],
|
||||||
|
|
|
@ -71,10 +71,10 @@ class MyRoundSliderThumpShape extends SliderComponentShape {
|
||||||
begin: _disabledThumbRadius,
|
begin: _disabledThumbRadius,
|
||||||
end: enabledThumbRadius,
|
end: enabledThumbRadius,
|
||||||
);
|
);
|
||||||
final ColorTween colorTween = ColorTween(
|
// final ColorTween colorTween = ColorTween(
|
||||||
begin: sliderTheme.disabledThumbColor,
|
// begin: sliderTheme.disabledThumbColor,
|
||||||
end: sliderTheme.thumbColor,
|
// end: sliderTheme.thumbColor,
|
||||||
);
|
// );
|
||||||
|
|
||||||
canvas.drawCircle(
|
canvas.drawCircle(
|
||||||
center,
|
center,
|
||||||
|
@ -157,7 +157,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
|
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
|
||||||
return Selector<AudioPlayerNotifier, Tuple3<bool, int, double>>(
|
return Selector<AudioPlayerNotifier, Tuple3<bool, int, double>>(
|
||||||
selector: (_, audio) =>
|
selector: (_, audio) =>
|
||||||
Tuple3(audio.showStopWatch, audio.timeLeft, audio.switchValue),
|
Tuple3(audio.startSleepTimer, audio.timeLeft, audio.switchValue),
|
||||||
builder: (_, data, __) {
|
builder: (_, data, __) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 300,
|
height: 300,
|
||||||
|
@ -547,17 +547,14 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
Spacer(),
|
Spacer(),
|
||||||
Selector<AudioPlayerNotifier, Tuple3<EpisodeBrief, bool, bool>>(
|
Selector<AudioPlayerNotifier, Tuple3<EpisodeBrief, bool, bool>>(
|
||||||
selector: (_, audio) => Tuple3(
|
selector: (_, audio) => Tuple3(
|
||||||
audio.episode, audio.stopOnComplete, audio.showStopWatch),
|
audio.episode, audio.stopOnComplete, audio.startSleepTimer),
|
||||||
builder: (_, data, __) {
|
builder: (_, data, __) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.all(12.0),
|
padding: EdgeInsets.all(5.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.all(5.0),
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
height: 30.0,
|
height: 30.0,
|
||||||
width: 30.0,
|
width: 30.0,
|
||||||
|
@ -568,7 +565,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 5.0),
|
padding: EdgeInsets.symmetric(horizontal: 5.0),
|
||||||
width: 200,
|
width: 150,
|
||||||
child: Text(
|
child: Text(
|
||||||
data.item1.feedTitle,
|
data.item1.feedTitle,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
|
@ -578,6 +575,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
Spacer(),
|
Spacer(),
|
||||||
LastPosition(),
|
LastPosition(),
|
||||||
IconButton(
|
IconButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
onPressed: () => Navigator.push(
|
onPressed: () => Navigator.push(
|
||||||
context,
|
context,
|
||||||
SlideUptRoute(
|
SlideUptRoute(
|
||||||
|
@ -1007,8 +1005,9 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
builder: (_, audioplay, __) {
|
builder: (_, audioplay, __) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Spacer(),
|
||||||
audioplay == BasicPlaybackState.playing
|
audioplay == BasicPlaybackState.playing
|
||||||
? InkWell(
|
? InkWell(
|
||||||
onTap:
|
onTap:
|
||||||
|
@ -1032,7 +1031,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.symmetric(vertical: 10.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 30.0,
|
height: 30.0,
|
||||||
width: 30.0,
|
width: 30.0,
|
||||||
|
@ -1214,7 +1213,7 @@ class _ImageRotateState extends State<ImageRotate>
|
||||||
return Transform.rotate(
|
return Transform.rotate(
|
||||||
angle: 2 * math.pi * _value,
|
angle: 2 * math.pi * _value,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.symmetric(vertical: 10.0),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|
|
@ -482,8 +482,8 @@ class ShowEpisode extends StatelessWidget {
|
||||||
padding: const EdgeInsets.all(5.0),
|
padding: const EdgeInsets.all(5.0),
|
||||||
sliver: SliverGrid(
|
sliver: SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
childAspectRatio: 1.0,
|
childAspectRatio: 1.5,
|
||||||
crossAxisCount: 3,
|
crossAxisCount: 2,
|
||||||
mainAxisSpacing: 6.0,
|
mainAxisSpacing: 6.0,
|
||||||
crossAxisSpacing: 6.0,
|
crossAxisSpacing: 6.0,
|
||||||
),
|
),
|
||||||
|
@ -529,15 +529,6 @@ class ShowEpisode extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
// decoration: BoxDecoration(
|
|
||||||
// border: Border.all(
|
|
||||||
// color: Theme.of(context).brightness ==
|
|
||||||
// Brightness.light
|
|
||||||
// ? Theme.of(context).primaryColor
|
|
||||||
// : Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
// width: 0.0,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -560,7 +551,7 @@ class ShowEpisode extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
episodes[index].isNew == 1
|
episodes[index].isNew == 1
|
||||||
? Text(
|
? Text(
|
||||||
'New',
|
'New',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -579,8 +570,8 @@ class ShowEpisode extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
episodes[index].title,
|
episodes[index].title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: _width / 32,
|
//fontSize: _width / 32,
|
||||||
),
|
),
|
||||||
maxLines: 4,
|
maxLines: 4,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
),
|
),
|
||||||
|
@ -588,17 +579,37 @@ class ShowEpisode extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: Container(
|
child: Row(
|
||||||
alignment: Alignment.bottomLeft,
|
children: <Widget>[
|
||||||
child: Text(
|
Container(
|
||||||
episodes[index].dateToString(),
|
alignment: Alignment.bottomLeft,
|
||||||
//podcast[index].pubDate.substring(4, 16),
|
child: Text(
|
||||||
style: TextStyle(
|
episodes[index].dateToString(),
|
||||||
fontSize: _width / 35,
|
//podcast[index].pubDate.substring(4, 16),
|
||||||
color: _c,
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
fontSize: _width / 35,
|
||||||
|
color: _c,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Spacer(),
|
||||||
|
episodes[index].duration != 0
|
||||||
|
? Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
(episodes[index].duration)
|
||||||
|
.toString() +
|
||||||
|
'mins',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: _width / 35,
|
||||||
|
// color: _c,
|
||||||
|
// fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Center(),
|
||||||
|
],
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -608,7 +619,7 @@ class ShowEpisode extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
childCount: (episodes.length > 3) ? 3 : episodes.length,
|
childCount: (episodes.length > 2) ? 2 : episodes.length,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -88,121 +88,142 @@ class _PlaylistPageState extends State<PlaylistPage> {
|
||||||
height: _topHeight,
|
height: _topHeight,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Expanded(
|
||||||
height: _topHeight,
|
flex: 2,
|
||||||
padding: EdgeInsets.only(
|
child: Container(
|
||||||
left: 70,
|
height: _topHeight,
|
||||||
),
|
padding: EdgeInsets.only(
|
||||||
alignment: Alignment.centerLeft,
|
left: 60,
|
||||||
child: RichText(
|
),
|
||||||
text: TextSpan(
|
alignment: Alignment.centerLeft,
|
||||||
text: _topHeight > 90 ? 'Playlist\n' : '',
|
child: RichText(
|
||||||
style: TextStyle(
|
text: TextSpan(
|
||||||
color:
|
text: _topHeight > 90 ? 'Playlist\n' : '',
|
||||||
Theme.of(context).textTheme.bodyText1.color,
|
style: TextStyle(
|
||||||
fontSize: 30,
|
color: Theme.of(context)
|
||||||
),
|
.textTheme
|
||||||
children: <TextSpan>[
|
.bodyText1
|
||||||
TextSpan(
|
.color,
|
||||||
text: episodes.length.toString(),
|
fontSize: 30,
|
||||||
style: GoogleFonts.cairo(
|
),
|
||||||
textStyle: TextStyle(
|
children: <TextSpan>[
|
||||||
color: Theme.of(context).accentColor,
|
TextSpan(
|
||||||
fontSize: 30,
|
text: episodes.length.toString(),
|
||||||
|
style: GoogleFonts.cairo(
|
||||||
|
textStyle: TextStyle(
|
||||||
|
color: Theme.of(context).accentColor,
|
||||||
|
fontSize: 25,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
TextSpan(
|
||||||
TextSpan(
|
text: episodes.length < 2
|
||||||
text: episodes.length < 2
|
? 'episode'
|
||||||
? ' episode '
|
: 'episodes',
|
||||||
: ' episodes ',
|
style: TextStyle(
|
||||||
style: TextStyle(
|
color: Theme.of(context).accentColor,
|
||||||
|
fontSize: 15,
|
||||||
|
)),
|
||||||
|
TextSpan(
|
||||||
|
text:
|
||||||
|
_sumPlaylistLength(episodes).toString(),
|
||||||
|
style: GoogleFonts.cairo(
|
||||||
|
textStyle: TextStyle(
|
||||||
color: Theme.of(context).accentColor,
|
color: Theme.of(context).accentColor,
|
||||||
fontSize: 20,
|
fontSize: 25,
|
||||||
)),
|
)),
|
||||||
TextSpan(
|
),
|
||||||
text: _sumPlaylistLength(episodes).toString(),
|
TextSpan(
|
||||||
style: GoogleFonts.cairo(
|
text: 'mins',
|
||||||
textStyle: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).accentColor,
|
color: Theme.of(context).accentColor,
|
||||||
fontSize: 30,
|
fontSize: 15,
|
||||||
)),
|
)),
|
||||||
),
|
],
|
||||||
TextSpan(
|
),
|
||||||
text: ' mins',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).accentColor,
|
|
||||||
fontSize: 20,
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Spacer(),
|
Expanded(
|
||||||
Container(
|
flex: 1,
|
||||||
padding: EdgeInsets.only(
|
child: Container(
|
||||||
right: 20,
|
padding: EdgeInsets.all(5.0),
|
||||||
),
|
margin: EdgeInsets.only(right: 20.0, bottom: 5.0),
|
||||||
child: data.item2
|
decoration: data.item2 ? BoxDecoration(
|
||||||
? _topHeight < 90
|
color: context.brightness == Brightness.dark ? Colors.grey[800] : Colors.grey[200],
|
||||||
? Row(
|
borderRadius:
|
||||||
mainAxisAlignment:
|
BorderRadius.all(Radius.circular(10.0)),
|
||||||
MainAxisAlignment.center,
|
) :
|
||||||
crossAxisAlignment:
|
BoxDecoration(
|
||||||
CrossAxisAlignment.center,
|
shape: BoxShape.circle,
|
||||||
children: <Widget>[
|
color: Colors.transparent
|
||||||
CircleAvatar(
|
),
|
||||||
radius: 12,
|
child: data.item2
|
||||||
backgroundImage: FileImage(File(
|
? _topHeight < 90
|
||||||
"${episodes.first.imagePath}")),
|
? Row(
|
||||||
),
|
mainAxisAlignment:
|
||||||
Padding(
|
MainAxisAlignment.center,
|
||||||
padding: EdgeInsets.symmetric(
|
crossAxisAlignment:
|
||||||
horizontal: 15),
|
CrossAxisAlignment.center,
|
||||||
child: SizedBox(
|
children: <Widget>[
|
||||||
width: 20,
|
CircleAvatar(
|
||||||
height: 15,
|
radius: 12,
|
||||||
child: WaveLoader()),
|
backgroundImage: FileImage(File(
|
||||||
),
|
"${episodes.first.imagePath}")),
|
||||||
],
|
|
||||||
)
|
|
||||||
: Column(
|
|
||||||
mainAxisAlignment:
|
|
||||||
MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment:
|
|
||||||
CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
CircleAvatar(
|
|
||||||
radius: 15,
|
|
||||||
//backgroundColor: _c.withOpacity(0.5),
|
|
||||||
backgroundImage: FileImage(File(
|
|
||||||
"${episodes.first.imagePath}")),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 150,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Text(
|
|
||||||
episodes.first.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.fade,
|
|
||||||
),
|
),
|
||||||
),
|
Padding(
|
||||||
Padding(
|
padding: EdgeInsets.symmetric(
|
||||||
padding: EdgeInsets.symmetric(
|
horizontal: 15),
|
||||||
horizontal: 15),
|
child: SizedBox(
|
||||||
child: SizedBox(
|
width: 20,
|
||||||
width: 20,
|
height: 15,
|
||||||
height: 15,
|
child: WaveLoader()),
|
||||||
child: WaveLoader()),
|
),
|
||||||
),
|
],
|
||||||
],
|
)
|
||||||
)
|
: Column(
|
||||||
: IconButton(
|
mainAxisAlignment:
|
||||||
icon: Icon(Icons.play_circle_filled,
|
MainAxisAlignment.center,
|
||||||
size: 40,
|
crossAxisAlignment:
|
||||||
color: Theme.of(context).accentColor),
|
CrossAxisAlignment.center,
|
||||||
onPressed: () => audio.playlistLoad(),
|
children: <Widget>[
|
||||||
),
|
CircleAvatar(
|
||||||
|
radius: 15,
|
||||||
|
//backgroundColor: _c.withOpacity(0.5),
|
||||||
|
backgroundImage: FileImage(File(
|
||||||
|
"${episodes.first.imagePath}")),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 150,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
episodes.first.title,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 15),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 15,
|
||||||
|
child: WaveLoader()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: IconButton(
|
||||||
|
padding: EdgeInsets.all(0),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
icon: Icon(Icons.play_circle_filled,
|
||||||
|
size: 40,
|
||||||
|
color: Theme.of(context).accentColor),
|
||||||
|
onPressed: () {
|
||||||
|
audio.playlistLoad();
|
||||||
|
// setState(() {});
|
||||||
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -286,6 +307,7 @@ class _DismissibleContainerState extends State<DismissibleContainer> {
|
||||||
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
|
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
|
||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: Duration(milliseconds: 300),
|
duration: Duration(milliseconds: 300),
|
||||||
|
alignment: Alignment.center,
|
||||||
height: _delete ? 0 : 95.0,
|
height: _delete ? 0 : 95.0,
|
||||||
child: _delete
|
child: _delete
|
||||||
? Container(
|
? Container(
|
||||||
|
|
|
@ -195,12 +195,12 @@ class DBHelper {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<PlayHistory>> getPlayHistory() async {
|
Future<List<PlayHistory>> getPlayHistory(int top) async {
|
||||||
var dbClient = await database;
|
var dbClient = await database;
|
||||||
List<Map> list = await dbClient.rawQuery(
|
List<Map> list = await dbClient.rawQuery(
|
||||||
"""SELECT title, enclosure_url, seconds, seek_value, add_date FROM PlayHistory
|
"""SELECT title, enclosure_url, seconds, seek_value, add_date FROM PlayHistory
|
||||||
ORDER BY add_date DESC
|
ORDER BY add_date DESC LIMIT ?
|
||||||
""");
|
""",[top]);
|
||||||
List<PlayHistory> playHistory = [];
|
List<PlayHistory> playHistory = [];
|
||||||
list.forEach((record) {
|
list.forEach((record) {
|
||||||
playHistory.add(PlayHistory(record['title'], record['enclosure_url'],
|
playHistory.add(PlayHistory(record['title'], record['enclosure_url'],
|
||||||
|
|
|
@ -173,7 +173,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_loadMore = false;
|
_loadMore = false;
|
||||||
_top = 33;
|
_top = 99;
|
||||||
_controller = ScrollController();
|
_controller = ScrollController();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,26 @@ class PlayedHistory extends StatefulWidget {
|
||||||
|
|
||||||
class _PlayedHistoryState extends State<PlayedHistory>
|
class _PlayedHistoryState extends State<PlayedHistory>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
Future<List<PlayHistory>> getPlayHistory() async {
|
Future<List<PlayHistory>> getPlayHistory(int top) async {
|
||||||
DBHelper dbHelper = DBHelper();
|
DBHelper dbHelper = DBHelper();
|
||||||
List<PlayHistory> playHistory;
|
List<PlayHistory> playHistory;
|
||||||
playHistory = await dbHelper.getPlayHistory();
|
playHistory = await dbHelper.getPlayHistory(top);
|
||||||
await Future.forEach(playHistory, (playHistory) async {
|
await Future.forEach(playHistory, (playHistory) async {
|
||||||
await playHistory.getEpisode();
|
await playHistory.getEpisode();
|
||||||
});
|
});
|
||||||
return playHistory;
|
return playHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_loadMoreData() async {
|
||||||
|
// await Future.delayed(Duration(seconds: 3));
|
||||||
|
if (mounted)
|
||||||
|
setState(() {
|
||||||
|
_top = _top + 100;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int _top = 100;
|
||||||
|
|
||||||
Future<List<SubHistory>> getSubHistory() async {
|
Future<List<SubHistory>> getSubHistory() async {
|
||||||
DBHelper dbHelper = DBHelper();
|
DBHelper dbHelper = DBHelper();
|
||||||
return await dbHelper.getSubHistory();
|
return await dbHelper.getSubHistory();
|
||||||
|
@ -126,94 +136,109 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
||||||
},
|
},
|
||||||
body: TabBarView(controller: _controller, children: <Widget>[
|
body: TabBarView(controller: _controller, children: <Widget>[
|
||||||
FutureBuilder<List<PlayHistory>>(
|
FutureBuilder<List<PlayHistory>>(
|
||||||
future: getPlayHistory(),
|
future: getPlayHistory(_top),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
double _width = MediaQuery.of(context).size.width;
|
double _width = MediaQuery.of(context).size.width;
|
||||||
return snapshot.hasData
|
return snapshot.hasData
|
||||||
? ListView.builder(
|
? NotificationListener<ScrollNotification>(
|
||||||
shrinkWrap: true,
|
onNotification: (ScrollNotification scrollInfo) {
|
||||||
scrollDirection: Axis.vertical,
|
if (scrollInfo.metrics.pixels ==
|
||||||
itemCount: snapshot.data.length,
|
scrollInfo.metrics.maxScrollExtent &&
|
||||||
itemBuilder: (BuildContext context, int index) {
|
snapshot.data.length == _top)
|
||||||
return Container(
|
_loadMoreData();
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
return true;
|
||||||
child: Column(
|
},
|
||||||
children: <Widget>[
|
child: ListView.builder(
|
||||||
ListTile(
|
//shrinkWrap: true,
|
||||||
title: Column(
|
scrollDirection: Axis.vertical,
|
||||||
mainAxisAlignment:
|
itemCount: snapshot.data.length,
|
||||||
MainAxisAlignment.start,
|
itemBuilder: (BuildContext context, int index) {
|
||||||
crossAxisAlignment:
|
return Container(
|
||||||
CrossAxisAlignment.start,
|
color:
|
||||||
children: <Widget>[
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
Text(
|
child: Column(
|
||||||
DateFormat.yMd().add_jm().format(
|
children: <Widget>[
|
||||||
snapshot.data[index].playdate),
|
ListTile(
|
||||||
style: TextStyle(
|
title: Column(
|
||||||
color: const Color(0xff67727d),
|
mainAxisAlignment:
|
||||||
fontSize: 15,
|
MainAxisAlignment.start,
|
||||||
fontStyle: FontStyle.italic),
|
crossAxisAlignment:
|
||||||
),
|
CrossAxisAlignment.start,
|
||||||
Text(
|
children: <Widget>[
|
||||||
snapshot.data[index].title,
|
Text(
|
||||||
maxLines: 2,
|
DateFormat.yMd().add_jm().format(
|
||||||
overflow: TextOverflow.ellipsis,
|
snapshot
|
||||||
),
|
.data[index].playdate),
|
||||||
],
|
|
||||||
),
|
|
||||||
subtitle: Container(
|
|
||||||
width: _width,
|
|
||||||
child: Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Icon(
|
|
||||||
Icons.timelapse,
|
|
||||||
color: Colors.grey[400],
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 2,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(
|
|
||||||
color: Colors.grey[400],
|
|
||||||
width: 2.0))),
|
|
||||||
width: _width *
|
|
||||||
snapshot.data[index]
|
|
||||||
.seekValue <
|
|
||||||
(_width - 120)
|
|
||||||
? _width *
|
|
||||||
snapshot
|
|
||||||
.data[index].seekValue
|
|
||||||
: _width - 120,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 2),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 50,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.accentColor,
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(10))),
|
|
||||||
padding: EdgeInsets.all(2),
|
|
||||||
child: Text(
|
|
||||||
_stringForSeconds(
|
|
||||||
snapshot.data[index].seconds),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white),
|
color:
|
||||||
|
const Color(0xff67727d),
|
||||||
|
fontSize: 15,
|
||||||
|
fontStyle: FontStyle.italic),
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
snapshot.data[index].title,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
subtitle: Container(
|
||||||
|
width: _width,
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(
|
||||||
|
Icons.timelapse,
|
||||||
|
color: Colors.grey[400],
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: 2,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: Colors
|
||||||
|
.grey[400],
|
||||||
|
width: 2.0))),
|
||||||
|
width: _width *
|
||||||
|
snapshot.data[index]
|
||||||
|
.seekValue <
|
||||||
|
(_width - 120)
|
||||||
|
? _width *
|
||||||
|
snapshot.data[index]
|
||||||
|
.seekValue
|
||||||
|
: _width - 120,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 2),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 50,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.accentColor,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(
|
||||||
|
Radius.circular(
|
||||||
|
10))),
|
||||||
|
padding: EdgeInsets.all(2),
|
||||||
|
child: Text(
|
||||||
|
_stringForSeconds(snapshot
|
||||||
|
.data[index].seconds),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
// Divider(height: 2),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
// Divider(height: 2),
|
);
|
||||||
],
|
}),
|
||||||
),
|
)
|
||||||
);
|
|
||||||
})
|
|
||||||
: Center(
|
: Center(
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,5 +41,8 @@ List<Libries> plugins = [
|
||||||
Libries('audio_service', mit, 'https://pub.dev/packages/audio_service'),
|
Libries('audio_service', mit, 'https://pub.dev/packages/audio_service'),
|
||||||
Libries('just_audio', apacheLicense, 'https://pub.dev/packages/just_audio'),
|
Libries('just_audio', apacheLicense, 'https://pub.dev/packages/just_audio'),
|
||||||
Libries('line_icons', gpl, 'https://pub.dev/packages/line_icons'),
|
Libries('line_icons', gpl, 'https://pub.dev/packages/line_icons'),
|
||||||
Libries('flutter_file_dialog', bsd, 'https://pub.dev/packages/flutter_file_dialog')
|
Libries('flutter_file_dialog', bsd, 'https://pub.dev/packages/flutter_file_dialog'),
|
||||||
|
Libries('flutter_linkify', mit, 'https://pub.dev/packages/flutter_linkify'),
|
||||||
|
Libries('extended_nested_scroll_view', mit, 'https://pub.dev/packages/extended_nested_scroll_view'),
|
||||||
|
Libries('connectivity', bsd, 'https://pub.dev/packages/connectivity'),
|
||||||
];
|
];
|
|
@ -195,7 +195,7 @@ class Settings extends StatelessWidget {
|
||||||
EdgeInsets.symmetric(horizontal: 25.0),
|
EdgeInsets.symmetric(horizontal: 25.0),
|
||||||
leading: Icon(LineIcons.map_signs_solid),
|
leading: Icon(LineIcons.map_signs_solid),
|
||||||
title: Text('Changelog'),
|
title: Text('Changelog'),
|
||||||
subtitle: Text('List of chagnes'),
|
subtitle: Text('List of changes'),
|
||||||
),
|
),
|
||||||
Divider(height: 2),
|
Divider(height: 2),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
@ -213,7 +213,7 @@ class Settings extends StatelessWidget {
|
||||||
Divider(height: 2),
|
Divider(height: 2),
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => _launchUrl(
|
onTap: () => _launchUrl(
|
||||||
'mailto:<xijieyin@gmail.com>?subject=Tsacdop Feedback'),
|
'mailto:<tsacdop.app@gmail.com>?subject=Tsacdop Feedback'),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.symmetric(horizontal: 25.0),
|
EdgeInsets.symmetric(horizontal: 25.0),
|
||||||
leading: Icon(LineIcons.bug_solid),
|
leading: Icon(LineIcons.bug_solid),
|
||||||
|
|
|
@ -58,7 +58,7 @@ class StorageSetting extends StatelessWidget {
|
||||||
EdgeInsets.only(left: 80.0, right: 25),
|
EdgeInsets.only(left: 80.0, right: 25),
|
||||||
title: Text('Ask before using cellular data'),
|
title: Text('Ask before using cellular data'),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'Ask to confirem when using cellular data to download episodes.'),
|
'Ask to confirm when using cellular data to download episodes.'),
|
||||||
trailing: Selector<SettingState, bool>(
|
trailing: Selector<SettingState, bool>(
|
||||||
selector: (_, settings) =>
|
selector: (_, settings) =>
|
||||||
settings.downloadUsingData,
|
settings.downloadUsingData,
|
||||||
|
|
|
@ -8,4 +8,5 @@ extension ContextExtension on BuildContext{
|
||||||
Brightness get brightness => Theme.of(this).brightness;
|
Brightness get brightness => Theme.of(this).brightness;
|
||||||
double get width => MediaQuery.of(this).size.width;
|
double get width => MediaQuery.of(this).size.width;
|
||||||
double get height => MediaQuery.of(this).size.width;
|
double get height => MediaQuery.of(this).size.width;
|
||||||
|
TextTheme get textTheme => Theme.of(this).textTheme;
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
//Fork from https://github.com/divyanshub024/day_night_switch
|
//Fork from https://github.com/divyanshub024/day_night_switch
|
||||||
|
//Copyright https://github.com/divyanshub024
|
||||||
|
//Apache License 2.0 https://github.com/divyanshub024/day_night_switch/blob/master/LICENSE
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
|
|
|
@ -104,7 +104,7 @@ class EpisodeGrid extends StatelessWidget {
|
||||||
const EdgeInsets.only(top: 5.0, bottom: 5.0, left: 15.0, right: 15.0),
|
const EdgeInsets.only(top: 5.0, bottom: 5.0, left: 15.0, right: 15.0),
|
||||||
sliver: SliverGrid(
|
sliver: SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
childAspectRatio: 1.0,
|
childAspectRatio: 1,
|
||||||
crossAxisCount: 3,
|
crossAxisCount: 3,
|
||||||
mainAxisSpacing: 6.0,
|
mainAxisSpacing: 6.0,
|
||||||
crossAxisSpacing: 6.0,
|
crossAxisSpacing: 6.0,
|
||||||
|
@ -213,7 +213,7 @@ class EpisodeGrid extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
episodes[index].title,
|
episodes[index].title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: _width / 32,
|
// fontSize: _width / 32,
|
||||||
),
|
),
|
||||||
maxLines: 4,
|
maxLines: 4,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
Forked from https://github.com/witochandra/webfeed
|
Forked from https://github.com/witochandra/webfeed
|
||||||
|
Copyright https://github.com/witochandra ALL RIGHT RESERVED
|
||||||
|
Mit License https://github.com/witochandra/webfeed/blob/master/LICENSE
|
|
@ -11,7 +11,7 @@ description: An easy-use podacasts player.
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 0.1.5
|
version: 0.1.6
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.6.0 <3.0.0"
|
sdk: ">=2.6.0 <3.0.0"
|
||||||
|
@ -56,7 +56,6 @@ dev_dependencies:
|
||||||
just_audio:
|
just_audio:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/stonega/just_audio.git
|
url: https://github.com/stonega/just_audio.git
|
||||||
rxdart: ^0.23.1
|
|
||||||
line_icons:
|
line_icons:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/galonsos/line_icons.git
|
url: https://github.com/galonsos/line_icons.git
|
||||||
|
|
Loading…
Reference in New Issue