Files
2026-09-15 15:44:13 +07:00

283 lines
8.8 KiB
Dart

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>[
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<String?>(null); // 暗网默认亚模块 id
final communityIndex = 0.obs; // 社区模块默认模块
final communitySubIndex = 0.obs; // 社区模块默认亚模块
/// 亚模块id -<主>tab - <模块 - 亚模块>
final moduleMap = <String, ModuleModel>{};
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<YinseinnerModel>(_onYinse);
_loginSub = eventBus.on<ReLoginEvent>(_onReLogin);
/// 组装所有
Future(() {
final app = Config.plateModule;
if (app == null) return;
void put(List<ModuleData> 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<HomeMainLogic>(tag: tag)
? Get.find<HomeMainLogic>(tag: tag)
: null;
void _openNavBar() {
_backToRoot();
jumpToPage(0);
_homeLogic()?.openEndDrawer();
}
//跳转直播
void _skipToLive() {
jumpToPage(1);
if (Get.isRegistered<ShortVideoMainLogic>()) {
Get.find<ShortVideoMainLogic>().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<CommunityMainLogic>()) {
Get.find<CommunityMainLogic>().jumpSubModule(module.sub);
if (module.sub == 0) {
if (Get.isRegistered<CommunityMainModuleLogic>()) {
Get.find<CommunityMainModuleLogic>().skipToTabIndex(module.module);
return;
}
} else {
final tag = [
"",
MediaStyle.Pic.name,
MediaStyle.Game.name,
MediaStyle.Novel.name
][module.sub];
if (Get.isRegistered<CartoonSubModuleLogic>(tag: tag)) {
Get.find<CartoonSubModuleLogic>(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();
}
}