-
Notifications
You must be signed in to change notification settings - Fork 305
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
Conversation
370a328
to
e91e9d5
Compare
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. |
There was a problem hiding this 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.
lib/model/database.dart
Outdated
from2To3: (m, schema) async { | ||
await m.createTable(schema.globalSettings); | ||
}, | ||
from3To4: (m, schema) async { | ||
await m.addColumn( | ||
schema.globalSettings, schema.globalSettings.browserPreference); |
There was a problem hiding this comment.
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.
lib/model/schema_versions.dart
Outdated
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. |
There was a problem hiding this comment.
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.
analysis_options.yaml
Outdated
# Generated code from drift can contain unused local variables. | ||
- lib/model/database.g.dart |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
lib/model/database.dart
Outdated
/// 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this 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?
analysis_options.yaml
Outdated
# Generated code from drift can contain unused local variables. | ||
- lib/model/database.g.dart |
There was a problem hiding this comment.
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?
test/widgets/content_test.dart
Outdated
.single.equals((url: Uri.parse(expectedLaunchUrl), mode: LaunchMode.platformDefault)); | ||
.single.equals((url: Uri.parse(expectedLaunchUrl), mode: LaunchMode.inAppBrowserView)); |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
lib/widgets/app.dart
Outdated
// 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), |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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).
test/widgets/theme_test.dart
Outdated
@@ -97,6 +100,27 @@ void main() { | |||
check(() => a.lerp(b, 0.5)).returnsNormally(); | |||
}); | |||
}); | |||
|
|||
testWidgets('follow globalSettings.themeSetting if not unset', (tester) async { |
There was a problem hiding this comment.
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);
test/widgets/settings_test.dart
Outdated
of: find.text('Use external browser'), | ||
matching: find.byType(SwitchListTile)); | ||
|
||
testWidgets('smoke', (tester) async { |
There was a problem hiding this comment.
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
)
Oh, and we have an issue for the theme setting 🙂 so the PR description and relevant commit can be marked as fixing that: |
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. |
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? |
Opened #1375. |
Forgot to post a message here. This PR is ready for review.
Good point! The string is "Open links with in-app browser"; switched to that instead. |
Thanks, LGTM! Marking for Greg's review. |
20349a1
to
15df1d9
Compare
Still need to make some updates the browser settings changes. Will push again once I'm done. |
Updated the PR. This should be ready for review again! |
There was a problem hiding this 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.
lib/model/database.dart
Outdated
/// 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 { |
There was a problem hiding this comment.
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)
lib/widgets/app.dart
Outdated
child: Builder( | ||
builder: (context) { | ||
return MaterialApp( |
There was a problem hiding this comment.
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):
child: Builder( | |
builder: (context) { | |
return MaterialApp( | |
child: Builder(builder: (context) { | |
return MaterialApp( |
lib/model/settings.dart
Outdated
import 'binding.dart'; | ||
import 'database.dart'; | ||
|
||
/// The user's choice of visual theme for the app |
There was a problem hiding this comment.
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:
/// The user's choice of visual theme for the app | |
/// The user's choice of visual theme for the app. |
test/model/store_checks.dart
Outdated
@@ -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> { |
There was a problem hiding this comment.
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
lib/model/store.dart
Outdated
GlobalSettingsData get globalSettings => _globalSettings; | ||
GlobalSettingsData _globalSettings; | ||
|
||
/// Update the global settings in the store, return the new version. |
There was a problem hiding this comment.
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:
/// 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".
test/model/store_checks.dart
Outdated
@@ -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'); |
There was a problem hiding this comment.
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
test/model/test_store.dart
Outdated
TestGlobalStore({required super.globalSettings, required super.accounts}) | ||
: _globalSettings = globalSettings; | ||
|
||
GlobalSettingsData? _globalSettings; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GlobalSettingsData? _globalSettings; | |
GlobalSettingsData _globalSettings; |
right?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/model/settings.dart
Outdated
switch (themeSetting) { | ||
case null: | ||
return zulipLocalizations.themeSettingSystem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use switch-expression
test/flutter_checks.dart
Outdated
@@ -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> { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
test/model/database_test.dart
Outdated
|
||
final after = v4.DatabaseAtV4(schema.newConnection()); | ||
final globalSettings = await after.select(after.globalSettings).getSingle(); | ||
check(globalSettings.themeSetting).equals(ThemeSetting.light.name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
check(globalSettings.themeSetting).equals(ThemeSetting.light.name); | |
check(globalSettings).themeSetting.equals(ThemeSetting.light.name); |
(then cascade as usual)
There was a problem hiding this comment.
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.
test/model/database_test.dart
Outdated
import 'schemas/schema_v2.dart' as v2; | ||
import 'store_checks.dart'; | ||
import 'schemas/schema_v3.dart' as v3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: keep sorted
lib/widgets/settings.dart
Outdated
const _BrowserPreferenceSetting(), | ||
const _ThemeSetting(), |
There was a problem hiding this comment.
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.
Updated the PR. This should be ready now. |
There was a problem hiding this 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()); |
There was a problem hiding this comment.
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
test/model/store_test.dart
Outdated
check(notifyCount).equals(1); | ||
}); | ||
|
||
// TOOD integration tests with sqlite |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
// TOOD integration tests with sqlite | |
// TODO integration tests with sqlite |
test/model/store_test.dart
Outdated
check(globalStore).globalSettings.browserPreference.equals( | ||
BrowserPreference.external); |
There was a problem hiding this comment.
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.
lib/model/settings.dart
Outdated
UrlLaunchMode get urlLaunchMode { | ||
if (browserPreference != null) { | ||
return switch (browserPreference!) { | ||
BrowserPreference.embedded => UrlLaunchMode.platformDefault, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
test/widgets/content_test.dart
Outdated
check(testBinding.takeLaunchUrlCalls()) | ||
.single.equals(( | ||
url: Uri.parse('https://example/'), mode: LaunchMode.platformDefault)); |
There was a problem hiding this comment.
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:
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)); |
lib/model/settings.dart
Outdated
/// Use the in-app browser. | ||
embedded, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about:
/// 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
This should be ready for review. Made some follow-up comments to #1167 (comment). |
There was a problem hiding this 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.
lib/model/settings.dart
Outdated
/// 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, |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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).
This contains a fix for simolus3/drift#3384. Signed-off-by: Zixuan James Li <[email protected]>
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]>
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]>
Thanks! Updated the PR and the first comment in this thread. |
Thanks! Looks good; merging. |
Work towards #97.
Fixes #1216.
screenshots