241 lines
8.3 KiB
Dart
241 lines
8.3 KiB
Dart
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:aslan/chatvibe_core/constants/at_global_config.dart';
|
||
import 'package:aslan/chatvibe_data/sources/local/user_manager.dart';
|
||
import 'package:aslan/chatvibe_features/index/main_route.dart';
|
||
import 'package:aslan/chatvibe_managers/user_profile_manager.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:aslan/chatvibe_core/routes/at_fluro_navigator.dart';
|
||
import 'package:aslan/chatvibe_ui/widgets/countdown_timer.dart';
|
||
|
||
import '../../chatvibe_managers/room_manager.dart';
|
||
|
||
///Home页面
|
||
class ATIndexHomePage extends StatefulWidget {
|
||
@override
|
||
_ATIndexHomePageState createState() => _ATIndexHomePageState();
|
||
}
|
||
|
||
class _ATIndexHomePageState extends State<ATIndexHomePage>
|
||
with TickerProviderStateMixin {
|
||
TabController? _tabController;
|
||
final List<Widget> _pages = [];
|
||
final List<Widget> _tabs = [];
|
||
bool refresh = false; // 👈 改为 false,初始显示加载
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
// 在构建完成后加载数据
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
_updateTabs();
|
||
// 监听家族状态变化
|
||
Provider.of<ChatVibeUserProfileManager>(
|
||
context,
|
||
listen: false,
|
||
).bindFamilyUpdate(() {
|
||
_updateTabs();
|
||
// 数据更新后短暂显示加载,然后恢复(可根据需要调整)
|
||
setState(() {
|
||
refresh = false;
|
||
});
|
||
Future.delayed(Duration(milliseconds: 550), () {
|
||
if (mounted) {
|
||
setState(() {
|
||
refresh = true;
|
||
});
|
||
}
|
||
});
|
||
});
|
||
});
|
||
Provider.of<ChatVibeRoomManager>(context, listen: false).getMyRoom();
|
||
}
|
||
|
||
void _updateTabs() {
|
||
_tabController?.dispose();
|
||
_pages.clear();
|
||
|
||
final strategy = ATGlobalConfig.businessLogicStrategy;
|
||
_pages.addAll(strategy.getHomeTabPages(context));
|
||
|
||
_tabController = TabController(
|
||
length: _pages.length,
|
||
vsync: this,
|
||
initialIndex: strategy.getHomeInitialTabIndex(),
|
||
);
|
||
// 可选:监听切换事件
|
||
_tabController?.addListener(() {});
|
||
|
||
// 数据更新完成后,刷新界面
|
||
if (mounted) {
|
||
setState(() {
|
||
refresh = true;
|
||
});
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_tabController?.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
// 如果数据未准备好,显示加载指示器
|
||
if (!refresh || _tabController == null || _pages.isEmpty) {
|
||
return Center(
|
||
child: Container(
|
||
decoration: BoxDecoration(
|
||
color: Colors.black26,
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
width: 55.w,
|
||
height: 55.w,
|
||
child: const CupertinoActivityIndicator(),
|
||
),
|
||
);
|
||
}
|
||
|
||
// 正常渲染界面
|
||
_tabs.clear();
|
||
final strategy = ATGlobalConfig.businessLogicStrategy;
|
||
_tabs.addAll(strategy.getHomeTabLabels(context));
|
||
|
||
return Stack(
|
||
children: [
|
||
Scaffold(
|
||
resizeToAvoidBottomInset: false,
|
||
backgroundColor: Colors.transparent,
|
||
body: Column(
|
||
children: [
|
||
// 自定义顶部栏(包含状态栏和 TabBar)
|
||
SafeArea(
|
||
child: Row(
|
||
children: [
|
||
// TabBar 直接放在这里
|
||
TabBar(
|
||
labelColor: Colors.white,
|
||
tabAlignment:
|
||
ATGlobalConfig.businessLogicStrategy
|
||
.shouldShowFamilyTab()
|
||
? TabAlignment.start
|
||
: null,
|
||
isScrollable:
|
||
ATGlobalConfig.businessLogicStrategy
|
||
.shouldShowFamilyTab(),
|
||
splashFactory: NoSplash.splashFactory,
|
||
overlayColor: MaterialStateProperty.all(
|
||
Colors.transparent,
|
||
),
|
||
indicator: const BoxDecoration(),
|
||
unselectedLabelColor: Colors.white,
|
||
labelStyle: TextStyle(
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 17.sp,
|
||
),
|
||
unselectedLabelStyle: TextStyle(
|
||
fontWeight: FontWeight.normal,
|
||
fontSize: 14.sp,
|
||
),
|
||
indicatorColor: Colors.transparent,
|
||
dividerColor: Colors.transparent,
|
||
controller: _tabController,
|
||
tabs: _tabs,
|
||
),
|
||
Spacer(),
|
||
Container(
|
||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
IconButton(
|
||
icon: Image.asset(
|
||
"atu_images/index/at_icon_serach.png",
|
||
width: 20.w,
|
||
height: 20.w,
|
||
),
|
||
onPressed:
|
||
() => ATNavigatorUtils.push(
|
||
context,
|
||
MainRoute.mainSearch,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
// TabBarView 直接作为剩余空间
|
||
Expanded(
|
||
child: TabBarView(controller: _tabController, children: _pages),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
Selector<ChatVibeUserProfileManager, bool>(
|
||
selector:
|
||
(_, __) =>
|
||
ATGlobalConfig.businessLogicStrategy
|
||
.shouldShowFirstRechargePrompt(),
|
||
builder: (context, shouldShowFirstRechargePrompt, child) {
|
||
if (ATGlobalConfig.isReview) return Container();
|
||
final strategy = ATGlobalConfig.businessLogicStrategy;
|
||
if (shouldShowFirstRechargePrompt) {
|
||
final position = strategy.getFirstRechargePosition();
|
||
return PositionedDirectional(
|
||
top: position['top'],
|
||
bottom: position['bottom'],
|
||
start: position['start'],
|
||
end: position['end'],
|
||
child: GestureDetector(
|
||
child: Column(
|
||
children: [
|
||
Image.asset(
|
||
"atu_images/index/at_icon_first_recharge_tag.png",
|
||
height: 70.w,
|
||
),
|
||
Transform.translate(
|
||
offset: Offset(0, -10),
|
||
child: Container(
|
||
height: 23.w,
|
||
width: 100.w,
|
||
alignment: AlignmentDirectional.center,
|
||
decoration: BoxDecoration(
|
||
image: DecorationImage(
|
||
image: AssetImage(
|
||
"atu_images/index/at_icon_first_recharge_btn.png",
|
||
),
|
||
fit: BoxFit.fill,
|
||
),
|
||
),
|
||
child: CountdownTimer(
|
||
expiryDate: DateTime.fromMillisecondsSinceEpoch(
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.firstRechargeEndTime ??
|
||
0,
|
||
),
|
||
color: Colors.white,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
onTap: () {
|
||
strategy.onFirstRechargeTap(context);
|
||
},
|
||
),
|
||
);
|
||
}
|
||
return Container();
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
}
|