opt.: migrate fl_lib

This commit is contained in:
lollipopkit
2024-05-14 22:29:37 +08:00
parent 248430e5b0
commit 04dfede535
136 changed files with 686 additions and 3896 deletions

View File

@@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
abstract final class Funcs {
static const int _defaultDurationTime = 377;
static const String _defaultThrottleId = 'default';
static final Map<String, int> startTimeMap = <String, int>{
_defaultThrottleId: 0
};
static void throttle(
VoidCallback? func, {
String id = _defaultThrottleId,
int duration = _defaultDurationTime,
Function? continueClick,
}) {
final currentTime = DateTime.now().millisecondsSinceEpoch;
if (currentTime - (startTimeMap[id] ?? 0) > duration) {
func?.call();
startTimeMap[id] = DateTime.now().millisecondsSinceEpoch;
} else {
continueClick?.call();
}
}
}

View File

@@ -1,14 +1,6 @@
import 'package:file_picker/file_picker.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:plain_notification_token/plain_notification_token.dart';
import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/data/res/provider.dart';
Future<String?> pickOneFile() async {
Pros.app.moveBg = false;
final result = await FilePicker.platform.pickFiles(type: FileType.any);
Pros.app.moveBg = true;
return result?.files.single.path;
}
Future<String?> getToken() async {
if (isIOS) {
@@ -29,22 +21,3 @@ String? getFileName(String? path) {
}
return path.split('/').last;
}
/// Join two path with `/`
String pathJoin(String path1, String path2) {
return path1 + (path1.endsWith('/') ? '' : '/') + path2;
}
/// Check if a url is a file url (ends with a file extension)
bool isFileUrl(String url) => url.split('/').last.contains('.');
int get timeStamp => DateTime.now().millisecondsSinceEpoch;
bool isBaseType(Object? obj) {
return obj is String ||
obj is int ||
obj is double ||
obj is bool ||
obj is List ||
obj is Map;
}

View File

@@ -1,104 +0,0 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';
// ignore: depend_on_referenced_packages
import 'package:local_auth_android/local_auth_android.dart';
// ignore: depend_on_referenced_packages
import 'package:local_auth_ios/types/auth_messages_ios.dart';
import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/utils/platform/base.dart';
import 'package:local_auth/error_codes.dart' as errs;
import 'package:toolbox/data/res/store.dart';
abstract final class BioAuth {
static final _auth = LocalAuthentication();
static final isPlatformSupported = isAndroid || isIOS || isWindows;
static bool _isAuthing = false;
static Future<bool> get isAvail async {
if (!isPlatformSupported) return false;
if (!await _auth.canCheckBiometrics) {
return false;
}
final biometrics = await _auth.getAvailableBiometrics();
/// [biometrics] on Android and Windows is returned with error
/// Handle it specially
if (isAndroid || isWindows) return biometrics.isNotEmpty;
return biometrics.contains(BiometricType.face) ||
biometrics.contains(BiometricType.fingerprint);
}
static Future<void> go([int count = 0]) async {
if (Stores.setting.useBioAuth.fetch()) {
if (!_isAuthing) {
_isAuthing = true;
final val = await goWithResult();
_isAuthing = false;
switch (val) {
case AuthResult.success:
break;
case AuthResult.fail:
case AuthResult.cancel:
go(count + 1);
break;
case AuthResult.notAvail:
Stores.setting.useBioAuth.put(false);
break;
}
}
}
}
static Future<AuthResult> goWithResult() async {
if (!await isAvail) return AuthResult.notAvail;
try {
await _auth.stopAuthentication();
final reuslt = await _auth.authenticate(
localizedReason: l10n.authRequired,
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
authMessages: [
AndroidAuthMessages(
biometricHint: l10n.bioAuth,
biometricNotRecognized: l10n.failed,
biometricRequiredTitle: l10n.authRequired,
biometricSuccess: l10n.success,
cancelButton: l10n.cancel,
),
IOSAuthMessages(
lockOut: l10n.authRequired,
cancelButton: l10n.ok,
),
]);
if (reuslt) {
return AuthResult.success;
}
return AuthResult.fail;
} on PlatformException catch (e) {
switch (e.code) {
case errs.notEnrolled:
return AuthResult.notAvail;
case errs.lockedOut:
case errs.permanentlyLockedOut:
exit(0);
}
return AuthResult.cancel;
}
}
}
enum AuthResult {
success,
// Not match
fail,
// User cancel
cancel,
// Device doesn't support biometrics
notAvail,
}

View File

@@ -1,57 +0,0 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:toolbox/core/extension/stringx.dart';
enum OS {
android,
ios,
linux,
macos,
windows,
web,
fuchsia,
unknown;
static final type = () {
if (kIsWeb) {
return OS.web;
}
if (Platform.isAndroid) {
return OS.android;
}
if (Platform.isIOS) {
return OS.ios;
}
if (Platform.isLinux) {
return OS.linux;
}
if (Platform.isMacOS) {
return OS.macos;
}
if (Platform.isWindows) {
return OS.windows;
}
if (Platform.isFuchsia) {
return OS.fuchsia;
}
return OS.unknown;
}();
@override
String toString() => switch (this) {
OS.macos => 'macOS',
OS.ios => 'iOS',
final val => val.name.upperFirst,
};
}
final isAndroid = OS.type == OS.android;
final isIOS = OS.type == OS.ios;
final isLinux = OS.type == OS.linux;
final isMacOS = OS.type == OS.macos;
final isWindows = OS.type == OS.windows;
final isWeb = OS.type == OS.web;
final isMobile = OS.type == OS.ios || OS.type == OS.android;
final isDesktop =
OS.type == OS.linux || OS.type == OS.macos || OS.type == OS.windows;

View File

@@ -1,26 +0,0 @@
import 'dart:io';
import 'package:toolbox/core/utils/platform/base.dart';
final _pathSep = Platform.pathSeparator;
String get pathSeparator => _pathSep;
/// Available only on desktop,
/// return null on mobile
String? getHomeDir() {
final envVars = Platform.environment;
if (isMacOS || isLinux) {
return envVars['HOME'];
} else if (isWindows) {
return envVars['UserProfile'];
}
return null;
}
/// Join two paths with platform specific separator
String joinPath(String path1, String path2) {
if (isWindows) {
return path1 + (path1.endsWith('\\') ? '' : '\\') + path2;
}
return path1 + (path1.endsWith('/') ? '' : '/') + path2;
}

View File

@@ -1,13 +0,0 @@
import 'package:permission_handler/permission_handler.dart';
abstract final class PermUtils {
static Future<bool> request(Permission permission) async {
final status = await permission.status;
if (status.isGranted) {
return true;
} else {
final result = await permission.request();
return result.isGranted;
}
}
}

View File

@@ -1,43 +0,0 @@
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:share_plus/share_plus.dart';
import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/res/provider.dart';
abstract final class Shares {
static Future<bool> files(List<String> filePaths) async {
for (final filePath in filePaths) {
if (!await File(filePath).exists()) {
return false;
}
}
var text = '';
if (filePaths.length == 1) {
text = filePaths.first.split('/').last;
} else {
text = '${filePaths.length} ${l10n.files}';
}
Pros.app.moveBg = false;
// ignore: deprecated_member_use
await Share.shareFiles(filePaths, subject: text);
Pros.app.moveBg = true;
return filePaths.isNotEmpty;
}
static Future<bool> text(String text) async {
Pros.app.moveBg = false;
await Share.share(text);
Pros.app.moveBg = true;
return true;
}
static void copy(String text) {
Clipboard.setData(ClipboardData(text: text));
}
static Future<String?> paste([String type = 'text/plain']) async {
final data = await Clipboard.getData(type);
return data?.text;
}
}

View File

@@ -1,7 +1,7 @@
import 'dart:async';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/res/provider.dart';
@@ -14,6 +14,7 @@ abstract final class KeybordInteractive {
try {
final res = await (ctx ?? Pros.app.ctx)?.showPwdDialog(
title: '2FA ${l10n.pwd}',
id: spi.id,
label: spi.id,
);
return res == null ? null : [res];

View File

@@ -2,13 +2,13 @@ import 'dart:async';
import 'dart:io';
import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:icloud_storage/icloud_storage.dart';
import 'package:logging/logging.dart';
import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/sync.dart';
import '../../../data/model/app/error.dart';
import '../../../data/res/path.dart';
abstract final class ICloud {
static const _containerId = 'iCloud.tech.lolli.serverbox';
@@ -31,7 +31,7 @@ abstract final class ICloud {
try {
await ICloudStorage.upload(
containerId: _containerId,
filePath: localPath ?? '${await Paths.doc}/$relativePath',
filePath: localPath ?? '${Paths.doc}/$relativePath',
destinationRelativePath: relativePath,
onProgress: (stream) {
stream.listen(
@@ -85,7 +85,7 @@ abstract final class ICloud {
await ICloudStorage.download(
containerId: _containerId,
relativePath: relativePath,
destinationFilePath: localPath ?? '${await Paths.doc}/$relativePath',
destinationFilePath: localPath ?? '${Paths.doc}/$relativePath',
onProgress: (stream) {
stream.listen(
null,
@@ -139,7 +139,7 @@ abstract final class ICloud {
}
}));
final docPath = await Paths.doc;
final docPath = Paths.doc;
/// compare files in iCloud and local
missions.addAll(allFiles.map((file) async {
@@ -205,7 +205,7 @@ abstract final class ICloud {
return;
}
final dlFile = await File(await Paths.bak).readAsString();
final dlFile = await File(Paths.bakPath).readAsString();
final dlBak = await Computer.shared.start(Backup.fromJsonString, dlFile);
await dlBak.restore();

View File

@@ -1,10 +1,10 @@
import 'dart:io';
import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:logging/logging.dart';
import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/error.dart';
import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:webdav_client/webdav_client.dart';
@@ -37,7 +37,7 @@ abstract final class Webdav {
}) async {
try {
await _client.writeFile(
localPath ?? '${await Paths.doc}/$relativePath',
localPath ?? '${Paths.doc}/$relativePath',
_prefix + relativePath,
);
} catch (e, s) {
@@ -64,7 +64,7 @@ abstract final class Webdav {
try {
await _client.readFile(
_prefix + relativePath,
localPath ?? '${await Paths.doc}/$relativePath',
localPath ?? '${Paths.doc}/$relativePath',
);
} catch (e) {
_logger.warning('Download $relativePath failed');
@@ -104,7 +104,7 @@ abstract final class Webdav {
}
try {
final dlFile = await File(await Paths.bak).readAsString();
final dlFile = await File(Paths.bakPath).readAsString();
final dlBak = await Computer.shared.start(Backup.fromJsonString, dlFile);
await dlBak.restore();
} catch (e) {

View File

@@ -1,14 +1,12 @@
import 'dart:async';
import 'dart:io';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:url_launcher/url_launcher.dart';
import 'misc.dart';
import '../extension/uint8list.dart';
Future<bool> openUrl(String url) async {
return await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
}