| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- import 'dart:convert';
- import 'package:get/get.dart';
- import 'package:nomo/app/base/base_controller.dart';
- import 'package:nomo/app/data/sp/ix_sp.dart';
- import 'package:nomo/pigeons/core_api.g.dart';
- import 'package:nomo/utils/log/logger.dart';
- /// 分流隧道模式枚举
- enum SplitTunnelingMode {
- exclude, // 排除选中的应用
- include, // 仅包含选中的应用
- none, // 不选择任何应用
- }
- /// 应用数据模型
- class AppInfo {
- final String name;
- final String packageName;
- final String icon;
- AppInfo({required this.name, required this.packageName, required this.icon});
- }
- class SplittunnelingSelectappController extends BaseController {
- // 排除模式选中的应用列表
- final RxList<AppInfo> excludeSelectedApps = <AppInfo>[].obs;
- // 包含模式选中的应用列表
- final RxList<AppInfo> includeSelectedApps = <AppInfo>[].obs;
- // 所有应用列表
- final RxList<AppInfo> allApps = <AppInfo>[].obs;
- // 当前模式
- final Rx<SplitTunnelingMode> currentMode = SplitTunnelingMode.exclude.obs;
- static const String TAG = 'SplittunnelingSelectappController';
- // 缓存键
- static const String _cachedAppsKey = 'splittunneling_cached_apps';
- static const String _excludeSelectedAppsKey =
- 'splittunneling_exclude_selected_apps';
- static const String _includeSelectedAppsKey =
- 'splittunneling_include_selected_apps';
- @override
- void onInit() {
- super.onInit();
- _loadCachedData();
- getApps();
- }
- /// 加载缓存数据
- void _loadCachedData() {
- // 加载缓存的应用数据
- final cachedAppsJson = IXSP.getString(_cachedAppsKey);
- if (cachedAppsJson != null) {
- try {
- final cachedApps = jsonDecode(cachedAppsJson) as List;
- final apps = cachedApps
- .map(
- (app) => AppInfo(
- name: app['name'],
- packageName: app['packageName'],
- icon: app['icon'],
- ),
- )
- .toList();
- allApps.value = apps;
- setSuccess();
- } catch (e) {
- log(TAG, '加载缓存应用数据失败: $e');
- }
- }
- // 加载当前模式
- currentMode.value = Get.arguments as SplitTunnelingMode;
- _loadSelectedApps(currentMode.value);
- }
- /// 初始化应用数据
- Future<void> getApps() async {
- // 如果已经有缓存数据,先显示缓存,然后异步更新
- if (allApps.isNotEmpty) {
- setSuccess();
- } else {
- setLoading();
- }
- final newApps = <AppInfo>[];
- final appsJson = await CoreApi().getApps();
- if (appsJson != null) {
- final apps = jsonDecode(appsJson);
- for (dynamic app in apps) {
- if (app is Map) {
- String appName = app['appName'];
- String packageName = app['packageName'];
- String icon = app['icon'];
- newApps.add(
- AppInfo(name: appName, packageName: packageName, icon: icon),
- );
- }
- }
- // 更新应用列表
- allApps.value = newApps;
- // 缓存应用数据
- _cacheAppsData(newApps);
- // 重新加载选中的应用(因为应用列表可能已更新)
- _loadSelectedApps(currentMode.value);
- if (allApps.isNotEmpty) {
- setSuccess();
- } else {
- setEmpty();
- }
- }
- }
- /// 缓存应用数据
- void _cacheAppsData(List<AppInfo> apps) {
- try {
- final appsJson = jsonEncode(
- apps
- .map(
- (app) => {
- 'name': app.name,
- 'packageName': app.packageName,
- 'icon': app.icon,
- },
- )
- .toList(),
- );
- IXSP.setString(_cachedAppsKey, appsJson);
- } catch (e) {
- log(TAG, '缓存应用数据失败: $e');
- }
- }
- /// 加载选中的应用
- void _loadSelectedApps(SplitTunnelingMode mode) {
- final key = mode == SplitTunnelingMode.exclude
- ? _excludeSelectedAppsKey
- : _includeSelectedAppsKey;
- final selectedAppsJson = IXSP.getString(key);
- if (selectedAppsJson != null) {
- try {
- final selectedPackageNames =
- jsonDecode(selectedAppsJson) as List<dynamic>;
- // 按照保存的顺序重建列表
- final selectedAppsList = <AppInfo>[];
- for (final packageName in selectedPackageNames) {
- final app = allApps.firstWhere(
- (app) => app.packageName == packageName,
- orElse: () => AppInfo(name: '', packageName: packageName, icon: ''),
- );
- if (app.name.isNotEmpty) {
- // 只添加有效的应用
- selectedAppsList.add(app);
- }
- }
- if (mode == SplitTunnelingMode.exclude) {
- excludeSelectedApps.value = selectedAppsList;
- } else {
- includeSelectedApps.value = selectedAppsList;
- }
- } catch (e) {
- log(
- TAG,
- '加载${mode == SplitTunnelingMode.exclude ? "排除" : "包含"}模式选中应用数据失败: $e',
- );
- }
- }
- }
- /// 保存选中的应用
- void _saveSelectedApps(SplitTunnelingMode mode) {
- try {
- final selectedApps = mode == SplitTunnelingMode.exclude
- ? excludeSelectedApps
- : includeSelectedApps;
- final selectedPackageNames = selectedApps
- .map((app) => app.packageName)
- .toList();
- final selectedAppsJson = jsonEncode(selectedPackageNames);
- final key = mode == SplitTunnelingMode.exclude
- ? _excludeSelectedAppsKey
- : _includeSelectedAppsKey;
- IXSP.setString(key, selectedAppsJson);
- } catch (e) {
- log(
- TAG,
- '保存${mode == SplitTunnelingMode.exclude ? "排除" : "包含"}模式选中应用数据失败: $e',
- );
- }
- }
- /// 切换应用选择状态
- void toggleAppSelection(AppInfo app) {
- if (currentMode.value == SplitTunnelingMode.exclude) {
- if (excludeSelectedApps.contains(app)) {
- excludeSelectedApps.remove(app);
- } else {
- excludeSelectedApps.add(app);
- }
- _saveSelectedApps(SplitTunnelingMode.exclude);
- } else {
- if (includeSelectedApps.contains(app)) {
- includeSelectedApps.remove(app);
- } else {
- includeSelectedApps.add(app);
- }
- _saveSelectedApps(SplitTunnelingMode.include);
- }
- }
- /// 检查应用是否已选择
- bool isAppSelected(AppInfo app) {
- if (currentMode.value == SplitTunnelingMode.exclude) {
- return excludeSelectedApps.contains(app);
- } else {
- return includeSelectedApps.contains(app);
- }
- }
- /// 取消选择所有应用
- void deselectAllApps() {
- if (currentMode.value == SplitTunnelingMode.exclude) {
- excludeSelectedApps.clear();
- _saveSelectedApps(SplitTunnelingMode.exclude);
- } else {
- includeSelectedApps.clear();
- _saveSelectedApps(SplitTunnelingMode.include);
- }
- }
- /// 选择所有应用
- void selectAllApps() {
- if (currentMode.value == SplitTunnelingMode.exclude) {
- excludeSelectedApps.value = List.from(allApps);
- _saveSelectedApps(SplitTunnelingMode.exclude);
- } else {
- includeSelectedApps.value = List.from(allApps);
- _saveSelectedApps(SplitTunnelingMode.include);
- }
- }
- /// 获取当前模式选中的应用列表
- List<AppInfo> get selectedApps {
- return currentMode.value == SplitTunnelingMode.exclude
- ? excludeSelectedApps
- : includeSelectedApps;
- }
- /// 获取未选择的应用列表
- List<AppInfo> get unselectedApps {
- return allApps.where((app) => !isAppSelected(app)).toList();
- }
- }
|