Add localizely logo.

Tap logo in homepage to taggle dark mode.
Update open sorce libraries.
This commit is contained in:
stonegate 2020-07-16 17:35:01 +08:00
parent c5f2e4bdc1
commit 1d7d772323
19 changed files with 83 additions and 577 deletions

View File

@ -24,7 +24,7 @@ The podcasts search engine is powered by [ListenNotes](https://listennotes.com).
* Auto syncing in background
* Listen and subscribe history record
* Dark mode / Accent color
* Download for offline playing
* Download for offline play
* Auto download new episodes / Auto delete outdated downloads
More to come...

BIN
assets/localizely_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -227,13 +227,13 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsDefaultGridPodcast" : MessageLookupByLibrary.simpleMessage("Podcast page"),
"settingsDefaultGridRecent" : MessageLookupByLibrary.simpleMessage("Recent tab"),
"settingsDiscovery" : MessageLookupByLibrary.simpleMessage("Discovery Features Again"),
"settingsEnableSyncing" : MessageLookupByLibrary.simpleMessage("Enable Syncing"),
"settingsEnableSyncing" : MessageLookupByLibrary.simpleMessage("Enable syncing"),
"settingsEnableSyncingDes" : MessageLookupByLibrary.simpleMessage("Refresh all podcasts in the background to get leatest episodes"),
"settingsExportDes" : MessageLookupByLibrary.simpleMessage("Export and import app settings"),
"settingsFeedback" : MessageLookupByLibrary.simpleMessage("Feedback"),
"settingsFeedbackDes" : MessageLookupByLibrary.simpleMessage("Bugs and features request"),
"settingsHistory" : MessageLookupByLibrary.simpleMessage("History"),
"settingsHistoryDes" : MessageLookupByLibrary.simpleMessage("Listen date"),
"settingsHistoryDes" : MessageLookupByLibrary.simpleMessage("Listen data"),
"settingsInfo" : MessageLookupByLibrary.simpleMessage("Info"),
"settingsInterface" : MessageLookupByLibrary.simpleMessage("Interface"),
"settingsLanguages" : MessageLookupByLibrary.simpleMessage("Languages"),
@ -248,7 +248,7 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsNetworkCellular" : MessageLookupByLibrary.simpleMessage("Ask before using cellular data"),
"settingsNetworkCellularAuto" : MessageLookupByLibrary.simpleMessage("Auto download using cellular data"),
"settingsNetworkCellularAutoDes" : MessageLookupByLibrary.simpleMessage("You can set podcast auto download in group manage page"),
"settingsNetworkCellularDes" : MessageLookupByLibrary.simpleMessage("Ask to confirm when using cellulae data to download episodes"),
"settingsNetworkCellularDes" : MessageLookupByLibrary.simpleMessage("Ask to confirm when using cellular data to download episodes"),
"settingsPlayDes" : MessageLookupByLibrary.simpleMessage("Playlist and player"),
"settingsPopupMenu" : MessageLookupByLibrary.simpleMessage("Episodes popup menu"),
"settingsPopupMenuDes" : MessageLookupByLibrary.simpleMessage("Change the popup menu of episode"),
@ -283,6 +283,7 @@ class MessageLookup extends MessageLookupByLibrary {
"toastFileError" : MessageLookupByLibrary.simpleMessage("File error, subscribe failed"),
"toastFileNotValid" : MessageLookupByLibrary.simpleMessage("File not valid"),
"toastHomeGroupNotSupport" : MessageLookupByLibrary.simpleMessage("Home group is not supported"),
"toastImportSettingsSuccess" : MessageLookupByLibrary.simpleMessage("Import settings successfully"),
"toastOneGroup" : MessageLookupByLibrary.simpleMessage("At least select one group"),
"toastPodcastRecovering" : MessageLookupByLibrary.simpleMessage("Recovering, wait for a moment"),
"toastReadFile" : MessageLookupByLibrary.simpleMessage("Read file successfully"),

View File

@ -233,7 +233,7 @@ class MessageLookup extends MessageLookupByLibrary {
"settingsFeedback" : MessageLookupByLibrary.simpleMessage("反馈"),
"settingsFeedbackDes" : MessageLookupByLibrary.simpleMessage("意见与建议"),
"settingsHistory" : MessageLookupByLibrary.simpleMessage("历史记录"),
"settingsHistoryDes" : MessageLookupByLibrary.simpleMessage("播放日期"),
"settingsHistoryDes" : MessageLookupByLibrary.simpleMessage("收听记录"),
"settingsInfo" : MessageLookupByLibrary.simpleMessage("信息"),
"settingsInterface" : MessageLookupByLibrary.simpleMessage("界面"),
"settingsLanguages" : MessageLookupByLibrary.simpleMessage("语言"),
@ -283,6 +283,7 @@ class MessageLookup extends MessageLookupByLibrary {
"toastFileError" : MessageLookupByLibrary.simpleMessage("文件错误,导入失败"),
"toastFileNotValid" : MessageLookupByLibrary.simpleMessage("文件错误"),
"toastHomeGroupNotSupport" : MessageLookupByLibrary.simpleMessage("Home 分组不支持此功能"),
"toastImportSettingsSuccess" : MessageLookupByLibrary.simpleMessage("导入设置成功"),
"toastOneGroup" : MessageLookupByLibrary.simpleMessage("请至少选择一个分组"),
"toastPodcastRecovering" : MessageLookupByLibrary.simpleMessage("恢复中,请稍后"),
"toastReadFile" : MessageLookupByLibrary.simpleMessage("读取文件成功"),

View File

@ -1559,10 +1559,10 @@ class S {
);
}
/// `Enable Syncing`
/// `Enable syncing`
String get settingsEnableSyncing {
return Intl.message(
'Enable Syncing',
'Enable syncing',
name: 'settingsEnableSyncing',
desc: '',
args: [],
@ -1619,10 +1619,10 @@ class S {
);
}
/// `Listen date`
/// `Listen data`
String get settingsHistoryDes {
return Intl.message(
'Listen date',
'Listen data',
name: 'settingsHistoryDes',
desc: '',
args: [],
@ -1769,10 +1769,10 @@ class S {
);
}
/// `Ask to confirm when using cellulae data to download episodes`
/// `Ask to confirm when using cellular data to download episodes`
String get settingsNetworkCellularDes {
return Intl.message(
'Ask to confirm when using cellulae data to download episodes',
'Ask to confirm when using cellular data to download episodes',
name: 'settingsNetworkCellularDes',
desc: '',
args: [],
@ -2129,6 +2129,16 @@ class S {
);
}
/// `Import settings successfully`
String get toastImportSettingsSuccess {
return Intl.message(
'Import settings successfully',
name: 'toastImportSettingsSuccess',
desc: '',
args: [],
);
}
/// `At least select one group`
String get toastOneGroup {
return Intl.message(

View File

@ -6,7 +6,7 @@ import 'package:line_icons/line_icons.dart';
import '../util/context_extension.dart';
const String version = '0.4.0';
const String version = '0.4.5';
class AboutApp extends StatelessWidget {
_launchUrl(String url) async {

View File

@ -20,11 +20,12 @@ import '../util/context_extension.dart';
import '../util/custompaint.dart';
import '../state/download_state.dart';
import '../state/podcast_group.dart';
import '../state/setting_state.dart';
import 'playlist.dart';
import 'import_ompl.dart';
import 'audioplayer.dart';
import 'addpodcast.dart';
import 'popupmenu.dart';
import 'home_menu.dart';
import 'home_groups.dart';
import 'download_list.dart';
@ -89,6 +90,7 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = (width - 20) / 3 + 140;
var settings = Provider.of<SettingState>(context, listen: false);
final s = context.s;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
@ -195,14 +197,25 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
},
),
),
Image(
image: Theme.of(context)
.brightness ==
Brightness.light
? AssetImage('assets/text.png')
: AssetImage(
'assets/text_light.png'),
height: 30,
GestureDetector(
onTap: () => {
Theme.of(context).brightness ==
Brightness.light
? settings.setTheme =
ThemeMode.dark
: settings.setTheme =
ThemeMode.light
},
child: Image(
image: Theme.of(context)
.brightness ==
Brightness.light
? AssetImage(
'assets/text.png')
: AssetImage(
'assets/text_light.png'),
height: 30,
),
),
DescribedFeatureOverlay(
featureId: menuFeature,

View File

@ -1,69 +0,0 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
import '../util/context_extension.dart';
class ClipPreview extends StatefulWidget {
final String filePath;
ClipPreview({this.filePath, Key key}) : super(key: key);
@override
_ClipPreviewState createState() => _ClipPreviewState();
}
class _ClipPreviewState extends State<ClipPreview> {
VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.file(File(widget.filePath))
..initialize().then((_) {
setState(() {});
});
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.light,
systemNavigationBarColor: Colors.black,
systemNavigationBarIconBrightness: Brightness.dark,
),
child: Scaffold(
appBar: AppBar(backgroundColor: Colors.black),
backgroundColor: Colors.black,
body: Center(
child: _controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
),
floatingActionButton: FloatingActionButton(
backgroundColor: context.accentColor,
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
),
);
}
}

View File

@ -1,469 +0,0 @@
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:line_icons/line_icons.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:tsacdop/home/preview.dart';
import 'package:wc_flutter_share/wc_flutter_share.dart';
import 'package:tuple/tuple.dart';
import '../state/audio_state.dart';
import '../util/context_extension.dart';
import '../util/custom_slider.dart';
import '../util/pageroute.dart';
final List<BoxShadow> _customShadow = [
BoxShadow(blurRadius: 26, offset: Offset(-6, -6), color: Colors.white),
BoxShadow(
blurRadius: 8,
offset: Offset(2, 2),
color: Colors.grey[600].withOpacity(0.4))
];
final List<BoxShadow> _customShadowNight = [
BoxShadow(
blurRadius: 6,
offset: Offset(-1, -1),
color: Colors.grey[100].withOpacity(0.3)),
BoxShadow(blurRadius: 8, offset: Offset(2, 2), color: Colors.black)
];
String _stringForSeconds(int seconds) {
if (seconds == null) return null;
return '${(seconds ~/ 60)}:${(seconds.truncate() % 60).toString().padLeft(2, '0')}';
}
class ShareClip extends StatefulWidget {
ShareClip({Key key}) : super(key: key);
@override
_ShareClipState createState() => _ShareClipState();
}
class _ShareClipState extends State<ShareClip> {
int _durationSelected;
int _startPosition;
bool _startConfirm;
List<int> _durationToSelect = [30, 60, 90, 120];
Widget _animatedWidget;
Widget _toastWidget;
@override
void initState() {
super.initState();
_durationSelected = 60;
_startPosition = 0;
_startConfirm = false;
_animatedWidget = Center();
_toastWidget = Center();
}
_formatSeconds(int s) {
switch (s) {
case 30:
return "30sec";
break;
case 60:
return "1min";
break;
case 90:
return "90sec";
break;
case 120:
return "2min";
break;
default:
return '';
break;
}
}
_setShareButton(ShareStatus status, String filePath) {
switch (status) {
case ShareStatus.generate:
_animatedWidget = Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
)),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2),
),
Text('Clipping'),
],
);
_toastWidget = Text('May take one minute',
style: TextStyle(color: const Color(0xff67727d)));
break;
case ShareStatus.download:
_animatedWidget = Text('Loading');
break;
case ShareStatus.complete:
_animatedWidget = Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(Icons.share),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2),
),
Text('Share'),
],
);
_toastWidget = Row(
children: [
Text('Preview'),
IconButton(
icon: Icon(LineIcons.play_solid),
onPressed: () {
if (filePath != '')
Navigator.push(
context,
SlideLeftRoute(
page: ClipPreview(
filePath: filePath,
)),
);
}),
],
);
break;
case ShareStatus.undefined:
_animatedWidget = Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(LineIcons.cut_solid),
Padding(
padding: EdgeInsets.symmetric(horizontal: 2),
),
Text('Clip')
],
);
_toastWidget = Center();
break;
case ShareStatus.error:
_animatedWidget = Text('Retry');
_toastWidget = Text('Something wrong happened');
break;
}
}
@override
Widget build(BuildContext context) {
var audio = Provider.of<AudioPlayerNotifier>(context, listen: false);
return Container(
height: 300,
width: double.infinity,
color: context.primaryColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 20.0),
height: 60.0,
// color: context.primaryColorDark,
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 20.0),
height: 20.0,
// color: context.primaryColorDark,
alignment: Alignment.centerLeft,
child: Text(
'Share Clip',
style: TextStyle(
color: Theme.of(context).accentColor,
fontWeight: FontWeight.bold,
fontSize: 16),
),
),
Spacer(),
Selector<AudioPlayerNotifier, Tuple2<ShareStatus, String>>(
selector: (_, audio) =>
Tuple2(audio.shareStatus, audio.shareFile ?? ''),
builder: (_, data, __) {
_setShareButton(data.item1, data.item2);
return Row(
mainAxisSize: MainAxisSize.min,
children: [
AnimatedSwitcher(
transitionBuilder: (child, animation) =>
ScaleTransition(scale: animation, child: child),
duration: Duration(milliseconds: 500),
child: _toastWidget),
Container(
margin: EdgeInsets.symmetric(horizontal: 10),
alignment: Alignment.center,
height: 40,
width: 120,
decoration: BoxDecoration(
color: context.primaryColor,
borderRadius:
BorderRadius.all(Radius.circular(20)),
border: Border.all(
color: Theme.of(context).brightness ==
Brightness.dark
? Colors.black12
: Colors.white10,
width: 1),
boxShadow: Theme.of(context).brightness ==
Brightness.dark
? _customShadowNight
: _customShadow),
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius:
BorderRadius.all(Radius.circular(15)),
onTap: () async {
if (data.item1 == ShareStatus.undefined ||
data.item1 ==
ShareStatus.error) if (_startConfirm)
audio.shareClip(
_startPosition, _durationSelected);
else
Fluttertoast.showToast(
msg: 'Please confirm start position',
gravity: ToastGravity.BOTTOM,
);
else if (data.item1 == ShareStatus.complete) {
File file = File(data.item2);
final Uint8List bytes =
await file.readAsBytes();
await WcFlutterShare.share(
sharePopupTitle: 'share Clip',
fileName: data.item2.split('/').last,
mimeType: 'video/mp4',
bytesOfFile: bytes.buffer.asUint8List());
audio.setShareStatue = ShareStatus.undefined;
}
},
child: SizedBox(
height: 40,
width: 100,
child: Center(
child: AnimatedSwitcher(
transitionBuilder: (child, animation) =>
ScaleTransition(
scale: animation, child: child),
duration: Duration(milliseconds: 700),
child: _animatedWidget)),
),
),
),
),
],
);
},
),
],
),
),
Consumer<AudioPlayerNotifier>(builder: (_, data, __) {
return Container(
padding: EdgeInsets.only(top: 5, left: 10, right: 10),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor:
Theme.of(context).brightness == Brightness.dark
? Colors.black38
: Colors.grey[400],
inactiveTrackColor: Theme.of(context).primaryColorDark,
trackHeight: 20.0,
trackShape: MyRectangularTrackShape(),
thumbColor: Theme.of(context).accentColor,
thumbShape: MyRoundSliderThumpShape(
enabledThumbRadius: 10.0,
disabledThumbRadius: 10.0,
thumbCenterColor: context.accentColor),
overlayColor: Theme.of(context).accentColor.withAlpha(32),
overlayShape: RoundSliderOverlayShape(overlayRadius: 4.0),
),
child: Slider(
value: data.seekSliderValue,
onChanged: (double val) {
audio.sliderSeek(val);
}),
),
);
}),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 150,
width: 200,
child: Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Center(
child: Selector<AudioPlayerNotifier, int>(
selector: (_, audio) => audio.backgroundAudioPosition,
builder: (_, position, __) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: Text.rich(
TextSpan(
text: 'Start at \n',
style:
TextStyle(color: context.accentColor),
children: [
TextSpan(
text: !_startConfirm
? _stringForSeconds(
position ~/ 1000)
: _stringForSeconds(
_startPosition),
style: context.textTheme.headline5
.copyWith(
color: _startConfirm
? context.accentColor
: null)),
]),
textAlign: TextAlign.center,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
padding: EdgeInsets.symmetric(
horizontal: 10.0),
onPressed: () => audio.forwardAudio(-30),
iconSize: 25.0,
icon: Icon(Icons.replay_30),
color: Colors.grey[500]),
InkWell(
onTap: () => setState(() {
if (!_startConfirm)
_startPosition = position ~/ 1000;
_startConfirm = !_startConfirm;
}),
child: Container(
margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
boxShadow: !_startConfirm
? (context.brightness ==
Brightness.dark)
? _customShadowNight
: _customShadow
: null,
color: _startConfirm
? Theme.of(context).accentColor
: Theme.of(context).primaryColor,
shape: BoxShape.circle),
alignment: Alignment.center,
width: 40,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
LineIcons.thumbtack_solid,
color: _startConfirm
? Colors.white
: null,
)),
),
),
IconButton(
padding: EdgeInsets.symmetric(
horizontal: 10.0),
onPressed: () => audio.forwardAudio(10),
iconSize: 25.0,
icon: Icon(Icons.forward_10),
color: Colors.grey[500]),
],
),
],
);
},
),
),
),
),
Container(
height: 100,
width: 2,
color: context.primaryColorDark,
),
SizedBox(
height: 150,
width: 200,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Center(
child: Wrap(
direction: Axis.horizontal,
children: _durationToSelect
.map<Widget>((e) => InkWell(
onTap: () =>
setState(() => _durationSelected = e),
child: Container(
margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(15)),
boxShadow: e != _durationSelected
? (context.brightness ==
Brightness.dark)
? _customShadowNight
: _customShadow
: null,
color: (e == _durationSelected)
? Theme.of(context).accentColor
: Theme.of(context).primaryColor,
),
alignment: Alignment.center,
width: 70,
height: 30,
child: Text(_formatSeconds(e),
style: TextStyle(
fontWeight: FontWeight.bold,
color: (e == _durationSelected)
? Colors.white
: null)),
),
))
.toList(),
),
)),
),
],
),
),
Container(
height: 20,
padding: EdgeInsets.symmetric(horizontal: 20),
child: InkWell(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
onTap: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('experimental'),
Icon(
LineIcons.info_circle_solid,
size: 20.0,
color: context.accentColor,
),
],
),
),
),
],
),
);
}
}

