node_controller.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import '../../../../config/translations/strings_enum.dart';
  4. import '../../../constants/iconfont/iconfont.dart';
  5. import '../../../controllers/api_controller.dart';
  6. import '../../../controllers/core_controller.dart';
  7. import '../../../data/models/launch/groups.dart';
  8. import '../../../data/sp/ix_sp.dart';
  9. class NodeController extends GetxController {
  10. final coreController = Get.find<CoreController>();
  11. final ApiController _apiController = Get.find<ApiController>();
  12. // Groups 数据
  13. final _groups = Rxn<Groups>();
  14. Groups? get groups => _groups.value;
  15. set groups(Groups? value) => _groups.value = value;
  16. // 游戏tab列表
  17. final _tabTextList = <String>[].obs;
  18. List<String> get tabTextList => _tabTextList;
  19. set tabTextList(List<String> value) => _tabTextList.assignAll(value);
  20. // 当前选中的 Tab 索引
  21. final _currentTabIndex = 0.obs;
  22. int get currentTabIndex => _currentTabIndex.value;
  23. set currentTabIndex(int value) => _currentTabIndex.value = value;
  24. // 保存每个 tab 中每个国家的展开/收缩状态
  25. // key 格式: "tabIndex_countryCode"
  26. final Map<String, bool> expandedStates = {};
  27. // 当前选中的tab
  28. String getCurrentTab() {
  29. return tabTextList[currentTabIndex];
  30. }
  31. // 列表刷新状态
  32. final _isRefreshing = false.obs;
  33. bool get isRefreshing => _isRefreshing.value;
  34. @override
  35. void onInit() {
  36. super.onInit();
  37. _loadGroups();
  38. }
  39. /// 加载 Groups 数据
  40. void _loadGroups() {
  41. final launch = IXSP.getLaunch();
  42. if (launch?.groups != null) {
  43. groups = launch!.groups;
  44. _updateTabList();
  45. }
  46. }
  47. void updateGroups(Groups? groups) {
  48. this.groups = groups;
  49. _updateTabList();
  50. }
  51. /// 更新 Tab 列表
  52. void _updateTabList() {
  53. final tabs = <String>[];
  54. // 添加 Normal tab
  55. if (groups?.normal != null && groups!.normal!.list?.isNotEmpty == true) {
  56. tabs.add(Strings.tabAll.tr);
  57. }
  58. // 添加 Streaming tab
  59. if (groups?.streaming != null &&
  60. groups!.streaming!.list?.isNotEmpty == true) {
  61. tabs.add(Strings.tabStreaming.tr);
  62. }
  63. tabTextList = tabs;
  64. }
  65. /// 根据 tab 索引获取对应的数据
  66. Normal? getDataByTabIndex(int tabIndex) {
  67. if (tabIndex == 0) {
  68. return groups?.normal;
  69. } else if (tabIndex == 1) {
  70. return groups?.streaming;
  71. }
  72. return null;
  73. }
  74. IconData getTabIcon(int tabIndex) {
  75. if (tabIndex == 0) {
  76. return IconFont.icon24;
  77. } else if (tabIndex == 1) {
  78. return IconFont.icon25;
  79. }
  80. return IconFont.icon24;
  81. }
  82. /// 获取国家的展开状态
  83. bool getExpandedState(int tabIndex, String countryCode) {
  84. final key = '${tabIndex}_$countryCode';
  85. return expandedStates[key] ?? false; // 默认收缩
  86. }
  87. /// 设置国家的展开状态
  88. void setExpandedState(int tabIndex, String countryCode, bool expanded) {
  89. final key = '${tabIndex}_$countryCode';
  90. expandedStates[key] = expanded;
  91. }
  92. /// 当 Launch 数据更新时刷新节点
  93. void refreshOnLaunchChanged() {
  94. _loadGroups();
  95. }
  96. // 设置tab选中状态
  97. void setTabSelected(int tabIndex) {
  98. currentTabIndex = tabIndex;
  99. coreController.locationSelectionType = tabTextList[tabIndex];
  100. }
  101. /// 主动刷新列表
  102. void refreshLocations() async {
  103. try {
  104. _isRefreshing.value = true;
  105. // 保持至少2秒的刷新过程
  106. final results = await Future.wait([
  107. _apiController.getLocations(),
  108. Future.delayed(const Duration(milliseconds: 1500)),
  109. ]);
  110. final groups = results[0] as Groups;
  111. updateGroups(groups);
  112. _isRefreshing.value = false;
  113. } catch (_) {
  114. // TODO: 捕捉异常写入日志
  115. Future.delayed(const Duration(milliseconds: 1500), () {
  116. _isRefreshing.value = false;
  117. });
  118. }
  119. }
  120. }