diff --git a/lib/features/home/presentation/calendar_day_list.dart b/lib/features/home/presentation/calendar_day_list.dart index 58626dd..a855311 100644 --- a/lib/features/home/presentation/calendar_day_list.dart +++ b/lib/features/home/presentation/calendar_day_list.dart @@ -58,7 +58,8 @@ class _CalendarDayListState extends ConsumerState { // Clean up animation IDs for tasks that are no longer in the data. _completingTaskIds.removeWhere((id) => !state.overdueTasks.any((t) => t.task.id == id) && - !state.dayTasks.any((t) => t.task.id == id)); + !state.dayTasks.any((t) => t.task.id == id) && + !state.prePopulatedTasks.any((t) => t.task.id == id)); return _buildContent(context, state, l10n, theme); }, @@ -82,8 +83,12 @@ class _CalendarDayListState extends ConsumerState { // State (e): Celebration — today is selected and all tasks are done // (totalTaskCount > 0 so at least some task exists somewhere, but today - // has none remaining after completion). - if (isToday && state.dayTasks.isEmpty && state.overdueTasks.isEmpty && state.totalTaskCount > 0) { + // has none remaining after completion, including no pre-populated tasks). + if (isToday && + state.dayTasks.isEmpty && + state.overdueTasks.isEmpty && + state.prePopulatedTasks.isEmpty && + state.totalTaskCount > 0) { return _buildCelebration(l10n, theme); } @@ -269,6 +274,24 @@ class _CalendarDayListState extends ConsumerState { )); } + // Pre-populated tasks section (upcoming tasks within interval window). + if (state.prePopulatedTasks.isNotEmpty) { + items.add(_buildSectionHeader( + 'Demnächst', + theme, + color: theme.colorScheme.onSurface.withValues(alpha: 0.5), + )); + for (final tw in state.prePopulatedTasks) { + items.add(_buildAnimatedTaskRow( + tw, + isOverdue: false, + showRoomTag: showRoomTag, + canComplete: true, + isPrePopulated: true, + )); + } + } + return ListView(children: items); } @@ -291,6 +314,7 @@ class _CalendarDayListState extends ConsumerState { required bool isOverdue, required bool showRoomTag, required bool canComplete, + bool isPrePopulated = false, }) { final isCompleting = _completingTaskIds.contains(tw.task.id); @@ -300,6 +324,7 @@ class _CalendarDayListState extends ConsumerState { taskWithRoom: tw, isOverdue: isOverdue, showRoomTag: showRoomTag, + isPrePopulated: false, // Completing tasks always show full styling. ); } @@ -309,6 +334,7 @@ class _CalendarDayListState extends ConsumerState { isOverdue: isOverdue, showRoomTag: showRoomTag, canComplete: canComplete, + isPrePopulated: isPrePopulated, onCompleted: () => _onTaskCompleted(tw.task.id), ); } @@ -321,11 +347,13 @@ class _CompletingTaskRow extends StatefulWidget { required this.taskWithRoom, required this.isOverdue, required this.showRoomTag, + this.isPrePopulated = false, }); final TaskWithRoom taskWithRoom; final bool isOverdue; final bool showRoomTag; + final bool isPrePopulated; @override State<_CompletingTaskRow> createState() => _CompletingTaskRowState(); @@ -372,6 +400,7 @@ class _CompletingTaskRowState extends State<_CompletingTaskRow> taskWithRoom: widget.taskWithRoom, isOverdue: widget.isOverdue, showRoomTag: widget.showRoomTag, + isPrePopulated: widget.isPrePopulated, onCompleted: () {}, // Already completing — ignore repeat taps. ), ), diff --git a/lib/features/home/presentation/calendar_task_row.dart b/lib/features/home/presentation/calendar_task_row.dart index 8cb26de..43d8780 100644 --- a/lib/features/home/presentation/calendar_task_row.dart +++ b/lib/features/home/presentation/calendar_task_row.dart @@ -14,6 +14,10 @@ const _overdueColor = Color(0xFFE07A5F); /// /// When [isOverdue] is true the task name uses coral text to visually /// distinguish overdue carry-over from today's regular tasks. +/// +/// When [isPrePopulated] is true the entire row is rendered at 0.55 opacity +/// to indicate it is not yet due (visible within interval window, but due +/// date is in the future). class CalendarTaskRow extends StatelessWidget { const CalendarTaskRow({ super.key, @@ -22,6 +26,7 @@ class CalendarTaskRow extends StatelessWidget { this.isOverdue = false, this.showRoomTag = true, this.canComplete = true, + this.isPrePopulated = false, }); final TaskWithRoom taskWithRoom; @@ -38,12 +43,16 @@ class CalendarTaskRow extends StatelessWidget { /// When false, the checkbox is disabled (e.g. for future tasks). final bool canComplete; + /// When true, the row is rendered at 0.55 opacity to indicate an + /// upcoming (not-yet-due) pre-populated task within its interval window. + final bool isPrePopulated; + @override Widget build(BuildContext context) { final theme = Theme.of(context); final task = taskWithRoom.task; - return ListTile( + final tile = ListTile( onTap: () => context.go( '/rooms/${taskWithRoom.roomId}/tasks/${taskWithRoom.task.id}', ), @@ -79,5 +88,7 @@ class CalendarTaskRow extends StatelessWidget { ) : null, ); + + return isPrePopulated ? Opacity(opacity: 0.55, child: tile) : tile; } }