Skip to content

Commit

Permalink
fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
zsakvo committed Mar 5, 2023
1 parent f088608 commit 87494a2
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 71 deletions.
73 changes: 54 additions & 19 deletions lib/provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import 'dart:async';
import 'dart:convert';

import 'dart:io' as io;

import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart';
Expand All @@ -12,13 +11,13 @@ import 'package:google_sign_in/google_sign_in.dart';
import 'package:googleapis/drive/v3.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import 'package:kakunin/main.dart';
import 'package:kakunin/router.dart';
import 'package:kakunin/screen/home/home_model.dart';
import 'package:kakunin/utils/encode.dart';
import 'package:kakunin/utils/log.dart';
import 'package:kakunin/utils/parse.dart';
import 'package:kakunin/utils/snackbar.dart';
import 'package:path_provider/path_provider.dart';

enum CloudAccountType { Google, WebDav, DropBox, AliYun }

Expand All @@ -29,25 +28,60 @@ class CloudAccount {
final bool isLogin;
final DriveApi? gDriveApi;
final File? gFile;
final String? localDir;

CloudAccount({this.isLogin = false, this.user, this.usage, this.total, this.gDriveApi, this.gFile});
CloudAccount({this.isLogin = false, this.user, this.usage, this.total, this.gDriveApi, this.gFile, this.localDir});

CloudAccount copyWith(
{String? user, String? usage, String? total, bool? isLogin, DriveApi? gDriveApi, final File? gFile}) {
{String? user,
String? usage,
String? total,
bool? isLogin,
DriveApi? gDriveApi,
final File? gFile,
String? localDir}) {
return CloudAccount(
user: user ?? this.user,
usage: usage ?? this.usage,
total: total ?? this.total,
isLogin: isLogin ?? this.isLogin,
gDriveApi: gDriveApi ?? this.gDriveApi,
gFile: gFile ?? this.gFile);
gFile: gFile ?? this.gFile,
localDir: localDir ?? this.localDir);
}

Map<String, dynamic> toMap() {
return {
'user': user,
'usage': usage,
'total': total,
'isLogin': isLogin,
'gDriveApi': gDriveApi?.toString(),
'gFile': gFile?.toString(),
'localDir': localDir,
};
}

factory CloudAccount.fromMap(Map<String, dynamic> map) {
return CloudAccount(
user: map['user'],
usage: map['usage'],
total: map['total'],
isLogin: map['isLogin'] ?? false,
gDriveApi: null,
gFile: null,
localDir: map['localDir'],
);
}

String toJson() => json.encode(toMap());

factory CloudAccount.fromJson(String source) => CloudAccount.fromMap(json.decode(source));
}

