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
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6106e81
Refactoring of Messaging UI
Crdzbird Jun 14, 2021
61ce577
changes on reactions builder
Crdzbird Jun 15, 2021
d2d9cb3
Removed Builder and moved into a independent widget
Crdzbird Jun 15, 2021
b493345
Fix issue on messaging emoji picker
Crdzbird Jun 15, 2021
afc3af2
Scroll fix
Crdzbird Jun 15, 2021
8e14a05
Removed unnecessary widget
Crdzbird Jun 15, 2021
abe8ff9
Working on functionalities
Crdzbird Jun 17, 2021
0c503fd
code reduction on keyboard
Crdzbird Jun 17, 2021
2820578
Temporary return to old message bar (with new functionality)
Crdzbird Jun 17, 2021
f14a2da
Fix on ui and added functionality on dotted
Crdzbird Jun 17, 2021
81a4a17
Adding gesture recognition and base handler
Crdzbird Jun 17, 2021
7b6abcf
using wechat from git
Crdzbird Jun 17, 2021
ff0785b
fix issue related with voice recording double tap to recognize gesture
Crdzbird Jun 20, 2021
7de6107
Replaced voice_recorder code
Crdzbird Jun 21, 2021
9b1bd3c
Pull from kr/contact_scanning into crdzbird/permission_handler
Crdzbird Jun 21, 2021
8cfb670
Fix on merge from branches
Crdzbird Jun 21, 2021
2f358af
Documentation of pan_gesture and voice_recorder
Crdzbird Jun 21, 2021
bc055b8
tiny UI fix
cosmicespresso Jun 21, 2021
44f8e56
fix reaction emoji alignment
cosmicespresso Jun 21, 2021
de36c9f
changed ui of reaction list
Crdzbird Jun 21, 2021
15c9c00
Fix of position on recording red circle, height fix
Crdzbird Jun 21, 2021
bab6f7b
Merge remote-tracking branch 'origin/crdzbird/permission_handler' int…
Crdzbird Jun 21, 2021
5c07bc4
Reduced pixel gap to stop recording.
Crdzbird Jun 21, 2021
03c1d1f
Commented segment of code that throws an exception
Crdzbird Jun 21, 2021
3ad2531
Code changes on home, conversation and voice_recorder
Crdzbird Jun 23, 2021
95482ba
Removed unneded function
Crdzbird Jun 23, 2021
1b3579d
Removed debug prints
Crdzbird Jun 23, 2021
15d8800
linter
Crdzbird Jun 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 23 additions & 53 deletions lib/messaging/conversation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'package:lantern/messaging/messaging_model.dart';
import 'package:lantern/messaging/widgets/disappearing_timer_action.dart';
import 'package:lantern/messaging/widgets/message_bubble.dart';
import 'package:lantern/messaging/widgets/messaging_emoji_picker.dart';
import 'package:lantern/messaging/widgets/staging_container_item.dart';
import 'package:lantern/messaging/widgets/voice_recorder.dart';
import 'package:lantern/model/model.dart';
Expand All @@ -22,8 +23,9 @@ import 'package:wechat_camera_picker/wechat_camera_picker.dart';

class Conversation extends StatefulWidget {
final Contact _contact;
final ScrollController scrollController;

Conversation(this._contact) : super();
Conversation(this._contact, this.scrollController) : super();

@override
_ConversationState createState() => _ConversationState();
Expand Down Expand Up @@ -315,7 +317,7 @@ class _ConversationState extends State<Conversation>
padding: const EdgeInsets.all(8),
child: _buildMessageBar(context),
),
if (_emojiShowing) _buildEmojiKeyboard(),
_buildEmojiKeyboard(width: 150.0),
]),
// Voice recorder
if (_recording)
Expand Down Expand Up @@ -351,6 +353,7 @@ class _ConversationState extends State<Conversation>
itemCount: messageRecords.length,
itemBuilder: (context, index) {
return MessageBubble(
scrollController: widget.scrollController,
message: messageRecords.elementAt(index),
priorMessage: index >= messageRecords.length - 1
? null
Expand Down Expand Up @@ -457,55 +460,22 @@ class _ConversationState extends State<Conversation>
]);
}

