tsacdop-podcast-app-android/lib/settings/data_backup.dart

291 lines
11 KiB
Dart

import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:line_icons/line_icons.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:wc_flutter_share/wc_flutter_share.dart';
import '../service/ompl_build.dart';
import '../state/podcast_group.dart';
import '../state/setting_state.dart';
import '../type/settings_backup.dart';
import '../util/extension_helper.dart';
class DataBackup extends StatefulWidget {
@override
_DataBackupState createState() => _DataBackupState();
}
class _DataBackupState extends State<DataBackup> {
Future<File> _exportOmpl(BuildContext context) async {
var groups = context.read<GroupList>().groups;
var ompl = PodcastsBackup(groups).omplBuilder();
var tempdir = await getTemporaryDirectory();
var now = DateTime.now();
var datePlus = now.year.toString() +
now.month.toString() +
now.day.toString() +
now.second.toString();
var file = File(join(tempdir.path, 'tsacdop_ompl_$datePlus.xml'));
await file.writeAsString(ompl.toString());
return file;
}
Future<void> _saveFile(File file) async {
final params = SaveFileDialogParams(sourceFilePath: file.path);
await FlutterFileDialog.saveFile(params: params);
}
Future<void> _shareFile(File file) async {
final bytes = await file.readAsBytes();
await WcFlutterShare.share(
sharePopupTitle: 'share Clip',
fileName: file.path.split('/').last,
mimeType: 'text/plain',
bytesOfFile: bytes.buffer.asUint8List());
}
Future<File> _exportSetting(BuildContext context) async {
var settings = context.read<SettingState>();
var settingsBack = await settings.backup();
var json = settingsBack.toJson();
var tempdir = await getTemporaryDirectory();
var now = DateTime.now();
var datePlus = now.year.toString() +
now.month.toString() +
now.day.toString() +
now.second.toString();
var file = File(join(tempdir.path, 'tsacdop_settings_$datePlus.json'));
await file.writeAsString(jsonEncode(json));
return file;
}
Future _importSetting(String path, BuildContext context) async {
final s = context.s;
var settings = context.read<SettingState>();
var file = File(path);
try {
var json = file.readAsStringSync();
var backup = SettingsBackup.fromJson(jsonDecode(json));
await settings.restore(backup);
Fluttertoast.showToast(
msg: s.toastImportSettingsSuccess,
gravity: ToastGravity.BOTTOM,
);
} catch (e) {
developer.log(e, name: 'Import settings');
Fluttertoast.showToast(
msg: s.toastFileError,
gravity: ToastGravity.BOTTOM,
);
}
}
void _getFilePath(BuildContext context) async {
final s = context.s;
try {
var filePath = await FilePicker.getFilePath(type: FileType.any);
if (filePath == '') {
return;
}
Fluttertoast.showToast(
msg: s.toastReadFile,
gravity: ToastGravity.BOTTOM,
);
_importSetting(filePath, context);
} on PlatformException catch (e) {
developer.log(e.toString(), name: 'Get file path');
}
}
@override
Widget build(BuildContext context) {
final s = context.s;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarIconBrightness: Theme.of(context).accentColorBrightness,
systemNavigationBarColor: Theme.of(context).primaryColor,
systemNavigationBarIconBrightness:
Theme.of(context).accentColorBrightness,
),
child: Scaffold(
appBar: AppBar(
elevation: 0,
title: Text(s.settingsBackup),
backgroundColor: context.primaryColor,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(10.0),
),
Container(
height: 30.0,
padding: EdgeInsets.symmetric(horizontal: 70),
alignment: Alignment.centerLeft,
child: Text(s.subscribe,
style: context.textTheme.bodyText1
.copyWith(color: Theme.of(context).accentColor)),
),
Padding(
padding:
EdgeInsets.only(left: 70.0, right: 20, top: 10, bottom: 10),
child: Text(s.subscribeExportDes),
),
Padding(
padding: EdgeInsets.only(left: 70.0, right: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
side: BorderSide(color: Colors.green[700])),
highlightedBorderColor: Colors.green[700],
child: Row(
children: [
Icon(
LineIcons.save,
color: Colors.green[700],
size: context.textTheme.headline6.fontSize,
),
SizedBox(width: 10),
Text(s.save,
style: TextStyle(color: Colors.green[700])),
],
),
onPressed: () async {
var file = await _exportOmpl(context);
await _saveFile(file);
}),
SizedBox(width: 10),
OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
side: BorderSide(color: Colors.blue[700])),
highlightedBorderColor: Colors.blue[700],
child: Row(
children: [
Icon(
Icons.share,
size: context.textTheme.headline6.fontSize,
color: Colors.blue[700],
),
SizedBox(width: 10),
Text(s.share,
style: TextStyle(color: Colors.blue[700])),
],
),
onPressed: () async {
var file = await _exportOmpl(context);
await _shareFile(file);
})
],
),
),
Divider(),
Container(
height: 30.0,
padding: EdgeInsets.symmetric(horizontal: 70),
alignment: Alignment.centerLeft,
child: Text(s.settings,
style: context.textTheme.bodyText1
.copyWith(color: Theme.of(context).accentColor)),
),
Padding(
padding:
EdgeInsets.only(left: 70.0, right: 20, top: 10, bottom: 10),
child: Text(s.settingsExportDes),
),
Padding(
padding: EdgeInsets.only(left: 70.0, right: 10),
child: Wrap(children: [
OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
side: BorderSide(color: Colors.green[700])),
highlightedBorderColor: Colors.green[700],
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
LineIcons.save,
color: Colors.green[700],
size: context.textTheme.headline6.fontSize,
),
SizedBox(width: 10),
Text(s.save,
style: TextStyle(color: Colors.green[700])),
],
),
onPressed: () async {
var file = await _exportSetting(context);
await _saveFile(file);
}),
SizedBox(width: 10),
OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
side: BorderSide(color: Colors.blue[700])),
highlightedBorderColor: Colors.blue[700],
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.share,
size: context.textTheme.headline6.fontSize,
color: Colors.blue[700],
),
SizedBox(width: 10),
Text(s.share,
style: TextStyle(color: Colors.blue[700])),
],
),
onPressed: () async {
var file = await _exportSetting(context);
await _shareFile(file);
}),
SizedBox(width: 10),
ButtonTheme(
height: 32,
child: OutlineButton(
highlightedBorderColor: Colors.red[700],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
side: BorderSide(color: Colors.red[700])),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
LineIcons.paperclip_solid,
size: context.textTheme.headline6.fontSize,
color: Colors.red[700],
),
SizedBox(width: 10),
Text(s.import,
style: TextStyle(color: Colors.red[700])),
],
),
onPressed: () {
_getFilePath(context);
}),
),
]),
),
Divider()
],
)),
);
}
}