class CloudAccountNotifier extends StateNotifier<CloudAccount> {
CloudAccountNotifier({required this.ref}) : super(CloudAccount(isLogin: false)) {
// login();
}
CloudAccountNotifier({required this.ref})
: super(CloudAccount(isLogin: false, localDir: spInstance.getString("localDir")));
final dynamic ref;
late CloudAccountType accountType;
final GoogleSignIn googleSignIn = GoogleSignIn(
Expand All @@ -71,12 +105,12 @@ class CloudAccountNotifier extends StateNotifier<CloudAccount> {
if (googleAccount != null) {
final client = await googleSignIn.authenticatedClient();
final driveApi = DriveApi(client!);
state = CloudAccount(isLogin: true, user: googleAccount.email, gDriveApi: driveApi);
state = state.copyWith(isLogin: true, user: googleAccount.email, gDriveApi: driveApi);
getQuota();
searchBackUpFile();
}
} else {
state = CloudAccount(isLogin: false);
state = state.copyWith(isLogin: false);
}
break;
default:
Expand Down Expand Up @@ -125,7 +159,7 @@ class CloudAccountNotifier extends StateNotifier<CloudAccount> {
switch (accountType) {
case CloudAccountType.Google:
googleSignIn.signOut();
state = CloudAccount(isLogin: false);
state = state.copyWith(isLogin: false);
break;
default:
}
Expand Down Expand Up @@ -171,16 +205,17 @@ class CloudAccountNotifier extends StateNotifier<CloudAccount> {

backUpLocal() async {
final text = Encode.clear(ref);
late final io.File file;
if (io.Platform.isAndroid) {
file = io.File("/sdcard/Download/kakunin.otp");
String? selectedDirectory = state.localDir ?? await FilePicker.platform.getDirectoryPath();
if (selectedDirectory != null) {
spInstance.setString("localDir", selectedDirectory);
state = state.copyWith(localDir: selectedDirectory);
io.File file = io.File("$selectedDirectory/kakunin.otp");
file.createSync();
file.writeAsStringSync(text);
showSnackBar("备份成功");
} else {
final downloadsDir = await getDownloadsDirectory();
file = io.File("${downloadsDir!.path}/../kakunin.otp");
showErrorSnackBar("请先选好备份位置");
}
file.createSync();
file.writeAsStringSync(text);
showSnackBar("备份成功");
}

restoreGoogle() async {
Expand Down
101 changes: 61 additions & 40 deletions lib/screen/backup/backup_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,44 +121,6 @@ class _BackupViewState extends ConsumerState<BackupView> {
ref.read(cloudAccountProvider.notifier).login(CloudAccountType.Google, handle: true);
},
),
Container(
margin: const EdgeInsets.only(top: 16),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
"云端",
style: TextStyle(color: Theme.of(context).colorScheme.primary),
),
),
ListTile(
contentPadding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
title: Text(
"备份数据",
style: titleStyle,
),
subtitle: Text(
"上云有风险,隐私自己管 :_)",
style: subTitleStyle,
),
onTap: () async {
ref.read(cloudAccountProvider.notifier).backUp();
},
),
ListTile(
contentPadding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
title: Text(
"恢复数据",
style: titleStyle,
),
subtitle: Text(
cloudAccount.gFile == null
? "暂未找到备份文件"
: "文件大小:${Parse.formatFileSize(cloudAccount.gFile!.size)}\n修改时间:${cloudAccount.gFile!.modifiedTime!.toLocal()}",
style: subTitleStyle,
),
onTap: () async {
ref.read(cloudAccountProvider.notifier).restoreGoogle();
},
),
const Divider(
indent: 16,
endIndent: 16,
Expand All @@ -168,14 +130,73 @@ class _BackupViewState extends ConsumerState<BackupView> {
horizontalTitleGap: 0,
contentPadding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
subtitle: Text(
CloudUtil.getHint(CloudAccountType.Google),
"您的数据会经过 RSA 加密后存放在云端,但是其对应的公私钥均可以在本应用的源代码中找到,请自行注意保管妥当备份数据。",
textAlign: TextAlign.justify,
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.7),
fontSize: 13,
),
),
),
...cloudAccount.isLogin
? [
Container(
margin: const EdgeInsets.only(top: 16),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: Text(
"云端",
style: TextStyle(color: Theme.of(context).colorScheme.primary),
),
),
ListTile(
contentPadding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
title: Text(
"备份数据",
style: titleStyle,
),
subtitle: Text(
"上云有风险,隐私自己管 :_)",
style: subTitleStyle,
),
onTap: () async {
ref.read(cloudAccountProvider.notifier).backUp();
},
),
ListTile(
contentPadding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
title: Text(
"恢复数据",
style: titleStyle,
),
subtitle: Text(
cloudAccount.gFile == null
? "暂未找到备份文件"
: "文件大小:${Parse.formatFileSize(cloudAccount.gFile!.size)}\n修改时间:${cloudAccount.gFile!.modifiedTime!.toLocal()}",
style: subTitleStyle,
),
onTap: () async {
ref.read(cloudAccountProvider.notifier).restoreGoogle();
},
),
const Divider(
indent: 16,
endIndent: 16,
),
ListTile(
leading: const Icon(Icons.help_outline_outlined),
horizontalTitleGap: 0,
contentPadding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
subtitle: Text(
CloudUtil.getHint(CloudAccountType.Google),
textAlign: TextAlign.justify,
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.7),
fontSize: 13,
),
),
),
]
: [const SizedBox.shrink()],
Container(
margin: const EdgeInsets.only(top: 16),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
Expand All @@ -191,7 +212,7 @@ class _BackupViewState extends ConsumerState<BackupView> {
style: titleStyle,
),
subtitle: Text(
"导出明文数据到 /sdcard/Download/kakunin.otp",
cloudAccount.localDir != null ? "目前备份于 ${cloudAccount.localDir}" : "尚未选择备份位置",
style: subTitleStyle,
),
onTap: () async {
Expand Down
21 changes: 11 additions & 10 deletions lib/screen/config/config_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:kakunin/main.dart';
import 'package:kakunin/utils/log.dart';
import 'package:kakunin/utils/snackbar.dart';
import 'package:local_auth/local_auth.dart';
import 'package:url_launcher/url_launcher.dart';

Expand Down Expand Up @@ -118,8 +119,15 @@ class _ConfigViewState extends ConsumerState<ConfigView> {
),
trailing: Switch(
value: needAuth.value,
onChanged: (value) {
needAuth.value = value;
onChanged: (value) async {
try {
final bool didAuthenticate = await auth.authenticate(localizedReason: '请验证您的身份信息');
if (didAuthenticate) {
needAuth.value = !needAuth.value;
}
} on PlatformException {
showErrorSnackBar("您的系统没有注册任何认证方式");
}
},
// onChanged: (value) => setSpBool("dynamicColor", !value, dynamicColor),
),
Expand All @@ -130,14 +138,7 @@ class _ConfigViewState extends ConsumerState<ConfigView> {
needAuth.value = !needAuth.value;
}
} on PlatformException {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"您的系统没有注册任何认证方式",
style: TextStyle(color: Theme.of(context).colorScheme.onErrorContainer),
),
backgroundColor: Theme.of(context).colorScheme.errorContainer,
behavior: SnackBarBehavior.floating,
));
showErrorSnackBar("您的系统没有注册任何认证方式");
}
},
),
Expand Down
2 changes: 1 addition & 1 deletion lib/screen/home/components/list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class ListItemViewState extends ConsumerState<ListItemView> {
),
),
onTap: () {
FlutterClipboard.copy(token.value).then((value) => ScaffoldMessenger.of(context)
FlutterClipboard.copy(token.value.replaceAll(" ", "")).then((value) => ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(behavior: SnackBarBehavior.floating, content: Text("验证码复制成功"))));
},
onLongPress: () {
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/cloud.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class CloudUtil {
static getHint(CloudAccountType type) {
switch (type) {
case CloudAccountType.Google:
return "程序会在 Google 云端硬盘上新建名为 kakunin.otp 的文件作为备份数据。请保证您的云端(包括回收站在内)只有一个该名字的文件存在。\n数据经过 RSA 加密,其公私钥可在应用源代码中自行查看";
return "程序会在 Google 云端硬盘上新建名为 kakunin.otp 的文件作为备份数据。请保证您的云端(包括回收站在内)只有一个该名字的文件存在。";
default:
}
}
Expand Down

0 comments on commit 87494a2

Please sign in to comment.