focus-flow/apps/focus_flow_flutter/lib/composition/demo_scheduler_composition.dart

196 lines
5.4 KiB
Dart

import 'package:scheduler_core/scheduler_core.dart';
import '../controllers/scheduler_command_controller.dart';
import '../controllers/scheduler_read_controller.dart';
class DemoSchedulerComposition {
DemoSchedulerComposition._({
required this.store,
required this.todayQuery,
required this.managementUseCases,
required this.commandUseCases,
required this.now,
required this.date,
});
final InMemoryApplicationUnitOfWork store;
final GetTodayStateQuery todayQuery;
final V1ApplicationManagementUseCases managementUseCases;
final V1ApplicationCommandUseCases commandUseCases;
final DateTime now;
final CivilDate date;
factory DemoSchedulerComposition.seeded({
bool includeTodayItems = true,
bool includeBacklogItems = true,
}) {
final now = DateTime.utc(2026, 6, 25, 9, 15);
final date = CivilDate(2026, 6, 25);
final createdAt = DateTime.utc(2026, 6, 20, 8);
final project = ProjectProfile(id: 'home', name: 'Home', colorKey: 'home');
final store = InMemoryApplicationUnitOfWork(
initialProjects: [project],
initialOwnerSettings: [
OwnerSettings(
ownerId: 'owner-1',
timeZoneId: 'UTC',
compactModeEnabled: true,
backlogStalenessSettings: const BacklogStalenessSettings(
greenMaxAge: Duration(days: 2),
blueMaxAge: Duration(days: 6),
),
),
],
initialTasks: [
if (includeTodayItems) ...[
_scheduledTask(
id: 'plan-day',
title: 'Plan the day',
type: TaskType.flexible,
start: DateTime.utc(2026, 6, 25, 9),
end: DateTime.utc(2026, 6, 25, 9, 30),
createdAt: createdAt,
),
_scheduledTask(
id: 'appointment',
title: 'Appointment',
type: TaskType.inflexible,
start: DateTime.utc(2026, 6, 25, 10),
end: DateTime.utc(2026, 6, 25, 10, 45),
createdAt: createdAt,
),
_scheduledTask(
id: 'rest',
title: 'Protected rest',
type: TaskType.freeSlot,
start: DateTime.utc(2026, 6, 25, 11),
end: DateTime.utc(2026, 6, 25, 11, 30),
createdAt: createdAt,
),
],
if (includeBacklogItems) ...[
_backlogTask(
id: 'fresh',
title: 'Send project update',
createdAt: now.subtract(const Duration(days: 1)),
),
_backlogTask(
id: 'stale',
title: 'Sort receipts',
createdAt: now.subtract(const Duration(days: 9)),
),
],
],
);
return DemoSchedulerComposition._(
store: store,
todayQuery: GetTodayStateQuery(
applicationStore: store,
timeZoneResolver: const FixedOffsetTimeZoneResolver.utc(),
),
managementUseCases: V1ApplicationManagementUseCases(
applicationStore: store,
),
commandUseCases: V1ApplicationCommandUseCases(
applicationStore: store,
timeZoneResolver: const FixedOffsetTimeZoneResolver.utc(),
),
now: now,
date: date,
);
}
UiReadController<TodayState> createTodayController() {
return ApplicationReadController<TodayState>(
read: () {
return todayQuery.execute(
GetTodayStateRequest(
context: context('ui-read-today'),
date: date,
includeNextFlexibleItem: true,
),
);
},
isEmpty: (state) {
return state.timelineItems.isEmpty && state.pendingNotices.isEmpty;
},
);
}
UiReadController<BacklogQueryResult> createBacklogController() {
return ApplicationReadController<BacklogQueryResult>(
read: () {
return managementUseCases.getBacklog(
GetBacklogRequest(
context: context('ui-read-backlog'),
sortKey: BacklogSortKey.age,
),
);
},
isEmpty: (state) => state.items.isEmpty,
);
}
SchedulerCommandController createCommandController({
required ReadRefresh refreshReads,
}) {
return SchedulerCommandController(
commands: commandUseCases,
contextFor: context,
localDate: date,
refreshReads: refreshReads,
);
}
ApplicationOperationContext context(String operationId) {
return ApplicationOperationContext.start(
operationId: operationId,
ownerTimeZone: OwnerTimeZoneContext(
ownerId: 'owner-1',
timeZoneId: 'UTC',
),
clock: FixedClock(now),
idGenerator: SequentialIdGenerator(prefix: operationId),
);
}
}
Task _scheduledTask({
required String id,
required String title,
required TaskType type,
required DateTime start,
required DateTime end,
required DateTime createdAt,
}) {
return Task(
id: id,
title: title,
projectId: 'home',
type: type,
status: TaskStatus.planned,
priority: PriorityLevel.medium,
reward: RewardLevel.medium,
difficulty: DifficultyLevel.easy,
durationMinutes: end.difference(start).inMinutes,
scheduledStart: start,
scheduledEnd: end,
createdAt: createdAt,
updatedAt: createdAt,
);
}
Task _backlogTask({
required String id,
required String title,
required DateTime createdAt,
}) {
return Task.quickCapture(
id: id,
title: title,
projectId: 'home',
createdAt: createdAt,
updatedAt: createdAt,
);
}