This commit is contained in:
ytc1012
2025-11-27 18:30:49 +08:00
parent 15252dfd88
commit ef44d11c32
4 changed files with 215 additions and 190 deletions

View File

@@ -50,24 +50,32 @@ class CompleteScreen extends StatelessWidget {
children: [ children: [
const SizedBox(height: 40), const SizedBox(height: 40),
// Success Icon // You focused for X minutes with success icon - left-right layout
const Text( Row(
'', mainAxisAlignment: MainAxisAlignment.center,
style: TextStyle(fontSize: 64), crossAxisAlignment: CrossAxisAlignment.center,
), children: [
// Star icon on the left
const SizedBox(height: 32), const Text('', style: TextStyle(fontSize: 64)),
const SizedBox(width: 20),
// You focused for X minutes // Text content on the right
Text( Column(
l10n.youFocusedFor, mainAxisAlignment: MainAxisAlignment.center,
style: AppTextStyles.headline, crossAxisAlignment: CrossAxisAlignment.start,
), children: [
Text(l10n.youFocusedFor, style: AppTextStyles.headline),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
l10n.minutesValue(focusedMinutes, l10n.minutes(focusedMinutes)), l10n.minutesValue(
focusedMinutes,
l10n.minutes(focusedMinutes),
),
style: AppTextStyles.largeNumber, style: AppTextStyles.largeNumber,
), ),
],
),
],
),
const SizedBox(height: 32), const SizedBox(height: 32),
@@ -99,7 +107,10 @@ class CompleteScreen extends StatelessWidget {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
Text( Text(
l10n.distractionsCount(todayDistractions, l10n.times(todayDistractions)), l10n.distractionsCount(
todayDistractions,
l10n.times(todayDistractions),
),
style: AppTextStyles.bodyText, style: AppTextStyles.bodyText,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
@@ -207,30 +218,29 @@ class CompleteScreen extends StatelessWidget {
color: AppColors.primary, color: AppColors.primary,
), ),
), ),
const Text( const Text('', style: TextStyle(fontSize: 24)),
'',
style: TextStyle(fontSize: 24),
),
], ],
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Divider(thickness: 1, color: AppColors.textSecondary.withValues(alpha: 0.2)), Divider(
thickness: 1,
color: AppColors.textSecondary.withValues(alpha: 0.2),
),
const SizedBox(height: 12), const SizedBox(height: 12),
// Points breakdown // Points breakdown
_buildPointRow( _buildPointRow(l10n.basePoints, '+$basePoints', AppColors.success),
l10n.basePoints,
'+$basePoints',
AppColors.success,
),
if (honestyBonus > 0) ...[ if (honestyBonus > 0) ...[
const SizedBox(height: 8), const SizedBox(height: 8),
_buildPointRow( _buildPointRow(
l10n.honestyBonus, l10n.honestyBonus,
'+$honestyBonus', '+$honestyBonus',
AppColors.success, AppColors.success,
subtitle: l10n.distractionsRecorded(distractionCount, l10n.distractions(distractionCount)), subtitle: l10n.distractionsRecorded(
distractionCount,
l10n.distractions(distractionCount),
),
), ),
], ],
], ],
@@ -300,7 +310,10 @@ class CompleteScreen extends StatelessWidget {
} }
/// Build achievement unlocked cards /// Build achievement unlocked cards
List<Widget> _buildAchievementCards(BuildContext context, AppLocalizations l10n) { List<Widget> _buildAchievementCards(
BuildContext context,
AppLocalizations l10n,
) {
return newAchievements.map((achievementId) { return newAchievements.map((achievementId) {
final achievement = AchievementConfig.getById(achievementId); final achievement = AchievementConfig.getById(achievementId);
if (achievement == null) return const SizedBox.shrink(); if (achievement == null) return const SizedBox.shrink();
@@ -328,10 +341,7 @@ class CompleteScreen extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(achievement.icon, style: const TextStyle(fontSize: 32)),
achievement.icon,
style: const TextStyle(fontSize: 32),
),
const SizedBox(width: 12), const SizedBox(width: 12),
Text( Text(
l10n.achievementUnlocked, l10n.achievementUnlocked,

View File

@@ -237,7 +237,8 @@ class _FocusScreenState extends State<FocusScreen> with WidgetsBindingObserver {
basePoints: pointsData['basePoints']!, basePoints: pointsData['basePoints']!,
honestyBonus: pointsData['honestyBonus']!, honestyBonus: pointsData['honestyBonus']!,
totalPoints: pointsData['totalPoints']!, totalPoints: pointsData['totalPoints']!,
newAchievements: pointsData['newAchievements'] as List<String>, newAchievements:
pointsData['newAchievements'] as List<String>,
encouragementService: widget.encouragementService, encouragementService: widget.encouragementService,
), ),
), ),
@@ -448,15 +449,9 @@ class _FocusScreenState extends State<FocusScreen> with WidgetsBindingObserver {
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
body: SafeArea( body: SafeArea(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column(
children: [
SizedBox(height: MediaQuery.of(context).size.height * 0.2),
SizedBox(height: MediaQuery.of(context).size.height * 0.2),
// Timer Display Component // Timer Display Component
TimerDisplay(remainingSeconds: _remainingSeconds), TimerDisplay(remainingSeconds: _remainingSeconds),
@@ -479,12 +474,6 @@ class _FocusScreenState extends State<FocusScreen> with WidgetsBindingObserver {
resumeText: l10n.resume, resumeText: l10n.resume,
stopText: l10n.stopSession, stopText: l10n.stopSession,
), ),
SizedBox(height: MediaQuery.of(context).size.height * 0.2),
SizedBox(height: MediaQuery.of(context).size.height * 0.2),
],
),
),
),
], ],
), ),
), ),