Offstage _buildEmojiKeyboard() {
// https://github.com/Fintasys/emoji_picker_flutter
return Offstage(
offstage: !_emojiShowing,
child: Container(
height: 200,
child: EmojiPicker(
onEmojiSelected: (Category category, Emoji emoji) {
setState(() {
_isSendIconVisible = true;
});
_newMessage
..text += emoji.emoji
..selection = TextSelection.fromPosition(
TextPosition(offset: _newMessage.text.length));
},
onBackspacePressed: () {
_newMessage
..text = _newMessage.text.characters.skipLast(1).toString()
..selection = TextSelection.fromPosition(
TextPosition(offset: _newMessage.text.length));
},
config: Config(
columns: 10,
emojiSizeMax: 17.0,
verticalSpacing: 0,
horizontalSpacing: 0,
initCategory: Category.SMILEYS,
bgColor: const Color(0xFFF2F2F2),
// TODO: generalize in theme
indicatorColor: Colors.black,
// TODO: generalize in theme
iconColor: Colors.grey,
iconColorSelected: Colors.black,
// TODO: generalize in theme
progressIndicatorColor: Colors.black,
// TODO: generalize in theme
backspaceColor: Colors.black,
// TODO: generalize in theme
showRecentsTab: true,
recentsLimit: 28,
noRecentsText: 'No Recents'.i18n,
noRecentsStyle:
const TextStyle(fontSize: 16, color: Colors.black26),
// TODO: generalize in theme
categoryIcons: const CategoryIcons(),
buttonMode: ButtonMode.MATERIAL,
)),
),
);
}
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

Widget _buildEmojiKeyboard({required double width}) => MessagingEmojiPicker(
showEmojis: _emojiShowing,
emptySuggestions: 'No Recents'.i18n,
width: width,
onBackspacePressed: () {
_newMessage
..text = _newMessage.text.characters.skipLast(1).toString()
..selection = TextSelection.fromPosition(
TextPosition(offset: _newMessage.text.length));
},
onEmojiSelected: (category, emoji) {
setState(() => _isSendIconVisible = true);
_newMessage
..text += emoji.emoji
..selection = TextSelection.fromPosition(
TextPosition(offset: _newMessage.text.length));
},
);
}
7 changes: 5 additions & 2 deletions lib/messaging/messaging.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import 'conversations.dart';

class MessagesTab extends StatefulWidget {
final String _initialRoute;
final ScrollController scrollController;
final dynamic _initialRouteArguments;

MessagesTab(this._initialRoute, this._initialRouteArguments);
MessagesTab(
this.scrollController, this._initialRoute, this._initialRouteArguments);

@override
_MessagesTabState createState() => _MessagesTabState();
Expand Down Expand Up @@ -40,7 +42,8 @@ class _MessagesTabState extends State<MessagesTab>
break;
case '/conversation':
builder = (BuildContext context) => Conversation(
settings.arguments ?? widget._initialRouteArguments);
settings.arguments ?? widget._initialRouteArguments,
widget.scrollController);
break;
default:
throw Exception('unknown route ${settings.name}');
Expand Down
33 changes: 12 additions & 21 deletions lib/messaging/widgets/message_bubble.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:lantern/messaging/widgets/reactions.dart';
import 'package:lantern/model/model.dart';
import 'package:lantern/model/protos_flutteronly/messaging.pb.dart';
import 'package:lantern/package_store.dart';
Expand All @@ -18,11 +19,13 @@ class MessageBubble extends StatelessWidget {
required this.contact,
required this.onReply,
required this.onTapReply,
required this.scrollController,
}) : super(key: key);

final PathAndValue<StoredMessage> message;
final StoredMessage? priorMessage;
final StoredMessage? nextMessage;
final ScrollController scrollController;
final Contact contact;
final Function(StoredMessage?) onReply;
final Function(PathAndValue<StoredMessage>) onTapReply;
Expand Down Expand Up @@ -109,26 +112,6 @@ class MessageBubble extends StatelessWidget {
BuildContext context,
MessagingModel model,
) {
final reactionOptions = reactions.keys.toList();
final reactionArray = reactionOptions
.map((e) => Container(
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 4),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 4),
child: GestureDetector(
onTap: () {
model.react(message, e);
Navigator.pop(context);
},
child: Transform.scale(
scale: 1.3,
child: Text(e, style: const TextStyle(fontSize: 16))),
),
),
))
.toList(growable: false);

