import 'dart:async'; import 'package:get/get.dart'; import 'package:hgdj/assets_tool/images.dart'; import 'package:hgdj/config/config.dart'; import 'package:hgdj/hj_model/home/plate_model.dart'; import 'package:hgdj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:hgdj/hj_utils/const.dart'; import 'package:hgdj/hj_utils/free_play_manager.dart'; import 'package:hgdj/tools_base/global_store/store.dart'; import '../../tools_base/event_bus/event_bus_util.dart'; import '../../tools_base/event_bus/events.dart'; import '../../tools_base/toast.dart'; import '../cartoon/cartoon_sub_module_logic.dart'; import '../community/community/community_module_logic.dart'; import '../community/community_main_page_page/community_main_logic.dart'; import '../home/home_main_logic.dart'; import '../home/provider/home_update_marker_provider.dart'; import '../mine/mine_vip/vip_product_manager.dart'; import '../short_video/short_main_video_logic.dart'; import 'drama_tip_bubble.dart'; import 'main_page.dart'; import 'provider/msg_provider.dart'; class MainPageBinding extends Bindings { @override void dependencies() { Get.lazyPut(() => MainPageLogic()); } } /// 亚模块 id 在底栏里的落点 class ModuleModel { final int tab; //底部 tab 下标 final int sub; //顶部 tab 下标 final int module; //顶部 tab 下的亚模块下标 ModuleModel({required this.tab, required this.sub, required this.module}); } //tab数据模型 class MainTabModel { final String title; //title final String imageNor; //nor图片 final String imageSel; //选中图片 MainTabModel({ required this.title, required this.imageNor, required this.imageSel, }); } class MainPageLogic extends GetxController { final tabs = [ MainTabModel( title: '主页', imageNor: 'home_0_0.png'.homePath, imageSel: 'home_0_1.png'.homePath, ), MainTabModel( title: '短剧', imageNor: 'home_1_0.png'.homePath, imageSel: 'home_1_1.png'.homePath, ), MainTabModel( title: Config.darkWebIconName?.isNotEmpty == true ? Config.darkWebIconName! : '暗网', imageNor: 'home_2_0.png'.homePath, imageSel: 'home_2_1.png'.homePath, ), MainTabModel( title: 'AI', imageNor: 'home_3_0.png'.homePath, imageSel: 'home_3_1.png'.homePath, ), MainTabModel( title: '社区', imageNor: 'home_4_0.png'.homePath, imageSel: 'home_4_1.png'.homePath, ), MainTabModel( title: '我的', imageNor: 'home_5_0.png'.homePath, imageSel: 'home_5_1.png'.homePath, ), ]; /// 当前底部 tab 下标:内容页(LazyIndexedStack)和底栏选中态的唯一真相源。 /// 启动固定落在短剧 final curPageIndex = DramaTipBubble.dramaTab.obs; final shortIndex = (-1).obs; // -1 = 用短剧频道的默认页(AI短剧) final darkInitTabId = Rx(null); // 暗网默认亚模块 id final communityIndex = 0.obs; // 社区模块默认模块 final communitySubIndex = 0.obs; // 社区模块默认亚模块 /// 亚模块id -<主>tab - <模块 - 亚模块> final moduleMap = {}; late StreamSubscription _yinseSub; late StreamSubscription _loginSub; DateTime? _lastBackAt; //上次返回键点击时间 //暗网 tab 关掉后,排在它后面的 tab 整体前移一位 int get aiTab => Config.darkWebEnable ? 3 : 2; int get communityTab => Config.darkWebEnable ? 4 : 3; @override void onInit() { super.onInit(); if (!Config.darkWebEnable) { tabs.removeAt(2); } MineMsgProvider().loadData(); HomeUpdateMarkerProvider().loadData(); //启动就落在短剧:引导气泡不该再亮(这里早于 DramaTipBubble.start 的读盘) if (curPageIndex.value == DramaTipBubble.dramaTab) DramaTipBubble.hide(); _yinseSub = eventBus.on(_onYinse); _loginSub = eventBus.on(_onReLogin); /// 组装所有 Future(() { final app = Config.plateModule; if (app == null) return; void put(List modules, int tab, int sub) { modules.asMap().forEach((i, e) => moduleMap[e.id ?? ''] = ModuleModel(tab: tab, sub: sub, module: i)); } put(app.homePage, 0, 0); // 暗网 tab 关掉时不登记其亚模块:没有对应 tab,再按 tab=2 跳会落到 AI 页 if (Config.darkWebEnable) put(app.deepWeb, 2, 0); put(app.community, communityTab, 0); put(app.picsUi, communityTab, 1); put(app.gameUi, communityTab, 2); put(app.novel, communityTab, 3); }); } void _onReLogin(ReLoginEvent event) { _backToRoot(); jumpToPage(0); globalStore.refreshWallet(); MineMsgProvider() .loadData(); //内含 refreshPayPopup:重拉支付分层配置,即时刷新浮窗/我的横幅/播放器横幅 unawaited(FreePlayManager().refresh()); //切号:免费观看次数是账户维度的,不重拉会一直用着上个账号的次数 HomeUpdateMarkerProvider().loadData(); presaleProvider.refreshStatus(); //刷新预售权益 vipProductManager.reloadForUser(); //切号:按新用户权限重拉会员卡(预售等卡随权限/购买状态返回不同) _homeLogic()?.tabCtr?.index = 0; } void _onYinse(YinseinnerModel model) { switch (model.routeName) { case 'navigation_bar': //导航栏 亚模块菜单弹出 _openNavBar(); case 'module': case 'community_module': //媒体库亚模块分类 _backToRoot(); _matchModule(model.id); case 'live_streaming': //直播 _backToRoot(); _skipToLive(); case 'ai': _backToRoot(); _skipToAi(); } } //首页/暗网共用 HomeMainLogic,靠 tag 区分;页面还没建时返回 null HomeMainLogic? _homeLogic([String tag = 'HomeMainLogic']) => Get.isRegistered(tag: tag) ? Get.find(tag: tag) : null; void _openNavBar() { _backToRoot(); jumpToPage(0); _homeLogic()?.openEndDrawer(); } //跳转直播 void _skipToLive() { jumpToPage(1); if (Get.isRegistered()) { Get.find().jumpToLive(); } else { shortIndex.value = 0; //直播固定在第一个 } } //跳转ai void _skipToAi() => jumpToPage(aiTab); void _matchModule(String? id) { if (id == null) return; final module = moduleMap[id]; if (module == null) return; //首页和暗网 tab 可自动排序, 不用 HomeModuleProvider 处理 if (module.tab == 0) { _homeLogic()?.gotoTabId(id); jumpToPage(0); } else if (module.tab == 2) { //tab==2 只在暗网开启时才登记进 moduleMap(见 onInit),所以这里下标可直接写 2 final darkLogic = _homeLogic('HomeMainLogic_dark'); if (darkLogic != null) { darkLogic.gotoTabId(id); } else { darkInitTabId.value = id; } jumpToPage(2); } else if (module.tab == communityTab) { _skipToCommunity(module); jumpToPage(communityTab); } } //社区对应 logic 已建就直接切,没建就记下来等页面自己读 void _skipToCommunity(ModuleModel module) { if (Get.isRegistered()) { Get.find().jumpSubModule(module.sub); if (module.sub == 0) { if (Get.isRegistered()) { Get.find().skipToTabIndex(module.module); return; } } else { final tag = [ "", MediaStyle.Pic.name, MediaStyle.Game.name, MediaStyle.Novel.name ][module.sub]; if (Get.isRegistered(tag: tag)) { Get.find(tag: tag) .skipToTabIndex(module.module); return; } } } communityIndex.value = module.sub; communitySubIndex.value = module.module; } //返回首页 void _backToRoot() => Get.until((route) => route.settings.name == MainPage.routeName); /// 切 tab:内容页和底栏选中态都监听 curPageIndex,改它一处即可 void jumpToPage(int index) { curPageIndex.value = index; if (index == DramaTipBubble.dramaTab) DramaTipBubble.hide(); //进了短剧就别再指着它 } /// 双击返回退出:2 秒内连按两次返回键才真正退出 bool confirmExit() { final now = DateTime.now(); // 物理键,两次间隔大于 2 秒,退出请求无效 if (_lastBackAt == null || now.difference(_lastBackAt!) > const Duration(seconds: 2)) { _lastBackAt = now; showToast('再次返回即可退出'); return false; } // 退出请求有效 _lastBackAt = null; return true; } @override void onClose() { _yinseSub.cancel(); _loginSub.cancel(); super.onClose(); } }