feat(todo): a project's Calendar as a month on wide windows (ADR 0033, D17)
From 720 pixels of the Calendar's own width on, a month grid in place of the agenda: the month's weeks from the week's first day, the days of the months beside it muted, each day with as many of its tasks as fit and the rest counted, opening the day's tasks in a sheet; past days with their overdue and done tasks. A task held and dropped on another day moves there (moveTask), a day's free space tapped adds a task on it, a line tapped opens its task. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
0373f723e7
commit
0b6f79244f
1 changed files with 761 additions and 51 deletions
|
|
@ -171,4 +171,89 @@ void main() {
|
|||
);
|
||||
expect(shown(calendar), {today: 'a,b'});
|
||||
});
|
||||
|
||||
group('a month as a grid (D17)', () {
|
||||
test('its weeks from the one with its first day to the one with its '
|
||||
'last, starting on the week’s first day', () {
|
||||
// November 2026 starts on a Sunday and ends on a Monday.
|
||||
expect(monthWeeks(const Day(2026, 11, 1), DateTime.monday), [
|
||||
const Day(2026, 10, 26),
|
||||
const Day(2026, 11, 2),
|
||||
const Day(2026, 11, 9),
|
||||
const Day(2026, 11, 16),
|
||||
const Day(2026, 11, 23),
|
||||
const Day(2026, 11, 30),
|
||||
]);
|
||||
expect(monthWeeks(const Day(2026, 11, 20), DateTime.sunday), [
|
||||
const Day(2026, 11, 1),
|
||||
const Day(2026, 11, 8),
|
||||
const Day(2026, 11, 15),
|
||||
const Day(2026, 11, 22),
|
||||
const Day(2026, 11, 29),
|
||||
]);
|
||||
// February 2027 fills four weeks from a Monday.
|
||||
expect(monthWeeks(const Day(2027, 2, 1), DateTime.monday), hasLength(4));
|
||||
});
|
||||
|
||||
test('each day from its first to before its end with its tasks, past '
|
||||
'ones too, done ones where kept, by time', () {
|
||||
final days = monthOf(
|
||||
[
|
||||
task('none'),
|
||||
task('late', day: today.plus(-3)),
|
||||
task('done', day: today.plus(-1), completed: true),
|
||||
task('noon', day: today.plus(2), time: 12 * 60),
|
||||
task('morning', day: today.plus(2), time: 8 * 60),
|
||||
task('after', day: today.plus(30)),
|
||||
],
|
||||
today,
|
||||
from: today.plus(-5),
|
||||
to: today.plus(30),
|
||||
);
|
||||
expect(days.keys.first, today.plus(-5));
|
||||
expect(days, hasLength(35));
|
||||
expect(
|
||||
{
|
||||
for (final MapEntry(:key, :value) in days.entries)
|
||||
if (value.isNotEmpty)
|
||||
key: [for (final entry in value) entry.task.id].join(','),
|
||||
},
|
||||
{
|
||||
today.plus(-3): 'late',
|
||||
today.plus(-1): 'done',
|
||||
today.plus(2): 'morning,noon',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('later times of repeating tasks from today on alone, where asked', () {
|
||||
final weekly = task(
|
||||
'weekly',
|
||||
day: today.plus(-7),
|
||||
repeat: const Repeat(RepeatUnit.week),
|
||||
);
|
||||
expect(
|
||||
monthOf([weekly], today, from: today.plus(-14), to: today.plus(14))
|
||||
.values
|
||||
.expand((entries) => entries)
|
||||
.map((entry) => entry.task.content.date!.day),
|
||||
[today.plus(-7)],
|
||||
);
|
||||
final days = monthOf(
|
||||
[weekly],
|
||||
today,
|
||||
from: today.plus(-14),
|
||||
to: today.plus(14),
|
||||
occurrences: true,
|
||||
);
|
||||
final later = [
|
||||
for (final MapEntry(:key, :value) in days.entries)
|
||||
for (final entry in value)
|
||||
if (entry.occurrence) key,
|
||||
];
|
||||
// Overdue a week, done today it would come a week on, then the
|
||||
// grid ends.
|
||||
expect(later, [today.plus(7)]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue