72 lines
2.4 KiB
Dart
72 lines
2.4 KiB
Dart
// SPDX-FileCopyrightText: 2026 FocusFlow contributors
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
/// Launches the FocusFlow Flutter desktop application.
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:scheduler_core/scheduler_core.dart'
|
|
as scheduler_core
|
|
show logger;
|
|
|
|
import 'app/focus_flow_app.dart';
|
|
import 'app/persistent_scheduler_composition.dart';
|
|
import 'app/runtime/focus_flow_file_logger.dart';
|
|
import 'app/runtime/focus_flow_runtime_config.dart';
|
|
|
|
export 'app/demo_scheduler_composition.dart';
|
|
export 'app/focus_flow_app.dart';
|
|
export 'app/persistent_scheduler_composition.dart';
|
|
|
|
/// Starts the FocusFlow app with the persistent SQLite scheduler composition.
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
var logger = FocusFlowFileLogger.disabled();
|
|
try {
|
|
final config = await FocusFlowRuntimeConfig.load();
|
|
logger = await FocusFlowFileLogger.open(config);
|
|
scheduler_core.logger.info(() => 'FocusFlow startup started.');
|
|
scheduler_core.logger.debug(
|
|
() => 'Runtime config loaded. fileLogging=${logger.isEnabled}',
|
|
);
|
|
final composition = await PersistentSchedulerComposition.open(
|
|
logger: logger,
|
|
);
|
|
scheduler_core.logger.info(() => 'FocusFlow startup completed.');
|
|
runApp(FocusFlowApp(composition: composition));
|
|
} on Object catch (error, stackTrace) {
|
|
scheduler_core.logger.error(
|
|
() => 'FocusFlow startup failed.',
|
|
error: error,
|
|
stackTrace: stackTrace,
|
|
);
|
|
runApp(_StartupFailureApp(message: error.toString()));
|
|
}
|
|
}
|
|
|
|
/// Minimal failure app shown when persistent startup cannot finish.
|
|
class _StartupFailureApp extends StatelessWidget {
|
|
/// Creates a startup failure app with [message].
|
|
const _StartupFailureApp({required this.message});
|
|
|
|
/// Diagnostic startup failure message.
|
|
final String message;
|
|
|
|
/// Builds the widget subtree for this component.
|
|
/// The method translates the current widget configuration and state into Flutter UI without mutating scheduler domain data.
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'FocusFlow',
|
|
debugShowCheckedModeBanner: false,
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Text('Unable to open local schedule data.\n$message'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|