diff --git a/lib/screens/complete_screen.dart b/lib/screens/complete_screen.dart index c2c0e2d..7006b74 100644 --- a/lib/screens/complete_screen.dart +++ b/lib/screens/complete_screen.dart @@ -50,23 +50,31 @@ class CompleteScreen extends StatelessWidget { children: [ const SizedBox(height: 40), - // Success Icon - const Text( - '✨', - style: TextStyle(fontSize: 64), - ), - - const SizedBox(height: 32), - - // You focused for X minutes - Text( - l10n.youFocusedFor, - style: AppTextStyles.headline, - ), - const SizedBox(height: 8), - Text( - l10n.minutesValue(focusedMinutes, l10n.minutes(focusedMinutes)), - style: AppTextStyles.largeNumber, + // You focused for X minutes with success icon - left-right layout + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Star icon on the left + const Text('✨', style: TextStyle(fontSize: 64)), + const SizedBox(width: 20), + // Text content on the right + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(l10n.youFocusedFor, style: AppTextStyles.headline), + const SizedBox(height: 8), + Text( + l10n.minutesValue( + focusedMinutes, + l10n.minutes(focusedMinutes), + ), + style: AppTextStyles.largeNumber, + ), + ], + ), + ], ), const SizedBox(height: 32), @@ -99,7 +107,10 @@ class CompleteScreen extends StatelessWidget { ), const SizedBox(height: 12), Text( - l10n.distractionsCount(todayDistractions, l10n.times(todayDistractions)), + l10n.distractionsCount( + todayDistractions, + l10n.times(todayDistractions), + ), style: AppTextStyles.bodyText, ), const SizedBox(height: 20), @@ -207,30 +218,29 @@ class CompleteScreen extends StatelessWidget { color: AppColors.primary, ), ), - const Text( - ' ⚡', - style: TextStyle(fontSize: 24), - ), + const Text(' ⚡', style: TextStyle(fontSize: 24)), ], ), 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), // Points breakdown - _buildPointRow( - l10n.basePoints, - '+$basePoints', - AppColors.success, - ), + _buildPointRow(l10n.basePoints, '+$basePoints', AppColors.success), if (honestyBonus > 0) ...[ const SizedBox(height: 8), _buildPointRow( l10n.honestyBonus, '+$honestyBonus', 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 - List _buildAchievementCards(BuildContext context, AppLocalizations l10n) { + List _buildAchievementCards( + BuildContext context, + AppLocalizations l10n, + ) { return newAchievements.map((achievementId) { final achievement = AchievementConfig.getById(achievementId); if (achievement == null) return const SizedBox.shrink(); @@ -328,10 +341,7 @@ class CompleteScreen extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - achievement.icon, - style: const TextStyle(fontSize: 32), - ), + Text(achievement.icon, style: const TextStyle(fontSize: 32)), const SizedBox(width: 12), Text( l10n.achievementUnlocked, diff --git a/lib/screens/focus_screen.dart b/lib/screens/focus_screen.dart index 6f4c94d..ed41de0 100644 --- a/lib/screens/focus_screen.dart +++ b/lib/screens/focus_screen.dart @@ -237,7 +237,8 @@ class _FocusScreenState extends State with WidgetsBindingObserver { basePoints: pointsData['basePoints']!, honestyBonus: pointsData['honestyBonus']!, totalPoints: pointsData['totalPoints']!, - newAchievements: pointsData['newAchievements'] as List, + newAchievements: + pointsData['newAchievements'] as List, encouragementService: widget.encouragementService, ), ), @@ -448,42 +449,30 @@ class _FocusScreenState extends State with WidgetsBindingObserver { backgroundColor: AppColors.background, body: SafeArea( child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, 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 + TimerDisplay(remainingSeconds: _remainingSeconds), - // Timer Display Component - TimerDisplay(remainingSeconds: _remainingSeconds), + const SizedBox(height: 80), - const SizedBox(height: 80), + // "I got distracted" Button Component + DistractionButton( + onPressed: _showDistractionSheet, + buttonText: l10n.iGotDistracted, + ), - // "I got distracted" Button Component - DistractionButton( - onPressed: _showDistractionSheet, - buttonText: l10n.iGotDistracted, - ), + const SizedBox(height: 16), - const SizedBox(height: 16), - - // Control Buttons Component - ControlButtons( - isPaused: _isPaused, - onTogglePause: _togglePause, - onStopEarly: _stopEarly, - pauseText: l10n.pause, - resumeText: l10n.resume, - stopText: l10n.stopSession, - ), - SizedBox(height: MediaQuery.of(context).size.height * 0.2), - SizedBox(height: MediaQuery.of(context).size.height * 0.2), - ], - ), - ), + // Control Buttons Component + ControlButtons( + isPaused: _isPaused, + onTogglePause: _togglePause, + onStopEarly: _stopEarly, + pauseText: l10n.pause, + resumeText: l10n.resume, + stopText: l10n.stopSession, ), ], ), diff --git a/lib/screens/history_screen.dart b/lib/screens/history_screen.dart index 162dabe..49526e6 100644 --- a/lib/screens/history_screen.dart +++ b/lib/screens/history_screen.dart @@ -278,11 +278,11 @@ class _HistoryScreenState extends State { ); }, child: Container( - margin: const EdgeInsets.only(bottom: 12), - color: Colors.black.withValues(alpha: 0.05), + margin: const EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppColors.white, - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.divider, width: 1), boxShadow: [ BoxShadow( @@ -299,13 +299,13 @@ class _HistoryScreenState extends State { timeStr, style: const TextStyle( fontFamily: 'Nunito', - fontSize: 16, - fontWeight: FontWeight.w600, + fontSize: 18, + fontWeight: FontWeight.w700, color: AppColors.textPrimary, ), ), - const SizedBox(width: 16), + const SizedBox(width: 20), // Duration Expanded( @@ -317,11 +317,16 @@ class _HistoryScreenState extends State { 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) Padding( - padding: const EdgeInsets.only(top: 4), + padding: const EdgeInsets.only(top: 6), child: Text( l10n.distractionsCount( session.distractionCount, @@ -329,7 +334,7 @@ class _HistoryScreenState extends State { ), style: const TextStyle( fontFamily: 'Nunito', - fontSize: 14, + fontSize: 16, fontWeight: FontWeight.w400, color: AppColors.textSecondary, ), @@ -341,18 +346,18 @@ class _HistoryScreenState extends State { // Status badge Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: session.completed ? AppColors.success.withValues(alpha: 0.1) : AppColors.distractionButton, - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(12), ), child: Text( '$statusEmoji $statusText', style: TextStyle( fontFamily: 'Nunito', - fontSize: 12, + fontSize: 14, fontWeight: FontWeight.w600, color: session.completed ? AppColors.success @@ -362,10 +367,10 @@ class _HistoryScreenState extends State { ), // Arrow indicator - const SizedBox(width: 8), + const SizedBox(width: 12), const Icon( Icons.arrow_forward_ios, - size: 12, + size: 16, color: AppColors.textSecondary, ), ], diff --git a/lib/screens/session_detail_screen.dart b/lib/screens/session_detail_screen.dart index 905059f..5b56896 100644 --- a/lib/screens/session_detail_screen.dart +++ b/lib/screens/session_detail_screen.dart @@ -41,130 +41,124 @@ class SessionDetailScreen extends StatelessWidget { return Scaffold( backgroundColor: AppColors.background, appBar: AppBar( - title: const Text('会话详情'), + title: Text(l10n.history), backgroundColor: AppColors.background, ), body: SafeArea( - child: Padding( + child: SingleChildScrollView( padding: const EdgeInsets.all(24.0), - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox(height: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Session Date and Time + _buildSessionHeader(context, l10n), - // Session Date and Time - _buildSessionHeader(context, l10n), + const SizedBox(height: 18), - const SizedBox(height: 32), - - // Focused Time Section - Text(l10n.youFocusedFor, style: AppTextStyles.headline), - const SizedBox(height: 8), - Text( - l10n.minutesValue( - session.actualMinutes, - l10n.minutes(session.actualMinutes), - ), - style: AppTextStyles.largeNumber, + // Focused Time Section + Text(l10n.youFocusedFor, style: AppTextStyles.headline), + const SizedBox(height: 8), + Text( + l10n.minutesValue( + session.actualMinutes, + l10n.minutes(session.actualMinutes), ), + style: AppTextStyles.largeNumber, + ), - const SizedBox(height: 32), + const SizedBox(height: 24), - // Points Earned Section - _buildPointsCard( - context, - l10n, - pointsEarned, - basePoints, - honestyBonus, + // Points Earned Section + _buildPointsCard( + context, + l10n, + pointsEarned, + basePoints, + honestyBonus, + ), + + const SizedBox(height: 16), + + // Session Stats Card + Container( + width: double.infinity, + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: AppColors.white, + borderRadius: BorderRadius.circular(16), ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //Text(l10n.history, style: AppTextStyles.headline), + const SizedBox(height: 16), - const SizedBox(height: 16), - - // Session Stats Card - Container( - width: double.infinity, - padding: const EdgeInsets.all(24), - decoration: BoxDecoration( - color: AppColors.white, - borderRadius: BorderRadius.circular(16), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('会话统计', style: AppTextStyles.headline), - const SizedBox(height: 16), - - _buildStatRow( - icon: '⏱️', - label: '计划时长', - value: l10n.minutesValue( - session.durationMinutes, - l10n.minutes(session.durationMinutes), - ), + _buildStatRow( + icon: '⏱️', + label: l10n.defaultFocusDuration, + value: l10n.minutesValue( + session.durationMinutes, + l10n.minutes(session.durationMinutes), ), - const SizedBox(height: 12), + ), + const SizedBox(height: 12), - _buildStatRow( - icon: '✅', - label: '实际专注', - value: l10n.minutesValue( - session.actualMinutes, - l10n.minutes(session.actualMinutes), - ), + _buildStatRow( + icon: '✅', + label: l10n.youFocusedFor, + value: l10n.minutesValue( + session.actualMinutes, + l10n.minutes(session.actualMinutes), ), - const SizedBox(height: 12), + ), + const SizedBox(height: 12), - _buildStatRow( - icon: '🤚', - label: '分心次数', - value: l10n.distractionsCount( - session.distractionCount, - l10n.times(session.distractionCount), - ), - ), - const SizedBox(height: 12), + _buildStatRow( + icon: '🤚', + label: 'Distractions', + value: + '${session.distractionCount} ${l10n.times(session.distractionCount)}', + ), + const SizedBox(height: 12), - _buildStatRow( - icon: '🏁', - label: '状态', - value: session.completed - ? l10n.completed - : l10n.stoppedEarly, - ), - const SizedBox(height: 20), + _buildStatRow( + icon: '🏁', + label: 'Status', + value: session.completed + ? l10n.completed + : l10n.stoppedEarly, + ), + const SizedBox(height: 20), - Text( - '"$encouragement"', - style: AppTextStyles.encouragementQuote, - ), - ], - ), + Text( + '"$encouragement"', + style: AppTextStyles.encouragementQuote, + ), + ], ), + ), - const SizedBox(height: 16), + const SizedBox(height: 16), - // Achievements Unlocked Section - if (sessionAchievements.isNotEmpty) - ..._buildAchievementCards(context, l10n, sessionAchievements), + // Achievements Unlocked Section + if (sessionAchievements.isNotEmpty) + ..._buildAchievementCards(context, l10n, sessionAchievements), - const SizedBox(height: 24), + const SizedBox(height: 24), - // Total Points Display - Text( - l10n.totalPoints(progress.totalPoints), - style: const TextStyle( - fontFamily: 'Nunito', - fontSize: 16, - fontWeight: FontWeight.w600, - color: AppColors.primary, - ), + // Total Points Display + Text( + l10n.totalPoints(progress.totalPoints), + style: const TextStyle( + fontFamily: 'Nunito', + fontSize: 16, + fontWeight: FontWeight.w600, + color: AppColors.primary, ), + ), - const SizedBox(height: 40), - ], - ), + const SizedBox(height: 40), + ], ), ), ), @@ -182,16 +176,36 @@ class SessionDetailScreen extends StatelessWidget { return Container( width: double.infinity, - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.white, - borderRadius: BorderRadius.circular(16), + borderRadius: BorderRadius.circular(12), ), - child: Column( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(dateStr, style: AppTextStyles.headline), - const SizedBox(height: 8), - Text(timeStr, style: AppTextStyles.largeNumber), + Text( + dateStr, + 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: [ Text(icon, style: const TextStyle(fontSize: 20)), const SizedBox(width: 12), - Text(label, style: AppTextStyles.bodyText), - const Spacer(), + Expanded( + child: Text( + label, + style: AppTextStyles.bodyText, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ), + const SizedBox(width: 8), Text( value, style: const TextStyle( @@ -428,7 +449,7 @@ class SessionDetailScreen extends StatelessWidget { List achievements, ) { return [ - Text('解锁的成就', style: AppTextStyles.headline), + Text(l10n.achievements, style: AppTextStyles.headline), const SizedBox(height: 16), ...achievements.map((achievement) { return Container( @@ -457,7 +478,7 @@ class SessionDetailScreen extends StatelessWidget { Text(achievement.icon, style: const TextStyle(fontSize: 32)), const SizedBox(width: 12), Text( - '成就解锁!', + l10n.achievementUnlocked, style: const TextStyle( fontFamily: 'Nunito', fontSize: 18,