View File

@ -355,7 +355,7 @@
"@settingsDefaultGridRecent": {},
"settingsDiscovery": "Discovery Features Again",
"@settingsDiscovery": {},
"settingsEnableSyncing": "Enable Syncing",
"settingsEnableSyncing": "Enable syncing",
"@settingsEnableSyncing": {},
"settingsEnableSyncingDes": "Refresh all podcasts in the background to get leatest episodes",
"@settingsEnableSyncingDes": {},
@ -367,7 +367,7 @@
"@settingsFeedbackDes": {},
"settingsHistory": "History",
"@settingsHistory": {},
"settingsHistoryDes": "Listen date",
"settingsHistoryDes": "Listen data",
"@settingsHistoryDes": {},
"settingsInfo": "Info",
"@settingsInfo": {},
@ -397,7 +397,7 @@
"@settingsNetworkCellularAuto": {},
"settingsNetworkCellularAutoDes": "You can set podcast auto download in group manage page",
"@settingsNetworkCellularAutoDes": {},
"settingsNetworkCellularDes": "Ask to confirm when using cellulae data to download episodes",
"settingsNetworkCellularDes": "Ask to confirm when using cellular data to download episodes",
"@settingsNetworkCellularDes": {},
"settingsPlayDes": "Playlist and player",
"@settingsPlayDes": {},
@ -481,6 +481,8 @@
"@toastFileNotValid": {},
"toastHomeGroupNotSupport": "Home group is not supported",
"@toastHomeGroupNotSupport": {},
"toastImportSettingsSuccess": "Import settings successfully",
"@toastImportSettingsSuccess": {},
"toastOneGroup": "At least select one group",
"@toastOneGroup": {},
"toastPodcastRecovering": "Recovering, wait for a moment",

