Notrufnummern-Datenbasis, Ländererkennung, State-Management und Lokalisierung (AP1-AP7)

Implementiert den kompletten Kern-Flow der Emergency App gemäß docs/plan.md:
- Notrufnummern-Datenbasis für 199 Länder + Modelle/Repository (AP1)
- DialerService für tel:-Notrufe ohne Auto-Dial (AP2)
- Statisches UI mit Panik-Button-Fallback (AP3)
- Priorisierte Ländererkennung: SIM/Netz -> GPS/Geocoding -> Cache (AP4)
- EmergencyProvider verdrahtet Repository/LocationService mit der UI (AP5)
- Manuelle Länderauswahl als Fallback samt eigener Priorität (AP6)
- UI-Lokalisierung (de/en/fr/es), an erkanntes Land gekoppelt (AP7)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
root
2026-07-24 11:29:38 +02:00
co-authored by Claude Sonnet 5
parent 40e95cc495
commit e3aa088bc2
54 changed files with 7550 additions and 145 deletions
+56
View File
@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'core/country_locale_map.dart';
import 'features/home/home_screen.dart';
import 'l10n/app_localizations.dart';
import 'providers/emergency_provider.dart';
import 'repositories/emergency_number_repository.dart';
import 'services/location_service.dart';
/// Wurzel-Widget der App.
///
/// [repository] und [locationService] sind injizierbar, damit Tests eigene
/// (ggf. gefakte) Instanzen für den intern erzeugten [EmergencyProvider]
/// verwenden können, statt echte Asset-I/O bzw. SIM/GPS/Cache-Zugriffe
/// anzustoßen. Wird stattdessen direkt ein fertiger [provider] übergeben,
/// werden [repository]/[locationService] ignoriert das erlaubt Tests, den
/// `EmergencyProvider` selbst zu faken bzw. vorab zu befüllen.
class App extends StatelessWidget {
const App({super.key, this.repository, this.locationService, this.provider});
final EmergencyNumberRepository? repository;
final LocationService? locationService;
final EmergencyProvider? provider;
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<EmergencyProvider>(
create: (_) =>
provider ??
EmergencyProvider(
repository: repository ?? EmergencyNumberRepository(),
locationService: locationService ?? LocationService(),
),
// AP7 (Lokalisierung): `locale` wird reaktiv aus dem erkannten Land
// berechnet (docs/plan.md, Abschnitt 2 + 8), daher ein Consumer statt
// eines einmalig gebauten MaterialApp ändert sich `country` (z. B.
// nach manueller Länderauswahl aus AP6), rebuildet auch die App-Sprache.
child: Consumer<EmergencyProvider>(
builder: (context, emergencyProvider, _) {
return MaterialApp(
title: 'Emergency',
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.red)),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: resolveAppLocale(
emergencyProvider.country?.isoCode,
AppLocalizations.supportedLocales,
),
home: const HomeScreen(),
);
},
),
);
}
}