138 lines
3.5 KiB
Dart
138 lines
3.5 KiB
Dart
/// Location Local Data Source
|
|
///
|
|
/// Handles Hive caching for cities and wards.
|
|
library;
|
|
|
|
import 'package:hive_ce/hive.dart';
|
|
import 'package:worker/core/constants/storage_constants.dart';
|
|
import 'package:worker/core/database/hive_service.dart';
|
|
import 'package:worker/features/account/data/models/city_model.dart';
|
|
import 'package:worker/features/account/data/models/ward_model.dart';
|
|
|
|
/// Location Local Data Source
|
|
///
|
|
/// Provides offline-first caching for cities and wards using Hive.
|
|
class LocationLocalDataSource {
|
|
final HiveService _hiveService;
|
|
|
|
LocationLocalDataSource(this._hiveService);
|
|
|
|
// ============================================================================
|
|
// CITIES
|
|
// ============================================================================
|
|
|
|
/// Get city box
|
|
Box<dynamic> get _cityBox => _hiveService.getBox(HiveBoxNames.cityBox);
|
|
|
|
/// Get all cached cities
|
|
List<CityModel> getCities() {
|
|
try {
|
|
final cities = _cityBox.values.whereType<CityModel>().toList();
|
|
return cities;
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// Save cities to cache
|
|
Future<void> saveCities(List<CityModel> cities) async {
|
|
try {
|
|
// Only clear if there are existing cities
|
|
if (_cityBox.isNotEmpty) {
|
|
await _cityBox.clear();
|
|
}
|
|
|
|
for (final city in cities) {
|
|
await _cityBox.put(city.code, city);
|
|
}
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
/// Get city by code
|
|
CityModel? getCityByCode(String code) {
|
|
try {
|
|
return _cityBox.get(code) as CityModel?;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// Check if cities are cached
|
|
bool hasCities() {
|
|
return _cityBox.isNotEmpty;
|
|
}
|
|
|
|
// ============================================================================
|
|
// WARDS
|
|
// ============================================================================
|
|
|
|
/// Get ward box
|
|
Box<dynamic> get _wardBox => _hiveService.getBox(HiveBoxNames.wardBox);
|
|
|
|
/// Get cached wards for a city
|
|
///
|
|
/// Wards are stored with key: "cityCode_wardCode"
|
|
List<WardModel> getWards(String cityCode) {
|
|
try {
|
|
final wards = _wardBox.values
|
|
.whereType<WardModel>()
|
|
.where((ward) {
|
|
// Check if this ward belongs to the city
|
|
final key = '${cityCode}_${ward.code}';
|
|
return _wardBox.containsKey(key);
|
|
})
|
|
.toList();
|
|
|
|
return wards;
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// Save wards for a specific city to cache
|
|
Future<void> saveWards(String cityCode, List<WardModel> wards) async {
|
|
try {
|
|
// Remove old wards for this city (only if they exist)
|
|
final keysToDelete = _wardBox.keys
|
|
.where((key) => key.toString().startsWith('${cityCode}_'))
|
|
.toList();
|
|
|
|
if (keysToDelete.isNotEmpty) {
|
|
for (final key in keysToDelete) {
|
|
await _wardBox.delete(key);
|
|
}
|
|
}
|
|
|
|
// Save new wards
|
|
for (final ward in wards) {
|
|
final key = '${cityCode}_${ward.code}';
|
|
await _wardBox.put(key, ward);
|
|
}
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
/// Check if wards are cached for a city
|
|
bool hasWards(String cityCode) {
|
|
return _wardBox.keys.any((key) => key.toString().startsWith('${cityCode}_'));
|
|
}
|
|
|
|
/// Clear all cached data
|
|
Future<void> clearAll() async {
|
|
try {
|
|
// Only clear if boxes are not empty
|
|
if (_cityBox.isNotEmpty) {
|
|
await _cityBox.clear();
|
|
}
|
|
if (_wardBox.isNotEmpty) {
|
|
await _wardBox.clear();
|
|
}
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|