View File

@ -367,7 +367,7 @@
"@settingsFeedbackDes": {},
"settingsHistory": "历史记录",
"@settingsHistory": {},
"settingsHistoryDes": "播放日期",
"settingsHistoryDes": "收听记录",
"@settingsHistoryDes": {},
"settingsInfo": "信息",
"@settingsInfo": {},
@ -481,6 +481,8 @@
"@toastFileNotValid": {},
"toastHomeGroupNotSupport": "Home 分组不支持此功能",
"@toastHomeGroupNotSupport": {},
"toastImportSettingsSuccess": "导入设置成功",
"@toastImportSettingsSuccess": {},
"toastOneGroup": "请至少选择一个分组",
"@toastOneGroup": {},
"toastPodcastRecovering": "恢复中,请稍后",

View File

@ -64,7 +64,7 @@ class _DataBackupState extends State<DataBackup> {
now.day.toString() +
now.second.toString();
var file = File(join(tempdir.path, 'tsacdop_settings_$datePlus.json'));
await file.writeAsString(json.toString());
await file.writeAsString(jsonEncode(json));
return file;
}
@ -76,11 +76,15 @@ class _DataBackupState extends State<DataBackup> {
String json = file.readAsStringSync();
SettingsBackup backup = SettingsBackup.fromJson(jsonDecode(json));
await settings.restore(backup);
Fluttertoast.showToast(
msg: s.toastImportSettingsSuccess,
gravity: ToastGravity.BOTTOM,
);
} catch (e) {
print(e);
Fluttertoast.showToast(
msg: s.toastFileError,
gravity: ToastGravity.TOP,
gravity: ToastGravity.BOTTOM,
);
}
}
@ -95,7 +99,7 @@ class _DataBackupState extends State<DataBackup> {
print('File Path' + filePath);
Fluttertoast.showToast(
msg: s.toastReadFile,
gravity: ToastGravity.TOP,
gravity: ToastGravity.BOTTOM,
);
_importSetting(filePath, context);
} on PlatformException catch (e) {
@ -262,7 +266,7 @@ class _DataBackupState extends State<DataBackup> {
mainAxisSize: MainAxisSize.min,
children: [
Icon(
LineIcons.file_import_solid,
LineIcons.paperclip_solid,
size: context.textTheme.headline6.fontSize,
color: Colors.red[700],
),

View File

@ -95,12 +95,21 @@ class _LanguagesSettingState extends State<LanguagesSetting> {
onTap: () => _launchUrl(
'mailto:<tsacdop.app@gmail.com>?subject=Tsacdop localization project'),
contentPadding: const EdgeInsets.only(left: 75, right: 20),
title: Align(
alignment: Alignment.centerLeft,
child: Image(
image: Theme.of(context).brightness ==
Brightness.light
? AssetImage('assets/localizely_logo.png')
: AssetImage('assets/localizely_logo_light.png'),
height: 20),
),
subtitle: Text(
"If you'd like to contribute to support more languages, please contact me."),
trailing: IconButton(
icon: Icon(LineIcons.heart),
onPressed: () => _launchUrl(
'mailto:<tsacdop.app@gmail.com>?subject=Tsacdop localization project')),
// trailing: IconButton(
// icon: Icon(LineIcons.heart),
// onPressed: () => _launchUrl(
// 'mailto:<tsacdop.app@gmail.com>?subject=Tsacdop localization project')),
),
],
))),

