feat(todo): 3-day grid's blocks dragged to another day and time, or onto All day (ADR 0033, D17)
A block held and dragged moves its task to another of the three days shown and another time, its top snapping to a quarter hour, the time it would take shown under the pointer, its duration, recurrence and reminders kept; dropped on a day's All day it loses its time and duration. Either can be undone for a moment. A later time of a repeating task doesn't move. DayDropArea's move is now moveTask, shared by both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
51ebed41cd
commit
0373f723e7
1 changed files with 399 additions and 49 deletions
|
|
@ -810,6 +810,140 @@ void main() {
|
|||
expect(date.duration, const Duration(minutes: 30));
|
||||
});
|
||||
|
||||
group('a block held and dragged', () {
|
||||
/// Holds [from], moves to [to] in steps and lets go.
|
||||
Future<void> drag(WidgetTester tester, Offset from, Offset to) async {
|
||||
final gesture = await tester.startGesture(from);
|
||||
await tester.pump(
|
||||
kLongPressTimeout + const Duration(milliseconds: 50),
|
||||
);
|
||||
for (var step = 1; step <= 10; step++) {
|
||||
await gesture.moveTo(Offset.lerp(from, to, step / 10)!);
|
||||
await tester.pump();
|
||||
}
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
/// Tomorrow's 9:00 dentist, an hour long, weekly, in the 3-day grid;
|
||||
/// its ID.
|
||||
Future<String> dentist(WidgetTester tester) async {
|
||||
final today = Day.of(DateTime.now());
|
||||
await start(tester, usedBefore: true);
|
||||
await seed(
|
||||
tester,
|
||||
TaskContent(
|
||||
title: 'Dentist',
|
||||
projectId: inbox(),
|
||||
date: TaskDate(
|
||||
today.plus(1),
|
||||
time: 9 * 60,
|
||||
duration: const Duration(hours: 1),
|
||||
repeat: const Repeat(RepeatUnit.week),
|
||||
),
|
||||
),
|
||||
);
|
||||
await threeDay(tester);
|
||||
final stored = await tester.runAsync(() => tasks().all());
|
||||
return stored!.single.id;
|
||||
}
|
||||
|
||||
Future<TaskDate> dateOf(WidgetTester tester) async {
|
||||
final stored = await tester.runAsync(() => tasks().all());
|
||||
return stored!.single.content!.date!;
|
||||
}
|
||||
|
||||
testWidgets('onto another day and hour moves its task there, its '
|
||||
'duration and recurrence kept, the place under the pointer '
|
||||
'snapping to a quarter hour; which can be undone', (tester) async {
|
||||
final id = await dentist(tester);
|
||||
final today = Day.of(DateTime.now());
|
||||
final block = find.byKey(ThreeDayGrid.blockKey(id, today.plus(1)));
|
||||
await tester.ensureVisible(block);
|
||||
await tester.pumpAndSettle();
|
||||
// Held 20 minutes below its top, dropped where 14:27 is under the
|
||||
// pointer: its top at 14:07, which snaps to 14:00.
|
||||
final from = tester.getTopLeft(block) + const Offset(10, 20);
|
||||
final column = tester.getTopLeft(
|
||||
find.byKey(ThreeDayGrid.columnKey(today)),
|
||||
);
|
||||
await drag(tester, from, column + const Offset(20, 14 * 60 + 27));
|
||||
|
||||
expect(
|
||||
find.byKey(quickAddTitleKey),
|
||||
findsNothing,
|
||||
reason: 'the hold a drag, not a new task',
|
||||
);
|
||||
final moved = await dateOf(tester);
|
||||
expect(moved.day, today);
|
||||
expect(moved.time, 14 * 60);
|
||||
expect(moved.duration, const Duration(hours: 1));
|
||||
expect(moved.repeat, const Repeat(RepeatUnit.week));
|
||||
expect(find.byKey(ThreeDayGrid.blockKey(id, today)), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Undo'));
|
||||
await tester.pumpAndSettle();
|
||||
final back = await dateOf(tester);
|
||||
expect(back.day, today.plus(1));
|
||||
expect(back.time, 9 * 60);
|
||||
});
|
||||
|
||||
testWidgets('onto a day’s All day takes its time away', (tester) async {
|
||||
final id = await dentist(tester);
|
||||
final today = Day.of(DateTime.now());
|
||||
final block = find.byKey(ThreeDayGrid.blockKey(id, today.plus(1)));
|
||||
await tester.ensureVisible(block);
|
||||
await tester.pumpAndSettle();
|
||||
final from = tester.getTopLeft(block) + const Offset(10, 20);
|
||||
final allDay = tester.getCenter(
|
||||
find.byKey(ThreeDayGrid.allDayKey(today.plus(2))),
|
||||
);
|
||||
await drag(tester, from, allDay);
|
||||
|
||||
final moved = await dateOf(tester);
|
||||
expect(moved.day, today.plus(2));
|
||||
expect(moved.time, isNull);
|
||||
expect(moved.duration, isNull);
|
||||
expect(moved.repeat, const Repeat(RepeatUnit.week));
|
||||
});
|
||||
|
||||
testWidgets('a later time of a repeating task stays where it is', (
|
||||
tester,
|
||||
) async {
|
||||
final id = await dentist(tester);
|
||||
await tester.tap(find.byTooltip('Display'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(
|
||||
find.widgetWithText(SwitchListTile, 'Future occurrences'),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.widgetWithText(FilledButton, 'Done'));
|
||||
await tester.pumpAndSettle();
|
||||
// Today's grid shows tomorrow and the day after; the next time is
|
||||
// a week on.
|
||||
await tester.tap(find.byTooltip('Later days'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byTooltip('Later days'));
|
||||
await tester.pumpAndSettle();
|
||||
final today = Day.of(DateTime.now());
|
||||
final later = find.byKey(ThreeDayGrid.blockKey(id, today.plus(8)));
|
||||
await tester.ensureVisible(later);
|
||||
await tester.pumpAndSettle();
|
||||
final column = tester.getTopLeft(
|
||||
find.byKey(ThreeDayGrid.columnKey(today.plus(6))),
|
||||
);
|
||||
await drag(
|
||||
tester,
|
||||
tester.getTopLeft(later) + const Offset(10, 20),
|
||||
column + const Offset(20, 14 * 60),
|
||||
);
|
||||
|
||||
final date = await dateOf(tester);
|
||||
expect(date.day, today.plus(1));
|
||||
expect(date.time, 9 * 60);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('its filters keep the agenda to what they ask for; Reset '
|
||||
'all puts it back', (tester) async {
|
||||
await start(tester, usedBefore: true);
|
||||
|
|
|
|||
Loading…
Reference in a new issue