import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; class M3uSourcesState { final List sources; final String? defaultUrl; M3uSourcesState({required this.sources, this.defaultUrl}); M3uSourcesState copyWith({List? sources, String? defaultUrl}) => M3uSourcesState( sources: sources ?? this.sources, defaultUrl: defaultUrl ?? this.defaultUrl, ); } class M3uSourcesNotifier extends StateNotifier { static const _kSourcesKey = 'm3u_sources'; static const _kDefaultKey = 'm3u_default'; M3uSourcesNotifier() : super(M3uSourcesState(sources: [], defaultUrl: null)); Future load() async { final sp = await SharedPreferences.getInstance(); final list = sp.getStringList(_kSourcesKey) ?? []; final def = sp.getString(_kDefaultKey); state = state.copyWith(sources: list, defaultUrl: def); } Future add(String url) async { final u = url.trim(); if (u.isEmpty) return; if (state.sources.contains(u)) return; final updated = [...state.sources, u]; state = state.copyWith(sources: updated); final sp = await SharedPreferences.getInstance(); await sp.setStringList(_kSourcesKey, updated); } Future remove(String url) async { final updated = state.sources.where((s) => s != url).toList(); String? def = state.defaultUrl; if (def == url) def = null; state = state.copyWith(sources: updated, defaultUrl: def); final sp = await SharedPreferences.getInstance(); await sp.setStringList(_kSourcesKey, updated); if (def == null) await sp.remove(_kDefaultKey); else await sp.setString(_kDefaultKey, def); } Future setDefault(String? url) async { state = state.copyWith(defaultUrl: url); final sp = await SharedPreferences.getInstance(); if (url == null) await sp.remove(_kDefaultKey); else await sp.setString(_kDefaultKey, url); } } final m3uSourcesProvider = StateNotifierProvider((ref) { return M3uSourcesNotifier(); });