Files
slogan/lib/features/home/home_page.dart
T
adminandClaude Opus 4.7 3e457b700a refactor: 前端改 2 Tab(穿搭向导 + 我的入口)
- 主框架收敛为「穿搭」「我的」两个 tab:
  - 穿搭 = 造型方案制作向导:个人信息完整性检查(4 类照片 +
    身形参数,缺失引导去完善)+ 任务参数(日期范围/地点)+ 已有方案
  - 我的 = 个人信息管理入口:用户卡片(昵称/会员状态)+ 我的形象 /
    我的衣橱 / 会员中心入口 + 退出登录
- profile_page 移除退出登录(归「我的」页)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 16:25:36 +08:00

138 lines
3.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/ads/ads_service.dart';
import '../mine/mine_page.dart';
import '../outfit/outfit_page.dart';
/// 主框架:2 Tab(穿搭 = 造型方案制作向导 / 我的 = 个人信息管理入口)
class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
@override
ConsumerState<HomePage> createState() => _HomePageState();
}
class _HomePageState extends ConsumerState<HomePage> {
int _index = 0;
bool _splashShown = false;
@override
void initState() {
super.initState();
// 开屏广告:仅广告开通时展示一次(P0 Mock 下 pangleAppId 为空 → 跳过)
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_splashShown) return;
if (!ref.read(adsServiceProvider).enabled) return;
_splashShown = true;
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (_) => _SplashAdOverlay(
onSkip: () => Navigator.of(context).pop(),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _index,
children: const [
OutfitPage(),
MinePage(),
],
),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
destinations: const [
NavigationDestination(
icon: Icon(Icons.auto_awesome_outlined),
selectedIcon: Icon(Icons.auto_awesome),
label: '穿搭'),
NavigationDestination(
icon: Icon(Icons.person_outline),
selectedIcon: Icon(Icons.person),
label: '我的'),
],
),
);
}
}
/// 开屏广告:3 秒倒计时后自动关闭,右上角可手动跳过
class _SplashAdOverlay extends StatefulWidget {
final VoidCallback onSkip;
const _SplashAdOverlay({required this.onSkip});
@override
State<_SplashAdOverlay> createState() => _SplashAdOverlayState();
}
class _SplashAdOverlayState extends State<_SplashAdOverlay> {
Timer? _timer;
int _seconds = 3;
@override
void initState() {
super.initState();
_timer = Timer.periodic(const Duration(seconds: 1), (_) {
if (_seconds <= 1) {
_timer?.cancel();
if (mounted) widget.onSkip();
return;
}
setState(() => _seconds -= 1);
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
child: ColoredBox(
color: Theme.of(context).colorScheme.primaryContainer,
child: Stack(
children: [
const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.campaign_outlined, size: 64),
SizedBox(height: 12),
Text('开屏广告位',
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text('P1 接入穿山甲开屏广告',
style: TextStyle(fontSize: 12, color: Colors.grey)),
],
),
),
Positioned(
top: 24,
right: 24,
child: OutlinedButton(
onPressed: widget.onSkip,
child: Text('跳过($_seconds'),
),
),
],
),
),
);
}
}