Bug fixes

Change home group preview grid to 2
This commit is contained in:
stonegate 2020-04-02 17:52:26 +08:00
parent 0a0e0a45f5
commit 5dc490f83f
18 changed files with 394 additions and 300 deletions

BIN
assets/shownote.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -126,7 +126,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
bool _stopOnComplete = false;
Timer _stopTimer;
int _timeLeft = 0;
bool _showStopWatch = false;
bool _startSleepTimer = false;
double _switchValue = 0;
bool _autoPlay = true;
DateTime _current;
@ -144,7 +144,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
bool get queueUpdate => _queueUpdate;
EpisodeBrief get episode => _episode;
bool get stopOnComplete => _stopOnComplete;
bool get showStopWatch => _showStopWatch;
bool get startSleepTimer => _startSleepTimer;
bool get autoPlay => _autoPlay;
int get timeLeft => _timeLeft;
double get switchValue => _switchValue;
@ -165,8 +165,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
_queueUpdate = false;
await AudioService.connect();
bool running = await AudioService.running;
if (running) {
}
if (running) {}
}
loadPlaylist() async {
@ -217,13 +216,13 @@ class AudioPlayerNotifier extends ChangeNotifier {
await AudioService.connect();
}
await AudioService.start(
backgroundTaskEntrypoint: _audioPlayerTaskEntrypoint,
androidNotificationChannelName: 'Tsacdop',
notificationColor: 0xFF4d91be,
androidNotificationIcon: 'drawable/ic_notification',
enableQueue: true,
androidStopOnRemoveTask: true,
androidStopForegroundOnPause: true);
backgroundTaskEntrypoint: _audioPlayerTaskEntrypoint,
androidNotificationChannelName: 'Tsacdop',
notificationColor: 0xFF4d91be,
androidNotificationIcon: 'drawable/ic_notification',
enableQueue: true,
androidStopOnRemoveTask: true,
);
_playerRunning = true;
if (_autoPlay) {
await Future.forEach(_queue.playlist, (episode) async {
@ -312,7 +311,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
}
notifyListeners();
}
if (_audioState == BasicPlaybackState.stopped) {
if (_audioState == BasicPlaybackState.stopped || _playerRunning == false) {
timer.cancel();
}
});
@ -325,6 +324,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
_seekSliderValue = 0;
_episode = _queue.playlist.first;
_playerRunning = true;
_queueUpdate = !_queueUpdate;
notifyListeners();
_startAudioService(_lastPostion ?? 0);
}
@ -397,9 +397,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
int pos = _backgroundAudioPosition + s * 1000;
AudioService.seekTo(pos);
}
seekTo(int position) async{
if (_audioState != BasicPlaybackState.connecting &&
seekTo(int position) async {
if (_audioState != BasicPlaybackState.connecting &&
_audioState != BasicPlaybackState.none)
await AudioService.seekTo(position);
}
@ -417,9 +417,9 @@ class AudioPlayerNotifier extends ChangeNotifier {
}
}
//Set sleep time
//Set sleep timer
sleepTimer(int mins) {
_showStopWatch = true;
_startSleepTimer= true;
_switchValue = 1;
notifyListeners();
_timeLeft = mins * 60;
@ -432,12 +432,14 @@ class AudioPlayerNotifier extends ChangeNotifier {
notifyListeners();
}
});
_stopTimer = Timer(Duration(minutes: mins), () {
_stopTimer = Timer(Duration(minutes: mins), () {
_stopOnComplete = false;
_showStopWatch = false;
_startSleepTimer= false;
_switchValue = 0;
_playerRunning = false;
notifyListeners();
AudioService.stop();
notifyListeners();
AudioService.disconnect();
});
}
@ -445,7 +447,7 @@ class AudioPlayerNotifier extends ChangeNotifier {
cancelTimer() {
_stopTimer.cancel();
_timeLeft = 0;
_showStopWatch = false;
_startSleepTimer= false;
_switchValue = 0;
notifyListeners();
}

View File

@ -16,13 +16,16 @@ import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:tsacdop/class/audiostate.dart';
import 'package:tsacdop/class/episodebrief.dart';
import 'package:tsacdop/local_storage/sqflite_localpodcast.dart';
import 'package:tsacdop/util/context_extension.dart';
import 'episodedownload.dart';
class EpisodeDetail extends StatefulWidget {
final EpisodeBrief episodeItem;
final String heroTag;
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
_EpisodeDetailState createState() => _EpisodeDetailState();
@ -38,7 +41,8 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
Future getSDescription(String url) async {
var dbHelper = DBHelper();
_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)
setState(() {
_loaddes = true;
@ -93,7 +97,7 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
child: Scaffold(
backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar(
// title: Text(widget.episodeItem.feedTitle),
// title: Text(widget.episodeItem.feedTitle),
centerTitle: true,
),
body: Stack(
@ -197,13 +201,12 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
padding: EdgeInsets.only(top: 5.0),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
//physics: AlwaysScrollableScrollPhysics(),
controller: _controller,
child: _loaddes
? (_description.contains('<'))
? Html(
padding:
EdgeInsets.only(left: 20.0, right: 20, bottom: 10),
padding: EdgeInsets.only(
left: 20.0, right: 20, bottom: 10),
defaultTextStyle: TextStyle(height: 1.8),
data: _description,
linkStyle: TextStyle(
@ -215,24 +218,48 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
},
useRichText: true,
)
: Container(
padding:
EdgeInsets.only(left: 20.0, right: 20.0, bottom: 10.0),
alignment: Alignment.topLeft,
child: SelectableLinkify(
onOpen: (link) {
_launchUrl(link.url);
},
text: _description,
style: TextStyle(
height: 1.8,
),
linkStyle: TextStyle(
color: Theme.of(context).accentColor,
decoration: TextDecoration.underline,
),
),
)
: _description.length > 0
? Container(
padding: EdgeInsets.only(
left: 20.0,
right: 20.0,
bottom: 10.0),
alignment: Alignment.topLeft,
child: SelectableLinkify(
onOpen: (link) {
_launchUrl(link.url);
},
text: _description,
style: TextStyle(
height: 1.8,
),
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(),
),
),
@ -259,10 +286,9 @@ class _EpisodeDetailState extends State<EpisodeDetail> {
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: MenuBar(
episodeItem: widget.episodeItem,
heroTag: widget.heroTag,
hide: widget.hide
),
episodeItem: widget.episodeItem,
heroTag: widget.heroTag,
hide: widget.hide),
),
),
);
@ -279,7 +305,8 @@ class MenuBar extends StatefulWidget {
final EpisodeBrief episodeItem;
final String heroTag;
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
_MenuBarState createState() => _MenuBarState();
}
@ -349,10 +376,11 @@ class _MenuBarState extends State<MenuBar> {
height: 30.0,
width: 30.0,
color: Theme.of(context).scaffoldBackgroundColor,
child: widget.hide ? Center() :
CircleAvatar(
backgroundImage:
FileImage(File("${widget.episodeItem.imagePath}"))),
child: widget.hide
? Center()
: CircleAvatar(
backgroundImage:
FileImage(File("${widget.episodeItem.imagePath}"))),
),
),
),

View File

@ -72,20 +72,19 @@ class AboutApp extends StatelessWidget {
image: AssetImage('assets/logo.png'),
height: 80,
),
Text('Version: 0.1.5'),
Text('Version: 0.1.6'),
],
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 50),
height: 50,
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,
),
),
Padding(
padding: EdgeInsets.all(5.0),
padding: EdgeInsets.all(10.0),
),
Container(
padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
@ -113,7 +112,7 @@ class AboutApp extends StatelessWidget {
'https://twitter.com/shimenmen'),
_listItem(
context,
'Stone Gate',
'Medium',
LineIcons.medium,
'https://medium.com/@stonegate'),
],

