feat(app): the week's rest day sits in its header, beside the day shown
All checks were successful
CI / check (push) Successful in 9m31s
CI / deploy (push) Successful in 14s

Asked for on 2026-10-07: the rest day moves from below the week into the
week's header, between the day shown and Today and the arrows. From
medium windows on it stays a chip; on a phone, where the date, a chip
and the arrows don't fit in a row, it is a snowflake toggle with "Rest
day" as its tooltip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-07 12:22:59 +02:00
commit 712aa5f7f7
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 59 additions and 18 deletions

View file

@ -6,10 +6,11 @@ import 'package:intl/intl.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:material_ui/material_ui.dart';
/// The week of [selected] day: the day named on top with going a day back
/// or on and back to today, Monday to Sunday as boxes with how each stands,
/// and making the day picked a rest day when it is today or to come and
/// not studied.
/// The week of [selected] day: on top the day named, making it a rest day
/// when it is today or to come and not studied (a chip, on a phone a
/// snowflake toggle for the room; decided 2026-10-07), and going a day back
/// or on and back to today; below, Monday to Sunday as boxes with how each
/// stands.
class const WeekOverview({
/// The day picked.
required final DateTime selected,
@ -42,6 +43,7 @@ class const WeekOverview({
final picked = week.where((day) => day.day == selected).firstOrNull;
final canRest =
!selected.isBefore(today) && picked?.state != DayState.studied;
final resting = restDays.contains(selected);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
@ -55,9 +57,34 @@ class const WeekOverview({
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
if (canRest && beside)
Padding(
padding: const EdgeInsets.only(left: 8, right: 4),
child: FilterChip(
avatar: const Icon(LucideIcons.snowflake, size: 16),
label: Text(l10n.weekRestDay),
selected: resting,
onSelected: (_) => onToggleRestDay(),
),
)
else if (canRest)
IconButton(
tooltip: l10n.weekRestDay,
isSelected: resting,
icon: const Icon(LucideIcons.snowflake),
style: resting
? IconButton.styleFrom(
backgroundColor: theme.colorScheme.secondaryContainer,
foregroundColor: theme.colorScheme.onSecondaryContainer,
)
: null,
onPressed: onToggleRestDay,
),
if (selected != today)
TextButton(
onPressed: () => onSelect(today),
@ -91,18 +118,6 @@ class const WeekOverview({
),
],
),
if (canRest)
Padding(
padding: const EdgeInsets.only(top: 10),
child: Center(
child: FilterChip(
avatar: const Icon(LucideIcons.snowflake, size: 16),
label: Text(l10n.weekRestDay),
selected: restDays.contains(selected),
onSelected: (_) => onToggleRestDay(),
),
),
),
],
);
}

View file

@ -25,8 +25,8 @@ void main() {
settingsGateway = FakeSettingsGateway();
});
Future<void> showHome(WidgetTester tester) async {
tester.view.physicalSize = const Size(1200, 1600);
Future<void> showHome(WidgetTester tester, {double width = 1200}) async {
tester.view.physicalSize = Size(width, 1600);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
await pumpApp(
@ -94,6 +94,32 @@ void main() {
expect(streak(tester), 1);
});
testWidgets("the rest day sits in the week's header, beside the day "
'shown', (tester) async {
await showHome(tester);
final restDay = tester.getRect(find.text('Rest day'));
final previous = tester.getRect(find.byTooltip('Previous day'));
expect(restDay.center.dy, closeTo(previous.center.dy, 2));
expect(restDay.right, lessThan(previous.left));
});
testWidgets('on a phone, the rest day is a snowflake button in the '
"week's header", (tester) async {
await showHome(tester, width: 360);
expect(find.text('Rest day'), findsNothing);
final restDay = find.byTooltip('Rest day');
expect(
tester.getRect(restDay).center.dy,
closeTo(tester.getRect(find.byTooltip('Previous day')).center.dy, 2),
);
await tester.tap(restDay);
await tester.pumpAndSettle();
expect(streak(tester), 1);
});
testWidgets('a long press arranges the dashboard: a widget hidden stays '
'hidden', (tester) async {
await showHome(tester);