Update kernel

Add import profile via QR code image
This commit is contained in:
chen08209
2024-05-11 17:02:34 +08:00
parent 472cea9037
commit a134c32493
54 changed files with 804 additions and 268 deletions

View File

@@ -8,7 +8,7 @@ export 'num.dart';
export 'navigation.dart';
export 'window.dart';
export 'system.dart';
export 'file.dart';
export 'picker.dart';
export 'android.dart';
export 'launch.dart';
export 'protocol.dart';

View File

@@ -2,6 +2,8 @@ import 'dart:ui';
import 'package:flutter/material.dart';
const appName = "FlClash";
class AppConstant {
final packageName = "com.follow.clash";
final name = "FlClash";

View File

@@ -1,15 +1,7 @@
import 'package:fl_clash/application.dart';
import 'package:fl_clash/controller.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
extension BuildContextExtension on BuildContext {
AppController get appController {
final appController =
findAncestorStateOfType<ApplicationState>()?.appController;
assert(appController != null, "only use application environment");
return appController!;
}
CommonScaffoldState? get commonScaffoldState {
return findAncestorStateOfType<CommonScaffoldState>();

View File

@@ -1,23 +1,27 @@
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:zxing2/qrcode.dart';
import 'package:image/image.dart' as img;
class Other {
static Color? getDelayColor(int? delay) {
Color? getDelayColor(int? delay) {
if (delay == null) return null;
if (delay < 0) return Colors.red;
if (delay < 600) return Colors.green;
return const Color(0xFFC57F0A);
}
static String getDateStringLast2(int value) {
String getDateStringLast2(int value) {
var valueRaw = "0$value";
return valueRaw.substring(
valueRaw.length - 2,
);
}
static String getTimeDifference(DateTime dateTime) {
String getTimeDifference(DateTime dateTime) {
var currentDateTime = DateTime.now();
var difference = currentDateTime.difference(dateTime);
var inHours = difference.inHours;
@@ -27,7 +31,7 @@ class Other {
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
}
static String getTimeText(int? timeStamp) {
String getTimeText(int? timeStamp) {
if (timeStamp == null) {
return '00:00:00';
}
@@ -39,7 +43,7 @@ class Other {
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
}
static Locale? getLocaleForString(String? localString) {
Locale? getLocaleForString(String? localString) {
if (localString == null) return null;
var localSplit = localString.split("_");
if (localSplit.length == 1) {
@@ -57,7 +61,7 @@ class Other {
return null;
}
static int sortByChar(String a, String b) {
int sortByChar(String a, String b) {
if (a.isEmpty && b.isEmpty) {
return 0;
}
@@ -77,7 +81,7 @@ class Other {
}
}
static String getOverwriteLabel(String label) {
String getOverwriteLabel(String label) {
final reg = RegExp(r'\((\d+)\)$');
final matches = reg.allMatches(label);
if (matches.isNotEmpty) {
@@ -89,21 +93,7 @@ class Other {
}
}
// static FutureOr<void> Function(T p) debounce<T>(void Function(T? p) func,
// {Duration? duration}) {
// Timer? timer;
// return ([T? p]) {
// if (timer != null) {
// timer?.cancel();
// }
// timer = Timer(duration ?? const Duration(milliseconds: 300), () {
// func(p);
// });
// };
// }
static String getTrayIconPath() {
String getTrayIconPath() {
if (Platform.isWindows) {
return "assets/images/app_icon.ico";
} else {
@@ -111,7 +101,7 @@ class Other {
}
}
static int compareVersions(String version1, String version2) {
int compareVersions(String version1, String version2) {
List<String> v1 = version1.split('+')[0].split('.');
List<String> v2 = version2.split('+')[0].split('.');
int major1 = int.parse(v1[0]);
@@ -133,4 +123,30 @@ class Other {
int build2 = version2.contains('+') ? int.parse(version2.split('+')[1]) : 0;
return build1.compareTo(build2);
}
Future<String?> parseQRCode(Uint8List? bytes) {
return Isolate.run<String?>(() {
if (bytes == null) return null;
img.Image? image = img.decodeImage(bytes);
LuminanceSource source = RGBLuminanceSource(
image!.width,
image.height,
image
.convert(numChannels: 4)
.getBytes(order: img.ChannelOrder.abgr)
.buffer
.asInt32List(),
);
final bitmap = BinaryBitmap(GlobalHistogramBinarizer(source));
final reader = QRCodeReader();
try {
final result = reader.decode(bitmap);
return result.text;
} catch (_) {
return null;
}
});
}
}
final other = Other();

View File

@@ -1,11 +1,12 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:fl_clash/common/app_localizations.dart';
import 'package:fl_clash/common/common.dart';
import 'package:image_picker/image_picker.dart';
import 'package:fl_clash/models/models.dart';
class FileUtil {
static Future<Result<PlatformFile>> pickerConfig() async {
class Picker {
Future<Result<PlatformFile>> pickerConfigFile() async {
FilePickerResult? filePickerResult;
if (Platform.isAndroid) {
filePickerResult = await FilePicker.platform.pickFiles(
@@ -26,4 +27,17 @@ class FileUtil {
}
return Result.success(data: file);
}
Future<Result<String>> pickerConfigQRCode() async {
final xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
final bytes = await xFile?.readAsBytes();
if (bytes == null) return Result.error();
final result = await other.parseQRCode(bytes);
if (result == null || !result.isUrl) {
return Result.error(message: appLocalizations.pleaseUploadValidQrcode);
}
return Result.success(data: result);
}
}
final picker = Picker();

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/models.dart';
@@ -29,8 +28,7 @@ class Preferences {
try {
return ClashConfig.fromJson(clashConfigMap);
} catch (e) {
debugPrint(e.toString());
return null;
throw e.toString();
}
}
@@ -50,8 +48,7 @@ class Preferences {
try {
return Config.fromJson(configMap);
} catch (e) {
debugPrint(e.toString());
return null;
throw e.toString();
}
}

View File

@@ -29,7 +29,7 @@ class Request {
final packageInfo = await appPackage.packageInfoCompleter.future;
final version = packageInfo.version;
final hasUpdate =
Other.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
other.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
if (!hasUpdate) return Result.error();
return Result.success(data: body['body']);
}