parent
3f2dba63c2
commit
c9de380180
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,5 +1,14 @@
|
|||
# Tsacdop Changelog
|
||||
|
||||
## v0.4.0
|
||||
|
||||
Release date 2020/7/8
|
||||
|
||||
### New features
|
||||
|
||||
* Localization, changed all UI strings in app to support locale, support languages include en & zh right now.
|
||||
* Changed episode popup menu UI, add a switch to tap to open popup men.
|
||||
|
||||
## v0.3.6
|
||||
|
||||
Release date 2020/6/30
|
||||
|
@ -52,4 +61,3 @@ Release date 2020/6/16
|
|||
### Other
|
||||
|
||||
* Add privacy policy.
|
||||
|
||||
|
|
18
README.md
18
README.md
|
@ -4,13 +4,17 @@
|
|||
<img src="https://raw.githubusercontent.com/stonega/tsacdop/master/android/app/src/main/res/mipmap-xhdpi/text.png" art = "Tsacdop"/>
|
||||
</p>
|
||||
|
||||
![CircleCI](https://img.shields.io/circleci/build/github/stonega/tsacdop?token=efe1331861e017144f2abb363acd95197e436dad) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/stonega/tsacdop) [![GooglePlay](https://img.shields.io/badge/Google-PlayStore-%2323CCC6)](https://play.google.com/store/apps/details?id=com.stonegate.tsacdop)
|
||||
[![Build Status - Cirrus][]][Build status]
|
||||
[![GitHub Release][]][Github Release - Recent]
|
||||
[![Github Downloads][]][Github Release - Recent]
|
||||
[![Localizely][]][Localizely - Website]
|
||||
[![Google Play - Icon][]][Google Play]
|
||||
|
||||
## About
|
||||
|
||||
Enjoy podcasts with Tsacdop.
|
||||
|
||||
Tsacdop is a podcast player developed with flutter, a clean, simply beautiful and friendly app, only support Android right now.
|
||||
Tsacdop is a podcast player developed with flutter, a clean, simply beautiful and friendly app, and is free and opensource.
|
||||
|
||||
Credit to flutter team and all involved plugins, especially [webfeed](https://github.com/witochandra/webfeed) and [Just_Audio](https://pub.dev/packages/just_audio).
|
||||
|
||||
|
@ -122,3 +126,13 @@ A few resources to get you started if this is your first Flutter project:
|
|||
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.dev/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference.
|
||||
|
||||
[Build Status - Cirrus]: https://circleci.com/gh/stonega/tsacdop/tree/master.svg?style=shield
|
||||
[Build status]: https://circleci.com/gh/stonega/tsacdop/tree/master
|
||||
[Github Release]: https://img.shields.io/github/v/release/stonega/tsacdop
|
||||
[Github Release - Recent]: https://github.com/stonega/tsacdop/releases
|
||||
[Github Downloads]: https://img.shields.io/github/downloads/stonega/tsacdop/total?color=%230000d&label=downloads
|
||||
[Localizely]: https://img.shields.io/badge/dynamic/json?color=%2326c6da&label=localizely&query=%24.languages.length&url=https%3A%2F%2Fapi.localizely.com%2Fv1%2Fprojects%2Fbde4e9bd-4cb2-449b-9de2-18f231ddb47d%2Fstatus
|
||||
[Localizely - Website]: https://localizely.com/
|
||||
[Google Play - Icon]: https://img.shields.io/badge/google-playStore-%2323CCC6
|
||||
[Google Play]: https://play.google.com/store/apps/details?id=com.stonegate.tsacdop
|
||||
|
|
|
@ -37,11 +37,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
|
||||
static m8(count) => "${Intl.plural(count, zero: 'In an hour', one: '${count} hour ago', other: '${count} hours ago')}";
|
||||
|
||||
static m9(count) => "${Intl.plural(count, zero: '', one: '${count} hour', other: '${count} hours')}";
|
||||
static m9(count) => "${Intl.plural(count, zero: '0 hour', one: '${count} hour', other: '${count} hours')}";
|
||||
|
||||
static m10(count) => "${Intl.plural(count, zero: '', one: '${count} minute ago', other: '${count} minutes ago')}";
|
||||
static m10(count) => "${Intl.plural(count, zero: 'Just now', one: '${count} minute ago', other: '${count} minutes ago')}";
|
||||
|
||||
static m11(count) => "${Intl.plural(count, zero: '', one: '${count} min', other: '${count} mins')}";
|
||||
static m11(count) => "${Intl.plural(count, zero: '0 min', one: '${count} min', other: '${count} mins')}";
|
||||
|
||||
static m12(title) => "Fetch data ${title}";
|
||||
|
||||
|
|
|
@ -37,11 +37,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
|
||||
static m8(count) => "${Intl.plural(count, zero: '刚刚', other: '${count}小时前')}";
|
||||
|
||||
static m9(count) => "${Intl.plural(count, zero: '', other: '${count} 小时')}";
|
||||
static m9(count) => "${Intl.plural(count, zero: '0小时', other: '${count} 小时')}";
|
||||
|
||||
static m10(count) => "${Intl.plural(count, zero: '', other: '${count}分钟前')}";
|
||||
static m10(count) => "${Intl.plural(count, zero: '刚刚', other: '${count}分钟前')}";
|
||||
|
||||
static m11(count) => "${Intl.plural(count, zero: '', other: '${count}分钟')}";
|
||||
static m11(count) => "${Intl.plural(count, zero: '0分钟', other: '${count}分钟')}";
|
||||
|
||||
static m12(title) => "获取数据 ${title}";
|
||||
|
||||
|
|
|
@ -734,11 +734,11 @@ class S {
|
|||
);
|
||||
}
|
||||
|
||||
/// `{count, plural, zero{} one{{count} hour} other{{count} hours}}`
|
||||
/// `{count, plural, zero{0 hour} one{{count} hour} other{{count} hours}}`
|
||||
String hoursCount(num count) {
|
||||
return Intl.plural(
|
||||
count,
|
||||
zero: '',
|
||||
zero: '0 hour',
|
||||
one: '$count hour',
|
||||
other: '$count hours',
|
||||
name: 'hoursCount',
|
||||
|
@ -947,11 +947,11 @@ class S {
|
|||
);
|
||||
}
|
||||
|
||||
/// `{count, plural, zero{} one{{count} minute ago} other{{count} minutes ago}}`
|
||||
/// `{count, plural, zero{Just now} one{{count} minute ago} other{{count} minutes ago}}`
|
||||
String minsAgo(num count) {
|
||||
return Intl.plural(
|
||||
count,
|
||||
zero: '',
|
||||
zero: 'Just now',
|
||||
one: '$count minute ago',
|
||||
other: '$count minutes ago',
|
||||
name: 'minsAgo',
|
||||
|
@ -960,11 +960,11 @@ class S {
|
|||
);
|
||||
}
|
||||
|
||||
/// `{count, plural, zero{} one{{count} min} other{{count} mins}}`
|
||||
/// `{count, plural, zero{0 min} one{{count} min} other{{count} mins}}`
|
||||
String minsCount(num count) {
|
||||
return Intl.plural(
|
||||
count,
|
||||
zero: '',
|
||||
zero: '0 min',
|
||||
one: '$count min',
|
||||
other: '$count mins',
|
||||
name: 'minsCount',
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:line_icons/line_icons.dart';
|
|||
|
||||
import '../util/context_extension.dart';
|
||||
|
||||
const String version = '0.3.6';
|
||||
const String version = '0.4.0';
|
||||
|
||||
class AboutApp extends StatelessWidget {
|
||||
_launchUrl(String url) async {
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
},
|
||||
"hoursAgo": "{count, plural, zero{In an hour} one{{count} hour ago} other{{count} hours ago}}",
|
||||
"@hoursAgo": {},
|
||||
"hoursCount": "{count, plural, zero{} one{{count} hour} other{{count} hours}}",
|
||||
"hoursCount": "{count, plural, zero{0 hour} one{{count} hour} other{{count} hours}}",
|
||||
"@hoursCount": {},
|
||||
"introFourthPage": "Long press on episode card for quick actions.",
|
||||
"@introFourthPage": {},
|
||||
|
@ -198,9 +198,9 @@
|
|||
"@menuViewRSS": {},
|
||||
"menuVisitSite": "Visit Site",
|
||||
"@menuVisitSite": {},
|
||||
"minsAgo": "{count, plural, zero{} one{{count} minute ago} other{{count} minutes ago}}",
|
||||
"minsAgo": "{count, plural, zero{Just now} one{{count} minute ago} other{{count} minutes ago}}",
|
||||
"@minsAgo": {},
|
||||
"minsCount": "{count, plural, zero{} one{{count} min} other{{count} mins}}",
|
||||
"minsCount": "{count, plural, zero{0 min} one{{count} min} other{{count} mins}}",
|
||||
"@minsCount": {},
|
||||
"network": "Network",
|
||||
"@network": {},
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
},
|
||||
"hoursAgo": "{count, plural, zero{刚刚} other{{count}小时前}}",
|
||||
"@hoursAgo": {},
|
||||
"hoursCount": "{count, plural, zero{} other{{count} 小时}}",
|
||||
"hoursCount": "{count, plural, zero{0小时} other{{count} 小时}}",
|
||||
"@hoursCount": {},
|
||||
"introFourthPage": "长按节目打开快捷菜单。",
|
||||
"@introFourthPage": {},
|
||||
|
@ -198,9 +198,9 @@
|
|||
"@menuViewRSS": {},
|
||||
"menuVisitSite": "访问网站",
|
||||
"@menuVisitSite": {},
|
||||
"minsAgo": "{count, plural, zero{} other{{count}分钟前}}",
|
||||
"minsAgo": "{count, plural, zero{刚刚} other{{count}分钟前}}",
|
||||
"@minsAgo": {},
|
||||
"minsCount": "{count, plural, zero{} other{{count}分钟}}",
|
||||
"minsCount": "{count, plural, zero{0分钟} other{{count}分钟}}",
|
||||
"@minsCount": {},
|
||||
"network": "网络",
|
||||
"@network": {},
|
||||
|
|
|
@ -143,7 +143,7 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
: Center(),
|
||||
background: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 50, left: 50, right: 50, bottom: 30),
|
||||
top: 50, left: 20, right: 20, bottom: 20),
|
||||
child: FutureBuilder<List<FlSpot>>(
|
||||
future: getData(),
|
||||
builder: (context, snapshot) {
|
||||
|
@ -161,14 +161,14 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
TabBar(
|
||||
controller: _controller,
|
||||
indicatorColor: context.accentColor,
|
||||
labelColor: context.textColor,
|
||||
labelStyle: context.textTheme.headline6,
|
||||
tabs: <Widget>[
|
||||
Tab(
|
||||
child: Text(s.listen,
|
||||
style: context.textTheme.headline6),
|
||||
child: Text(s.listen),
|
||||
),
|
||||
Tab(
|
||||
child: Text(s.subscribe,
|
||||
style: context.textTheme.headline6),
|
||||
child: Text(s.subscribe),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -195,11 +195,13 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
scrollDirection: Axis.vertical,
|
||||
itemCount: snapshot.data.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
double seekValue =
|
||||
snapshot.data[index].seekValue;
|
||||
double seconds = snapshot.data[index].seconds;
|
||||
return Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 5),
|
||||
color:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
color: context.scaffoldBackgroundColor,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
|
@ -214,8 +216,8 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
snapshot
|
||||
.data[index].playdate),
|
||||
style: TextStyle(
|
||||
color:
|
||||
const Color(0xff67727d),
|
||||
color: context.textColor
|
||||
.withOpacity(0.8),
|
||||
fontSize: 15,
|
||||
fontStyle: FontStyle.italic),
|
||||
),
|
||||
|
@ -226,73 +228,60 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
),
|
||||
],
|
||||
),
|
||||
subtitle: Container(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.timelapse,
|
||||
color: Colors.grey[400],
|
||||
subtitle: 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 * seekValue <
|
||||
(_width - 120)
|
||||
? _width * seekValue
|
||||
: _width - 120,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 2),
|
||||
),
|
||||
Container(
|
||||
width: 50,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: context.accentColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(
|
||||
Radius.circular(10))),
|
||||
padding: EdgeInsets.all(2),
|
||||
child: Text(
|
||||
seconds == 0 && seekValue == 1
|
||||
? s.mark
|
||||
: _stringForSeconds(
|
||||
seconds),
|
||||
style: TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
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(
|
||||
snapshot.data[index]
|
||||
.seconds ==
|
||||
0 &&
|
||||
snapshot.data[index]
|
||||
.seekValue ==
|
||||
1
|
||||
? s.mark
|
||||
: _stringForSeconds(
|
||||
snapshot.data[index]
|
||||
.seconds),
|
||||
style: TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Divider(height: 2),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
)
|
||||
: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
child: SizedBox(
|
||||
height: 25,
|
||||
width: 25,
|
||||
child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -322,7 +311,8 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
DateFormat.yMd().add_jm().format(
|
||||
snapshot.data[index].subDate),
|
||||
style: TextStyle(
|
||||
color: const Color(0xff67727d),
|
||||
color: context.textColor
|
||||
.withOpacity(0.8),
|
||||
fontSize: 15,
|
||||
fontStyle: FontStyle.italic),
|
||||
),
|
||||
|
@ -341,13 +331,6 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
.data[index].delDate)),
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
// Text(snapshot.data[index].delDate
|
||||
// .difference(snapshot
|
||||
// .data[index].subDate)
|
||||
// .inDays
|
||||
// .toString() +
|
||||
// ' day on your device'),
|
||||
|
||||
trailing: !_status
|
||||
? Material(
|
||||
color: Colors.transparent,
|
||||
|
@ -370,7 +353,10 @@ class _PlayedHistoryState extends State<PlayedHistory>
|
|||
);
|
||||
})
|
||||
: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
child: SizedBox(
|
||||
height: 25,
|
||||
width: 25,
|
||||
child: CircularProgressIndicator()),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -465,13 +451,40 @@ class HistoryChart extends StatelessWidget {
|
|||
border: Border(
|
||||
left: BorderSide(color: Colors.red, width: 2),
|
||||
)),
|
||||
lineTouchData: LineTouchData(
|
||||
enabled: true,
|
||||
touchTooltipData: LineTouchTooltipData(
|
||||
tooltipBgColor: context.scaffoldBackgroundColor,
|
||||
fitInsideHorizontally: true,
|
||||
getTooltipItems: (touchedBarSpots) {
|
||||
return touchedBarSpots.map((barSpot) {
|
||||
return LineTooltipItem(context.s.minsCount(barSpot.y.toInt()),
|
||||
context.textTheme.subtitle1);
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
getTouchedSpotIndicator: (barData, spotIndexes) {
|
||||
return spotIndexes.map((spotIndex) {
|
||||
return TouchedSpotIndicatorData(
|
||||
FlLine(color: Colors.transparent),
|
||||
FlDotData(
|
||||
show: true,
|
||||
getDotPainter: (spot, percent, barData, index) {
|
||||
return FlDotCirclePainter(
|
||||
radius: 3,
|
||||
color: context.accentColor,
|
||||
strokeWidth: 4,
|
||||
strokeColor: context.primaryColor);
|
||||
}));
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
lineBarsData: [
|
||||
LineChartBarData(
|
||||
spots: this.stats,
|
||||
isCurved: false,
|
||||
colors: [
|
||||
context.accentColor,
|
||||
],
|
||||
isCurved: true,
|
||||
colors: [context.accentColor],
|
||||
preventCurveOverShooting: true,
|
||||
barWidth: 3,
|
||||
isStrokeCapRound: true,
|
||||
belowBarData: BarAreaData(
|
||||
|
@ -480,15 +493,23 @@ class HistoryChart extends StatelessWidget {
|
|||
gradientTo: Offset(0, 1),
|
||||
gradientColorStops: [
|
||||
0.3,
|
||||
0.8
|
||||
0.8,
|
||||
0.99
|
||||
],
|
||||
colors: [
|
||||
context.accentColor.withOpacity(0.6),
|
||||
context.accentColor.withOpacity(0.1)
|
||||
context.accentColor.withOpacity(0.1),
|
||||
context.accentColor.withOpacity(0)
|
||||
]),
|
||||
dotData: FlDotData(
|
||||
show: true,
|
||||
),
|
||||
show: true,
|
||||
getDotPainter: (spot, percent, barData, index) {
|
||||
return FlDotCirclePainter(
|
||||
radius: 2,
|
||||
color: context.primaryColor,
|
||||
strokeWidth: 3,
|
||||
strokeColor: context.accentColor);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
10
pubspec.yaml
10
pubspec.yaml
|
@ -1,7 +1,7 @@
|
|||
name: tsacdop
|
||||
description: An easy-use podacasts player.
|
||||
|
||||
version: 0.3.6+19
|
||||
version: 0.4.0+20
|
||||
|
||||
environment:
|
||||
sdk: ">=2.6.0 <3.0.0"
|
||||
|
@ -29,17 +29,17 @@ dependencies:
|
|||
url_launcher: ^5.4.10
|
||||
image: ^2.1.12
|
||||
shared_preferences: ^0.5.7
|
||||
uuid: ^2.0.4
|
||||
uuid: ^2.2.0
|
||||
tuple: ^1.0.3
|
||||
cached_network_image: ^2.2.0+1
|
||||
workmanager: ^0.2.2
|
||||
fl_chart: ^0.10.0
|
||||
workmanager: ^0.2.3
|
||||
fl_chart: ^0.10.1
|
||||
audio_service: ^0.8.0
|
||||
flutter_file_dialog: ^0.0.5
|
||||
flutter_linkify: ^3.1.3
|
||||
extended_nested_scroll_view: ^0.4.0
|
||||
connectivity: ^0.4.8+2
|
||||
flare_flutter: ^2.0.3
|
||||
flare_flutter: ^2.0.5
|
||||
rxdart: ^0.24.0
|
||||
wc_flutter_share: ^0.2.1
|
||||
video_player: ^0.10.11
|
||||
|
|
Loading…
Reference in New Issue