View File

@ -70,5 +70,8 @@ List<Libries> plugins = [
Libries('flutter_isolate', mit, 'https://pub.dev/packages/flutter_isolate'),
Libries('auto_animated', mit, 'https://pub.dev/packages/auto_animated'),
Libries('wc_flutter_share', apacheLicense,
'https://pub.dev/packages/wc_flutter_share')
'https://pub.dev/packages/wc_flutter_share'),
Libries('flutter_time_picker_spinner', 'unknow',
'https://pub.dev/packages/flutter_time_picker_spinner'),
Libries('focused_menu', mit, 'https://pub.dev/packages/focused_menu')
];

View File

@ -782,7 +782,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
if (_playing == null) {
_playing = true;
int cacheMax =
await cacheStorage.getInt(defaultValue: 500 * 1024 * 1024);
await cacheStorage.getInt(defaultValue: 200 * 1024 * 1024);
// await AudioServiceBackground.setQueue(_queue);
await _audioPlayer.setUrl(mediaItem.id, cacheMax);

View File

@ -94,8 +94,8 @@ class EpisodeGrid extends StatelessWidget {
Future<bool> _getTapToOpenPopupMenu() async {
KeyValueStorage tapToOpenPopupMenuStorage =
KeyValueStorage(tapToOpenPopupMenuKey);
int boo = await tapToOpenPopupMenuStorage.getInt(defaultValue: 0);
return boo == 1;
bool boo = await tapToOpenPopupMenuStorage.getBool(defaultValue: false);
return boo;
}
_markListened(EpisodeBrief episode) async {

View File

@ -1,7 +1,7 @@
name: tsacdop
description: An easy-use podacasts player.
version: 0.4.0+20
version: 0.4.5+21
environment:
sdk: ">=2.6.0 <3.0.0"
@ -42,7 +42,6 @@ dependencies:
flare_flutter: ^2.0.5
rxdart: ^0.24.0
wc_flutter_share: ^0.2.1
video_player: ^0.10.11
auto_animated: ^2.1.0
feature_discovery: ^0.10.0
flutter_isolate: ^1.0.0+14