-
Notifications
You must be signed in to change notification settings - Fork 309
msglist: Add message action sheet with "Share" button #12
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
Conversation
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! Very nice. Some comments.
It feels like we're having to put this together out of lower-level pieces than I would expect — like the Flutter Material implementation of these bottom sheets is incomplete, and not just in the need for a Material 3 update (flutter/flutter#111448). But I think the result will be good.
|
||
flutter_ios_podfile_setup | ||
|
||
target 'Runner' 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.
Can you say a bit about how you produced this first commit?
I tried adding just the pubspec.yaml
line and then running flutter pub get
and then flutter run -d <an iOS device>
. That produced much of the same generated code, but with a few differences, so I wonder if you did something different.
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 re-made the commit and wrote a proper commit message.
lib/widgets/action_sheet.dart
Outdated
// TODO: Share raw Markdown, right, not HTML? | ||
Share.share(message.content); |
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, agreed.
The raw Markdown won't always be ideal, either. But between the two, I'm pretty sure it'll be preferable more of the time.
(Fine to leave it as a TODO for this PR, though.)
lib/widgets/action_sheet.dart
Outdated
child: Wrap( | ||
// TODO: choose `runSpacing` / `spacing`, to control spacing between buttons | ||
|
||
children: _messageActionSheetButtons(message) | ||
), |
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 start by having this be a list of menu items — so a column where each item is an icon and then a label. Similar to this example in Material:
https://m3.material.io/components/bottom-sheets/guidelines#bb88001e-5e28-42a5-bda9-95fc67407121
but I think that's also what I usually see in apps.
The flexibility to do more things with the layout will definitely come in handy later: in particular it'll let us offer a row of common reactions. But if the list of distinct actions like "Share" gets long enough that we really need this wrapped layout for it… then that's probably too many regardless of layout, more actions than people are going to want to read through.
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 the specific layout for menu items, perhaps try Material's specs for a menu:
https://m3.material.io/components/menus/specs#6928c7b9-2c6e-4ff6-98a6-55883fb299bd
That seems to be mainly about menus in somewhat different settings, not a bottom sheet, so may not fit exactly. But probably a good starting point.
// Clip.hardEdge looks bad; Clip.antiAliasWithSaveLayer looks pixel-perfect | ||
// on my iPhone 13 Pro but is marked as "much slower": | ||
// https://api.flutter.dev/flutter/dart-ui/Clip.html | ||
clipBehavior: Clip.antiAlias, |
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.
Huh — on my Pixel 5, I can't actually spot a difference regardless of what value I put here. Even Clip.none
. (And I even restarted, just in case I was missing something about whether hot reload would work; but still nothing changed.)
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 one took some extra steps for me to reproduce. Did you test by adding enough content in the sheet that it became scrollable, then as you scrolled down, watch what happened as the content crossed the curved boundary of the sheet in the corner?
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.
Ahh, I see. No, I didn't — I just looked at the corners of the sheet itself, without anything scrolling into them.
// (Things break with `expand: true`, the default; not sure why.) | ||
expand: false, |
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.
Huh, weird. Specifically, what I see is that the bottom sheet then starts out occupying the whole screen, as if initialChildSize
was 1.0 instead of 0.5.
That doesn't seem like what the docs call for. May be a bug. Or maybe it's somehow related to the Stack
that sits above 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.
Noting in a code comment.
child: Column( | ||
// Extend DraggableScrollableSheet to full width so the whole | ||
// sheet responds to drag/scroll uniformly. There's probably a | ||
// better way to do this. | ||
crossAxisAlignment: CrossAxisAlignment.stretch, | ||
|
||
children: [ | ||
Builder(builder: builder), | ||
], | ||
), |
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 yeah, I went looking for how to do this and found it somewhat tricky.
Here's a pretty clean solution, though:
child: Column( | |
// Extend DraggableScrollableSheet to full width so the whole | |
// sheet responds to drag/scroll uniformly. There's probably a | |
// better way to do this. | |
crossAxisAlignment: CrossAxisAlignment.stretch, | |
children: [ | |
Builder(builder: builder), | |
], | |
), | |
child: FractionallySizedBox( | |
widthFactor: 1.0, | |
child: Builder(builder: builder), | |
), |
What that does is force the child to have a width that is the max width the parent allowed, while for the height passing through the same constraints (both min and max) that the parent gave.
return DraggableScrollableSheet( | ||
// Enough less than 1 as to not extend into the device's top inset | ||
maxChildSize: 0.75, |
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.
If you open the sheet, then drag it lightly down, it just moves down with your finger and then stops there, still open. That feels odd — it should go all the way closed, I think.
It looks like one can fix this by setting initialChildSize
slightly larger than minChildSize
.
"Slightly", because if you set them equal then there's some odd other behavior: you try to drag it closed, and get the glowing overscroll indicator. (At least on Android.) But e.g. initialChildSize: 0.26
, with the default minChildSize
of 0.25, fixes 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.
Here's a related upstream issue, to watch out for when setting these DraggableScrollableSheet
parameters:
flutter/flutter#116982
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.
There's also this messy thread with people describing several different issues:
flutter/flutter#36283 (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.
Yeah, while I was experimenting with snap: true
, ISTR noticing a behavior like the one described in flutter/flutter#116982.
625fbd0
to
9f91af8
Compare
Thanks for the review! Revision pushed. |
Ah, not ready to merge actually (so I'll convert to a draft): there's still that issue with |
9f91af8
to
7fcbe99
Compare
With flutter/flutter#121554 resolved by my PR flutter/flutter#122118 (merged today 🎉), our action sheet now behaves well with |
7fcbe99
to
cb776b8
Compare
(Just rebased and resolved a conflict.) |
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! Looks good. One comment-comment below, and: it'd be good to bump the Flutter version constraint, so that the pubspec calls for a version with that safe-area fix.
lib/widgets/action_sheet.dart
Outdated
// TODO: to support iPads, we're asked to give a | ||
// `sharePositionOrigin` param, or risk crashing / hanging: | ||
// https://pub.dev/packages/share_plus#ipad |
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.
Wacky. That is definitely below the quality standards that would apply to a first-party plugin.
Upstream threads:
fluttercommunity/plus_plugins#870 (comment)
fluttercommunity/plus_plugins#305 (comment)
And it sounds like the old first-party plugin it replaced didn't have this problem:
fluttercommunity/plus_plugins#305 (comment)
Well, the TODO is good enough for merging for the prototype.
minChildSize: 0.25, | ||
initialChildSize: 0.26, |
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 leave a comment pointing to #12 (comment) for why we're setting one of these to epsilon more than the other.
Agreed. From the |
The merged commit was flutter/flutter@23b7bbd89, and my plan is to wait for a new version tag to appear in the GitHub UI in the list of refs that include my commit: |
cb776b8
to
17b508d
Compare
Thanks for the review! Revision pushed, and I think you were going to test on Linux desktop? |
This gets us flutter/flutter@23b7bbd89 (flutter/flutter#122118), which we'll use to make a nice prototype for the message action sheet, coming soon.
This plugin seems to work fine so far. When using its main API, `Share.share()`, on iOS, I get some log output that could be noise, and also some that might hint at some layout glitches but that I haven't noticed as being user-visible: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/flutter.3A.20.60share_plus.60/near/1506606 Here's what I did to install: - Added the new dependency line to pubspec.yaml - Ran `flutter pub get` - Tried to build/run on my iPhone, and in the `pod install` phase, got this error: [!] Automatically assigning platform `iOS` with version `11.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform` and fixed by uncommenting the `platform` line in ios/Podfile - Tried to build/run on my iPhone, and in the `pod install` phase, got a different error: [!] Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`. and fixed by removing a `target 'RunnerTests' do` block in the iOS and macOS Podfiles. Those blocks were added because of flutter/flutter@2a502363e, which we recently took when upgrading to the Flutter beta 3.8.0-10.1.pre. We were missing new iOS code that those blocks refer to, added in that same Flutter commit. There doesn't seem to be an automatic step that would give us that code, but docs are in the works if we ever want to add it manually: flutter/flutter#96421 (comment) Anyway, it doesn't seem like a lot of code; probably a simple "Hello World" example. Leave it out for now, but cleanly, by deleting those dangling references in the Podfiles. - Built and ran successfully on my iPhone; the `pod install` phase succeeded, generating ios/Podfile.lock and adding reasonable-looking lines in some Xcode files in ios/ (CocoaPods stuff). - (Same with macOS, for the files in macos/.)
17b508d
to
182cdf9
Compare
182cdf9
to
64c7670
Compare
Revision pushed, with a TODO mentioning the just-filed #24. |
Thanks! Looks good now; merging. (I tested on Linux, and the UI all works fine. The sharing feature doesn't seem very effective, but I'm not sure what it could usefully do instead.) |
No description provided.