Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support some client settings; add settings page #1167

Merged
merged 7 commits into from
Mar 11, 2025
Merged

Conversation

PIG208
Copy link
Member

@PIG208 PIG208 commented Dec 17, 2024

Work towards #97.

Fixes #1216.

screenshots
non-default default

@PIG208 PIG208 force-pushed the pr-settings branch 3 times, most recently from 370a328 to e91e9d5 Compare December 17, 2024 00:28
@gnprice
Copy link
Member

gnprice commented Dec 17, 2024

Thanks for taking this on! Looking forward to it.

One first high-level comment: in the branch we merge, let's have at least one of these two settings get added as its own separate commit, complete with a migration. That way we have a nice demonstration of what it'll look like to add each new setting in the future.

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've skimmed now through more of this code. A few other high-level comments below.

Comment on lines 142 to 155
from2To3: (m, schema) async {
await m.createTable(schema.globalSettings);
},
from3To4: (m, schema) async {
await m.addColumn(
schema.globalSettings, schema.globalSettings.browserPreference);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db: Start generating step by step migration helper

https://drift.simonbinder.eu/migrations/step_by_step/#manual-generation

Hmm, interesting. Yeah, this seems useful — I think this migration to 4 is already an example where this structure lets the new migration get added as just a separate thing, and with the more manual structure we'd have to have logic for it to interact with the migration to 3.

import 'package:drift/drift.dart' as i1;
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import

// GENERATED BY drift_dev, DO NOT MODIFY.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give this a .g.dart name, so it's clear in a more uniform way that it's generated.

Comment on lines 7 to 10
# Generated code from drift can contain unused local variables.
- lib/model/database.g.dart
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reported as a bug in Drift — it's fine for the generated code to do this but then it should contain an ignore comment for it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed simolus3/drift#3384 for that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That issue has been marked as fixed! 🎉 So can we drop this commit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that there will be a release with this patch soon (last one was 2 weeks ago). If not we can just ask politely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a good time to ask Simon nicely about when he anticipates making the next release. It looks like he's not doing the thing where every bugfix prompts an immediate release.

If a release doesn't come out shortly, let's just have this branch upgrade our drift_dev to a version from Git, namely the commit that fixed this small bug.

Comment on lines 46 to 52
/// The visual theme of the app.
///
/// See [zulipThemeData] for how themes are determined.
///
/// Renaming existing enum values will invalidate the database.
/// Write a migration if such a change is necessary.
enum ThemeSetting {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put these enum definitions in a new file lib/model/settings.dart.

Then that can also be the home of other logic we add in the future for individual settings.

@PIG208 PIG208 changed the title wip; Store some client settings Support some client settings; add settings page Feb 21, 2025
@PIG208 PIG208 marked this pull request as ready for review February 21, 2025 00:32
@PIG208 PIG208 added the maintainer review PR ready for review by Zulip maintainers label Feb 21, 2025
@PIG208 PIG208 requested a review from chrisbobbe February 21, 2025 00:37
Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exciting!

One question: what UI text does zulip-mobile use for the browser setting? Would it make sense to copy that?

Comment on lines 7 to 10
# Generated code from drift can contain unused local variables.
- lib/model/database.g.dart
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That issue has been marked as fixed! 🎉 So can we drop this commit?

Comment on lines 485 to 525
.single.equals((url: Uri.parse(expectedLaunchUrl), mode: LaunchMode.platformDefault));
.single.equals((url: Uri.parse(expectedLaunchUrl), mode: LaunchMode.inAppBrowserView));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db: Store browser preference in database

I think these test changes are meant for a later commit:

content: Follow browser preference setting when opening links

(caught with git rebase --exec 'tools/check --diff @~')

@@ -76,7 +76,7 @@ abstract class ZulipBinding {
}

/// Get the app's singleton [GlobalStore],
/// calling [loadGlobalStore] if not already loaded.
/// loading it asynchronously if not already loaded.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

store [nfc]: Update outdated references to loadGlobalStore

commit-message nit: truncate commit ID to 9 characters

Comment on lines 224 to 226
// The context has to be taken from the [Builder] because
// [zulipThemeData] requires access to [GlobalStoreWidget] in the tree.
// TODO: any way to remove the [Builder], like how we pulled out
// [_handleGenerateInitialRoutes]?
theme: zulipThemeData(context),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could have GlobalStoreWidget take a buildChild param instead of child (or support passing one or the other 🤷‍♂️), and it would pass its own context to buildChild?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chose to name it builder to match Builder.builder and refactored places that use GlobalStoreWidget (one in lib and a handful in tests).

@@ -97,6 +100,27 @@ void main() {
check(() => a.lerp(b, 0.5)).returnsNormally();
});
});

