181 lines
5.0 KiB
Dart
181 lines
5.0 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import '../models/city_model.dart';
|
|
import '../constants.dart';
|
|
|
|
// SharedPreferences Provider
|
|
final sharedPreferencesProvider = Provider<Future<SharedPreferences>>((
|
|
ref,
|
|
) async {
|
|
return SharedPreferences.getInstance();
|
|
});
|
|
|
|
// 城市列表 Provider
|
|
final cityListProvider = NotifierProvider<CityListNotifier, List<CityModel>>(
|
|
() {
|
|
final notifier = CityListNotifier();
|
|
notifier._initialize();
|
|
return notifier;
|
|
},
|
|
);
|
|
|
|
class CityListNotifier extends Notifier<List<CityModel>> {
|
|
static const String _citiesKey = 'saved_cities';
|
|
static const String _currentCityKey = 'current_city';
|
|
bool _initialized = false;
|
|
|
|
@override
|
|
List<CityModel> build() {
|
|
if (!_initialized) {
|
|
_initialize();
|
|
}
|
|
return [];
|
|
}
|
|
|
|
// 初始化加载城市列表
|
|
Future<void> _initialize() async {
|
|
if (_initialized) return;
|
|
_initialized = true;
|
|
await _loadCities();
|
|
}
|
|
|
|
// 加载保存的城市列表
|
|
Future<void> _loadCities() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final citiesJson = prefs.getStringList(_citiesKey);
|
|
|
|
if (citiesJson != null && citiesJson.isNotEmpty) {
|
|
final cities = citiesJson
|
|
.map((json) => CityModel.fromJson(jsonDecode(json)))
|
|
.toList();
|
|
state = cities;
|
|
} else {
|
|
// 如果没有保存的城市,添加默认城市
|
|
final defaultCityModel = CityModel(
|
|
name: defaultCity.split(',').first.trim(),
|
|
query: defaultCity,
|
|
isDefault: true,
|
|
);
|
|
state = [defaultCityModel];
|
|
await _saveCities();
|
|
}
|
|
}
|
|
|
|
// 保存城市列表
|
|
Future<void> _saveCities() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final citiesJson = state.map((city) => jsonEncode(city.toJson())).toList();
|
|
await prefs.setStringList(_citiesKey, citiesJson);
|
|
}
|
|
|
|
// 添加城市
|
|
Future<bool> addCity(CityModel city) async {
|
|
// 检查是否已存在
|
|
if (state.any((c) => c.query.toLowerCase() == city.query.toLowerCase())) {
|
|
return false; // 城市已存在
|
|
}
|
|
|
|
// 如果这是第一个城市,设为默认
|
|
final newCity = state.isEmpty
|
|
? city.copyWith(isDefault: true)
|
|
: city.copyWith(isDefault: false);
|
|
|
|
state = [...state, newCity];
|
|
await _saveCities();
|
|
return true;
|
|
}
|
|
|
|
// 获取当前状态
|
|
List<CityModel> get currentState => state;
|
|
|
|
// 删除城市
|
|
Future<void> removeCity(String query) async {
|
|
if (state.length <= 1) {
|
|
return; // 至少保留一个城市
|
|
}
|
|
|
|
final cityToRemove = state.firstWhere((c) => c.query == query);
|
|
final wasDefault = cityToRemove.isDefault;
|
|
|
|
state = state.where((c) => c.query != query).toList();
|
|
|
|
// 如果删除的是默认城市,将第一个城市设为默认
|
|
if (wasDefault && state.isNotEmpty) {
|
|
state = [state.first.copyWith(isDefault: true), ...state.skip(1)];
|
|
await setCurrentCity(state.first.query);
|
|
}
|
|
|
|
await _saveCities();
|
|
}
|
|
|
|
// 设置当前城市
|
|
Future<void> setCurrentCity(String query) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_currentCityKey, query);
|
|
|
|
// 更新默认标记
|
|
state = state.map((city) {
|
|
return city.copyWith(isDefault: city.query == query);
|
|
}).toList();
|
|
await _saveCities();
|
|
}
|
|
|
|
// 获取当前城市
|
|
Future<String> getCurrentCity() async {
|
|
// 确保已初始化
|
|
if (!_initialized) {
|
|
await _initialize();
|
|
}
|
|
|
|
// 如果 state 为空,等待加载完成
|
|
if (state.isEmpty) {
|
|
await _loadCities();
|
|
}
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final currentCityQuery = prefs.getString(_currentCityKey);
|
|
|
|
if (currentCityQuery != null &&
|
|
state.any((c) => c.query == currentCityQuery)) {
|
|
return currentCityQuery;
|
|
}
|
|
|
|
// 如果没有当前城市或当前城市不在列表中,返回默认城市
|
|
if (state.isEmpty) {
|
|
// 如果仍然为空,返回默认城市查询字符串
|
|
return defaultCity;
|
|
}
|
|
|
|
final defaultCityModel = state.firstWhere(
|
|
(c) => c.isDefault,
|
|
orElse: () => state.first,
|
|
);
|
|
return defaultCityModel.query;
|
|
}
|
|
|
|
// 通过查询字符串查找城市
|
|
CityModel? findCityByQuery(String query) {
|
|
try {
|
|
return state.firstWhere(
|
|
(c) => c.query.toLowerCase() == query.toLowerCase(),
|
|
);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 当前城市 Provider
|
|
final currentCityProvider = FutureProvider<String>((ref) async {
|
|
final cityListNotifier = ref.read(cityListProvider.notifier);
|
|
return await cityListNotifier.getCurrentCity();
|
|
});
|
|
|
|
// 城市列表 Notifier 扩展方法
|
|
extension CityListNotifierExtension on CityListNotifier {
|
|
Future<void> addCityAsync(CityModel city) => addCity(city);
|
|
Future<void> removeCityAsync(String query) => removeCity(query);
|
|
Future<void> setCurrentCityAsync(String query) => setCurrentCity(query);
|
|
}
|