if (wasDeleted) {
final humanizedSenderName =
matchIdToDisplayName(msg.remotelyDeletedBy.id, contact);
Expand All @@ -139,7 +122,15 @@ class MessageBubble extends StatelessWidget {
return FocusedMenuHolder(
menuItems: [
FocusedMenuItem(
title: Row(children: [...reactionArray]),
title: Flexible(
fit: FlexFit.tight,
child: Reactions(
scrollController: scrollController,
reactionOptions: reactions.keys.toList(),
message: message,
messagingModel: model,
),
),
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 replaced by a flexible to avoid any error rendering, is better to use flex instead of Expanded because flexible takes the needed space, and expanded takes all. and also each component inside flexible wrapped in flex can be auto adjusted

onPressed: () {},
),
FocusedMenuItem(
Expand Down
56 changes: 56 additions & 0 deletions lib/messaging/widgets/messaging_emoji_picker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:flutter/material.dart';

class MessagingEmojiPicker extends StatelessWidget {
final bool showEmojis;
final String emptySuggestions;
final double height;
final double width;
final Function(Category, Emoji) onEmojiSelected;
final VoidCallback? onBackspacePressed;

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.

this.onBackspacePressed,
required this.width,
required this.onEmojiSelected,
Key? key,
}) : super(key: key);

@override
Widget build(BuildContext context) => AnimatedCrossFade(
firstChild: const SizedBox(),
secondChild: _showEmojiKeyBoard(context: context),
firstCurve: Curves.easeIn,
secondCurve: Curves.easeOut,
reverseDuration: const Duration(milliseconds: 600),
crossFadeState:
!showEmojis ? CrossFadeState.showFirst : CrossFadeState.showSecond,
duration: const Duration(milliseconds: 600),
);

Widget _showEmojiKeyBoard({required BuildContext context}) => Container(
height: height,
child: EmojiPicker(
key: key,
onBackspacePressed: onBackspacePressed,
onEmojiSelected: onEmojiSelected,
config: Config(
initCategory: Category.SMILEYS,
columns: 10,
emojiSizeMax: 17.0,
iconColor: Theme.of(context).primaryIconTheme.color ?? Colors.grey,
iconColorSelected:
Theme.of(context).accentIconTheme.color ?? Colors.blue,
noRecentsStyle: Theme.of(context).textTheme.bodyText1 ??
const TextStyle(fontSize: 16, color: Colors.black26),
progressIndicatorColor: Theme.of(context).indicatorColor,
noRecentsText: emptySuggestions,
bgColor: Theme.of(context).backgroundColor,
indicatorColor: Theme.of(context).indicatorColor,
),
),
);
}
45 changes: 45 additions & 0 deletions lib/messaging/widgets/reactions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:lantern/messaging/messaging_model.dart';
import 'package:lantern/model/model.dart';
import 'package:lantern/model/protos_flutteronly/messaging.pbserver.dart';

class Reactions extends StatelessWidget {
final List<String> reactionOptions;
final MessagingModel messagingModel;
final PathAndValue<StoredMessage> message;
final ScrollController scrollController;
const Reactions(
{required this.reactionOptions,
required this.message,
required this.messagingModel,
required this.scrollController,
Key? key})
: super(key: key);

@override
Widget build(BuildContext context) => ListView.separated(
scrollDirection: Axis.horizontal,
physics: const ClampingScrollPhysics(),
controller: scrollController,
itemBuilder: (context, index) => GestureDetector(
onTap: () async {
await messagingModel.react(message, reactionOptions[index]);
Navigator.pop(context);
},
child: Center(
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
child: Text(
reactionOptions[index],
style: Theme.of(context).textTheme.headline6,
),
),
),
),
separatorBuilder: (context, index) => const SizedBox(
width: 12.0,
),
itemCount: reactionOptions.length,
);
}
Loading