checkpoint: focus seed 1.0.1 localized dev switch

This commit is contained in:
2026-06-11 23:35:49 +08:00
parent c51abdfb73
commit d06dc35ee6
72 changed files with 6155 additions and 1390 deletions
@@ -0,0 +1,181 @@
import 'package:flutter/material.dart';
import '../../../app/app_theme.dart';
import '../../../l10n/l10n.dart';
import '../../../models/today_progress.dart';
import '../../../widgets/surface_panel.dart';
class JourneyTimeline extends StatelessWidget {
const JourneyTimeline({
required this.progress,
required this.onReflect,
super.key,
});
final TodayProgress progress;
final VoidCallback onReflect;
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
final items = [
_TimelineData(
title: l10n.progressIntention,
detail:
progress.hasIntention ? progress.intention : l10n.chooseOneOutcome,
icon: Icons.flag_outlined,
complete: progress.hasIntention,
),
_TimelineData(
title: l10n.progressFocus,
detail:
progress.hasFocus
? l10n.focusedMinutes(progress.focusMinutes)
: l10n.noFocusSessionYet,
icon: Icons.timer_outlined,
complete: progress.hasFocus,
),
_TimelineData(
title: l10n.progressHabits,
detail: l10n.habitsCompleted(
progress.completedHabits,
progress.totalHabits,
),
icon: Icons.eco_outlined,
complete: progress.hasHabits,
),
_TimelineData(
title: l10n.progressReflect,
detail:
progress.hasReflection
? l10n.reflectionCaptured
: l10n.reflectionAction,
icon: Icons.auto_awesome_outlined,
complete: progress.hasReflection,
action: progress.hasReflection ? null : onReflect,
),
_TimelineData(
title: l10n.growthTitle,
detail:
progress.hasReflection ? l10n.growthFlowerOpen : l10n.growthLocked,
icon: Icons.local_florist_outlined,
complete: progress.hasReflection,
),
];
return Column(
children: [
for (var index = 0; index < items.length; index++)
_TimelineItem(data: items[index], isLast: index == items.length - 1),
],
);
}
}
class _TimelineItem extends StatelessWidget {
const _TimelineItem({required this.data, required this.isLast});
final _TimelineData data;
final bool isLast;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final visuals = FocusSeedVisuals.of(context);
final accent =
data.icon == Icons.auto_awesome_outlined
? visuals.reflection
: theme.colorScheme.primary;
return IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
width: 38,
child: Column(
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
data.complete
? accent
: theme.colorScheme.surfaceContainerLowest,
border: Border.all(color: accent),
),
child: Icon(
data.complete ? Icons.check_rounded : data.icon,
size: 16,
color: data.complete ? theme.colorScheme.onPrimary : accent,
),
),
if (!isLast)
Expanded(
child: Container(
width: 2,
color:
data.complete
? accent.withValues(alpha: 0.55)
: theme.colorScheme.outlineVariant,
),
),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SurfacePanel(
padding: const EdgeInsets.all(14),
borderColor:
data.action == null ? null : accent.withValues(alpha: 0.5),
onTap: data.action,
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(data.title, style: theme.textTheme.labelLarge),
const SizedBox(height: 3),
Text(
data.detail,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
],
),
),
if (data.action != null)
Icon(Icons.arrow_forward_rounded, color: accent),
],
),
),
),
),
],
),
);
}
}
class _TimelineData {
const _TimelineData({
required this.title,
required this.detail,
required this.icon,
required this.complete,
this.action,
});
final String title;
final String detail;
final IconData icon;
final bool complete;
final VoidCallback? action;
}