import 'dart:io'; import 'package:get/get.dart'; import 'package:naiyouwl/app/controller/GlobalController.dart'; import 'package:naiyouwl/app/controller/controllers.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../common/LogHelper.dart'; import '../../../data/model/NodeMode.dart'; import '../../../network/api_service.dart'; enum NodeDisplayStrategy { All, LeastUsers, SelectedFirst, } class NodeController extends GetxController { //TODO: Implement NodeController final count = 0.obs; var isLoading = false.obs; var nodesToShow = [].obs; var nodeModes = []; var selectedIndex = (-1).obs; var errorMsg = ''.obs; var pingResults = {}.obs; //final selectedNodeId = (-1).obs; final isLoadingMap = {}.obs; var displayStrategy = Rx(NodeDisplayStrategy.All); Future tcpPing(NodeMode node) async { int? nodeId = node.id; isLoadingMap[nodeId] = true; // 开始ping时设置为true isLoadingMap.refresh(); // 通知观察者 final stopwatch = Stopwatch()..start(); Socket? socket; try { socket = await Socket.connect(node.host!, node.port!, timeout: const Duration(seconds: 3)); final elapsed = stopwatch.elapsedMilliseconds; pingResults[nodeId] = '${elapsed}ms'; // 使用普通的映射赋值 pingResults.refresh(); // 通知观察者 socket.destroy(); } catch (e) { pingResults[nodeId] = 'Error'; // 使用普通的映射赋值 pingResults.refresh(); // 通知观察者 } isLoadingMap[nodeId] = false; // ping结束后设置为false isLoadingMap.refresh(); // 通知观察者 } void pingAllNodes() async { for (var node in nodeModes) { tcpPing(node); // 这里用了 await 使其串行 ping,若希望并行可移除 await } } Future pingSingleNode(NodeMode node) async { await tcpPing(node); } void selectNode(NodeMode node) { controllers.global.selectedNode.value = node; _storeSelectedNode(node); controllers.global.swift(node.name); Get.back(); //selectedIndex.value = nodeModes.indexWhere((item) => item.id == node.id); } Future _storeSelectedNode(NodeMode node) async { final prefs = await SharedPreferences.getInstance(); // 为简化起见,我们只存储node的ID,但您可以根据需要存储更多信息 prefs.setInt('selectedNodeId', node.id); await controllers.global.loadSelectedNode(); } // Future loadSelectedNode() async { // final prefs = await SharedPreferences.getInstance(); // final selectedNodeId = prefs.getInt('selectedNodeId'); // if (selectedNodeId != null) { // //selectedIndex.value = nodeModes.indexWhere((item) => item.id == selectedNodeId); // selectedNode.value = nodeModes.firstWhere((node) => node.id == selectedNodeId); // } // } //自动选择人数最小的线路 NodeMode selectBestNode(List nodes) { return nodes.where((node) => node.countryCode == 'HK') //筛选地区是HK的节点 .reduce((value, element) => value.onlineUsers< element.onlineUsers? value : element); //选择人数最小的 } void selectMinOnlineUsersNodeInRegion(String region) { List nodesInRegion = nodeModes.where((node) => node.countryCode == region).toList(); if (nodesInRegion.isNotEmpty) { NodeMode? minNode = nodesInRegion.reduce((curr, next) => curr.onlineUsers! <= next.onlineUsers! ? curr : next); selectNode(minNode); } } void filterNodesWithLeastUsersInHK() { displayStrategy.value = NodeDisplayStrategy.LeastUsers; updateNodesToDisplay(); } void filterNodesByRegion(String region) { nodesToShow.value = nodeModes.where((node) => node.countryCode == region).toList(); updateNodesToDisplay(); } void showAllNodes() { displayStrategy.value = NodeDisplayStrategy.All; updateNodesToDisplay(); // nodesToShow.value = List.from(nodeModes); } void showSelectedFirst() { displayStrategy.value = NodeDisplayStrategy.SelectedFirst; updateNodesToDisplay(); // 如果需要,可以添加其他逻辑。 } void updateNodesToDisplay() { List nodes = List.from(nodeModes); switch (displayStrategy.value) { case NodeDisplayStrategy.LeastUsers: List filteredNodes = nodeModes.where((node) => node.countryCode == "hk" && node.onlineUsers != null).toList(); if (filteredNodes.isNotEmpty) { int? minUsers = filteredNodes.map((node) => node.onlineUsers!).reduce((curr, next) => curr < next ? curr : next); nodes = nodes.where((node) => node.onlineUsers == minUsers && node.countryCode == "hk").toList(); selectNode(nodes.first); } else { // Handle the case where no nodes match the criteria. Maybe display a message or use a fallback. nodes = []; // Empty list or some fallback } break; case NodeDisplayStrategy.SelectedFirst: break; case NodeDisplayStrategy.All: // // 将选中的节点移动到前面 // if (selectedNode.value != null) { // nodes.removeWhere((node) => node.id == selectedNode.value?.id); // nodes.insert(0, selectedNode.value!); // } break; default: // 不需要额外的处理,因为nodes已经包含所有节点。 break; } nodesToShow.value = nodes; // 使用 assignAll() 方法触发更新 } @override void onInit() { super.onInit(); nodeModes = controllers.global.nodeModes; nodesToShow.value = nodeModes; } @override void onReady() { super.onReady(); } @override void onClose() { super.onClose(); } void increment() => count.value++; }