import 'package:flutter/material.dart'; import 'package:iperf3gui/data/services/iperf3_service.dart'; import 'package:iperf3gui/domain/services/iperf3_runner.dart'; import 'package:iperf3gui/ui/features/test_run/test_run_screen.dart'; /// Application entry point, and the composition root. /// /// This is the only place that names a concrete [Iperf3Runner]. Everything /// above the data layer depends on the interface, so swapping the transport — /// or running the UI against a fake — touches nothing but this file. Future main() async { WidgetsFlutterBinding.ensureInitialized(); runApp(Iperf3GuiApp(runner: Iperf3Service())); } class Iperf3GuiApp extends StatelessWidget { const Iperf3GuiApp({required this.runner, super.key}); final Iperf3Runner runner; @override Widget build(BuildContext context) { return MaterialApp( title: 'iperf3-gui', theme: ThemeData( colorSchemeSeed: Colors.blue, useMaterial3: true, ), home: TestRunScreen(runner: runner), ); } }