diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 6ab7c04d..82c1fde7 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -1,14 +1,17 @@ import 'dart:ui'; +import 'package:dbus/dbus.dart'; import 'package:gsettings/gsettings.dart'; class SettingsService { final _settings = {}; Settings? lookup(String schemaId, {String? path}) { - return _settings[schemaId] ??= GSettingsSchema.lookup(schemaId) != null - ? Settings(schemaId, path: path) - : null; + try { + return _settings[schemaId] ??= Settings(schemaId, path: path); + } on GSettingsSchemaNotInstalledException catch (_) { + return null; + } } void dispose() { @@ -20,9 +23,16 @@ class SettingsService { class Settings { Settings(String schemaId, {String? path}) - : _settings = GSettings(schemaId: schemaId, path: path); + : _settings = GSettings(schemaId, path: path) { + _settings.keysChanged.listen((keys) { + for (final key in keys) { + _updateValue(key); + } + }); + } final GSettings _settings; + final _values = {}; final _listeners = {}; void addListener(VoidCallback listener) => _listeners.add(listener); @@ -33,7 +43,7 @@ class Settings { } } - void dispose() => _settings.dispose(); + void dispose() => _settings.close(); bool? boolValue(String key) => getValue(key); int? intValue(String key) => getValue(key); @@ -42,9 +52,44 @@ class Settings { Iterable? stringArrayValue(String key) => getValue(key)?.cast(); - T? getValue(String key) => _settings.value(key) as T?; - void setValue(String key, Object value) => _settings.setValue(key, value); - void resetValue(String key) => _settings.resetValue(key); + T? getValue(String key) => _values[key] ?? _updateValue(key); + + T? _updateValue(String key) { + try { + _settings.get(key).then((v) { + final value = v.toNative() as T?; + if (_values[key] != value) { + _values[key] = value; + notifyListeners(); + } + }); + } on GSettingsUnknownKeyException catch (_) {} + } + + Future setValue(String key, T value) async { + if (_values[key] == key) { + return; + } + _values[key] = value; + switch (T) { + case bool: + return _settings.set(key, DBusBoolean(value as bool)); + case int: + return _settings.set(key, DBusInt32(value as int)); + case double: + return _settings.set(key, DBusDouble(value as double)); + case String: + return _settings.set(key, DBusString(value as String)); + default: + break; + } + if (value is List) { + return _settings.set(key, DBusArray.string(value)); + } + throw UnsupportedError('Unsupported type: $T'); + } - void sync() => _settings.sync(); + Future resetValue(String key) { + return _settings.setAll({key: null}); + } } diff --git a/lib/view/app_theme.dart b/lib/view/app_theme.dart index 260d3c6f..f3ececde 100644 --- a/lib/view/app_theme.dart +++ b/lib/view/app_theme.dart @@ -17,7 +17,6 @@ class AppTheme extends ValueNotifier { _settings.setValue('gtk-theme', 'Yaru'); break; } - _settings.sync(); } @override diff --git a/pubspec.yaml b/pubspec.yaml index 968ef5a1..030b3bbd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: path: package flutter: sdk: flutter - gsettings: ^0.1.2+1 + gsettings: ^0.2.3 linux_system_info: ^0.0.7 mime: ^1.0.0 bluez: ^0.7.4 diff --git a/test/widgets/app_theme_test.dart b/test/widgets/app_theme_test.dart index 0d188edb..a38a61c4 100644 --- a/test/widgets/app_theme_test.dart +++ b/test/widgets/app_theme_test.dart @@ -15,7 +15,7 @@ void main() { AppTheme theme = AppTheme(settings); when(settings.setValue('gtk-theme', 'Yaru-dark')).thenAnswer( - (realInvocation) => true, + (realInvocation) async {}, ); theme.apply(Brightness.dark); @@ -30,7 +30,7 @@ void main() { AppTheme theme = AppTheme(settings); when(settings.setValue('gtk-theme', 'Yaru')).thenAnswer( - (realInvocation) => true, + (realInvocation) async {}, ); theme.apply(Brightness.light); diff --git a/test/widgets/app_theme_test.mocks.dart b/test/widgets/app_theme_test.mocks.dart index 86e278e0..3ba90844 100644 --- a/test/widgets/app_theme_test.mocks.dart +++ b/test/widgets/app_theme_test.mocks.dart @@ -2,6 +2,7 @@ // in settings/test/widgets/app_theme_test.dart. // Do not manually edit this file. +import 'dart:async' as _i4; import 'dart:ui' as _i3; import 'package:mockito/mockito.dart' as _i1; @@ -59,16 +60,15 @@ class MockSettings extends _i1.Mock implements _i2.Settings { T? getValue(String? key) => (super.noSuchMethod(Invocation.method(#getValue, [key])) as T?); @override - void setValue(String? key, Object? value) => - super.noSuchMethod(Invocation.method(#setValue, [key, value]), - returnValueForMissingStub: null); - @override - void resetValue(String? key) => - super.noSuchMethod(Invocation.method(#resetValue, [key]), - returnValueForMissingStub: null); + _i4.Future setValue(String? key, T? value) => + (super.noSuchMethod(Invocation.method(#setValue, [key, value]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); @override - void sync() => super.noSuchMethod(Invocation.method(#sync, []), - returnValueForMissingStub: null); + _i4.Future resetValue(String? key) => + (super.noSuchMethod(Invocation.method(#resetValue, [key]), + returnValue: Future.value(), + returnValueForMissingStub: Future.value()) as _i4.Future); @override String toString() => super.toString(); }