checkpoint: focus seed 1.0.1 localized dev switch
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user