Skip to content

Commit 7fd3730

Browse files
committed
wip; store: Add global settings
Signed-off-by: Zixuan James Li <[email protected]>
1 parent ff1d926 commit 7fd3730

File tree

4 files changed

+88
-4
lines changed

4 files changed

+88
-4
lines changed

lib/model/store.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ abstract class GlobalStore extends ChangeNotifier {
5757
/// A cache of the [Accounts] table in the underlying data store.
5858
final Map<int, Account> _accounts;
5959

60+
/// A cache of the [GlobalSettingsData] singleton in the underlying data store.
61+
GlobalSettingsData? _globalSettings;
62+
6063
// TODO settings (those that are per-device rather than per-account)
6164
// TODO push token, and other data corresponding to GlobalSessionState
6265

@@ -223,6 +226,40 @@ abstract class GlobalStore extends ChangeNotifier {
223226
/// Remove an account from the underlying data store.
224227
Future<void> doRemoveAccount(int accountId);
225228

229+
GlobalSettingsData? get globalSettingsSync => _globalSettings;
230+
231+
/// Get global settings from the store.
232+
///
233+
/// Use the cache if already loaded.
234+
/// Otherwise, load it from the underlying store.
235+
///
236+
/// Consider checking [globalSettingsSync] before using this.
237+
Future<GlobalSettingsData> getGlobalSettings() async {
238+
if (globalSettingsSync != null) return globalSettingsSync!;
239+
return await loadGlobalSettings();
240+
}
241+
242+
/// Load global settings from the underlying data store, unconditionally.
243+
///
244+
/// This should only be called from [getGlobalSettings].
245+
Future<GlobalSettingsData> loadGlobalSettings();
246+
247+
/// Update the global settings in the store, return the new version.
248+
///
249+
/// The global settings must already exist in the store.
250+
Future<GlobalSettingsData> updateGlobalSettings(GlobalSettingsCompanion data) async {
251+
assert(_globalSettings != null);
252+
await doUpdateGlobalSettings(data);
253+
_globalSettings = _globalSettings!.copyWithCompanion(data);
254+
notifyListeners();
255+
return _globalSettings!;
256+
}
257+
258+
/// Update the global settings in the underlying data store.
259+
///
260+
/// This should only be called from [updateGlobalSettings].
261+
Future<void> doUpdateGlobalSettings(GlobalSettingsCompanion data);
262+
226263
@override
227264
String toString() => '${objectRuntimeType(this, 'GlobalStore')}#${shortHash(this)}';
228265
}
@@ -835,6 +872,18 @@ class LiveGlobalStore extends GlobalStore {
835872
assert(rowsAffected == 1);
836873
}
837874

875+
@override
876+
Future<GlobalSettingsData> loadGlobalSettings() async {
877+
_globalSettings = await _db.ensureGlobalSettings();
878+
return _globalSettings!;
879+
}
880+
881+
@override
882+
Future<void> doUpdateGlobalSettings(GlobalSettingsCompanion data) async {
883+
final rowsAffected = await _db.update(_db.globalSettings).write(data);
884+
assert(rowsAffected == 1);
885+
}
886+
838887
@override
839888
String toString() => '${objectRuntimeType(this, 'LiveGlobalStore')}#${shortHash(this)}';
840889
}

lib/widgets/content.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import '../generated/l10n/zulip_localizations.dart';
1414
import '../model/avatar_url.dart';
1515
import '../model/binding.dart';
1616
import '../model/content.dart';
17+
import '../model/database.dart';
1718
import '../model/internal_link.dart';
1819
import 'code_block.dart';
1920
import 'dialog.dart';
@@ -1342,17 +1343,20 @@ void _launchUrl(BuildContext context, String urlString) async {
13421343
return;
13431344
}
13441345

1346+
final globalSettings = GlobalStoreWidget.of(context).globalSettingsSync;
13451347
bool launched = false;
13461348
String? errorMessage;
13471349
try {
13481350
launched = await ZulipBinding.instance.launchUrl(url,
1349-
mode: switch (defaultTargetPlatform) {
1351+
mode: switch ((globalSettings!.browserPreference, defaultTargetPlatform)) {
1352+
(BrowserPreference.embedded, _) => UrlLaunchMode.inAppBrowserView,
1353+
(BrowserPreference.external, _) => UrlLaunchMode.externalApplication,
13501354
// On iOS we prefer LaunchMode.externalApplication because (for
13511355
// HTTP URLs) LaunchMode.platformDefault uses SFSafariViewController,
13521356
// which gives an awkward UX as described here:
13531357
// https://chat.zulip.org/#narrow/stream/48-mobile/topic/in-app.20browser/near/1169118
1354-
TargetPlatform.iOS => UrlLaunchMode.externalApplication,
1355-
_ => UrlLaunchMode.platformDefault,
1358+
(BrowserPreference.none, TargetPlatform.iOS) => UrlLaunchMode.externalApplication,
1359+
(BrowserPreference.none, _) => UrlLaunchMode.platformDefault,
13561360
});
13571361
} on PlatformException catch (e) {
13581362
errorMessage = e.message;

lib/widgets/theme.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import 'package:flutter/material.dart';
22

33
import '../api/model/model.dart';
4+
import '../model/database.dart';
45
import 'content.dart';
56
import 'emoji_reaction.dart';
67
import 'message_list.dart';
78
import 'channel_colors.dart';
9+
import 'store.dart';
810
import 'text.dart';
911

1012
ThemeData zulipThemeData(BuildContext context) {
1113
final DesignVariables designVariables;
1214
final List<ThemeExtension> themeExtensions;
13-
Brightness brightness = MediaQuery.platformBrightnessOf(context);
15+
final globalSettings = GlobalStoreWidget.of(context).globalSettingsSync;
16+
Brightness brightness;
17+
switch (globalSettings!.themeSetting) {
18+
case ThemeSetting.none:
19+
brightness = MediaQuery.platformBrightnessOf(context);
20+
case ThemeSetting.light:
21+
brightness = Brightness.light;
22+
case ThemeSetting.dark:
23+
brightness = Brightness.dark;
24+
}
1425

1526
// This applies Material 3's color system to produce a palette of
1627
// appropriately matching and contrasting colors for use in a UI.

test/model/test_store.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:zulip/api/model/events.dart';
22
import 'package:zulip/api/model/initial_snapshot.dart';
33
import 'package:zulip/api/model/model.dart';
4+
import 'package:zulip/model/database.dart';
45
import 'package:zulip/model/store.dart';
56
import 'package:zulip/widgets/store.dart';
67

@@ -157,6 +158,25 @@ class TestGlobalStore extends GlobalStore {
157158
store: store, initialSnapshot: initialSnapshot);
158159
return Future.value(store);
159160
}
161+
162+
GlobalSettingsData? _globalSettings;
163+
164+
@override
165+
Future<GlobalSettingsData> loadGlobalSettings() async {
166+
if (_globalSettings != null) {
167+
return _globalSettings!;
168+
}
169+
_globalSettings = const GlobalSettingsData(
170+
themeSetting: ThemeSetting.none,
171+
browserPreference: BrowserPreference.none,
172+
);
173+
return Future.value(_globalSettings);
174+
}
175+
176+
@override
177+
Future<void> doUpdateGlobalSettings(GlobalSettingsCompanion data) async {
178+
_globalSettings = _globalSettings!.copyWithCompanion(data);
179+
}
160180
}
161181

162182
extension PerAccountStoreTestExtension on PerAccountStore {

0 commit comments

Comments
 (0)