Files
ttstd_family_care/lib/features/home/presentation/home_tab.dart
tongtongstudio 41d815336a feat(home): 实现管理平板信息页与管理消息页
- 新增首页平板信息卡片(定位、截图、使用时长、设备操作)
- 将消息 Tab 改为管理 Tab,增加横版菜单与消息列表
- 新增相册、闹钟、联系人、应用子页面路由
- 统一主色为桐桐绿并优化调试日志输出
2026-08-17 16:44:45 +08:00

336 lines
13 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 'package:cupertino_ui/cupertino_ui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/widgets/feature_ui.dart';
import '../../../l10n/app_localizations.dart';
/// 首页 Tab 内容(特性模块:home / presentation)。
///
/// 对应移动端设计稿的「平板信息页」:实时位置地图、最近截图、
/// 今日使用时长、设备操作(重启/关机/截屏/刷新/定位)与常用功能网格。
class HomeTab extends ConsumerWidget {
const HomeTab({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(l10n.appTitle,
style: const TextStyle(
fontSize: 20, fontWeight: FontWeight.w700, color: AppColors.ink)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(CupertinoIcons.location_fill,
size: 12, color: AppColors.green),
const SizedBox(width: 4),
Text('${l10n.homeDeviceName} · ${l10n.homeOnline}',
style: const TextStyle(fontSize: 12, color: AppColors.sub)),
const SizedBox(width: 8),
Container(
width: 30,
height: 30,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [Color(0xFF5B8DEF), Color(0xFF07C160)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: const Center(
child: Text('U',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w700,
color: CupertinoColors.white))),
),
],
),
),
child: SafeArea(
child: ListView(
padding: const EdgeInsets.only(bottom: 96),
children: [
_locationCard(l10n),
_screenshotsCard(l10n),
_usageCard(l10n),
_deviceOpsCard(l10n),
SectionTitle(l10n.homeCommon),
_commonCard(l10n),
],
),
),
);
}
Widget _cardHeader(
String emoji,
Color color,
String title, {
String? trailing,
}) =>
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Row(
children: [
Container(
width: 22,
height: 22,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(7),
),
child: Center(child: Text(emoji, style: const TextStyle(fontSize: 13))),
),
const SizedBox(width: 7),
Text(title,
style: const TextStyle(
fontSize: 15, fontWeight: FontWeight.w700, color: AppColors.ink)),
const Spacer(),
if (trailing != null)
Text(trailing,
style: const TextStyle(
fontSize: 12, fontWeight: FontWeight.w600, color: AppColors.green)),
],
),
);
Widget _locationCard(AppLocalizations l10n) => CardBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_cardHeader('📍', AppColors.green, l10n.homeLocation, trailing: l10n.homeLocating),
ClipRRect(
borderRadius: BorderRadius.circular(14),
child: Container(
height: 150,
color: const Color(0xFFF3F7FF),
child: Stack(
children: [
// 简易路网
Positioned(top: 38, left: 0, right: 0, height: 10, child: Container(color: CupertinoColors.white)),
Positioned(top: 96, left: 0, right: 0, height: 10, child: Container(color: CupertinoColors.white)),
Positioned(top: 0, bottom: 0, left: 120, width: 10, child: Container(color: CupertinoColors.white)),
Positioned(top: 0, bottom: 0, left: 240, width: 10, child: Container(color: CupertinoColors.white)),
// 定位标记
Positioned(
left: 0,
right: 0,
top: 46,
child: Center(
child: Container(
width: 30,
height: 30,
decoration: const BoxDecoration(
color: AppColors.green,
shape: BoxShape.circle,
),
child: const Center(
child: Icon(CupertinoIcons.location_fill,
color: CupertinoColors.white, size: 16),
),
),
),
),
Positioned(
left: 12,
bottom: 10,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
decoration: BoxDecoration(
color: CupertinoColors.white.withValues(alpha: 0.92),
borderRadius: BorderRadius.circular(10),
),
child: Text('📍 ${l10n.homeAddress}',
style: const TextStyle(fontSize: 12, color: AppColors.ink)),
),
),
],
),
),
),
],
),
);
Widget _screenshotsCard(AppLocalizations l10n) => CardBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_cardHeader('🖼️', AppColors.blue, l10n.homeScreenshots, trailing: l10n.homeViewAll),
SizedBox(
height: 120,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: 4,
separatorBuilder: (_, _) => const SizedBox(width: 10),
itemBuilder: (_, i) => Container(
width: 88,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
gradient: const LinearGradient(
colors: [AppColors.blue, AppColors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.all(6),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: CupertinoColors.black.withValues(alpha: 0.45),
borderRadius: BorderRadius.circular(6),
),
child: Text(['14:02', '13:20', '11:48', '09:15'][i],
style: const TextStyle(fontSize: 10, color: CupertinoColors.white)),
),
),
),
),
),
),
],
),
);
Widget _usageCard(AppLocalizations l10n) => CardBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_cardHeader('⏱️', AppColors.orange, l10n.homeUsage, trailing: l10n.homeUsageTrend),
Row(
children: [
// 环形进度(约 60%)
SizedBox(
width: 86,
height: 86,
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: 86,
height: 86,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: SweepGradient(
stops: const [0, 0.6, 0.6, 1],
colors: const [
AppColors.green,
AppColors.green,
AppColors.track,
AppColors.track,
],
),
),
),
Container(
width: 64,
height: 64,
decoration: const BoxDecoration(
color: CupertinoColors.white, shape: BoxShape.circle),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('3.4h',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700, color: AppColors.ink)),
Text(l10n.homeUsageToday,
style: const TextStyle(fontSize: 10, color: AppColors.sub)),
],
),
),
],
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
children: [
_usageBar('阅读', 0.55, AppColors.green),
_usageBar('视频', 0.30, AppColors.blue),
_usageBar('办公', 0.15, AppColors.orange),
],
),
),
],
),
],
),
);
Widget _usageBar(String name, double v, Color color) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
SizedBox(width: 42, child: Text(name, style: const TextStyle(fontSize: 12, color: Color(0xFF4B5563)))),
Expanded(
child: Container(
height: 7,
decoration: BoxDecoration(
color: AppColors.track,
borderRadius: BorderRadius.circular(4),
),
child: FractionallySizedBox(
alignment: Alignment.centerLeft,
widthFactor: v,
child: Container(
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(4),
),
),
),
),
),
],
),
);
Widget _deviceOpsCard(AppLocalizations l10n) => CardBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_cardHeader('⚡', AppColors.purple, l10n.homeDeviceOps),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconTile(emoji: '🔄', color: AppColors.blue, label: l10n.opRestart, size: 50, iconSize: 20),
IconTile(emoji: '🔌', color: AppColors.red, label: l10n.opShutdown, size: 50, iconSize: 20),
IconTile(emoji: '📸', color: AppColors.green, label: l10n.opScreenshot, size: 50, iconSize: 20),
IconTile(emoji: '🔃', color: AppColors.orange, label: l10n.opRefresh, size: 50, iconSize: 20),
IconTile(emoji: '📍', color: AppColors.purple, label: l10n.opLocate, size: 50, iconSize: 20),
],
),
],
),
);
Widget _commonCard(AppLocalizations l10n) => CardBox(
child: Column(
children: [
Row(
children: [
Expanded(child: IconTile(emoji: '📁', color: AppColors.blue, label: l10n.cfFileTransfer)),
Expanded(child: IconTile(emoji: '📷', color: AppColors.green, label: l10n.cfRemoteCam)),
Expanded(child: IconTile(emoji: '💬', color: AppColors.orange, label: l10n.cfMsgSync)),
Expanded(child: IconTile(emoji: '🧹', color: AppColors.purple, label: l10n.cfClean)),
],
),
const SizedBox(height: 14),
Row(
children: [
Expanded(child: IconTile(emoji: '📺', color: AppColors.red, label: l10n.cfMirror)),
Expanded(child: IconTile(emoji: '🔔', color: AppColors.teal, label: l10n.cfLost)),
Expanded(child: IconTile(emoji: '🔒', color: const Color(0xFF22C55E), label: l10n.cfAppLock)),
Expanded(child: IconTile(emoji: '➕', color: AppColors.gray, label: l10n.cfMore)),
],
),
],
),
);
}