import 'dart:async'; import 'dart:convert'; import 'dart:isolate'; import 'package:fl_clash/common/app_localizations.dart'; import 'package:fl_clash/common/system.dart'; import 'package:fl_clash/models/models.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; class App { static App? _instance; late MethodChannel methodChannel; Function()? onExit; App._internal() { methodChannel = const MethodChannel('app'); methodChannel.setMethodCallHandler((call) async { switch (call.method) { case 'exit': if (onExit != null) { await onExit!(); } case 'getText': try { return Intl.message(call.arguments as String); } catch (_) { return ''; } default: throw MissingPluginException(); } }); } factory App() { _instance ??= App._internal(); return _instance!; } Future moveTaskToBack() async { return await methodChannel.invokeMethod('moveTaskToBack'); } Future> getPackages() async { final packagesString = await methodChannel.invokeMethod('getPackages'); return Isolate.run>(() { final List packagesRaw = packagesString != null ? json.decode(packagesString) : []; return packagesRaw.map((e) => Package.fromJson(e)).toSet().toList(); }); } Future> getChinaPackageNames() async { final packageNamesString = await methodChannel.invokeMethod('getChinaPackageNames'); return Isolate.run>(() { final List packageNamesRaw = packageNamesString != null ? json.decode(packageNamesString) : []; return packageNamesRaw.map((e) => e.toString()).toList(); }); } Future openFile(String path) async { return await methodChannel.invokeMethod('openFile', { 'path': path, }) ?? false; } Future getPackageIcon(String packageName) async { final base64 = await methodChannel.invokeMethod('getPackageIcon', { 'packageName': packageName, }); if (base64 == null) { return null; } return MemoryImage(base64Decode(base64)); } Future tip(String? message) async { return await methodChannel.invokeMethod('tip', { 'message': '$message', }); } Future initShortcuts() async { return await methodChannel.invokeMethod( 'initShortcuts', appLocalizations.toggle, ); } Future updateExcludeFromRecents(bool value) async { return await methodChannel.invokeMethod('updateExcludeFromRecents', { 'value': value, }); } } final app = system.isAndroid ? App() : null;