Skip to content

Commit 6483514

Browse files
committed
settings [nfc]: Have settingsOf return whole store, not just data
To save code that consults the settings from an extra indirection ".data", we equip GlobalSettingsStore with getters for all the fields of the data class. This also makes the store now the natural home for the additional members that had been in an extension on the data class.
1 parent 1614322 commit 6483514

File tree

5 files changed

+43
-31
lines changed

5 files changed

+43
-31
lines changed

lib/model/settings.dart

+20-13
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,26 @@ enum BrowserPreference {
4444
external,
4545
}
4646

47-
extension GlobalSettingsHelpers on GlobalSettingsData {
47+
/// Store for the user's account-independent settings.
48+
///
49+
/// From UI code, use [GlobalStoreWidget.settingsOf] to get hold of
50+
/// an appropriate instance of this class.
51+
class GlobalSettingsStore extends ChangeNotifier {
52+
GlobalSettingsStore({required GlobalSettingsData data}) : _data = data;
53+
54+
/// A cache of the [GlobalSettingsData] singleton in the underlying data store.
55+
GlobalSettingsData _data;
56+
57+
/// The user's choice of [ThemeSetting];
58+
/// null means the device-level choice of theme.
59+
ThemeSetting? get themeSetting => _data.themeSetting;
60+
61+
/// The user's choice of [BrowserPreference];
62+
/// null means use our default choice.
63+
///
64+
/// Consider using [effectiveBrowserPreference] or [getUrlLaunchMode].
65+
BrowserPreference? get browserPreference => _data.browserPreference;
66+
4867
/// The value of [BrowserPreference] to use:
4968
/// the user's choice [browserPreference] if any, else our default.
5069
///
@@ -84,18 +103,6 @@ extension GlobalSettingsHelpers on GlobalSettingsData {
84103
return UrlLaunchMode.externalApplication;
85104
}
86105
}
87-
}
88-
89-
/// Store for the user's account-independent settings.
90-
///
91-
/// From UI code, use [GlobalStoreWidget.settingsOf] to get hold of
92-
/// the settings data.
93-
class GlobalSettingsStore extends ChangeNotifier {
94-
GlobalSettingsStore({required GlobalSettingsData data}) : _data = data;
95-
96-
/// A cache of the [GlobalSettingsData] singleton in the underlying data store.
97-
GlobalSettingsData get data => _data;
98-
GlobalSettingsData _data;
99106

100107
/// (Should only be called by [GlobalStore].)
101108
void update(GlobalSettingsCompanion data) {

lib/model/store.dart

+6-5
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ abstract class GlobalStore extends ChangeNotifier {
6363

6464
final GlobalSettingsStore settingsNotifier; // TODO rename as the store
6565

66-
/// A cache of the [GlobalSettingsData] singleton in the underlying data store.
66+
/// The store for the user's account-independent settings.
6767
///
68-
/// To be notified for changes to this value, subscribe to [settingsNotifier]
69-
/// (usually by calling [GlobalStoreWidget.settingsOf]).
70-
/// The [GlobalStore] itself will not notify its own listeners.
71-
GlobalSettingsData get globalSettings => settingsNotifier.data;
68+
/// When the settings data changes, the [GlobalSettingsStore] will notify
69+
/// its listeners, but the [GlobalStore] will not notify its own listeners.
70+
/// Consider using [GlobalStoreWidget.settingsOf], which automatically
71+
/// subscribes to changes in the [GlobalSettingsStore].
72+
GlobalSettingsStore get globalSettings => settingsNotifier;
7273

7374
/// Update the global settings in the store.
7475
Future<void> updateGlobalSettings(GlobalSettingsCompanion data) async {

lib/widgets/content.dart

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import '../model/avatar_url.dart';
1515
import '../model/binding.dart';
1616
import '../model/content.dart';
1717
import '../model/internal_link.dart';
18-
import '../model/settings.dart';
1918
import 'code_block.dart';
2019
import 'dialog.dart';
2120
import 'icons.dart';

lib/widgets/store.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ class GlobalStoreWidget extends StatefulWidget {
5353
return widget!.store;
5454
}
5555

56-
/// The user's [GlobalSettings] data, from the app's global data store.
56+
/// The user's [GlobalSettings] data within the app's global data store.
5757
///
5858
/// The given build context will be registered as a dependency and
59-
/// subscribed to changes in the [GlobalSettingsStore].
59+
/// subscribed to changes in the returned [GlobalSettingsStore].
6060
/// This means that when the setting values in the store change,
6161
/// the element at that build context will be rebuilt.
6262
///
@@ -69,10 +69,10 @@ class GlobalStoreWidget extends StatefulWidget {
6969
/// ```
7070
///
7171
/// See [of] for further discussion of how to use this kind of method.
72-
static GlobalSettingsData settingsOf(BuildContext context) {
72+
static GlobalSettingsStore settingsOf(BuildContext context) {
7373
final widget = context.dependOnInheritedWidgetOfExactType<_GlobalSettingsStoreInheritedWidget>();
7474
assert(widget != null, 'No GlobalStoreWidget ancestor');
75-
return widget!.store.data;
75+
return widget!.store;
7676
}
7777

7878
@override

test/model/store_checks.dart

+13-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import 'package:zulip/model/settings.dart';
1010
import 'package:zulip/model/store.dart';
1111
import 'package:zulip/model/unreads.dart';
1212

13+
extension GlobalSettingsDataChecks on Subject<GlobalSettingsData> {
14+
Subject<ThemeSetting?> get themeSetting => has((x) => x.themeSetting, 'themeSetting');
15+
Subject<BrowserPreference?> get browserPreference => has((x) => x.browserPreference, 'browserPreference');
16+
}
17+
1318
extension AccountChecks on Subject<Account> {
1419
Subject<int> get id => has((x) => x.id, 'id');
1520
Subject<Uri> get realmUrl => has((x) => x.realmUrl, 'realmUrl');
@@ -22,21 +27,21 @@ extension AccountChecks on Subject<Account> {
2227
Subject<String?> get ackedPushToken => has((x) => x.ackedPushToken, 'ackedPushToken');
2328
}
2429

30+
extension GlobalSettingsStoreChecks on Subject<GlobalSettingsStore> {
31+
Subject<ThemeSetting?> get themeSetting => has((x) => x.themeSetting, 'themeSetting');
32+
Subject<BrowserPreference?> get browserPreference => has((x) => x.browserPreference, 'browserPreference');
33+
Subject<BrowserPreference> get effectiveBrowserPreference => has((x) => x.effectiveBrowserPreference, 'effectiveBrowserPreference');
34+
Subject<UrlLaunchMode> getUrlLaunchMode(Uri url) => has((x) => x.getUrlLaunchMode(url), 'getUrlLaunchMode');
35+
}
36+
2537
extension GlobalStoreChecks on Subject<GlobalStore> {
26-
Subject<GlobalSettingsData> get globalSettings => has((x) => x.globalSettings, 'globalSettings');
38+
Subject<GlobalSettingsStore> get globalSettings => has((x) => x.globalSettings, 'globalSettings');
2739
Subject<Iterable<Account>> get accounts => has((x) => x.accounts, 'accounts');
2840
Subject<Iterable<int>> get accountIds => has((x) => x.accountIds, 'accountIds');
2941
Subject<Iterable<({ int accountId, Account account })>> get accountEntries => has((x) => x.accountEntries, 'accountEntries');
3042
Subject<Account?> getAccount(int id) => has((x) => x.getAccount(id), 'getAccount($id)');
3143
}
3244

33-
extension GlobalSettingsDataChecks on Subject<GlobalSettingsData> {
34-
Subject<ThemeSetting?> get themeSetting => has((x) => x.themeSetting, 'themeSetting');
35-
Subject<BrowserPreference?> get browserPreference => has((x) => x.browserPreference, 'browserPreference');
36-
Subject<BrowserPreference> get effectiveBrowserPreference => has((x) => x.effectiveBrowserPreference, 'effectiveBrowserPreference');
37-
Subject<UrlLaunchMode> getUrlLaunchMode(Uri url) => has((x) => x.getUrlLaunchMode(url), 'getUrlLaunchMode');
38-
}
39-
4045
extension PerAccountStoreChecks on Subject<PerAccountStore> {
4146
Subject<ApiConnection> get connection => has((x) => x.connection, 'connection');
4247
Subject<bool> get isLoading => has((x) => x.isLoading, 'isLoading');

0 commit comments

Comments
 (0)