medialocation_controller.dart 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import 'package:get/get.dart';
  2. import '../../../../utils/log/logger.dart';
  3. import '../../../../utils/system_helper.dart';
  4. import '../../../constants/enums.dart';
  5. import '../../../controllers/api_controller.dart';
  6. import '../../../controllers/base_core_api.dart';
  7. import '../../../controllers/core_controller.dart';
  8. import '../../../data/models/banner/banner_list.dart';
  9. import '../../../data/models/launch/groups.dart';
  10. import '../../../data/sp/ix_sp.dart';
  11. import '../../../dialog/error_dialog.dart';
  12. import '../../../modules/home/controllers/home_controller.dart';
  13. import '../../../routes/app_pages.dart';
  14. class MedialocationController extends GetxController {
  15. final TAG = 'MedialocationController';
  16. final ApiController apiController = Get.find<ApiController>();
  17. final CoreController coreController = Get.find<CoreController>();
  18. final HomeController homeController = Get.find<HomeController>();
  19. // VPN连接状态(计算属性,基于 coreController 状态和 bannerLocation)
  20. bool get isConnected =>
  21. _isSameLocation && coreController.state == ConnectionState.connected;
  22. bool get isConnecting =>
  23. _isSameLocation && coreController.state == ConnectionState.connecting ||
  24. coreController.state == ConnectionState.connectingVirtual;
  25. // 判断当前选中的节点是否是 bannerLocation
  26. bool get _isSameLocation {
  27. final location = bannerLocation.value;
  28. if (location == null) return false;
  29. final selectedLocation = homeController.selectedLocation;
  30. return selectedLocation != null &&
  31. (selectedLocation.id == location.id ||
  32. selectedLocation.code == location.code);
  33. }
  34. // Banner 数据
  35. final Rxn<Banner> banner = Rxn<Banner>();
  36. String get bannerTitle => banner.value?.title ?? 'Movies&TV';
  37. String get bannerImg => banner.value?.img ?? '';
  38. // Banner 列表
  39. final _bannerList = <Banner>[].obs;
  40. List<Banner> get bannerList => _bannerList;
  41. set bannerList(List<Banner> value) => _bannerList.assignAll(value);
  42. // Banner 背景图信息
  43. final Rxn<Banner> bannerInfo = Rxn<Banner>();
  44. String get bannerInfoImg => bannerInfo.value?.img ?? '';
  45. // Banner 关联的节点
  46. final Rxn<Location> bannerLocation = Rxn<Location>();
  47. @override
  48. void onInit() {
  49. super.onInit();
  50. if (Get.arguments != null) {
  51. if (Get.arguments['banner'] != null) {
  52. banner.value = Get.arguments['banner'] as Banner;
  53. }
  54. if (Get.arguments['type'] != null) {
  55. getBanner(position: Get.arguments['type'] as String);
  56. }
  57. }
  58. }
  59. /// 连接VPN - 连接到 bannerLocation
  60. void connect() {
  61. final location = bannerLocation.value;
  62. if (location == null) {
  63. log(TAG, 'Cannot connect: bannerLocation is null');
  64. return;
  65. }
  66. if (isConnecting) return;
  67. // 将 Location 转换为 Locations 并选中
  68. final locations = Locations(
  69. id: location.id,
  70. name: location.name,
  71. code: location.code,
  72. icon: location.icon,
  73. country: location.country,
  74. sort: location.sort,
  75. );
  76. // 选中节点并触发连接
  77. homeController.selectLocation(locations, locationSelectionType: 'media');
  78. coreController.selectLocationConnect();
  79. }
  80. /// 断开VPN
  81. void disconnect() {
  82. BaseCoreApi().disconnect();
  83. }
  84. /// 获取 banner 列表
  85. /// [position] banner 位置类型,如 "banner"、"media"、"nine" 等
  86. Future<void> getBanner({
  87. String position = 'media',
  88. bool isCache = true,
  89. }) async {
  90. try {
  91. // 先读取缓存数据
  92. final cacheBanners = IXSP.getBanner(position);
  93. if (cacheBanners != null && isCache) {
  94. if (cacheBanners.list != null && cacheBanners.list!.isNotEmpty) {
  95. bannerList = cacheBanners.list!;
  96. }
  97. if (cacheBanners.bannerInfo != null) {
  98. bannerInfo.value = cacheBanners.bannerInfo;
  99. }
  100. if (cacheBanners.location != null) {
  101. bannerLocation.value = cacheBanners.location;
  102. }
  103. log(TAG, 'Loaded banner from cache for position: $position');
  104. }
  105. // 请求最新数据
  106. final banners = await apiController.getBanner(position: position);
  107. if (banners.list != null && banners.list!.isNotEmpty) {
  108. bannerList = banners.list!;
  109. }
  110. if (banners.bannerInfo != null) {
  111. bannerInfo.value = banners.bannerInfo;
  112. }
  113. if (banners.location != null) {
  114. bannerLocation.value = banners.location;
  115. }
  116. // 保存到缓存
  117. await IXSP.saveBanner(position, banners);
  118. log(TAG, 'Banner updated and cached for position: $position');
  119. } catch (e) {
  120. log(TAG, 'Error loading banners for position $position: $e');
  121. }
  122. }
  123. //点击banner
  124. void onBannerTap(Banner? banner) {
  125. if (banner?.action == null) return;
  126. final action = BannerAction.values.firstWhere(
  127. (e) => e.toString().split('.').last == banner?.action,
  128. orElse: () => BannerAction.notice, // 默认值
  129. );
  130. switch (action) {
  131. case BannerAction.urlOut:
  132. if (banner?.data != null) {
  133. SystemHelper.openWebPage(banner!.data!);
  134. }
  135. break;
  136. case BannerAction.urlIn:
  137. if (banner?.data != null) {
  138. Get.toNamed(
  139. Routes.WEB,
  140. arguments: {
  141. 'title': banner?.title ?? '',
  142. 'url': banner?.data ?? '',
  143. },
  144. );
  145. }
  146. break;
  147. case BannerAction.deepLink:
  148. if (banner?.data != null) {
  149. // Handle deep link
  150. SystemHelper.handleDeepLink(banner!.data!);
  151. }
  152. break;
  153. case BannerAction.openPkg:
  154. if (banner?.data != null) {
  155. // Open specific package
  156. SystemHelper.openPackage(banner!.data!);
  157. }
  158. break;
  159. case BannerAction.notice:
  160. if (banner?.data != null) {
  161. // Show notice dialog
  162. ErrorDialog.show(
  163. title: banner?.title ?? '',
  164. message: banner?.content,
  165. );
  166. }
  167. break;
  168. case BannerAction.page:
  169. if (banner?.data != null) {
  170. final uri = Uri.parse(banner!.data!);
  171. Get.toNamed(
  172. uri.path,
  173. arguments: {...uri.queryParameters, 'banner': banner},
  174. );
  175. }
  176. break;
  177. }
  178. }
  179. }