View File

@@ -278,11 +278,11 @@ class _HistoryScreenState extends State<HistoryScreen> {
); );
}, },
child: Container( child: Container(
margin: const EdgeInsets.only(bottom: 12), margin: const EdgeInsets.only(bottom: 16),
color: Colors.black.withValues(alpha: 0.05), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.white, color: AppColors.white,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColors.divider, width: 1), border: Border.all(color: AppColors.divider, width: 1),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
@@ -299,13 +299,13 @@ class _HistoryScreenState extends State<HistoryScreen> {
timeStr, timeStr,
style: const TextStyle( style: const TextStyle(
fontFamily: 'Nunito', fontFamily: 'Nunito',
fontSize: 16, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w700,
color: AppColors.textPrimary, color: AppColors.textPrimary,
), ),
), ),
const SizedBox(width: 16), const SizedBox(width: 20),
// Duration // Duration
Expanded( Expanded(
@@ -317,11 +317,16 @@ class _HistoryScreenState extends State<HistoryScreen> {
session.actualMinutes, session.actualMinutes,
l10n.minutes(session.actualMinutes), l10n.minutes(session.actualMinutes),
), ),
style: AppTextStyles.bodyText, style: const TextStyle(
fontFamily: 'Nunito',
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
), ),
if (session.distractionCount > 0) if (session.distractionCount > 0)
Padding( Padding(
padding: const EdgeInsets.only(top: 4), padding: const EdgeInsets.only(top: 6),
child: Text( child: Text(
l10n.distractionsCount( l10n.distractionsCount(
session.distractionCount, session.distractionCount,
@@ -329,7 +334,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
), ),
style: const TextStyle( style: const TextStyle(
fontFamily: 'Nunito', fontFamily: 'Nunito',
fontSize: 14, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: AppColors.textSecondary, color: AppColors.textSecondary,
), ),
@@ -341,18 +346,18 @@ class _HistoryScreenState extends State<HistoryScreen> {
// Status badge // Status badge
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration( decoration: BoxDecoration(
color: session.completed color: session.completed
? AppColors.success.withValues(alpha: 0.1) ? AppColors.success.withValues(alpha: 0.1)
: AppColors.distractionButton, : AppColors.distractionButton,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(12),
), ),
child: Text( child: Text(
'$statusEmoji $statusText', '$statusEmoji $statusText',
style: TextStyle( style: TextStyle(
fontFamily: 'Nunito', fontFamily: 'Nunito',
fontSize: 12, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: session.completed color: session.completed
? AppColors.success ? AppColors.success
@@ -362,10 +367,10 @@ class _HistoryScreenState extends State<HistoryScreen> {
), ),
// Arrow indicator // Arrow indicator
const SizedBox(width: 8), const SizedBox(width: 12),
const Icon( const Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
size: 12, size: 16,
color: AppColors.textSecondary, color: AppColors.textSecondary,
), ),
], ],

View File

@@ -41,22 +41,19 @@ class SessionDetailScreen extends StatelessWidget {
return Scaffold( return Scaffold(
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
appBar: AppBar( appBar: AppBar(
title: const Text('会话详情'), title: Text(l10n.history),
backgroundColor: AppColors.background, backgroundColor: AppColors.background,
), ),
body: SafeArea( body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const SizedBox(height: 20),
// Session Date and Time // Session Date and Time
_buildSessionHeader(context, l10n), _buildSessionHeader(context, l10n),
const SizedBox(height: 32), const SizedBox(height: 18),
// Focused Time Section // Focused Time Section
Text(l10n.youFocusedFor, style: AppTextStyles.headline), Text(l10n.youFocusedFor, style: AppTextStyles.headline),
@@ -69,7 +66,7 @@ class SessionDetailScreen extends StatelessWidget {
style: AppTextStyles.largeNumber, style: AppTextStyles.largeNumber,
), ),
const SizedBox(height: 32), const SizedBox(height: 24),
// Points Earned Section // Points Earned Section
_buildPointsCard( _buildPointsCard(
@@ -93,12 +90,12 @@ class SessionDetailScreen extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('会话统计', style: AppTextStyles.headline), //Text(l10n.history, style: AppTextStyles.headline),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildStatRow( _buildStatRow(
icon: '⏱️', icon: '⏱️',
label: '计划时长', label: l10n.defaultFocusDuration,
value: l10n.minutesValue( value: l10n.minutesValue(
session.durationMinutes, session.durationMinutes,
l10n.minutes(session.durationMinutes), l10n.minutes(session.durationMinutes),
@@ -108,7 +105,7 @@ class SessionDetailScreen extends StatelessWidget {
_buildStatRow( _buildStatRow(
icon: '', icon: '',
label: '实际专注', label: l10n.youFocusedFor,
value: l10n.minutesValue( value: l10n.minutesValue(
session.actualMinutes, session.actualMinutes,
l10n.minutes(session.actualMinutes), l10n.minutes(session.actualMinutes),
@@ -118,17 +115,15 @@ class SessionDetailScreen extends StatelessWidget {
_buildStatRow( _buildStatRow(
icon: '🤚', icon: '🤚',
label: '分心次数', label: 'Distractions',
value: l10n.distractionsCount( value:
session.distractionCount, '${session.distractionCount} ${l10n.times(session.distractionCount)}',
l10n.times(session.distractionCount),
),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
_buildStatRow( _buildStatRow(
icon: '🏁', icon: '🏁',
label: '状态', label: 'Status',
value: session.completed value: session.completed
? l10n.completed ? l10n.completed
: l10n.stoppedEarly, : l10n.stoppedEarly,
@@ -167,7 +162,6 @@ class SessionDetailScreen extends StatelessWidget {
), ),
), ),
), ),
),
); );
} }
@@ -182,16 +176,36 @@ class SessionDetailScreen extends StatelessWidget {
return Container( return Container(
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColors.white, color: AppColors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(12),
), ),
child: Column( child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text(dateStr, style: AppTextStyles.headline), Text(
const SizedBox(height: 8), dateStr,
Text(timeStr, style: AppTextStyles.largeNumber), style: const TextStyle(
fontFamily: 'Nunito',
fontSize: 16,
fontWeight: FontWeight.w600,
color: AppColors.textSecondary,
),
),
const SizedBox(width: 12),
const Text('', style: TextStyle(color: AppColors.textSecondary)),
const SizedBox(width: 12),
Text(
timeStr,
style: const TextStyle(
fontFamily: 'Nunito',
fontSize: 18,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
),
),
], ],
), ),
); );
@@ -341,8 +355,15 @@ class SessionDetailScreen extends StatelessWidget {
children: [ children: [
Text(icon, style: const TextStyle(fontSize: 20)), Text(icon, style: const TextStyle(fontSize: 20)),
const SizedBox(width: 12), const SizedBox(width: 12),
Text(label, style: AppTextStyles.bodyText), Expanded(
const Spacer(), child: Text(
label,
style: AppTextStyles.bodyText,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
const SizedBox(width: 8),
Text( Text(
value, value,
style: const TextStyle( style: const TextStyle(
@@ -428,7 +449,7 @@ class SessionDetailScreen extends StatelessWidget {
List<AchievementConfig> achievements, List<AchievementConfig> achievements,
) { ) {
return [ return [
Text('解锁的成就', style: AppTextStyles.headline), Text(l10n.achievements, style: AppTextStyles.headline),
const SizedBox(height: 16), const SizedBox(height: 16),
...achievements.map((achievement) { ...achievements.map((achievement) {
return Container( return Container(
@@ -457,7 +478,7 @@ class SessionDetailScreen extends StatelessWidget {
Text(achievement.icon, style: const TextStyle(fontSize: 32)), Text(achievement.icon, style: const TextStyle(fontSize: 32)),
const SizedBox(width: 12), const SizedBox(width: 12),
Text( Text(
'成就解锁!', l10n.achievementUnlocked,
style: const TextStyle( style: const TextStyle(
fontFamily: 'Nunito', fontFamily: 'Nunito',
fontSize: 18, fontSize: 18,