View File

@ -71,10 +71,10 @@ class MyRoundSliderThumpShape extends SliderComponentShape {
begin: _disabledThumbRadius,
end: enabledThumbRadius,
);
final ColorTween colorTween = ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.thumbColor,
);
// final ColorTween colorTween = ColorTween(
// begin: sliderTheme.disabledThumbColor,
// end: sliderTheme.thumbColor,
// );
canvas.drawCircle(
center,
@ -157,7 +157,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
return Selector<AudioPlayerNotifier, Tuple3<bool, int, double>>(
selector: (_, audio) =>
Tuple3(audio.showStopWatch, audio.timeLeft, audio.switchValue),
Tuple3(audio.startSleepTimer, audio.timeLeft, audio.switchValue),
builder: (_, data, __) {
return Container(
height: 300,
@ -547,17 +547,14 @@ class _PlayerWidgetState extends State<PlayerWidget> {
Spacer(),
Selector<AudioPlayerNotifier, Tuple3<EpisodeBrief, bool, bool>>(
selector: (_, audio) => Tuple3(
audio.episode, audio.stopOnComplete, audio.showStopWatch),
audio.episode, audio.stopOnComplete, audio.startSleepTimer),
builder: (_, data, __) {
return Container(
padding: EdgeInsets.all(12.0),
padding: EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(5.0),
),
Container(
height: 30.0,
width: 30.0,
@ -568,7 +565,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
),
Container(
padding: EdgeInsets.symmetric(horizontal: 5.0),
width: 200,
width: 150,
child: Text(
data.item1.feedTitle,
maxLines: 1,
@ -578,6 +575,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
Spacer(),
LastPosition(),
IconButton(
padding: EdgeInsets.zero,
onPressed: () => Navigator.push(
context,
SlideUptRoute(
@ -1007,8 +1005,9 @@ class _PlayerWidgetState extends State<PlayerWidget> {
builder: (_, audioplay, __) {
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Spacer(),
audioplay == BasicPlaybackState.playing
? InkWell(
onTap:
@ -1032,7 +1031,7 @@ class _PlayerWidgetState extends State<PlayerWidget> {
alignment: Alignment.center,
children: <Widget>[
Container(
padding: EdgeInsets.all(10.0),
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Container(
height: 30.0,
width: 30.0,
@ -1214,7 +1213,7 @@ class _ImageRotateState extends State<ImageRotate>
return Transform.rotate(
angle: 2 * math.pi * _value,
child: Container(
padding: EdgeInsets.all(10.0),
padding: EdgeInsets.symmetric(vertical: 10.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
child: Container(

View File

@ -482,8 +482,8 @@ class ShowEpisode extends StatelessWidget {
padding: const EdgeInsets.all(5.0),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1.0,
crossAxisCount: 3,
childAspectRatio: 1.5,
crossAxisCount: 2,
mainAxisSpacing: 6.0,
crossAxisSpacing: 6.0,
),
@ -529,15 +529,6 @@ class ShowEpisode extends StatelessWidget {
);
},
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),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
@ -560,7 +551,7 @@ class ShowEpisode extends StatelessWidget {
),
),
Spacer(),
episodes[index].isNew == 1
episodes[index].isNew == 1
? Text(
'New',
style: TextStyle(
@ -579,8 +570,8 @@ class ShowEpisode extends StatelessWidget {
child: Text(
episodes[index].title,
style: TextStyle(
fontSize: _width / 32,
),
//fontSize: _width / 32,
),
maxLines: 4,
overflow: TextOverflow.fade,
),
@ -588,17 +579,37 @@ class ShowEpisode extends StatelessWidget {
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.bottomLeft,
child: Text(
episodes[index].dateToString(),
//podcast[index].pubDate.substring(4, 16),
style: TextStyle(
fontSize: _width / 35,
color: _c,
fontStyle: FontStyle.italic,
child: Row(
children: <Widget>[
Container(
alignment: Alignment.bottomLeft,
child: Text(
episodes[index].dateToString(),
//podcast[index].pubDate.substring(4, 16),
style: TextStyle(
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,
),
),
),

View File

@ -88,121 +88,142 @@ class _PlaylistPageState extends State<PlaylistPage> {
height: _topHeight,
child: Row(
children: <Widget>[
Container(
height: _topHeight,
padding: EdgeInsets.only(
left: 70,
),
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
text: _topHeight > 90 ? 'Playlist\n' : '',
style: TextStyle(
color:
Theme.of(context).textTheme.bodyText1.color,
fontSize: 30,
),
children: <TextSpan>[
TextSpan(
text: episodes.length.toString(),
style: GoogleFonts.cairo(
textStyle: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 30,
Expanded(
flex: 2,
child: Container(
height: _topHeight,
padding: EdgeInsets.only(
left: 60,
),
alignment: Alignment.centerLeft,
child: RichText(
text: TextSpan(
text: _topHeight > 90 ? 'Playlist\n' : '',
style: TextStyle(
color: Theme.of(context)
.textTheme
.bodyText1
.color,
fontSize: 30,
),
children: <TextSpan>[
TextSpan(
text: episodes.length.toString(),
style: GoogleFonts.cairo(
textStyle: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 25,
),
),
),
),
TextSpan(
text: episodes.length < 2
? ' episode '
: ' episodes ',
style: TextStyle(
TextSpan(
text: episodes.length < 2
? 'episode'
: 'episodes',
style: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 15,
)),
TextSpan(
text:
_sumPlaylistLength(episodes).toString(),
style: GoogleFonts.cairo(
textStyle: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 20,
fontSize: 25,
)),
TextSpan(
text: _sumPlaylistLength(episodes).toString(),
style: GoogleFonts.cairo(
textStyle: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 30,
)),
),
TextSpan(
text: ' mins',
style: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 20,
)),
],
),
TextSpan(
text: 'mins',
style: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 15,
)),
],
),
),
),
),
Spacer(),
Container(
padding: EdgeInsets.only(
right: 20,
),
child: data.item2
? _topHeight < 90
? Row(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 12,
backgroundImage: FileImage(File(
"${episodes.first.imagePath}")),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15),
child: SizedBox(
width: 20,
height: 15,
child: WaveLoader()),
),
],
)
: 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,
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(5.0),
margin: EdgeInsets.only(right: 20.0, bottom: 5.0),
decoration: data.item2 ? BoxDecoration(
color: context.brightness == Brightness.dark ? Colors.grey[800] : Colors.grey[200],
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
) :
BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent
),
child: data.item2
? _topHeight < 90
? Row(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[
CircleAvatar(
radius: 12,
backgroundImage: FileImage(File(
"${episodes.first.imagePath}")),
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15),
child: SizedBox(
width: 20,
height: 15,
child: WaveLoader()),
),
],
)
: IconButton(
icon: Icon(Icons.play_circle_filled,
size: 40,
color: Theme.of(context).accentColor),
onPressed: () => audio.playlistLoad(),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 15),
child: SizedBox(
width: 20,
height: 15,
child: WaveLoader()),
),
],
)
: 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,
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);
return AnimatedContainer(
duration: Duration(milliseconds: 300),
alignment: Alignment.center,
height: _delete ? 0 : 95.0,
child: _delete
? Container(

View File

@ -195,12 +195,12 @@ class DBHelper {
return result;
}
Future<List<PlayHistory>> getPlayHistory() async {
Future<List<PlayHistory>> getPlayHistory(int top) async {
var dbClient = await database;
List<Map> list = await dbClient.rawQuery(
"""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.forEach((record) {
playHistory.add(PlayHistory(record['title'], record['enclosure_url'],

View File

@ -173,7 +173,7 @@ class _PodcastDetailState extends State<PodcastDetail> {
void initState() {
super.initState();
_loadMore = false;
_top = 33;
_top = 99;
_controller = ScrollController();
}

View File

@ -13,16 +13,26 @@ class PlayedHistory extends StatefulWidget {
class _PlayedHistoryState extends State<PlayedHistory>
with SingleTickerProviderStateMixin {
Future<List<PlayHistory>> getPlayHistory() async {
Future<List<PlayHistory>> getPlayHistory(int top) async {
DBHelper dbHelper = DBHelper();
List<PlayHistory> playHistory;
playHistory = await dbHelper.getPlayHistory();
playHistory = await dbHelper.getPlayHistory(top);
await Future.forEach(playHistory, (playHistory) async {
await playHistory.getEpisode();
});
return playHistory;
}
_loadMoreData() async {
// await Future.delayed(Duration(seconds: 3));
if (mounted)
setState(() {
_top = _top + 100;
});
}
int _top = 100;
Future<List<SubHistory>> getSubHistory() async {
DBHelper dbHelper = DBHelper();
return await dbHelper.getSubHistory();
@ -126,94 +136,109 @@ class _PlayedHistoryState extends State<PlayedHistory>
},
body: TabBarView(controller: _controller, children: <Widget>[
FutureBuilder<List<PlayHistory>>(
future: getPlayHistory(),
future: getPlayHistory(_top),
builder: (context, snapshot) {
double _width = MediaQuery.of(context).size.width;
return snapshot.hasData
? ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: Column(
children: <Widget>[
ListTile(
title: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
DateFormat.yMd().add_jm().format(
snapshot.data[index].playdate),
style: TextStyle(
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),
? NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification scrollInfo) {
if (scrollInfo.metrics.pixels ==
scrollInfo.metrics.maxScrollExtent &&
snapshot.data.length == _top)
_loadMoreData();
return true;
},
child: ListView.builder(
//shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
color:
Theme.of(context).scaffoldBackgroundColor,
child: Column(
children: <Widget>[
ListTile(
title: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Text(
DateFormat.yMd().add_jm().format(
snapshot
.data[index].playdate),
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(
child: CircularProgressIndicator(),
);

View File

@ -41,5 +41,8 @@ List<Libries> plugins = [
Libries('audio_service', mit, 'https://pub.dev/packages/audio_service'),
Libries('just_audio', apacheLicense, 'https://pub.dev/packages/just_audio'),
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'),
];

View File

@ -195,7 +195,7 @@ class Settings extends StatelessWidget {
EdgeInsets.symmetric(horizontal: 25.0),
leading: Icon(LineIcons.map_signs_solid),
title: Text('Changelog'),
subtitle: Text('List of chagnes'),
subtitle: Text('List of changes'),
),
Divider(height: 2),
ListTile(
@ -213,7 +213,7 @@ class Settings extends StatelessWidget {
Divider(height: 2),
ListTile(
onTap: () => _launchUrl(
'mailto:<xijieyin@gmail.com>?subject=Tsacdop Feedback'),
'mailto:<tsacdop.app@gmail.com>?subject=Tsacdop Feedback'),
contentPadding:
EdgeInsets.symmetric(horizontal: 25.0),
leading: Icon(LineIcons.bug_solid),

View File

@ -58,7 +58,7 @@ class StorageSetting extends StatelessWidget {
EdgeInsets.only(left: 80.0, right: 25),
title: Text('Ask before using cellular data'),
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>(
selector: (_, settings) =>
settings.downloadUsingData,

View File

@ -8,4 +8,5 @@ extension ContextExtension on BuildContext{
Brightness get brightness => Theme.of(this).brightness;
double get width => MediaQuery.of(this).size.width;
double get height => MediaQuery.of(this).size.width;
TextTheme get textTheme => Theme.of(this).textTheme;
}

View File

@ -1,4 +1,7 @@
//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/gestures.dart';

View File

@ -104,7 +104,7 @@ class EpisodeGrid extends StatelessWidget {
const EdgeInsets.only(top: 5.0, bottom: 5.0, left: 15.0, right: 15.0),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1.0,
childAspectRatio: 1,
crossAxisCount: 3,
mainAxisSpacing: 6.0,
crossAxisSpacing: 6.0,
@ -213,7 +213,7 @@ class EpisodeGrid extends StatelessWidget {
child: Text(
episodes[index].title,
style: TextStyle(
fontSize: _width / 32,
// fontSize: _width / 32,
),
maxLines: 4,
overflow: TextOverflow.fade,

View File

@ -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

View File

@ -11,7 +11,7 @@ description: An easy-use podacasts player.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.1.5
version: 0.1.6
environment:
sdk: ">=2.6.0 <3.0.0"
@ -56,7 +56,6 @@ dev_dependencies:
just_audio:
git:
url: https://github.com/stonega/just_audio.git
rxdart: ^0.23.1
line_icons:
git:
url: https://github.com/galonsos/line_icons.git