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:
@@ -0,0 +1,70 @@
|
||||
import 'country_code_sources/cached_country_code_source.dart';
|
||||
import 'country_code_sources/country_code_source.dart';
|
||||
import 'country_code_sources/gps_country_code_source.dart';
|
||||
import 'country_code_sources/manual_country_code_source.dart';
|
||||
import 'country_code_sources/sim_country_code_source.dart';
|
||||
|
||||
/// Orchestriert die priorisierte Ermittlungskette für den aktuellen
|
||||
/// Ländercode (`docs/plan.md`, Abschnitt 6 + 8, AP4 + AP6):
|
||||
///
|
||||
/// 0. manuelle Auswahl des Nutzers (`shared_preferences`, übersteuert alles)
|
||||
/// 1. SIM/Netz-Ländercode (offline, primär)
|
||||
/// 2. GPS + Reverse-Geocoding (Fallback, ggf. Netz nötig)
|
||||
/// 3. zuletzt gespeicherter Code (`shared_preferences`)
|
||||
///
|
||||
/// Die erste Quelle, die einen nicht-`null`-Wert liefert, gewinnt; die
|
||||
/// übrigen Quellen werden dann nicht mehr angefragt. Nach einem Treffer über
|
||||
/// SIM oder GPS wird der Cache best-effort aktualisiert (Fehler dabei
|
||||
/// beeinflussen die Rückgabe nicht), damit ein späterer Aufruf ohne
|
||||
/// Netz/GPS/SIM trotzdem einen aktuellen Wert liefern kann. Die manuelle
|
||||
/// Auswahl (Stufe 0) wird bewusst **nicht** in diesen automatischen Cache
|
||||
/// (Stufe 3) geschrieben – beides sind getrennte Mechanismen mit eigenem
|
||||
/// `shared_preferences`-Key, siehe `ManualCountryCodeSource` und
|
||||
/// `CachedCountryCodeSource`.
|
||||
///
|
||||
/// `null` wird nur zurückgegeben, wenn wirklich alle Quellen fehlschlagen –
|
||||
/// die UI (AP5+) muss diesen Fall (`status = countryUnknown`) explizit
|
||||
/// behandeln.
|
||||
class LocationService {
|
||||
LocationService({
|
||||
CountryCodeSource? simSource,
|
||||
CountryCodeSource? gpsSource,
|
||||
CountryCodeCache? cacheSource,
|
||||
ManualCountryCodeStore? manualSource,
|
||||
}) : _simSource = simSource ?? const SimCountryCodeSource(),
|
||||
_gpsSource = gpsSource ?? GpsCountryCodeSource(),
|
||||
_cacheSource = cacheSource ?? const CachedCountryCodeSource(),
|
||||
_manualSource = manualSource ?? const ManualCountryCodeSource();
|
||||
|
||||
final CountryCodeSource _simSource;
|
||||
final CountryCodeSource _gpsSource;
|
||||
final CountryCodeCache _cacheSource;
|
||||
final ManualCountryCodeStore _manualSource;
|
||||
|
||||
Future<String?> resolveCountryCode() async {
|
||||
final manualResult = await _manualSource.resolve();
|
||||
if (manualResult != null) {
|
||||
return manualResult;
|
||||
}
|
||||
|
||||
final simResult = await _simSource.resolve();
|
||||
if (simResult != null) {
|
||||
await _cacheSource.save(simResult);
|
||||
return simResult;
|
||||
}
|
||||
|
||||
final gpsResult = await _gpsSource.resolve();
|
||||
if (gpsResult != null) {
|
||||
await _cacheSource.save(gpsResult);
|
||||
return gpsResult;
|
||||
}
|
||||
|
||||
return _cacheSource.resolve();
|
||||
}
|
||||
|
||||
/// Setzt oder löscht die manuelle Länderauswahl (`docs/plan.md`,
|
||||
/// Abschnitt 8, AP6). `isoCode == null` löscht eine zuvor gesetzte Auswahl
|
||||
/// wieder, sodass der nächste [resolveCountryCode]-Aufruf wieder auf die
|
||||
/// automatische Kette (SIM → GPS → Cache) zurückfällt.
|
||||
Future<void> setManualCountryCode(String? isoCode) => _manualSource.save(isoCode);
|
||||
}
|
||||
Reference in New Issue
Block a user