Skip to content
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

Merged
merged 28 commits into from
Jun 23, 2021

Conversation

Crdzbird
Copy link

@Crdzbird Crdzbird commented Jun 15, 2021

WIP there are gonna be more changes on the UI.

  • Do the tests pass? Consistently?
  • Did this change improve test coverage?
  • Has it been reviewed/approved by relevant teammates?
  • Can it be QA’d in staging or something like staging?
  • Is the code in question being linted? If not, consider adding a linter step to CI. If yes, make sure the linter is happy.
  • Do we know how we’re going to deploy this?
  • Are we clear on what the support and maintenance impact is?
  • Did you create new documentation? Is it accessible and in the right place?
  • Has existing documentation been updated?
  • Have you logged tickets for related technical debt with the label “techdebt”?

Crdzbird added 5 commits June 14, 2021 16:39
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
Copy link

@cosmicespresso cosmicespresso left a 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,

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)

Copy link
Author

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,

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?

Copy link
Author

@Crdzbird Crdzbird Jun 16, 2021

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

Choose a reason for hiding this comment

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

Regarding the emoji reactions, I don't think we want to be scrolling horizontally forever. The idea was that we'd have 5 main ones (which I had added) and then a "...." icon that would trigger the emoji keyboard (see below), where a user could pick any emoji.

Screen Shot 2021-06-16 at 12 17 40 PM

Copy link
Author

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

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.

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.

@Crdzbird
Copy link
Author

Crdzbird commented Jun 17, 2021

Screenshot_20210617-074010_Lantern.jpg
this is the final result following the ui style @Kallirroi also the implementation of the dots as emoji response is implemented on the recent commits.

@Crdzbird
Copy link
Author

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

@oxtoacart
Copy link

I know this is still a WIP, but I see a couple of issues:

  1. the message bar (smiley, text input, buttons) is not vertically centered

image

  1. I don't like the horizontal scrolling on the reaction emojis. IIUC the problem you're trying to solve is overflow on smaller screens. The design already includes a button with ellipses (...), which already provides a mechanism for handling overflow. The way that I think it should work is that we display as many emojis as the space allows and use the ellipses overflow for the rest.

@oxtoacart
Copy link

@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.

@Crdzbird
Copy link
Author

@Crdzbird
Copy link
Author

@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

@Crdzbird
Copy link
Author

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

@oxtoacart
Copy link

@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

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.

@cosmicespresso
Copy link

@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! 🙂

Crdzbird added 2 commits June 17, 2021 13:29
- 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();
Copy link
Author

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();
}
},
),
Copy link
Author

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

if (_recording)
VoiceRecorder(
onSwipeLeft: () => setState(() => _recording = false),
Copy link
Author

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

onEmojiTap: (showEmoji, messageSelected) => setState(() {
_emojiShowing = true;
_customEmojiResponse = true;
_storedMessage = messageSelected;
Copy link
Author

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)

onReply: (_message) {
setState(() {
_isReplying = true;
_quotedMessage = _message;
showKeyboard(); // TODO: this is clashing with Navigator.pop(context);
showKeyboard();
Copy link
Author

Choose a reason for hiding this comment

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

Fixed issue with navigator

)),
),
);
}
Copy link
Author

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,
Copy link
Author

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

Copy link

@cosmicespresso cosmicespresso left a 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:

shape: BoxShape.circle,
color: Colors.white,
boxShadow: [
BoxShadow(

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 💯

Copy link
Author

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

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.

Copy link
Author

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';
}

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 👍

@oxtoacart
Copy link

Alignment on the message box still looks wrong. It should be centered vertically, correct?

image

@oxtoacart
Copy link

The record button doesn't align correctly to the right of the screen on my Huawei Mate 9.

image

@oxtoacart
Copy link

Voice recordings aren't coming through

image

@Crdzbird
Copy link
Author

Crdzbird commented Jun 21, 2021

Alignment on the message box still looks wrong. It should be centered vertically, correct?

image

weird... on the test device, the alignment is always centered, Im gonna see if i can display that missalign on an emulated device 🤔
Screenshot_20210621-133953_Lantern.jpg

@oxtoacart
Copy link

Voice recordings aren't coming through

image

Looks like this problem is not new to this branch.

@Crdzbird
Copy link
Author

Crdzbird commented Jun 21, 2021

Voice recordings aren't coming through

image

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 👀

@oxtoacart
Copy link

Alignment on the message box still looks wrong. It should be centered vertically, correct?
image

weird... on the test device, the alignment is always centered, Im gonna see if i can display that missalign on an emulated device 🤔
Screenshot_20210621-133953_Lantern.jpg

If it helps any, the alignment is fine on ox/messaging.

Base automatically changed from kr/contact_scanning to ox/messaging June 22, 2021 16:09
Crdzbird added 2 commits June 22, 2021 19:59
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.
@Crdzbird Crdzbird requested a review from cosmicespresso June 23, 2021 02:02
import 'package:flutter/material.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';

class CountdownTimer extends StatelessWidget {
Copy link
Author

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(
Copy link
Author

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(
Copy link
Author

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(
Copy link
Author

@Crdzbird Crdzbird Jun 23, 2021

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(),
Copy link
Author

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 {
Copy link
Author

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.

@oxtoacart
Copy link

LGTM!

@oxtoacart oxtoacart merged commit 1edc354 into ox/messaging Jun 23, 2021
@oxtoacart oxtoacart deleted the crdzbird/permission_handler branch June 23, 2021 16:56
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants