Files
wushu/lib/views/home/care/care_poetry_page.dart
2026-04-02 22:30:49 +08:00

513 lines
18 KiB
Dart

/// 时间: 2026-04-02
/// 功能: 关怀模式诗词页面
/// 介绍: 关怀模式下显示的诗词页面,根据关怀设置显示不同内容
/// 最新变化: 2026-04-02 初始创建
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../services/get/home_controller.dart';
import '../../../services/get/theme_controller.dart';
import '../../../services/get/care_controller.dart';
import '../../../constants/app_constants.dart';
import '../home_part.dart';
import 'care_widgets.dart';
import 'pinyin_helper.dart';
class CarePoetryPage extends StatefulWidget {
const CarePoetryPage({super.key});
@override
State<CarePoetryPage> createState() => _CarePoetryPageState();
}
class _CarePoetryPageState extends State<CarePoetryPage>
with SingleTickerProviderStateMixin {
String _getTimeOfDayGreeting() {
final hour = DateTime.now().hour;
if (hour >= 5 && hour < 7) {
return '清晨了,呼吸新鲜空气';
} else if (hour >= 7 && hour < 9) {
return '早上好,元气满满';
} else if (hour >= 9 && hour < 12) {
return '上午好,努力工作';
} else if (hour >= 12 && hour < 14) {
return '中午了,吃顿好的';
} else if (hour >= 14 && hour < 17) {
return '下午了,喝杯咖啡';
} else if (hour >= 17 && hour < 19) {
return '傍晚了,休息一下';
} else if (hour >= 19 && hour < 22) {
return '晚上好,放松身心';
} else {
return '深夜了,注意身体';
}
}
late AnimationController _animationController;
late Animation<double> _fadeAnimation;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 500),
vsync: this,
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeOut),
);
_animationController.forward();
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final homeController = Get.find<HomeController>();
final themeController = Get.find<ThemeController>();
final careController = Get.find<CareController>();
return Obx(() {
final isDark = themeController.isDarkModeRx.value;
final primaryColor = themeController.currentThemeColor;
final poetryData = homeController.poetryData.value;
if (poetryData == null) {
return const Center(child: CircularProgressIndicator());
}
// 当诗词数据变化时,重新播放动画
_animationController.reset();
_animationController.forward();
return Scaffold(
backgroundColor: isDark ? const Color(0xFF121212) : Colors.grey[50],
body: SafeArea(
child: GestureDetector(
onTap: () async {
try {
await homeController.loadNextPoetry();
} catch (e) {
print('加载诗词失败: $e');
}
},
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: FadeTransition(
opacity: _fadeAnimation,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// 关怀模式开关
CarePageHeaderToggle(isDark: isDark),
const SizedBox(height: 16),
// 问候语bar
if (careController.selectedOptions.contains('问候语'))
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [primaryColor.withAlpha(204), primaryColor],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(12),
),
child: Row(
children: [
Icon(Icons.wb_sunny, color: Colors.white, size: 20),
const SizedBox(width: 8),
Expanded(
child: Text(
_getTimeOfDayGreeting(),
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
),
),
if (careController.selectedOptions.contains('问候语'))
const SizedBox(height: 16),
// 出处
if (careController.selectedOptions.contains('出处'))
_buildPoetrySource(poetryData, isDark, primaryColor),
if (careController.selectedOptions.contains('出处'))
const SizedBox(height: 24),
if (!careController.selectedOptions.contains('问候语') &&
!careController.selectedOptions.contains('出处'))
const SizedBox(height: 24),
// 诗词标题
if (careController.selectedOptions.contains('诗词'))
_buildPoetryTitle(poetryData, isDark, primaryColor),
const SizedBox(height: 24),
// 诗词内容
if (careController.selectedOptions.contains('诗词'))
GestureDetector(
onTap: () async {
try {
await homeController.loadNextPoetry();
} catch (e) {
print('加载诗词失败: $e');
}
},
child: _buildPoetryContent(
poetryData,
isDark,
primaryColor,
),
),
const SizedBox(height: 24),
// 原文
if (careController.selectedOptions.contains('原文'))
_buildPoetryOriginal(poetryData, isDark, primaryColor),
if (careController.selectedOptions.contains('原文'))
const SizedBox(height: 24),
const SizedBox(height: 24),
// 译文
if (careController.selectedOptions.contains('译文'))
_buildPoetryTranslation(poetryData, isDark, primaryColor),
const SizedBox(height: 24),
// 更多
if (careController.selectedOptions.contains('更多'))
_buildPoetryMore(poetryData, isDark, primaryColor),
const SizedBox(height: 48),
],
),
),
),
),
),
);
});
}
Widget _buildPoetryTitle(
dynamic poetryData,
bool isDark,
Color primaryColor,
) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Text(
poetryData.name ?? '未知标题',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: primaryColor,
),
textAlign: TextAlign.center,
),
);
}
Widget _buildPoetryContent(
dynamic poetryData,
bool isDark,
Color primaryColor,
) {
final themeController = Get.find<ThemeController>();
final careController = Get.find<CareController>();
final accentColor = themeController.currentAccentColor;
final content = poetryData.name ?? '';
final lines = content.split('\n');
final showPinyin = careController.pinyinEnabled;
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark
? accentColor.withOpacity(0.2)
: accentColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: lines.asMap().entries.map<Widget>((entry) {
int index = entry.key;
String line = entry.value;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Column(
children: [
if (showPinyin && line.trim().isNotEmpty)
Wrap(
alignment: WrapAlignment.center,
children: PinyinHelper.convertToCharPinyinList(line)
.asMap()
.entries
.map<Widget>((charEntry) {
int charIndex = charEntry.key;
var item = charEntry.value;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: AnimatedOpacity(
opacity: 1.0,
duration: Duration(
milliseconds: 300 + charIndex * 100,
),
curve: Curves.easeOut,
child: Column(
children: [
Text(
item['pinyin'] ?? '',
style: TextStyle(
fontSize: 12,
color: isDark
? Colors.grey[400]
: Colors.grey[600],
height: 1.2,
),
textAlign: TextAlign.center,
),
Text(
item['char'] ?? '',
style: TextStyle(
fontSize: 20,
color: primaryColor,
height: 1.6,
),
textAlign: TextAlign.center,
),
],
),
),
);
})
.toList(),
),
if (!showPinyin || line.trim().isEmpty)
Wrap(
alignment: WrapAlignment.center,
children: line.split('').asMap().entries.map<Widget>((
charEntry,
) {
int charIndex = charEntry.key;
String char = charEntry.value;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: AnimatedOpacity(
opacity: 1.0,
duration: Duration(
milliseconds: 300 + charIndex * 100,
),
curve: Curves.easeOut,
child: Text(
char,
style: TextStyle(
fontSize: 20,
color: primaryColor,
height: 1.6,
),
textAlign: TextAlign.center,
),
),
);
}).toList(),
),
],
),
);
}).toList(),
),
);
}
Widget _buildPoetrySource(
dynamic poetryData,
bool isDark,
Color primaryColor,
) {
final url = poetryData.url ?? '未知作者';
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Text(
url,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: primaryColor,
),
textAlign: TextAlign.center,
),
);
}
Widget _buildPoetryTranslation(
dynamic poetryData,
bool isDark,
Color primaryColor,
) {
final translation = poetryData.introduce ?? '暂无译文';
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Text(
translation,
style: TextStyle(
fontSize: 16,
color: isDark ? Colors.grey[300] : Colors.grey[700],
height: 1.6,
),
textAlign: TextAlign.center,
),
);
}
Widget _buildPoetryMore(dynamic poetryData, bool isDark, Color primaryColor) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Text(
'更多信息',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: primaryColor,
),
),
const SizedBox(height: 12),
Text(
'诗词解析、背景知识等内容将在此显示',
style: TextStyle(
fontSize: 14,
color: isDark ? Colors.grey[300] : Colors.grey[700],
),
textAlign: TextAlign.center,
),
],
),
);
}
Widget _buildPoetryOriginal(
dynamic poetryData,
bool isDark,
Color primaryColor,
) {
final original = poetryData.drtime ?? '暂无原文';
final careController = Get.find<CareController>();
final showPinyin = careController.pinyinEnabled;
final lines = original.split('\n');
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: lines.asMap().entries.map<Widget>((entry) {
int index = entry.key;
String line = entry.value;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Column(
children: [
if (showPinyin && line.trim().isNotEmpty)
Wrap(
alignment: WrapAlignment.center,
children: PinyinHelper.convertToCharPinyinList(line)
.asMap()
.entries
.map<Widget>((charEntry) {
int charIndex = charEntry.key;
var item = charEntry.value;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: AnimatedOpacity(
opacity: 1.0,
duration: Duration(
milliseconds: 300 + charIndex * 100,
),
curve: Curves.easeOut,
child: Column(
children: [
Text(
item['pinyin'] ?? '',
style: TextStyle(
fontSize: 12,
color: isDark
? Colors.grey[400]
: Colors.grey[600],
height: 1.2,
),
textAlign: TextAlign.center,
),
Text(
item['char'] ?? '',
style: TextStyle(
fontSize: 16,
color: primaryColor,
height: 1.6,
),
textAlign: TextAlign.center,
),
],
),
),
);
})
.toList(),
),
if (!showPinyin || line.trim().isEmpty)
Text(
line,
style: TextStyle(
fontSize: 16,
color: primaryColor,
height: 1.6,
),
textAlign: TextAlign.center,
),
],
),
);
}).toList(),
),
);
}
}