UI nit picks

This commit is contained in:
xsahil03x
2020-11-20 17:55:55 +05:30
parent 389656a477
commit c384588d5b
4 changed files with 102 additions and 111 deletions
+5 -4
View File
@@ -34,10 +34,8 @@ class ChipInputTextFieldState<T> extends State<ChipsInputTextField<T>> {
bool _pauseItemAddition = false; bool _pauseItemAddition = false;
void addItem(T item) { void addItem(T item) {
if (!_pauseItemAddition) { setState(() => _chips.add(item));
setState(() => _chips.add(item)); if (widget.onChipAdded != null) widget.onChipAdded(item);
if (widget.onChipAdded != null) widget.onChipAdded(item);
}
} }
void removeItem(T item) { void removeItem(T item) {
@@ -108,6 +106,9 @@ class ChipInputTextFieldState<T> extends State<ChipsInputTextField<T>> {
disabledBorder: InputBorder.none, disabledBorder: InputBorder.none,
contentPadding: const EdgeInsets.only(top: 4.0), contentPadding: const EdgeInsets.only(top: 4.0),
hintText: widget.hint, hintText: widget.hint,
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.5),
),
), ),
), ),
] ]
+54 -24
View File
@@ -309,6 +309,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
backgroundColor: Colors.white, backgroundColor: Colors.white,
@@ -367,7 +368,6 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
if (!_isSearchActive) if (!_isSearchActive)
Container( Container(
color: Colors.white54,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
Navigator.push( Navigator.push(
@@ -375,23 +375,26 @@ class _NewChatScreenState extends State<NewChatScreen> {
MaterialPageRoute(builder: (_) => NewGroupChatScreen()), MaterialPageRoute(builder: (_) => NewGroupChatScreen()),
); );
}, },
child: Row( child: Padding(
children: [ padding: const EdgeInsets.symmetric(vertical: 8),
NeumorphicButton( child: Row(
child: Icon( children: [
StreamIcons.group, NeumorphicButton(
color: Colors.blue.shade700, child: Icon(
StreamIcons.group,
color: Color(0xFF006CFF),
),
), ),
), SizedBox(width: 8),
SizedBox(width: 8), Text(
Text( 'Create a Group',
'Create a Group', style: TextStyle(
style: TextStyle( fontWeight: FontWeight.bold,
fontWeight: FontWeight.w500, fontSize: 16,
fontSize: 18, ),
), ),
), ],
], ),
), ),
), ),
), ),
@@ -425,20 +428,33 @@ class _NewChatScreenState extends State<NewChatScreen> {
), ),
Expanded( Expanded(
child: UserListView( child: UserListView(
filterByUserName: _userNameQuery,
selectedUsers: _selectedUsers, selectedUsers: _selectedUsers,
groupAlphabetically: _isSearchActive ? false : true, groupAlphabetically: _isSearchActive ? false : true,
onUserTap: (user, _) { onUserTap: (user, _) {
_controller.clear();
if (!_selectedUsers.contains(user)) { if (!_selectedUsers.contains(user)) {
_controller.clear();
_chipInputTextFieldState _chipInputTextFieldState
..addItem(user) ..addItem(user)
..pauseItemAddition(); ..pauseItemAddition();
} else {
_chipInputTextFieldState.removeItem(user);
} }
}, },
pagination: PaginationParams( pagination: PaginationParams(
limit: 25, limit: 25,
), ),
filter: {
if (_userNameQuery.isNotEmpty)
'name': {
r'$autocomplete': _userNameQuery,
}
},
sort: [
SortOption(
'name',
direction: 1,
),
],
emptyBuilder: (_) { emptyBuilder: (_) {
return LayoutBuilder( return LayoutBuilder(
builder: (context, viewportConstraints) { builder: (context, viewportConstraints) {
@@ -541,6 +557,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
appBar: AppBar( appBar: AppBar(
elevation: 1, elevation: 1,
backgroundColor: Colors.white, backgroundColor: Colors.white,
@@ -555,7 +572,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
IconButton( IconButton(
icon: Icon( icon: Icon(
StreamIcons.arrow_right, StreamIcons.arrow_right,
color: Colors.blue.shade700, color: Color(0xFF006CFF),
), ),
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
@@ -576,6 +593,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
Container( Container(
height: 36, height: 36,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white,
border: Border.all( border: Border.all(
color: Colors.grey.shade300, color: Colors.grey.shade300,
), ),
@@ -593,8 +611,10 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
color: Colors.black, color: Colors.black,
), ),
hintText: 'Search', hintText: 'Search',
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.5),
),
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
// isDense: true,
border: OutlineInputBorder( border: OutlineInputBorder(
borderSide: BorderSide.none, borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(24), borderRadius: BorderRadius.circular(24),
@@ -696,7 +716,6 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
), ),
Expanded( Expanded(
child: UserListView( child: UserListView(
filterByUserName: _userNameQuery,
selectedUsers: _selectedUsers, selectedUsers: _selectedUsers,
groupAlphabetically: _isSearchActive ? false : true, groupAlphabetically: _isSearchActive ? false : true,
onUserTap: (user, _) { onUserTap: (user, _) {
@@ -709,6 +728,18 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
pagination: PaginationParams( pagination: PaginationParams(
limit: 25, limit: 25,
), ),
filter: {
if (_userNameQuery.isNotEmpty)
'name': {
r'$autocomplete': _userNameQuery,
}
},
sort: [
SortOption(
'name',
direction: 1,
),
],
emptyBuilder: (_) { emptyBuilder: (_) {
return LayoutBuilder( return LayoutBuilder(
builder: (context, viewportConstraints) { builder: (context, viewportConstraints) {
@@ -797,6 +828,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
appBar: AppBar( appBar: AppBar(
elevation: 1, elevation: 1,
backgroundColor: Colors.white, backgroundColor: Colors.white,
@@ -840,12 +872,10 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
), ),
actions: [ actions: [
NeumorphicButton( NeumorphicButton(
padding: const EdgeInsets.all(8),
margin: const EdgeInsets.symmetric(vertical: 8),
child: IconButton( child: IconButton(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
icon: Icon(StreamIcons.check), icon: Icon(StreamIcons.check),
color: Colors.blue.shade700, color: Color(0xFF006CFF),
onPressed: _isGroupNameEmpty onPressed: _isGroupNameEmpty
? null ? null
: () async { : () async {
+13 -25
View File
@@ -1,50 +1,38 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
extension ColorUtils on Color {
Color mix(Color another, double amount) {
return Color.lerp(this, another, amount);
}
}
class NeumorphicButton extends StatelessWidget { class NeumorphicButton extends StatelessWidget {
final Widget child; final Widget child;
final Color backgroundColor; final Color backgroundColor;
final EdgeInsets margin;
final EdgeInsets padding;
const NeumorphicButton({ const NeumorphicButton({
Key key, Key key,
@required this.child, @required this.child,
this.backgroundColor = Colors.white, this.backgroundColor = Colors.white,
this.margin = const EdgeInsets.all(8),
this.padding = const EdgeInsets.all(14),
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
child: child, child: child,
margin: margin, margin: EdgeInsets.all(8.0),
padding: padding, height: 40,
width: 40,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle,
color: backgroundColor, color: backgroundColor,
gradient: LinearGradient( shape: BoxShape.circle,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
backgroundColor.mix(Colors.white, 0.2),
backgroundColor.mix(Colors.black, 0.1),
]),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
blurRadius: 1, color: Colors.grey[700],
color: backgroundColor.mix(Colors.white, 0.6), offset: Offset(0, 1.0),
blurRadius: 0.5,
spreadRadius: 0,
), ),
BoxShadow( BoxShadow(
blurRadius: 1, color: Colors.white,
color: backgroundColor.mix(Colors.black, 0.3), offset: Offset.zero,
) blurRadius: 0.5,
spreadRadius: 0,
),
], ],
), ),
); );
+30 -58
View File
@@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat/stream_chat.dart';
import 'package:stream_chat_flutter/src/users_bloc.dart'; import 'package:stream_chat_flutter/src/users_bloc.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -66,13 +65,7 @@ class UserListView extends StatefulWidget {
this.swipeToAction = false, this.swipeToAction = false,
this.pullToRefresh = true, this.pullToRefresh = true,
this.groupAlphabetically = false, this.groupAlphabetically = false,
this.filterByUserName = '', }) : super(key: key);
this.filterByUserNameStream,
}) : assert(
filterByUserName == null || filterByUserNameStream == null,
'Cannot provide both filterByUserName and filterByUserNameStream.',
),
super(key: key);
/// The builder that will be used in case of error /// The builder that will be used in case of error
final Widget Function(Error error) errorBuilder; final Widget Function(Error error) errorBuilder;
@@ -137,12 +130,6 @@ class UserListView extends StatefulWidget {
/// defaults to false /// defaults to false
final bool groupAlphabetically; final bool groupAlphabetically;
///
final String filterByUserName;
///
final Stream<String> filterByUserNameStream;
@override @override
_UserListViewState createState() => _UserListViewState(); _UserListViewState createState() => _UserListViewState();
} }
@@ -154,8 +141,8 @@ class _UserListViewState extends State<UserListView>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
final channelsBloc = UsersBloc.of(context); final usersBloc = UsersBloc.of(context);
channelsBloc.queryUsers( usersBloc.queryUsers(
filter: widget.filter, filter: widget.filter,
sort: widget.sort, sort: widget.sort,
pagination: widget.pagination, pagination: widget.pagination,
@@ -163,9 +150,9 @@ class _UserListViewState extends State<UserListView>
); );
_scrollController.addListener(() { _scrollController.addListener(() {
channelsBloc.queryUsersLoading.first.then((loading) { usersBloc.queryUsersLoading.first.then((loading) {
if (!loading) { if (!loading) {
_listenUserPagination(channelsBloc); _listenUserPagination(usersBloc);
} }
}); });
}); });
@@ -192,42 +179,28 @@ class _UserListViewState extends State<UserListView>
); );
} }
List<ListItem> _getFilteredItems(List<User> users, String query) {
if (widget.groupAlphabetically) {
var temp = users..sort((curr, next) => curr.name.compareTo(next.name));
temp = temp
.where((it) => it.name.toLowerCase().contains(query.toLowerCase()))
.toList();
final groupedUsers = <String, List<User>>{};
for (var e in temp) {
final alphabet = e.name[0];
groupedUsers[alphabet] = [...groupedUsers[alphabet] ?? [], e];
}
final items = <ListItem>[];
for (var key in groupedUsers.keys) {
items.add(ListHeaderItem(key));
items.addAll(groupedUsers[key].map((e) => ListUserItem(e)));
}
return items;
}
return users
.where((it) => it.name.toLowerCase().contains(query.toLowerCase()))
.map((e) => ListUserItem(e))
.toList();
}
Stream<List<ListItem>> _buildUserStream( Stream<List<ListItem>> _buildUserStream(
UsersBlocState usersBlocState, UsersBlocState usersBlocState,
) { ) {
if (widget.filterByUserNameStream == null) { return usersBlocState.usersStream.map(
return usersBlocState.usersStream.map( (users) {
(users) => _getFilteredItems(users, widget.filterByUserName), if (widget.groupAlphabetically) {
); var temp = users
} ..sort((curr, next) => curr.name.compareTo(next.name));
return Rx.combineLatest2( final groupedUsers = <String, List<User>>{};
usersBlocState.usersStream, for (var e in temp) {
widget.filterByUserNameStream, final alphabet = e.name[0];
_getFilteredItems, groupedUsers[alphabet] = [...groupedUsers[alphabet] ?? [], e];
}
final items = <ListItem>[];
for (var key in groupedUsers.keys) {
items.add(ListHeaderItem(key));
items.addAll(groupedUsers[key].map((e) => ListUserItem(e)));
}
return items;
}
return users.map((e) => ListUserItem(e)).toList();
},
); );
} }
@@ -378,14 +351,13 @@ class _UserListViewState extends State<UserListView>
key: ValueKey<String>('HEADER-$header'), key: ValueKey<String>('HEADER-$header'),
color: Colors.black.withOpacity(0.05), color: Colors.black.withOpacity(0.05),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal:8.0,vertical: 6), padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6),
child: Text( child: Text(
header, header,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 12, fontSize: 12,
color:Colors.black.withOpacity(0.3) color: Colors.black.withOpacity(0.3)),
),
), ),
), ),
); );
@@ -469,8 +441,8 @@ class _UserListViewState extends State<UserListView>
widget.pagination?.toJson()?.toString() != widget.pagination?.toJson()?.toString() !=
oldWidget.pagination?.toJson()?.toString() || oldWidget.pagination?.toJson()?.toString() ||
widget.options?.toString() != oldWidget.options?.toString()) { widget.options?.toString() != oldWidget.options?.toString()) {
final channelsBloc = UsersBloc.of(context); final usersBloc = UsersBloc.of(context);
channelsBloc.queryUsers( usersBloc.queryUsers(
filter: widget.filter, filter: widget.filter,
sort: widget.sort, sort: widget.sort,
pagination: widget.pagination, pagination: widget.pagination,