mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-07-20 19:11:05 +02:00
generic providers
This commit is contained in:
+175
-11
@@ -1,5 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import '../models/tile_provider.dart';
|
||||
|
||||
@@ -10,19 +12,74 @@ class SettingsState extends ChangeNotifier {
|
||||
static const String _offlineModePrefsKey = 'offline_mode';
|
||||
static const String _maxCamerasPrefsKey = 'max_cameras';
|
||||
static const String _uploadModePrefsKey = 'upload_mode';
|
||||
static const String _tileProviderPrefsKey = 'tile_provider';
|
||||
static const String _tileProvidersPrefsKey = 'tile_providers';
|
||||
static const String _selectedTileTypePrefsKey = 'selected_tile_type';
|
||||
static const String _legacyTestModePrefsKey = 'test_mode';
|
||||
|
||||
bool _offlineMode = false;
|
||||
int _maxCameras = 250;
|
||||
UploadMode _uploadMode = UploadMode.simulate;
|
||||
TileProviderType _tileProvider = TileProviderType.osmStreet;
|
||||
List<TileProvider> _tileProviders = [];
|
||||
String _selectedTileTypeId = '';
|
||||
|
||||
// Getters
|
||||
bool get offlineMode => _offlineMode;
|
||||
int get maxCameras => _maxCameras;
|
||||
UploadMode get uploadMode => _uploadMode;
|
||||
TileProviderType get tileProvider => _tileProvider;
|
||||
List<TileProvider> get tileProviders => List.unmodifiable(_tileProviders);
|
||||
String get selectedTileTypeId => _selectedTileTypeId;
|
||||
|
||||
/// Get the currently selected tile type
|
||||
TileType? get selectedTileType {
|
||||
for (final provider in _tileProviders) {
|
||||
for (final tileType in provider.tileTypes) {
|
||||
if (tileType.id == _selectedTileTypeId) {
|
||||
return tileType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get the provider that contains the selected tile type
|
||||
TileProvider? get selectedTileProvider {
|
||||
for (final provider in _tileProviders) {
|
||||
if (provider.tileTypes.any((type) => type.id == _selectedTileTypeId)) {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Get all available tile types from all providers
|
||||
List<TileType> get allAvailableTileTypes {
|
||||
final types = <TileType>[];
|
||||
for (final provider in _tileProviders) {
|
||||
types.addAll(provider.availableTileTypes);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/// Legacy getter for backward compatibility
|
||||
@Deprecated('Use selectedTileType instead')
|
||||
TileProviderType get tileProvider {
|
||||
// Map current selection to legacy enum for compatibility
|
||||
final selected = selectedTileType;
|
||||
if (selected == null) return TileProviderType.osmStreet;
|
||||
|
||||
switch (selected.id) {
|
||||
case 'osm_street':
|
||||
return TileProviderType.osmStreet;
|
||||
case 'google_hybrid':
|
||||
return TileProviderType.googleHybrid;
|
||||
case 'esri_satellite':
|
||||
return TileProviderType.arcgisSatellite;
|
||||
case 'mapbox_satellite':
|
||||
return TileProviderType.mapboxSatellite;
|
||||
default:
|
||||
return TileProviderType.osmStreet;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize settings from preferences
|
||||
Future<void> init() async {
|
||||
@@ -50,15 +107,53 @@ class SettingsState extends ChangeNotifier {
|
||||
await prefs.setInt(_uploadModePrefsKey, _uploadMode.index);
|
||||
}
|
||||
|
||||
// Load tile provider
|
||||
if (prefs.containsKey(_tileProviderPrefsKey)) {
|
||||
final idx = prefs.getInt(_tileProviderPrefsKey) ?? 0;
|
||||
if (idx >= 0 && idx < TileProviderType.values.length) {
|
||||
_tileProvider = TileProviderType.values[idx];
|
||||
// Load tile providers (default to built-in providers if none saved)
|
||||
await _loadTileProviders(prefs);
|
||||
|
||||
// Load selected tile type (default to first available)
|
||||
_selectedTileTypeId = prefs.getString(_selectedTileTypePrefsKey) ?? '';
|
||||
if (_selectedTileTypeId.isEmpty || selectedTileType == null) {
|
||||
final firstType = allAvailableTileTypes.firstOrNull;
|
||||
if (firstType != null) {
|
||||
_selectedTileTypeId = firstType.id;
|
||||
await prefs.setString(_selectedTileTypePrefsKey, _selectedTileTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadTileProviders(SharedPreferences prefs) async {
|
||||
if (prefs.containsKey(_tileProvidersPrefsKey)) {
|
||||
try {
|
||||
final providersJson = prefs.getString(_tileProvidersPrefsKey);
|
||||
if (providersJson != null) {
|
||||
final providersList = jsonDecode(providersJson) as List;
|
||||
_tileProviders = providersList
|
||||
.map((json) => TileProvider.fromJson(json))
|
||||
.toList();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Error loading tile providers: $e');
|
||||
// Fall back to defaults on error
|
||||
_tileProviders = DefaultTileProviders.createDefaults();
|
||||
}
|
||||
} else {
|
||||
// First time - use defaults
|
||||
_tileProviders = DefaultTileProviders.createDefaults();
|
||||
await _saveTileProviders(prefs);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveTileProviders(SharedPreferences prefs) async {
|
||||
try {
|
||||
final providersJson = jsonEncode(
|
||||
_tileProviders.map((provider) => provider.toJson()).toList(),
|
||||
);
|
||||
await prefs.setString(_tileProvidersPrefsKey, providersJson);
|
||||
} catch (e) {
|
||||
debugPrint('Error saving tile providers: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setOfflineMode(bool enabled) async {
|
||||
_offlineMode = enabled;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
@@ -82,10 +177,79 @@ class SettingsState extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> setTileProvider(TileProviderType provider) async {
|
||||
_tileProvider = provider;
|
||||
/// Select a tile type by ID
|
||||
Future<void> setSelectedTileType(String tileTypeId) async {
|
||||
if (_selectedTileTypeId != tileTypeId) {
|
||||
_selectedTileTypeId = tileTypeId;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_selectedTileTypePrefsKey, tileTypeId);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Add or update a tile provider
|
||||
Future<void> addOrUpdateTileProvider(TileProvider provider) async {
|
||||
final existingIndex = _tileProviders.indexWhere((p) => p.id == provider.id);
|
||||
if (existingIndex >= 0) {
|
||||
_tileProviders[existingIndex] = provider;
|
||||
} else {
|
||||
_tileProviders.add(provider);
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt(_tileProviderPrefsKey, provider.index);
|
||||
await _saveTileProviders(prefs);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Delete a tile provider
|
||||
Future<void> deleteTileProvider(String providerId) async {
|
||||
// Don't allow deleting all providers
|
||||
if (_tileProviders.length <= 1) return;
|
||||
|
||||
final providerToDelete = _tileProviders.firstWhereOrNull((p) => p.id == providerId);
|
||||
if (providerToDelete == null) return;
|
||||
|
||||
// If selected tile type belongs to this provider, switch to another
|
||||
if (providerToDelete.tileTypes.any((type) => type.id == _selectedTileTypeId)) {
|
||||
// Find first available tile type from remaining providers
|
||||
final remainingProviders = _tileProviders.where((p) => p.id != providerId).toList();
|
||||
final firstAvailable = remainingProviders
|
||||
.expand((p) => p.availableTileTypes)
|
||||
.firstOrNull;
|
||||
|
||||
if (firstAvailable != null) {
|
||||
_selectedTileTypeId = firstAvailable.id;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_selectedTileTypePrefsKey, _selectedTileTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
_tileProviders.removeWhere((p) => p.id == providerId);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await _saveTileProviders(prefs);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Legacy setter for backward compatibility
|
||||
@Deprecated('Use setSelectedTileType instead')
|
||||
Future<void> setTileProvider(TileProviderType provider) async {
|
||||
// Map legacy enum to new tile type ID
|
||||
String tileTypeId;
|
||||
switch (provider) {
|
||||
case TileProviderType.osmStreet:
|
||||
tileTypeId = 'osm_street';
|
||||
break;
|
||||
case TileProviderType.googleHybrid:
|
||||
tileTypeId = 'google_hybrid';
|
||||
break;
|
||||
case TileProviderType.arcgisSatellite:
|
||||
tileTypeId = 'esri_satellite';
|
||||
break;
|
||||
case TileProviderType.mapboxSatellite:
|
||||
tileTypeId = 'mapbox_satellite';
|
||||
break;
|
||||
}
|
||||
|
||||
await setSelectedTileType(tileTypeId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user