import 'dart:async'; import 'dart:convert'; import 'package:fl_clash/common/boot_record.dart'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/common/system_dns.dart'; import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/models/models.dart'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; class Preferences { static Preferences? _instance; var _store = ResolveOnce(_open); Future get isInit async => await _store.value != null; Preferences._internal(); static Future _open() async { try { return await SharedPreferences.getInstance(); } catch (_) { return null; } } @visibleForTesting Future rebind() async { _store = ResolveOnce(_open); await _store.value; } factory Preferences() { _instance ??= Preferences._internal(); return _instance!; } Future getVersion() async { final preferences = await _store.value; return preferences?.getInt('version') ?? 0; } Future setVersion(int version) async { final preferences = await _store.value; await preferences?.setInt('version', version); } Future saveShareState(SharedState shareState) async { final preferences = await _store.value; await preferences?.setString('sharedState', json.encode(shareState)); } Future?> getConfigMap() async { try { final preferences = await _store.value; final configString = preferences?.getString(configKey); if (configString == null) return null; final Map? configMap = json.decode(configString); return configMap; } catch (e) { commonPrint.log( 'getConfigMap error ${e.toString()}', logLevel: LogLevel.warning, ); return null; } } Future?> getClashConfigMap() async { try { final preferences = await _store.value; final clashConfigString = preferences?.getString(clashConfigKey); if (clashConfigString == null) return null; return json.decode(clashConfigString); } catch (e) { commonPrint.log( 'getClashConfigMap error ${e.toString()}', logLevel: LogLevel.warning, ); return null; } } Future clearClashConfig() async { try { final preferences = await _store.value; await preferences?.remove(clashConfigKey); return; } catch (e) { commonPrint.log( 'clearClashConfig error ${e.toString()}', logLevel: LogLevel.warning, ); return; } } Future getConfig() async { final configMap = await getConfigMap(); if (configMap == null) { return null; } return Config.fromJson(configMap); } Future saveConfig(Config config) async { final preferences = await _store.value; return preferences?.setString(configKey, json.encode(config)) ?? false; } Future getSystemDnsRecord() async { try { final sharedPreferencesIns = await _store.value; final raw = sharedPreferencesIns?.getString(systemDnsRecordKey); if (raw == null) { return null; } return SystemDnsRecord.fromJson(json.decode(raw)); } catch (e) { commonPrint.log( 'getSystemDnsRecord error ${e.toString()}', logLevel: LogLevel.warning, ); return null; } } Future saveSystemDnsRecord(SystemDnsRecord record) async { final sharedPreferencesIns = await _store.value; await sharedPreferencesIns?.setString( systemDnsRecordKey, json.encode(record), ); } Future clearSystemDnsRecord() async { final sharedPreferencesIns = await _store.value; await sharedPreferencesIns?.remove(systemDnsRecordKey); } Future getBootRecord() async { try { final sharedPreferencesIns = await _store.value; final raw = sharedPreferencesIns?.getString(bootRecordKey); if (raw == null) { return null; } return BootRecord.fromJson(json.decode(raw)); } catch (e) { commonPrint.log( 'getBootRecord error ${e.toString()}', logLevel: LogLevel.warning, ); return null; } } Future saveBootRecord(BootRecord record) async { final sharedPreferencesIns = await _store.value; await sharedPreferencesIns?.setString(bootRecordKey, json.encode(record)); } Future clearPreferences() async { final sharedPreferencesIns = await _store.value; await sharedPreferencesIns?.clear(); } } final preferences = Preferences();