-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Improvements on messaging UI, and fix on minor bugs on NestedScroll #154
Conversation
Reduced the nested code. Improve the building time and performance.
- Emojis display overflow or actions are overwritten
Resolved issue of scroll overlays pager on sublistviews
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.
Left some comments but works fine for me!
const MessagingEmojiPicker({ | ||
required this.showEmojis, | ||
required this.emptySuggestions, | ||
this.height = 200, |
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 totally fine for now, ideally we'd use some relative measure (% of viewport height)
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.
The height is using a percentage of the total height of the screen, and the width was removed because by default takes all the available space horizontally.
lib/ui/home.dart
Outdated
..onCancel = _handleDragCancel; | ||
}) | ||
}, | ||
behavior: HitTestBehavior.opaque, |
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.
in conversation.dart
I switched HitTestBehavior
to translucent
since the emoji reactions were not picked up very well, is it a problem?
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.
In my case i was receiving an overflow, and after that, for some reason when i try to scroll horizontally on the emoji response bubble, the movement was detected as a page transition, the workaround was to use a wrapper inside the pager and pass a controller to the desired widget, and once everything was done the ui recognize better the transitions
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 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.
Im gonna add the functionality to open the emoji container, however im thinking into still leaving the option to scroll, mainly because if one user decides to open the app on a phone with little dimensions, it can lead to a blank space. The alternative it can be to set those emojis in a Flexible space so it can adapt without scrolling @Kallirroi please tell me what do you think
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 think we'd need to test out both options and involve @Derekf5 - the infinite horizontal scrolling in such a small container might be a bit annoying for the user.
I think you are 100% right things need to be adapted for smaller screens, but we will potentially need to rethink how that entire popup menu behaves in that case, as opposed to just the reaction emojis.
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.
Sorry, I commented about this outside of this thread, but having both horizontal scroll and ellipses seems redundant. The ellipses provide a mechanism for handling overflow, which I think is more user friendly than horizontal scrolling.
- Created custom emoji selector. - Improve on rendering ui
|
Im still struggling about how to handle the widget transition between permission request and denied, without having to do more changes on the UI 🤔 for today im hopping to finish all the changes |
I know this is still a WIP, but I see a couple of issues:
|
@Crdzbird Is there a ticket(s) for the problem(s) that you're trying to solve? I'm a little concerned that we might be spending time on something that's not ticketed and not assigned to this sprint. |
@oxtoacart the thing with the reactions, is that when i start on the first try without the dots, they already took all the space of the screen,and already have some overflow by 7pixels on my device, when the dots where added then that overflow increments, so I decided to implement the scrolling interaction, also because the same reaction list was already inside a list view so I only add the change in case of the emojis reactions are too big to render on more devices |
Also if I used a flex then the reactions shrinks by a lot and it's kinda of uncomfortable to tap on the desired reaction reduced |
So I don't know how to implement it, but the best behavior would to display a variable number of emojis based on the available space, and always display the ellipses. |
@Crdzbird I just noticed that the horizontal dragging between screens messes up with the Voice Recorder (which needs to be swiped left to cancel). Take a look if you want! 🙂 |
- Created functionality when user tap on dots to add custom reaction. - Removed horizontal behaviour and replaced with a flexible manager. - Fix permission checker and reduced code base
if (_recording) { | ||
return; | ||
} | ||
|
||
model.startRecordingVoiceMemo().then((value) { | ||
_hasPermission = await model.startRecordingVoiceMemo(); |
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 have to change this into a fully async, previously this will continue the process leading to a render error, and when the user deny the permission the app gets confused and render the recording action
dismissKeyboard(); | ||
} | ||
}, | ||
), |
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.
To handle the events of drag, and more, it was necessary to add custom functions as required params, also for the emoji reaction with the 3 dots, a global function was declared and linked on the reactions.dart
lib/messaging/conversation.dart
Outdated
if (_recording) | ||
VoiceRecorder( | ||
onSwipeLeft: () => setState(() => _recording = 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.
This was needed to cancel the audio recording when the gesture detect that x is <= 200
lib/messaging/conversation.dart
Outdated
onEmojiTap: (showEmoji, messageSelected) => setState(() { | ||
_emojiShowing = true; | ||
_customEmojiResponse = true; | ||
_storedMessage = messageSelected; |
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 variable stores the message in which we desire to attach a custom emoji (not available from the 5 reactions by default)
lib/messaging/conversation.dart
Outdated
onReply: (_message) { | ||
setState(() { | ||
_isReplying = true; | ||
_quotedMessage = _message; | ||
showKeyboard(); // TODO: this is clashing with Navigator.pop(context); | ||
showKeyboard(); |
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.
Fixed issue with navigator
)), | ||
), | ||
); | ||
} |
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.
All of this was moved to separated widget classes, to have a more absolute control
@@ -40,7 +40,8 @@ class _MessagesTabState extends State<MessagesTab> | |||
break; | |||
case '/conversation': | |||
builder = (BuildContext context) => Conversation( | |||
settings.arguments ?? widget._initialRouteArguments); | |||
settings.arguments ?? widget._initialRouteArguments, |
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.
removed previous handler when the reactions were wrapped inside a list view with scroll
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.
Generally looks 👍 - I added two comments which I think are not blockers for merging this.
Some documentation feedback:
- do you mind providing a summary of the changes instead of "WIP there are gonna be more changes on the UI." in the opening comment? 😇
- I had opened this https://github.com/getlantern/android-lantern/issues/142 and this https://github.com/getlantern/android-lantern/issues/139 tickets recently, if you think the changes address either then connect them to this PR.
lib/messaging/widgets/reactions.dart
Outdated
shape: BoxShape.circle, | ||
color: Colors.white, | ||
boxShadow: [ | ||
BoxShadow( |
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.
not sure we should be adding the shadow here, personally I'd just skip it - otherwise looks and works 💯
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.
hhmmm... the other alternative is to use an ElevatedButton and manage the button states, (uploaded on latest commit)
clipBehavior: Clip.none, | ||
fit: StackFit.passthrough, | ||
children: [ | ||
isRecording |
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.
Recording is pretty broken for me:
- there is an uncaught exception with the
scrollListener
:_AssertionError ('package:scrollable_positioned_list/src/scrollable_positioned_list.dart': Failed assertion: line 226 pos 12: '_scrollableListState != null': is not true.)
- swiping left to cancel swipes entire screen to the VPN view
I suggest we create a new ticket for just focusing on the Voice Recorder separately, since it requires a lot of attention.
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.
@Kallirroi the error as I found is related to this segment of the code:
await _scrollController.scrollTo(
index: 00,
duration: const Duration(seconds: 1),
curve: Curves.easeInOutCubic);
at the moment I comment everything related to that and works fine
|
||
@override | ||
String get debugDescription => 'CustomPanRecognizer'; | ||
} |
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.
Nice, this sort of refactoring is very helpful for me to read 👍
The voice functionality isn't part of this PR, the only parts that I was working were related to the permission error, the swipe that isn't recognized and instead change the page and finally the reactions with the dots @oxtoacart that is gonna go on a different PR to handle the reproduction 👀 |
now the reactions states are working based on the UI Guideline in figma
…o crdzbird/permission_handler
- Line 117 of conversation.dart.
Removed everything related to page change. Replaced CustomWidget wit a GestureDetector, due to now the pager widget is unable to change between pages when the user swipe. - Improved performance and fix issue related when user cancel the recording. This was causing a buffer overflow on the audio recorder native and leading to an unexpected end of the app.
import 'package:flutter/material.dart'; | ||
import 'package:stop_watch_timer/stop_watch_timer.dart'; | ||
|
||
class CountdownTimer 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 was separated as an independent widget due to only be useful just to display a numeric countdown.
@@ -40,42 +40,37 @@ class StatusRowState extends State<StatusRow> { | |||
return Container( | |||
child: Opacity( | |||
opacity: 0.8, | |||
child: Flex( | |||
child: Wrap( |
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.
The wrap was needed because when the bubble options appears, the date of the message below creates an empty gap leading to a render problem
), | ||
), | ||
if (statusIcon != null) | ||
Flexible( |
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.
The wrap handle everything related to size for all the childrens, so the flexible can be removed
(e) => Flexible( | ||
child: Container( | ||
margin: const EdgeInsets.symmetric(horizontal: 4.0), | ||
child: TextButton( |
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.
By suggestion the previous ui of the reactions was replaced, and now is using a TextButton, we can gain access to a better button state handler and change the material state when the button is onHold, adding a nice elevation effect only to the pressed widget.
@@ -133,6 +132,7 @@ class _HomePageState extends State<HomePage> { | |||
body: PageView( | |||
onPageChanged: onPageChange, | |||
controller: _pageController, | |||
physics: const NeverScrollableScrollPhysics(), |
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.
Added an unscrollable physic due to the pager now being static
import 'package:flutter/material.dart'; | ||
|
||
/// Handle a native gesture detection without the need to have more than one listener | ||
class ForcedPanDetector 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.
I don't know if we are gonna need this for a future, this widget lets you handle an independent tap gesture without having to worry about any parent widget with a gesture detector recognize the tap as his own instead of the children.
LGTM! |
WIP there are gonna be more changes on the UI.