Update history chart UI.

Update readme badges.
This commit is contained in:
stonegate 2020-07-08 21:18:08 +08:00
parent 3f2dba63c2
commit c9de380180
10 changed files with 154 additions and 111 deletions

View File

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

View File

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

View File

@ -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}";

View File

@ -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}";

View File

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

View File

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

View File

@ -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": {},

View File

@ -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": {},

View File

@ -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);
}),
),
],
),

View File

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