Files
gp/lib/src/features/habits/habit_manager_sheet.dart
T
2026-09-27 23:40:22 +08:00

113 lines
4.0 KiB
Dart

import 'package:flutter/material.dart';
import '../../app/app_theme.dart';
import '../../application/focus_seed_controller.dart';
import '../../core/date_keys.dart';
import '../../l10n/l10n.dart';
import '../../widgets/app_bottom_sheet.dart';
import '../../widgets/app_empty_state.dart';
import '../../widgets/dialogs.dart';
import '../../widgets/loading_view.dart';
import '../today/widgets/compact_habit_row.dart';
Future<void> showHabitManagerSheet(
BuildContext context,
FocusSeedController controller,
) {
return showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
useSafeArea: true,
builder:
(context) => FractionallySizedBox(
heightFactor: 0.86,
child: AnimatedBuilder(
animation: controller,
builder: (context, _) {
final state = controller.state;
final l10n = context.l10n;
final visuals = FocusSeedVisuals.of(context);
if (state == null) {
return AppBottomSheetScaffold(
title: l10n.habitsTitle,
subtitle: l10n.habitsSubtitle,
icon: Icons.add_task_rounded,
accent: visuals.habit,
expand: true,
child: const LoadingView(),
);
}
final today = todayKey();
return AppBottomSheetScaffold(
title: l10n.habitsTitle,
subtitle: l10n.habitsSubtitle,
icon: Icons.add_task_rounded,
accent: visuals.habit,
expand: true,
trailing: IconButton.filledTonal(
tooltip: l10n.addHabit,
onPressed:
() => showHabitDialog(context, controller.addHabit),
icon: const Icon(Icons.add_rounded),
),
child:
state.habits.isEmpty
? _EmptyHabits(
onAdd:
() =>
showHabitDialog(context, controller.addHabit),
)
: ListView.separated(
padding: const EdgeInsets.fromLTRB(0, 2, 0, 24),
itemCount: state.habits.length,
separatorBuilder: (_, _) => const SizedBox(height: 8),
itemBuilder: (context, index) {
final habit = state.habits[index];
return CompactHabitRow(
habit: habit,
dateKey: today,
onToggle: () => controller.toggleHabit(habit),
onEdit:
() => showHabitDialog(
context,
(value) =>
controller.renameHabit(habit, value),
initialValue: habit.title,
),
onDelete:
() => confirmDeleteHabit(
context,
() => controller.deleteHabit(habit),
),
);
},
),
);
},
),
),
);
}
class _EmptyHabits extends StatelessWidget {
const _EmptyHabits({required this.onAdd});
final VoidCallback onAdd;
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
return AppEmptyState(
title: l10n.emptyHabitsTitle,
body: l10n.emptyHabitPrompt,
icon: Icons.add_task_rounded,
actionLabel: l10n.addHabit,
actionIcon: Icons.add_rounded,
onAction: onAdd,
accent: FocusSeedVisuals.of(context).habit,
illustrationHeight: 86,
padding: const EdgeInsets.all(28),
);
}
}