215 lines
7.6 KiB
Dart
215 lines
7.6 KiB
Dart
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:yumi/app/constants/sc_global_config.dart';
|
||
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
|
||
import 'package:yumi/modules/index/main_route.dart';
|
||
import 'package:yumi/services/auth/user_profile_manager.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
||
import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
|
||
import 'package:yumi/ui_kit/widgets/countdown_timer.dart';
|
||
|
||
///Home页面
|
||
class SCIndexHomePage extends StatefulWidget {
|
||
const SCIndexHomePage({super.key});
|
||
|
||
@override
|
||
State<SCIndexHomePage> createState() => _SCIndexHomePageState();
|
||
}
|
||
|
||
class _SCIndexHomePageState extends State<SCIndexHomePage>
|
||
with TickerProviderStateMixin {
|
||
TabController? _tabController;
|
||
final List<Widget> _pages = [];
|
||
final List<Widget> _tabs = [];
|
||
Locale? _lastLocale;
|
||
|
||
@override
|
||
void didChangeDependencies() {
|
||
super.didChangeDependencies();
|
||
final locale = Localizations.localeOf(context);
|
||
if (_lastLocale == locale && _tabController != null && _pages.isNotEmpty) {
|
||
return;
|
||
}
|
||
_lastLocale = locale;
|
||
_rebuildTabs();
|
||
}
|
||
|
||
void _rebuildTabs() {
|
||
final strategy = SCGlobalConfig.businessLogicStrategy;
|
||
final nextPages = strategy.getHomeTabPages(context);
|
||
final nextTabs = strategy.getHomeTabLabels(context);
|
||
if (nextPages.isEmpty || nextTabs.length != nextPages.length) {
|
||
return;
|
||
}
|
||
|
||
final desiredIndex =
|
||
_tabController?.index ?? strategy.getHomeInitialTabIndex();
|
||
final initialIndex = desiredIndex.clamp(0, nextPages.length - 1);
|
||
|
||
_tabController?.dispose();
|
||
_pages
|
||
..clear()
|
||
..addAll(nextPages);
|
||
_tabs
|
||
..clear()
|
||
..addAll(nextTabs);
|
||
|
||
_tabController = TabController(
|
||
length: _pages.length,
|
||
vsync: this,
|
||
initialIndex: initialIndex,
|
||
);
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_tabController?.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
if (_tabController == null || _pages.isEmpty || _tabs.isEmpty) {
|
||
return Center(
|
||
child: Container(
|
||
decoration: BoxDecoration(
|
||
color: Colors.black26,
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
width: 55.w,
|
||
height: 55.w,
|
||
child: const CupertinoActivityIndicator(),
|
||
),
|
||
);
|
||
}
|
||
|
||
return Stack(
|
||
children: [
|
||
Scaffold(
|
||
resizeToAvoidBottomInset: false,
|
||
backgroundColor: Colors.transparent,
|
||
body: Column(
|
||
children: [
|
||
// 自定义顶部栏(包含状态栏和 TabBar)
|
||
SafeArea(
|
||
child: Row(
|
||
children: [
|
||
// TabBar 直接放在这里
|
||
Expanded(
|
||
child: TabBar(
|
||
tabAlignment: TabAlignment.start,
|
||
isScrollable: true,
|
||
splashFactory: NoSplash.splashFactory,
|
||
overlayColor: WidgetStateProperty.all(
|
||
Colors.transparent,
|
||
),
|
||
indicator: const BoxDecoration(),
|
||
labelStyle: TextStyle(
|
||
fontWeight: FontWeight.bold,
|
||
fontStyle: FontStyle.italic,
|
||
fontSize: 19.sp,
|
||
color: SocialChatTheme.primaryLight,
|
||
),
|
||
unselectedLabelStyle: TextStyle(
|
||
fontWeight: FontWeight.normal,
|
||
fontSize: 14.sp,
|
||
color: Colors.white,
|
||
),
|
||
indicatorColor: Colors.transparent,
|
||
dividerColor: Colors.transparent,
|
||
controller: _tabController,
|
||
tabs: _tabs,
|
||
),
|
||
),
|
||
Container(
|
||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
IconButton(
|
||
icon: Image.asset(
|
||
"sc_images/index/sc_icon_serach.png",
|
||
width: 25.w,
|
||
height: 25.w,
|
||
),
|
||
onPressed:
|
||
() => SCNavigatorUtils.push(
|
||
context,
|
||
SCMainRoute.mainSearch,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
// TabBarView 直接作为剩余空间
|
||
Expanded(
|
||
child: TabBarView(controller: _tabController, children: _pages),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
Consumer<SocialChatUserProfileManager>(
|
||
builder: (context, ref, child) {
|
||
if (SCGlobalConfig.isReview) return Container();
|
||
final strategy = SCGlobalConfig.businessLogicStrategy;
|
||
if (strategy.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(
|
||
"sc_images/index/sc_icon_first_recharge_tag.webp",
|
||
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(
|
||
"sc_images/index/sc_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();
|
||
},
|
||
),
|
||
],
|
||
);
|
||
}
|
||
}
|