Skip to content

accounts ui: Offer Flutter's [LicensePage], to acknowledge software used by the app #101

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

Merged
merged 4 commits into from
May 31, 2023

Conversation

chrisbobbe
Copy link
Collaborator

@chrisbobbe chrisbobbe commented May 19, 2023

(EDITED following #101 (review) . Notably, this revision doesn't address #100.)


From this new page, the user can tap a button to show [LicensePage],
so resolving #99.

Fixes: #99

@chrisbobbe
Copy link
Collaborator Author

(Fixed a formatting nit I just noticed.)

chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request May 23, 2023
For a proposed UI to show the user the list of licenses tracked by
[LicenseRegistry], see PR zulip#101.
@gnprice
Copy link
Member

gnprice commented May 24, 2023

Design-wise, I think a standard solution here would be an "overflow menu" at the end of the app bar. See mentions of "overflow" in:
https://api.flutter.dev/flutter/material/AppBar/actions.html
https://api.flutter.dev/flutter/material/PopupMenuButton-class.html
https://m3.material.io/components/top-app-bar/guidelines

That would also have the advantage of imposing less of a constraint on how we lay out the list of accounts. Putting them at the top feels likely to be annoying for the common case of one or two accounts, for people using a phone and having to reach up to the top with their thumb.

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.

Rather than "help", I think I'd file this under an "about" area. So in full:

  • in app bar, overflow menu has an item "About Zulip"
  • That item goes to a screen that's just a settings-style page, with a couple of items on it
  • One is "Zulip" and a version number or something — just to help it feel less empty
  • The other is "Open-source licenses"
  • That one uses showLicensePage to go to the Flutter-provided license page.

Comment on lines 63 to 68
Builder(builder: (context) =>
MediaQuery.removePadding(
context: context,
removeBottom: true,
child: Expanded(
child: SingleChildScrollView(
Copy link
Member

Choose a reason for hiding this comment

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

This gets pretty long before it becomes clear what the payload is (with for (… in globalStore.accountEntries) and _buildAccountItem). It'd be good to pull out as a local variable.

@chrisbobbe
Copy link
Collaborator Author

chrisbobbe commented May 24, 2023

Sure, I'll update this soon.

That item goes to a screen that's just a settings-style page, with a couple of items on it

I'm wary of putting too much design work into a new "About" page at this early stage, when showAboutDialog and AboutDialog exist—whether by tailoring it a lot to its specific purpose, or building the right reusable widgets for generic "settings-style pages" we'll undoubtedly have several of eventually. I can try something quick with e.g. a ListView and ListTiles; how does that sound?

@gnprice
Copy link
Member

gnprice commented May 25, 2023

I can try something quick with e.g. a ListView and ListTiles; how does that sound?

Yeah, definitely would want to keep it to something quick. I think that plan sounds like a good one.

If you find that the tools at hand don't seem to give you a quick way to get something reasonable by that approach, then showAboutDialog would be fine. It just feels like a less typical UI in a mobile app. The dialog is also not particularly amenable to adding another item or two for things like a terms of service, whereas once there's a settings-style screen for "About" it's easy to throw one more item in there (and rename to like "About & terms").

chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request May 25, 2023
For a proposed UI to show the user the list of licenses tracked by
[LicenseRegistry], see PR zulip#101.
@chrisbobbe
Copy link
Collaborator Author

Thanks for the review! Revision pushed.

chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request May 26, 2023
For a proposed UI to show the user the list of licenses tracked by
[LicenseRegistry], see PR zulip#101.
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! This UI looks good. Two small comments in the code.


@override
Widget build(BuildContext context) {
final navigator = Navigator.of(context);
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 move this inside the onSelected callback. That way it doesn't add any work to do at build time, and we only do the work when the user has chosen to interact with the menu, which is much less common.

… Hm, in fact: I was about to write that this method is presumably cheap and so it doesn't much matter in this case and it's mostly a matter of maintaining good patterns — but it turns out that [Navigator.of] is actually expensive! From its docs:

This method can be expensive (it walks the element tree).

So yeah, definitely to be avoided in the build phase, and invoked only when handling an actual user interaction that needs it.

Copy link
Member

Choose a reason for hiding this comment

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

(And I guess that also makes an illustration of why deferring things from the build method that are really only needed in event handlers, even when one presumes they're probably cheap, is a good pattern — if you haven't carefully checked that they're cheap, you might be surprised.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Interesting! In the common case of an event handler that just has to walk the tree once (it doesn't need the NavigatorState for two or more tasks), it might make sense to favor Navigator.push(context, …) over Navigator.of(context).push(…), which would prevent the tree-walking work from straying outside the event handler, as it did in this revision.

Comment on lines 40 to 42
if (_packageInfo != null) ...[
ListTile(title: const Text('App version'), subtitle: Text(_packageInfo!.version)),
],
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, awkward that this info is async.

If we do find ourselves showing a frame or two where we don't have the version number yet, I think it'd be better to still show this list item and just have some kind of placeholder for the actual value, rather than leave out the whole list item. That should reduce the amount of visible jank.

So e.g.:

Suggested change
if (_packageInfo != null) ...[
ListTile(title: const Text('App version'), subtitle: Text(_packageInfo!.version)),
],
ListTile(
title: const Text('App version'),
subtitle: Text(_packageInfo?.version ?? '(…)')),

Copy link
Member

Choose a reason for hiding this comment

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

To simulate that situation, you can insert an await Future.delayed(…):

       final result = await PackageInfo.fromPlatform();
+      await Future.delayed(Duration(milliseconds: 20));
       setState(() {
         _packageInfo = result;

Like we do with the realm-url and username/password screens, which
also have this pattern:

      body: SafeArea(
        minimum: const EdgeInsets.all(8),
        child: Center(
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxWidth: 400),
These changes happened automatically for me when building for macOS.
…page

From this new page, the user can tap a button to show [LicensePage],
so resolving zulip#99.

Fixes: zulip#99
@chrisbobbe
Copy link
Collaborator Author

Thanks for the review! Revision pushed.

@gnprice gnprice merged commit 4d6f561 into zulip:main May 31, 2023
@gnprice
Copy link
Member

gnprice commented May 31, 2023

Thanks! Looks good; merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Offer LicensePage, to acknowledge software used by the app
2 participants