import 'package:get/get.dart'; import '../../../../utils/log/logger.dart'; import '../../../../utils/system_helper.dart'; import '../../../constants/enums.dart'; import '../../../controllers/api_controller.dart'; import '../../../controllers/base_core_api.dart'; import '../../../controllers/core_controller.dart'; import '../../../data/models/banner/banner_list.dart'; import '../../../data/models/launch/groups.dart'; import '../../../data/sp/ix_sp.dart'; import '../../../dialog/error_dialog.dart'; import '../../../modules/home/controllers/home_controller.dart'; import '../../../routes/app_pages.dart'; class MedialocationController extends GetxController { final TAG = 'MedialocationController'; final ApiController apiController = Get.find(); final CoreController coreController = Get.find(); final HomeController homeController = Get.find(); // VPN连接状态(计算属性,基于 coreController 状态和 bannerLocation) bool get isConnected => _isSameLocation && coreController.state == ConnectionState.connected; bool get isConnecting => _isSameLocation && coreController.state == ConnectionState.connecting || coreController.state == ConnectionState.connectingVirtual; // 判断当前选中的节点是否是 bannerLocation bool get _isSameLocation { final location = bannerLocation.value; if (location == null) return false; final selectedLocation = homeController.selectedLocation; return selectedLocation != null && (selectedLocation.id == location.id || selectedLocation.code == location.code); } // Banner 数据 final Rxn banner = Rxn(); String get bannerTitle => banner.value?.title ?? 'Movies&TV'; String get bannerImg => banner.value?.img ?? ''; // Banner 列表 final _bannerList = [].obs; List get bannerList => _bannerList; set bannerList(List value) => _bannerList.assignAll(value); // Banner 背景图信息 final Rxn bannerInfo = Rxn(); String get bannerInfoImg => bannerInfo.value?.img ?? ''; // Banner 关联的节点 final Rxn bannerLocation = Rxn(); @override void onInit() { super.onInit(); if (Get.arguments != null) { if (Get.arguments['banner'] != null) { banner.value = Get.arguments['banner'] as Banner; } if (Get.arguments['type'] != null) { getBanner(position: Get.arguments['type'] as String); } } } /// 连接VPN - 连接到 bannerLocation void connect() { final location = bannerLocation.value; if (location == null) { log(TAG, 'Cannot connect: bannerLocation is null'); return; } if (isConnecting) return; // 将 Location 转换为 Locations 并选中 final locations = Locations( id: location.id, name: location.name, code: location.code, icon: location.icon, country: location.country, sort: location.sort, ); // 选中节点并触发连接 homeController.selectLocation(locations, locationSelectionType: 'media'); coreController.selectLocationConnect(); } /// 断开VPN void disconnect() { BaseCoreApi().disconnect(); } /// 获取 banner 列表 /// [position] banner 位置类型,如 "banner"、"media"、"nine" 等 Future getBanner({ String position = 'media', bool isCache = true, }) async { try { // 先读取缓存数据 final cacheBanners = IXSP.getBanner(position); if (cacheBanners != null && isCache) { if (cacheBanners.list != null && cacheBanners.list!.isNotEmpty) { bannerList = cacheBanners.list!; } if (cacheBanners.bannerInfo != null) { bannerInfo.value = cacheBanners.bannerInfo; } if (cacheBanners.location != null) { bannerLocation.value = cacheBanners.location; } log(TAG, 'Loaded banner from cache for position: $position'); } // 请求最新数据 final banners = await apiController.getBanner(position: position); if (banners.list != null && banners.list!.isNotEmpty) { bannerList = banners.list!; } if (banners.bannerInfo != null) { bannerInfo.value = banners.bannerInfo; } if (banners.location != null) { bannerLocation.value = banners.location; } // 保存到缓存 await IXSP.saveBanner(position, banners); log(TAG, 'Banner updated and cached for position: $position'); } catch (e) { log(TAG, 'Error loading banners for position $position: $e'); } } //点击banner void onBannerTap(Banner? banner) { if (banner?.action == null) return; final action = BannerAction.values.firstWhere( (e) => e.toString().split('.').last == banner?.action, orElse: () => BannerAction.notice, // 默认值 ); switch (action) { case BannerAction.urlOut: if (banner?.data != null) { SystemHelper.openWebPage(banner!.data!); } break; case BannerAction.urlIn: if (banner?.data != null) { Get.toNamed( Routes.WEB, arguments: { 'title': banner?.title ?? '', 'url': banner?.data ?? '', }, ); } break; case BannerAction.deepLink: if (banner?.data != null) { // Handle deep link SystemHelper.handleDeepLink(banner!.data!); } break; case BannerAction.openPkg: if (banner?.data != null) { // Open specific package SystemHelper.openPackage(banner!.data!); } break; case BannerAction.notice: if (banner?.data != null) { // Show notice dialog ErrorDialog.show( title: banner?.title ?? '', message: banner?.content, ); } break; case BannerAction.page: if (banner?.data != null) { final uri = Uri.parse(banner!.data!); Get.toNamed( uri.path, arguments: {...uri.queryParameters, 'banner': banner}, ); } break; } } }