testWidgets('follow globalSettings.themeSetting if not unset', (tester) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow globalSettings.themeSetting if not unset

I know what you mean by "if not unset", but it feels slightly unsatisfying: we do still want to follow globalSettings.themeSetting if it's unset 🙂, but the details are just a bit more complicated for that value.

I also see that this test exercises the "unset" value, but incompletely: with "unset", let's also test that the theme responds when the device setting is changed:

      tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
      await tester.pump();
      check(zulipThemeData(element)).brightness.equals(Brightness.dark);

of: find.text('Use external browser'),
matching: find.byType(SwitchListTile));

testWidgets('smoke', (tester) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also test that the switch is in the right place, and responds correctly, when the setting hasn't been set yet (the part meant by "effective" in effectiveBrowserPreference)

@chrisbobbe
Copy link
Collaborator

Oh, and we have an issue for the theme setting 🙂 so the PR description and relevant commit can be marked as fixing that:

@PIG208
Copy link
Member Author

PIG208 commented Feb 25, 2025

There is also one for browser:

I didn't fix them because they do not implement a final design. Perhaps we can have a new design issue for the settings page.

@chrisbobbe
Copy link
Collaborator

I didn't fix them because they do not implement a final design. Perhaps we can have a new design issue for the settings page.

Sure, that sounds good: a new issue for redesigning the settings page as a whole. Then the individual issues, #1216 and #1228, don't need to stay open to track that redesign, and they can be marked as fixed in this PR; what do you think?

@PIG208
Copy link
Member Author

PIG208 commented Feb 25, 2025

Opened #1375.

@PIG208
Copy link
Member Author

PIG208 commented Feb 26, 2025

Forgot to post a message here. This PR is ready for review.

what UI text does zulip-mobile use for the browser setting? Would it make sense to copy that?

Good point! The string is "Open links with in-app browser"; switched to that instead.

@chrisbobbe
Copy link
Collaborator

Thanks, LGTM! Marking for Greg's review.

@chrisbobbe chrisbobbe assigned gnprice and unassigned gnprice Mar 3, 2025
@chrisbobbe chrisbobbe requested a review from gnprice March 3, 2025 21:37
@PIG208 PIG208 force-pushed the pr-settings branch 2 times, most recently from 20349a1 to 15df1d9 Compare March 5, 2025 01:15
@PIG208
Copy link
Member Author

PIG208 commented Mar 5, 2025

Still need to make some updates the browser settings changes. Will push again once I'm done.

@PIG208
Copy link
Member Author

PIG208 commented Mar 5, 2025

Updated the PR. This should be ready for review again!

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revision! Here's comments on the same prefix as before, 6 commits:
6230f5d do not merge; disable checks
f28eeda db: Store GlobalSettings in database
e6f9809 store [nfc]: Update outdated references to loadGlobalStore
3ef3507 test [nfc]: Use eg.globalStore when possible
9897cff store: Store global settings on global store
c54b92a theme: Track theme through global settings

All small, so I'll also take a look next at the subsequent commits.

/// These apply across all the user's accounts on this client (i.e. on this
/// install of the app on this device).
@DataClassName('GlobalSettingsData')
class GlobalSettings extends Table {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: order the class definitions matching #1167 (comment)

Comment on lines 216 to 218
child: Builder(
builder: (context) {
return MaterialApp(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: keep a bit more compact (and less indented):

Suggested change
child: Builder(
builder: (context) {
return MaterialApp(
child: Builder(builder: (context) {
return MaterialApp(

import 'binding.dart';
import 'database.dart';

/// The user's choice of visual theme for the app
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: summary line of dartdoc gets a period:

Suggested change
/// The user's choice of visual theme for the app
/// The user's choice of visual theme for the app.

@@ -47,3 +51,9 @@ extension PerAccountStoreChecks on Subject<PerAccountStore> {
Subject<RecentDmConversationsView> get recentDmConversationsView => has((x) => x.recentDmConversationsView, 'recentDmConversationsView');
Subject<AutocompleteViewManager> get autocompleteViewManager => has((x) => x.autocompleteViewManager, 'autocompleteViewManager');
}

extension GlobalSettingsDataChecks on Subject<GlobalSettingsData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: keep in logical order, matching the corresponding code

GlobalSettingsData get globalSettings => _globalSettings;
GlobalSettingsData _globalSettings;

/// Update the global settings in the store, return the new version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the syntax in the existing updateAccount doc is correct:

Suggested change
/// Update the global settings in the store, return the new version.
/// Update the global settings in the store, returning the new version.

Other examples would include "do A, resulting in B" or "do A, arriving at B".

@@ -24,6 +26,7 @@ extension GlobalStoreChecks on Subject<GlobalStore> {
Subject<Iterable<int>> get accountIds => has((x) => x.accountIds, 'accountIds');
Subject<Iterable<({ int accountId, Account account })>> get accountEntries => has((x) => x.accountEntries, 'accountEntries');
Subject<Account?> getAccount(int id) => has((x) => x.getAccount(id), 'getAccount($id)');
Subject<GlobalSettingsData> get globalSettings => has((x) => x.globalSettings, 'globalSettings');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: match order of the underlying properties

TestGlobalStore({required super.globalSettings, required super.accounts})
: _globalSettings = globalSettings;

GlobalSettingsData? _globalSettings;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GlobalSettingsData? _globalSettings;
GlobalSettingsData _globalSettings;

right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm or: what if we just leave this field out? Seems like the base class takes care of it.

And in the case of accounts we don't find we need a corresponding field here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It should be very similar to doUpdateAccount:

  @override
  Future<void> doUpdateAccount(int accountId, AccountsCompanion data) async {
    // Nothing to do.
  }

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, and here's comments from reading the next two commits:
91992c2 settings: Add settings page with vanilla Flutter widgets
2421036 db: Store browser preference in database

Comment on lines 24 to 26
switch (themeSetting) {
case null:
return zulipLocalizations.themeSettingSystem;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use switch-expression

@@ -74,6 +74,18 @@ extension ValueListenableChecks<T> on Subject<ValueListenable<T>> {
Subject<T> get value => has((c) => c.value, 'value');
}

extension ThemeDataChecks on Subject<ThemeData> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for logical ordering, put these Material-specific items down among the other Material-specific items near the end of the file

/// Update the global settings in the store, return the new version.
///
/// The global settings must already exist in the store.
Future<GlobalSettingsData> updateGlobalSettings(GlobalSettingsCompanion data) async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should get a couple of tests. See the GlobalStore.updateAccount tests for examples.


final after = v4.DatabaseAtV4(schema.newConnection());
final globalSettings = await after.select(after.globalSettings).getSingle();
check(globalSettings.themeSetting).equals(ThemeSetting.light.name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
check(globalSettings.themeSetting).equals(ThemeSetting.light.name);
check(globalSettings).themeSetting.equals(ThemeSetting.light.name);

(then cascade as usual)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… Oh I see, the type here is v4.GlobalSettingsData, not something more widely shared. OK, no need to have a checks-extension for it.

Comment on lines 11 to 12
import 'schemas/schema_v2.dart' as v2;
import 'store_checks.dart';
import 'schemas/schema_v3.dart' as v3;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: keep sorted

Comment on lines 27 to 26
const _BrowserPreferenceSetting(),
const _ThemeSetting(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like theme should come first — it's going to be a much more popular setting to consider.

@PIG208
Copy link
Member Author

PIG208 commented Mar 10, 2025

Updated the PR. This should be ready now.

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've now read the whole thing; comments below.

@@ -133,7 +384,6 @@ class $AccountsTable extends Accounts with TableInfo<$AccountsTable, Account> {
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
context.handle(_realmUrlMeta, const VerificationResult.success());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: generated code should update in tandem with the deps upgrade that causes it

check(notifyCount).equals(1);
});

// TOOD integration tests with sqlite
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
// TOOD integration tests with sqlite
// TODO integration tests with sqlite

Comment on lines 45 to 46
check(globalStore).globalSettings.browserPreference.equals(
BrowserPreference.external);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to test each setting as we add it; at that point we'd just be testing the generated code from Drift.

UrlLaunchMode get urlLaunchMode {
if (browserPreference != null) {
return switch (browserPreference!) {
BrowserPreference.embedded => UrlLaunchMode.platformDefault,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line doesn't look right, does it. 🙂 If the user has explicitly chosen in-app, let's make it in-app even if that isn't the default on a given platform.

(I think you may have asked me about this the other day, but if I said to keep this I was probably thinking of the spot a few lines below where we're defining our own defaults.)

Or is there a reason why that translation doesn't work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Android and iOS, platformDefault for HTTP URLs is already in-app browser view; I remember that we decided to keep platformDefault because that setting, "open links with in-app browser", applies to those links to the end-user as expected, but does not make sense for other types of links like mailto.

Testing this, it looks like attempting to open mailto links in-app results in an error:

E/flutter (14030): [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Invalid argument (url): To use an in-app web view, you must provide an http(s) URL.: Instance of '_SimpleUri'
E/flutter (14030): #0      launchUrl (package:url_launcher/src/url_launcher_uri.dart:49:5)
E/flutter (14030): #1      LiveZulipBinding.launchUrl (package:zulip/model/binding.dart:355:25)
E/flutter (14030): #2      _launchUrl (package:zulip/widgets/content.dart:1446:44)

The comment on the rationale of this is in the build method of the widget that controls this setting, but you bringing it up makes me feel that it probably fits better in the dartdoc of this extension method.

Copy link
Member Author

@PIG208 PIG208 Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or perhaps better, in the dartdoc for the embedded (or inApp) enum.

Comment on lines 810 to 812
check(testBinding.takeLaunchUrlCalls())
.single.equals((
url: Uri.parse('https://example/'), mode: LaunchMode.platformDefault));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: .single compacts nicely onto previous line:

Suggested change
check(testBinding.takeLaunchUrlCalls())
.single.equals((
url: Uri.parse('https://example/'), mode: LaunchMode.platformDefault));
check(testBinding.takeLaunchUrlCalls()).single.equals((
url: Uri.parse('https://example/'), mode: LaunchMode.platformDefault));

Comment on lines 40 to 41
/// Use the in-app browser.
embedded,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

Suggested change
/// Use the in-app browser.
embedded,
/// Use the in-app browser.
inApp,

Seems like that would best align the name with how we're calling it in other code and in the UI.

import 'page.dart';
import 'store.dart';

class SettingsPage extends StatelessWidget {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not aim to fully implement the wip design for the settings
page.  We offer it mainly to test settings, so the implementation is
kept as simple as possible.

WIP design:
  https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=446-21372&t=BZKpTQPSiBDNxwvB-0

Let's replace "WIP design" with more of a complete sentence — it keeps catching my eye as if the "WIP" is a marker about the state of this commit itself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, this is helpful:

This does not aim to fully implement the wip design for the settings
page.  We offer it mainly to test settings, so the implementation is
kept as simple as possible.

Old design for reference:
  https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=446-21372&t=BZKpTQPSiBDNxwvB-0

Let's make a couple of adjustments: s/wip design/draft design/, s/Old design/Draft design (old)/. That way (a) it more fully avoids that "wip" keyword 🙂, (b) it's a bit clearer that the two references are to the same design.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and a separate nit on the commit message:

settings: Add settings page with vanilla Flutter widgets

I'd read "vanilla Flutter widgets" first of all to mean package:flutter/widgets.dart, aka "the widgets library", in contrast to the Material or Cupertino libraries. Here what we actually mean is we're using Flutter's Material widgets, specifically the adaptive flavor of them.

So let's say:

settings: Add easy settings page using (adaptive) Material widgets

This will use generic Material-style controls on Android, and
generic iOS-style controls on iOS.

(and then the other information).

@PIG208
Copy link
Member Author

PIG208 commented Mar 11, 2025

This should be ready for review. Made some follow-up comments to #1167 (comment).

Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the revision!

The first 7/10 commits, up through the settings UI, are virtually ready to merge:
7629e44 fix url; deps: Update drift to 2.26.0
98a1a5a db: Store GlobalSettings in database
2ab1c5c store [nfc]: Update outdated references to loadGlobalStore
c84aed0 test [nfc]: Use eg.globalStore when possible
80da3ae store: Store global settings on global store
b214218 theme: Track theme through global settings
ed0afcb settings: Add settings page with vanilla Flutter widgets

but for the browser preference, there's still a substantive comment below. So let's split that part out to a followup PR.

For those first 7 commits, other than nits below, the first commit message just needs to be updated for merge.

Comment on lines 40 to 45
/// Use the in-app browser for HTTP links.
///
/// This translates to [UrlLaunchMode.platformDefault], so that non-in-app
/// browsers/apps will still be used for other types of links (e.g. mailto)
/// on both iOS and Android.
inApp,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, putting it here on the enum's doc is helpful for explanation (continuing from #1167 (comment)). Still this translation doesn't seem right.

The launchUrl doc says:

The default behavior of LaunchMode.platformDefault is up to each platform, and its behavior for a given platform may change over time as new modes are supported, so clients that want a specific mode should request it rather than rely on any currently observed default behavior.

so it's explicitly warning not to make the assumption this is making.

The logic in launchUrl that can reject inAppWebView is pretty specific:

  if ((mode == LaunchMode.inAppWebView ||
          mode == LaunchMode.inAppBrowserView) &&
      !(url.scheme == 'https' || url.scheme == 'http')) {
    throw ArgumentError.value(url, 'url',
        'To use an in-app web view, you must provide an http(s) URL.');
  }

so I think we can just have our own bit of logic that checks if the scheme is http or https, and if not then it replaces inAppBrowserView with platformDefault.

import 'page.dart';
import 'store.dart';

class SettingsPage extends StatelessWidget {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, this is helpful:

This does not aim to fully implement the wip design for the settings
page.  We offer it mainly to test settings, so the implementation is
kept as simple as possible.

Old design for reference:
  https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=446-21372&t=BZKpTQPSiBDNxwvB-0

Let's make a couple of adjustments: s/wip design/draft design/, s/Old design/Draft design (old)/. That way (a) it more fully avoids that "wip" keyword 🙂, (b) it's a bit clearer that the two references are to the same design.

import 'page.dart';
import 'store.dart';

class SettingsPage extends StatelessWidget {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and a separate nit on the commit message:

settings: Add settings page with vanilla Flutter widgets

I'd read "vanilla Flutter widgets" first of all to mean package:flutter/widgets.dart, aka "the widgets library", in contrast to the Material or Cupertino libraries. Here what we actually mean is we're using Flutter's Material widgets, specifically the adaptive flavor of them.

So let's say:

settings: Add easy settings page using (adaptive) Material widgets

This will use generic Material-style controls on Android, and
generic iOS-style controls on iOS.

(and then the other information).

PIG208 added 7 commits March 11, 2025 16:30
This contains a fix for simolus3/drift#3384.

Signed-off-by: Zixuan James Li <[email protected]>
These were supposed to be updated in commit fc80be1 where we
replaced loadGlobalStore with getGlobalStore.

`LiveGlobalBindings.load` is the only thing left analogous to the
previously referred to `loadGlobalStore` method. To avoid direct
referencce to this specific implementation on `GlobalStore`, mention
that loading it for the first time is expected to be asynchronous
instead.

Signed-off-by: Zixuan James Li <[email protected]>
Later we will add more required parameters to TestGlobalStore.

Signed-off-by: Zixuan James Li <[email protected]>
To add integration tests for global store with sqlite, we might want
to switch to LiveGlobalStore, or at least make part of it testable
with an in-memory database (like we do for database_test.dart).
Leaving that to the future.

Signed-off-by: Zixuan James Li <[email protected]>
This will use generic Material-style controls on Android, and
generic iOS-style controls on iOS.

This does not aim to fully implement the draft design for the settings
page.  We offer it mainly to test settings, so the implementation is
kept as simple as possible.

Draft design for reference:
  https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=446-21372&t=BZKpTQPSiBDNxwvB-0

Fixes: zulip#1216

Signed-off-by: Zixuan James Li <[email protected]>
@PIG208
Copy link
Member Author

PIG208 commented Mar 11, 2025

Thanks! Updated the PR and the first comment in this thread.

@gnprice
Copy link
Member

gnprice commented Mar 11, 2025

Thanks! Looks good; merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration review Added by maintainers when PR may be ready for integration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ui: Allow selecting a different dark/light-theme setting than device setting
3 participants