fix command layout

This commit is contained in:
Salvatore Giordano
2020-03-04 10:40:35 +01:00
parent 1ec09bac63
commit 0f0226ca69
5 changed files with 159 additions and 140 deletions
+6
View File
@@ -14,6 +14,8 @@ PODS:
- Reachability - Reachability
- path_provider (0.0.1): - path_provider (0.0.1):
- Flutter - Flutter
- path_provider_macos (0.0.1):
- Flutter
- Reachability (3.2) - Reachability (3.2)
- screen (0.0.1): - screen (0.0.1):
- Flutter - Flutter
@@ -38,6 +40,7 @@ DEPENDENCIES:
- image_picker (from `.symlinks/plugins/image_picker/ios`) - image_picker (from `.symlinks/plugins/image_picker/ios`)
- keyboard_visibility (from `.symlinks/plugins/keyboard_visibility/ios`) - keyboard_visibility (from `.symlinks/plugins/keyboard_visibility/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`)
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
- screen (from `.symlinks/plugins/screen/ios`) - screen (from `.symlinks/plugins/screen/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`)
@@ -64,6 +67,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/keyboard_visibility/ios" :path: ".symlinks/plugins/keyboard_visibility/ios"
path_provider: path_provider:
:path: ".symlinks/plugins/path_provider/ios" :path: ".symlinks/plugins/path_provider/ios"
path_provider_macos:
:path: ".symlinks/plugins/path_provider_macos/ios"
screen: screen:
:path: ".symlinks/plugins/screen/ios" :path: ".symlinks/plugins/screen/ios"
sqflite: sqflite:
@@ -87,6 +92,7 @@ SPEC CHECKSUMS:
image_picker: e3eacd46b94694dde7cf2705955cece853aa1a8f image_picker: e3eacd46b94694dde7cf2705955cece853aa1a8f
keyboard_visibility: 96a24de806fe6823c3ad956c01ba2ec6d056616f keyboard_visibility: 96a24de806fe6823c3ad956c01ba2ec6d056616f
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0
sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0
+7 -7
View File
@@ -3,13 +3,13 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
void main() async { void main() async {
final client = Client( final client = Client(
's2dxdhpxd94g', 'b67pax5b2wdq',
logLevel: Level.INFO, logLevel: Level.INFO,
); );
await client.setUser( await client.setUser(
User(id: 'falling-mountain-7'), User(id: 'falling-mountain-7'),
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNDE5MjI5YTMtODRhMC00MDZiLTkzNzEtN2NlOWE0ZTBhNjc2In0.J3SjGH4e4v7b3cg5EgWkljTxXj_HeHpCWn5ujEVv_H8', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZmFsbGluZy1tb3VudGFpbi03In0.AKgRXHMQQMz6vJAKszXdY8zMFfsAgkoUeZHlI-Szz9E',
); );
runApp(MyApp(client)); runApp(MyApp(client));
@@ -38,11 +38,11 @@ class ChannelListPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: ChannelListView( body: ChannelListView(
// filter: { filter: {
// 'members': { 'members': {
// '\$in': [StreamChat.of(context).user.id], '\$in': [StreamChat.of(context).user.id],
// } }
// }, },
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
limit: 20, limit: 20,
+1 -1
View File
@@ -89,7 +89,7 @@ class ChannelPreview extends StatelessWidget {
initialData: channel.state.typingEvents, initialData: channel.state.typingEvents,
builder: (context, snapshot) { builder: (context, snapshot) {
final typings = snapshot.data; final typings = snapshot.data;
final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5; final opacity = channel.state.unreadCount > 0 ? 1.0 : 0.5;
return typings.isNotEmpty return typings.isNotEmpty
? _buildTypings(typings, context, opacity) ? _buildTypings(typings, context, opacity)
: _buildLastMessage(context, opacity); : _buildLastMessage(context, opacity);
+129 -115
View File
@@ -118,10 +118,6 @@ class _MessageInputState extends State<MessageInput> {
} }
AnimatedCrossFade _animateSendButton(BuildContext context) { AnimatedCrossFade _animateSendButton(BuildContext context) {
print(
'_messageIsPresent || _attachments.isNotEmpty: ${_messageIsPresent || _attachments.isNotEmpty}');
print('_attachments.isNotEmpty: ${_attachments.isNotEmpty}');
print('_messageIsPresent: ${_messageIsPresent}');
return AnimatedCrossFade( return AnimatedCrossFade(
crossFadeState: (_messageIsPresent || _attachments.isNotEmpty) crossFadeState: (_messageIsPresent || _attachments.isNotEmpty)
? CrossFadeState.showFirst ? CrossFadeState.showFirst
@@ -214,46 +210,58 @@ class _MessageInputState extends State<MessageInput> {
RenderBox renderBox = context.findRenderObject(); RenderBox renderBox = context.findRenderObject();
final size = renderBox.size; final size = renderBox.size;
final offset = renderBox.localToGlobal(Offset.zero);
return OverlayEntry(builder: (_) { return OverlayEntry(builder: (context) {
return Positioned( return Positioned(
top: offset.dy - size.height, bottom: size.height + MediaQuery.of(context).viewInsets.bottom,
left: 0, left: 0,
right: 0, right: 0,
child: Material( child: Material(
color: StreamChatTheme.of(context).primaryColor, color: StreamChatTheme.of(context).primaryColor,
child: Flex( child: Container(
mainAxisSize: MainAxisSize.min, constraints: BoxConstraints.loose(Size.fromHeight(400)),
direction: Axis.vertical, decoration: BoxDecoration(
children: <Widget>[ boxShadow: [
ListView( BoxShadow(
padding: const EdgeInsets.all(0), spreadRadius: -8,
shrinkWrap: true, blurRadius: 5.0,
children: commands offset: Offset(0, -4),
.map((c) => ListTile( ),
title: Text.rich( ],
TextSpan( color: StreamChatTheme.of(context).primaryColor,
text: '${c.name}', ),
style: TextStyle(fontWeight: FontWeight.bold), child: Flex(
children: [ mainAxisSize: MainAxisSize.min,
TextSpan( direction: Axis.vertical,
text: ' ${c.args}', children: <Widget>[
style: TextStyle( ListView(
fontWeight: FontWeight.w300, padding: const EdgeInsets.all(0),
shrinkWrap: true,
children: commands
.map((c) => ListTile(
title: Text.rich(
TextSpan(
text: '${c.name}',
style: TextStyle(fontWeight: FontWeight.bold),
children: [
TextSpan(
text: ' ${c.args}',
style: TextStyle(
fontWeight: FontWeight.w300,
),
), ),
), ],
], ),
), ),
), subtitle: Text(c.description),
subtitle: Text(c.description), onTap: () {
onTap: () { _setCommand(c);
_setCommand(c); },
}, ))
)) .toList(),
.toList(), ),
), ],
], ),
), ),
), ),
); );
@@ -388,71 +396,7 @@ class _MessageInputState extends State<MessageInput> {
color: Colors.transparent, color: Colors.transparent,
child: IconButton( child: IconButton(
onPressed: () { onPressed: () {
showModalBottomSheet( _showAttachmentModal();
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
),
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(
'Add a file',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
ListTile(
leading: Icon(Icons.image),
title: Text('Upload a photo'),
onTap: () {
_pickFile(FileType.IMAGE, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.video_library),
title: Text('Upload a video'),
onTap: () {
_pickFile(FileType.VIDEO, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.camera_alt),
title: Text('Photo from camera'),
onTap: () {
ImagePicker.pickImage(source: ImageSource.camera);
_pickFile(FileType.IMAGE, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.videocam),
title: Text('Video from camera'),
onTap: () {
_pickFile(FileType.VIDEO, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.insert_drive_file),
title: Text('Upload a file'),
onTap: () {
_pickFile(FileType.ANY, false);
Navigator.pop(context);
},
),
],
);
});
}, },
icon: Icon( icon: Icon(
Icons.add_circle_outline, Icons.add_circle_outline,
@@ -461,6 +405,74 @@ class _MessageInputState extends State<MessageInput> {
); );
} }
void _showAttachmentModal() {
showModalBottomSheet(
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32),
topRight: Radius.circular(32),
),
),
context: context,
builder: (_) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(
'Add a file',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
ListTile(
leading: Icon(Icons.image),
title: Text('Upload a photo'),
onTap: () {
_pickFile(FileType.IMAGE, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.video_library),
title: Text('Upload a video'),
onTap: () {
_pickFile(FileType.VIDEO, false);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.camera_alt),
title: Text('Photo from camera'),
onTap: () {
ImagePicker.pickImage(source: ImageSource.camera);
_pickFile(FileType.IMAGE, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.videocam),
title: Text('Video from camera'),
onTap: () {
_pickFile(FileType.VIDEO, true);
Navigator.pop(context);
},
),
ListTile(
leading: Icon(Icons.insert_drive_file),
title: Text('Upload a file'),
onTap: () {
_pickFile(FileType.ANY, false);
Navigator.pop(context);
},
),
],
);
});
}
void _pickFile(FileType type, bool camera) async { void _pickFile(FileType type, bool camera) async {
File file; File file;
@@ -599,21 +611,23 @@ class _MessageInputState extends State<MessageInput> {
void initState() { void initState() {
super.initState(); super.initState();
_keyboardListener = _keyboardListener = KeyboardVisibilityNotification().addNewListener(
KeyboardVisibilityNotification().addNewListener(onHide: () { onHide: () {
if (_commandsOverlay != null) { if (_commandsOverlay != null) {
_commandsOverlay.remove(); _commandsOverlay.remove();
}
}, onShow: () {
if (_commandsOverlay != null) {
if (_textController.text.startsWith('/')) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_commandsOverlay = _buildOverlayEntry();
Overlay.of(context).insert(_commandsOverlay);
});
} }
} },
}); onShow: () {
if (_commandsOverlay != null) {
if (_textController.text.startsWith('/')) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_commandsOverlay = _buildOverlayEntry();
Overlay.of(context).insert(_commandsOverlay);
});
}
}
},
);
if (widget.editMessage != null) { if (widget.editMessage != null) {
_textController = TextEditingController(text: widget.editMessage.text); _textController = TextEditingController(text: widget.editMessage.text);
+16 -17
View File
@@ -687,26 +687,25 @@ class _MessageWidgetState extends State<MessageWidget>
} }
Row _buildReactionRow() { Row _buildReactionRow() {
final List<Widget> children =
widget.message.reactionCounts.keys.map((reactionType) {
return Text(
reactionToEmoji[reactionType] ?? '?',
) as Widget;
}).toList();
children.add(Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
widget.message.reactionCounts.values
.fold(0, (t, v) => v + t)
.toString(),
style: TextStyle(color: Colors.white),
),
));
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: children, children: [
...widget.message.reactionCounts.keys.map((reactionType) {
return Text(
reactionToEmoji[reactionType] ?? '?',
);
}),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
widget.message.reactionCounts.values
.fold(0, (t, v) => v + t)
.toString(),
style: TextStyle(color: Colors.white),
),
),
],
); );
} }