mirror of
https://github.com/lifegpc/eh_downloader_flutter.git
synced 2026-07-08 01:30:28 +08:00
Save preferences to same directory to binary file on Windows
This commit is contained in:
11
lib/config/base.dart
Normal file
11
lib/config/base.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
abstract interface class Config {
|
||||
Future<bool> clear();
|
||||
bool containsKey(String key);
|
||||
Object? get(String key);
|
||||
String? getString(String key);
|
||||
Future<bool> setString(String key, String value);
|
||||
int? getInt(String key);
|
||||
Future<bool> setInt(String key, int value);
|
||||
bool? getBool(String key);
|
||||
Future<bool> setBool(String key, bool value);
|
||||
}
|
||||
43
lib/config/shared_preferences.dart
Normal file
43
lib/config/shared_preferences.dart
Normal file
@@ -0,0 +1,43 @@
|
||||
import 'base.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class SharedPreferencesConfig implements Config {
|
||||
SharedPreferencesConfig(this._prefs);
|
||||
final SharedPreferences _prefs;
|
||||
@override
|
||||
Future<bool> clear() {
|
||||
return _prefs.clear();
|
||||
}
|
||||
@override
|
||||
bool containsKey(String key) {
|
||||
return _prefs.containsKey(key);
|
||||
}
|
||||
@override
|
||||
Object? get(String key) {
|
||||
return _prefs.get(key);
|
||||
}
|
||||
@override
|
||||
String? getString(String key) {
|
||||
return _prefs.getString(key);
|
||||
}
|
||||
@override
|
||||
Future<bool> setString(String key, String value) {
|
||||
return _prefs.setString(key, value);
|
||||
}
|
||||
@override
|
||||
int? getInt(String key) {
|
||||
return _prefs.getInt(key);
|
||||
}
|
||||
@override
|
||||
Future<bool> setInt(String key, int value) {
|
||||
return _prefs.setInt(key, value);
|
||||
}
|
||||
@override
|
||||
bool? getBool(String key) {
|
||||
return _prefs.getBool(key);
|
||||
}
|
||||
@override
|
||||
Future<bool> setBool(String key, bool value) {
|
||||
return _prefs.setBool(key, value);
|
||||
}
|
||||
}
|
||||
108
lib/config/windows.dart
Normal file
108
lib/config/windows.dart
Normal file
@@ -0,0 +1,108 @@
|
||||
import 'dart:convert' show json;
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/local.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'base.dart';
|
||||
import '../globals.dart';
|
||||
|
||||
final _log = Logger("WindowsConfig");
|
||||
|
||||
class WindowsConfig implements Config {
|
||||
WindowsConfig();
|
||||
FileSystem fs = const LocalFileSystem();
|
||||
Map<String, Object>? _cachedPreferences;
|
||||
File? _filePath;
|
||||
Future<File?> filePath() async {
|
||||
if (_filePath != null) return _filePath;
|
||||
final String? exe = await platformPath.getCurrentExe();
|
||||
if (exe == null) return null;
|
||||
final dir = path.dirname(exe);
|
||||
final name = path.basenameWithoutExtension(exe);
|
||||
return _filePath = fs.file(path.join(dir, "$name.json"));
|
||||
}
|
||||
|
||||
Future<Map<String, Object>> reload() async {
|
||||
Map<String, Object> preferences = <String, Object>{};
|
||||
final File? localDataFile = await filePath();
|
||||
if (localDataFile != null && localDataFile.existsSync()) {
|
||||
final String stringMap = localDataFile.readAsStringSync();
|
||||
if (stringMap.isNotEmpty) {
|
||||
final Object? data = json.decode(stringMap);
|
||||
if (data is Map) {
|
||||
preferences = data.cast<String, Object>();
|
||||
}
|
||||
}
|
||||
}
|
||||
_cachedPreferences = preferences;
|
||||
return preferences;
|
||||
}
|
||||
|
||||
Future<Map<String, Object>> _readPreferences() async {
|
||||
return _cachedPreferences ?? await reload();
|
||||
}
|
||||
|
||||
Future<bool> _writePreferences(Map<String, Object> preferences) async {
|
||||
try {
|
||||
final File? localDataFile = await filePath();
|
||||
if (localDataFile == null) {
|
||||
_log.warning('Unable to determine where to write preferences.');
|
||||
return false;
|
||||
}
|
||||
if (!localDataFile.existsSync()) {
|
||||
localDataFile.createSync(recursive: true);
|
||||
}
|
||||
final String stringMap = json.encode(preferences);
|
||||
localDataFile.writeAsStringSync(stringMap);
|
||||
} catch (e) {
|
||||
_log.severe('Error saving preferences to disk: ', e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> clear() async {
|
||||
final Map<String, Object> preferences = await _readPreferences();
|
||||
preferences.clear();
|
||||
return _writePreferences(preferences);
|
||||
}
|
||||
|
||||
Future<bool> setValue(String key, Object value) async {
|
||||
final Map<String, Object> preferences = await _readPreferences();
|
||||
preferences[key] = value;
|
||||
return _writePreferences(preferences);
|
||||
}
|
||||
|
||||
@override
|
||||
bool containsKey(String key) {
|
||||
return _cachedPreferences?.containsKey(key) ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Object? get(String key) => _cachedPreferences?[key];
|
||||
|
||||
@override
|
||||
String? getString(String key) => _cachedPreferences?[key] as String?;
|
||||
|
||||
@override
|
||||
Future<bool> setString(String key, String value) {
|
||||
return setValue(key, value);
|
||||
}
|
||||
|
||||
@override
|
||||
int? getInt(String key) => _cachedPreferences?[key] as int?;
|
||||
|
||||
@override
|
||||
Future<bool> setInt(String key, int value) {
|
||||
return setValue(key, value);
|
||||
}
|
||||
|
||||
@override
|
||||
bool? getBool(String key) => _cachedPreferences?[key] as bool?;
|
||||
|
||||
@override
|
||||
Future<bool> setBool(String key, bool value) {
|
||||
return setValue(key, value);
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,18 @@ import 'package:path_provider/path_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'api/client.dart';
|
||||
import 'auth.dart';
|
||||
import 'config/base.dart';
|
||||
import 'config/shared_preferences.dart';
|
||||
import 'config/windows.dart';
|
||||
import 'platform/path.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
final dio = Dio()
|
||||
..options.validateStatus = (int? _) {
|
||||
return true;
|
||||
}
|
||||
..options.extra['withCredentials'] = true;
|
||||
SharedPreferences? _prefs;
|
||||
Config? _prefs;
|
||||
EHApi? _api;
|
||||
|
||||
Future<void> prepareJar() async {
|
||||
@@ -28,10 +33,20 @@ Future<void> prepareJar() async {
|
||||
}
|
||||
|
||||
Future<void> preparePrefs() async {
|
||||
_prefs = await SharedPreferences.getInstance();
|
||||
if (isWindows) {
|
||||
try {
|
||||
var tmp = WindowsConfig();
|
||||
tmp.reload();
|
||||
_prefs = tmp;
|
||||
return;
|
||||
} catch (e) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
_prefs = SharedPreferencesConfig(await SharedPreferences.getInstance());
|
||||
}
|
||||
|
||||
SharedPreferences get prefs {
|
||||
Config get prefs {
|
||||
if (_prefs == null) {
|
||||
throw Exception('SharedPreferences not initialized');
|
||||
}
|
||||
@@ -77,3 +92,4 @@ EHApi get api {
|
||||
}
|
||||
|
||||
final AuthInfo auth = AuthInfo();
|
||||
final Path platformPath = Path();
|
||||
|
||||
@@ -42,6 +42,7 @@ Future<void> initLogger() async {
|
||||
}
|
||||
|
||||
void main() async {
|
||||
if (!kIsWeb) WidgetsFlutterBinding.ensureInitialized();
|
||||
bool? usePathUrl = const bool.fromEnvironment("usePathUrl");
|
||||
if (usePathUrl == true && kIsWeb) {
|
||||
usePathUrlStrategy();
|
||||
@@ -49,7 +50,6 @@ void main() async {
|
||||
if (!kIsWeb) await prepareJar();
|
||||
await preparePrefs();
|
||||
if (isDesktop) {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await windowManager.ensureInitialized();
|
||||
}
|
||||
await initLogger();
|
||||
|
||||
28
lib/platform/path.dart
Normal file
28
lib/platform/path.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import '../utils.dart';
|
||||
|
||||
final Logger _log = Logger("platformPath");
|
||||
|
||||
class Path {
|
||||
static const platform = MethodChannel("lifegpc.eh_downloader_flutter/path");
|
||||
String? _currentExe;
|
||||
bool _currentExeLoaded = false;
|
||||
|
||||
String? get currentExe => _currentExe;
|
||||
|
||||
Future<String?> getCurrentExe() async {
|
||||
if (_currentExeLoaded) return _currentExe;
|
||||
try {
|
||||
final String result = await platform.invokeMethod("getCurrentExe");
|
||||
_currentExe = result;
|
||||
} on PlatformException catch (e) {
|
||||
if (isWindows) {
|
||||
_log.warning("Failed to get current exe path:", e);
|
||||
}
|
||||
}
|
||||
_currentExeLoaded = true;
|
||||
return _currentExe;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user