Adds a real Ch∆In hub backend to the Flutter client as a sibling-path dependency on chain_client_sdk_dart, alongside the existing MockRepository (which stays the default until the flow.completed-to-Evaluation pipeline lands in Phase 0 week 1). Wiring HubSettings (lib/data/hub_endpoint.dart) — persists host / port / secure / token / useHub flags via SharedPreferences under the Studio-compatible hub.* keys. Distinct from the SDK's chain.HubEndpoint, which is a transport-level value type — HubSettings adapts in that direction. HubRepository (lib/data/hub_repository.dart) — implements EvaluationRepository on top of HubClient. connect() runs a 4-second healthy() probe; on failure returns a repository with isHealthy=false rather than throwing, so the UI can surface "hub-down" without an exception-handling round-trip. list() / byEli() return empty data in Phase 0 because no hub-side flow yet produces Evaluation objects in the lawheatmap-specific shape. main.dart — loads HubSettings on startup; if useHub=false starts with MockRepository (fast offline default), otherwise probes the hub and falls back to MockRepository on probe failure. No mid-session swap to keep the Phase 0 wiring simple; a settings save instructs the user to restart. HubStatusPage — read-only summary card at the top, editable endpoint form, "Verbindung testen" probe button, "Speichern" persist button. Live-flow runbook below describes the chain serve / install / run / approve sequence so a user can wire the real flow themselves once Phase 1 lands. flutter analyze: clean. flutter test: 2/2 passing. Smoke-launch on macOS: app boots, Dart VM service comes up, no runtime errors in mock mode. Signed-off-by: flemming-it <sf@flemming.it>
58 lines
1.9 KiB
Dart
58 lines
1.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
|
|
import 'data/hub_endpoint.dart';
|
|
import 'data/hub_repository.dart';
|
|
import 'data/repository.dart';
|
|
import 'pages/landing_page.dart';
|
|
import 'theme/lawheatmap_theme.dart';
|
|
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
final settings = await HubSettings.load();
|
|
final repository = await _pickRepository(settings);
|
|
runApp(LawHeatmapApp(repository: repository, settings: settings));
|
|
}
|
|
|
|
/// Decide which repository to start with.
|
|
///
|
|
/// useHub=false → Mock, no probe (fast offline start)
|
|
/// useHub=true, healthy → HubRepository
|
|
/// useHub=true, NOT ok → MockRepository (graceful fallback;
|
|
/// UI banner shows hub-down so the
|
|
/// user can re-try from settings)
|
|
Future<EvaluationRepository> _pickRepository(HubSettings settings) async {
|
|
if (!settings.useHub) return const MockRepository();
|
|
final hub = await HubRepository.connect(settings);
|
|
if (hub.isHealthy) return hub;
|
|
return const MockRepository();
|
|
}
|
|
|
|
class LawHeatmapApp extends StatelessWidget {
|
|
const LawHeatmapApp({
|
|
super.key,
|
|
this.repository = const MockRepository(),
|
|
this.settings,
|
|
});
|
|
|
|
final EvaluationRepository repository;
|
|
final HubSettings? settings;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'F∆I Law-Heatmap',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: LawHeatmapTheme.light(),
|
|
darkTheme: LawHeatmapTheme.dark(),
|
|
themeMode: ThemeMode.dark,
|
|
localizationsDelegates: const [
|
|
GlobalMaterialLocalizations.delegate,
|
|
GlobalWidgetsLocalizations.delegate,
|
|
GlobalCupertinoLocalizations.delegate,
|
|
],
|
|
supportedLocales: const [Locale('de'), Locale('en')],
|
|
home: LandingPage(repository: repository),
|
|
);
|
|
}
|
|
}
|