Merge branches 'feature/new-ui' and 'qa/new-chat-screens' of github.com:GetStream/stream-chat-flutter into qa/new-chat-screens
Conflicts: example/lib/group_chat_details_screen.dart example/lib/new_group_chat_screen.dart
This commit is contained in:
@@ -284,4 +284,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: eb001256612a59f8f9e4d083ad8b9671e69dd184
|
||||
|
||||
COCOAPODS: 1.10.0.rc.1
|
||||
COCOAPODS: 1.10.0
|
||||
|
||||
@@ -44,8 +44,7 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
|
||||
),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(
|
||||
StreamIcons.left,
|
||||
icon: StreamSvgIcon.left(
|
||||
color: Colors.black,
|
||||
),
|
||||
onPressed: () {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_icons.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
typedef ChipBuilder<T> = Widget Function(BuildContext context, T chip);
|
||||
typedef OnChipAdded<T> = void Function(T chip);
|
||||
@@ -124,13 +124,15 @@ class ChipInputTextFieldState<T> extends State<ChipsInputTextField<T>> {
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: IconButton(
|
||||
icon: Icon(
|
||||
_chips.isEmpty
|
||||
? StreamIcons.user
|
||||
: StreamIcons.user_add,
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
size: 24,
|
||||
),
|
||||
icon: _chips.isEmpty
|
||||
? StreamSvgIcon.user(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
size: 24,
|
||||
)
|
||||
: StreamSvgIcon.userAdd(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
size: 24,
|
||||
),
|
||||
onPressed:
|
||||
!_pauseItemAddition ? null : resumeItemAddition,
|
||||
alignment: Alignment.topRight,
|
||||
|
||||
@@ -196,8 +196,7 @@ class ChooseUserPage extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
leading: CircleAvatar(
|
||||
child: Icon(
|
||||
StreamIcons.settings,
|
||||
child: StreamSvgIcon.settings(
|
||||
color: Colors.black,
|
||||
),
|
||||
backgroundColor:
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'neumorphic_button.dart';
|
||||
|
||||
class GroupChatDetailsScreen extends StatefulWidget {
|
||||
final List<User> selectedUsers;
|
||||
@@ -53,173 +52,169 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
Navigator.pop(context, _selectedUsers);
|
||||
return false;
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
|
||||
appBar: AppBar(
|
||||
elevation: 1,
|
||||
backgroundColor: Colors.white,
|
||||
leading: const StreamBackButton(),
|
||||
title: Text(
|
||||
'Name of Group Chat',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
),
|
||||
return Scaffold(
|
||||
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
|
||||
appBar: AppBar(
|
||||
elevation: 1,
|
||||
backgroundColor: Colors.white,
|
||||
leading: const StreamBackButton(),
|
||||
title: Text(
|
||||
'Name of Group Chat',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
),
|
||||
centerTitle: true,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(kToolbarHeight),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'NAME',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _groupNameController,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
errorBorder: InputBorder.none,
|
||||
disabledBorder: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
hintText: 'Choose a group chat name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: Colors.black.withOpacity(.5)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
NeumorphicButton(
|
||||
child: IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
icon: Icon(StreamIcons.check),
|
||||
color: Color(0xFF006CFF),
|
||||
onPressed: _isGroupNameEmpty
|
||||
? null
|
||||
: () async {
|
||||
final groupName = _groupNameController.text;
|
||||
final client = StreamChat.of(context).client;
|
||||
final channel = client
|
||||
.channel('messaging', id: Uuid().v4(), extraData: {
|
||||
'members': [
|
||||
client.state.user.id,
|
||||
..._selectedUsers.map((e) => e.id),
|
||||
],
|
||||
'name': groupName,
|
||||
});
|
||||
await channel.watch();
|
||||
Navigator.of(context)
|
||||
..pop()
|
||||
..pushReplacement(
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
child: ChannelPage(),
|
||||
channel: channel,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.maxFinite,
|
||||
color: Colors.grey.shade50,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Text(
|
||||
'$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}',
|
||||
centerTitle: true,
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(kToolbarHeight),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'NAME',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12,
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _groupNameController,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
errorBorder: InputBorder.none,
|
||||
disabledBorder: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
hintText: 'Choose a group chat name',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: Colors.black.withOpacity(.5)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
NeumorphicButton(
|
||||
child: IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
icon: StreamSvgIcon.check(
|
||||
size: 24,
|
||||
color: _isGroupNameEmpty ? Colors.grey : Color(0xFF006CFF),
|
||||
),
|
||||
onPressed: _isGroupNameEmpty
|
||||
? null
|
||||
: () async {
|
||||
final groupName = _groupNameController.text;
|
||||
final client = StreamChat.of(context).client;
|
||||
final channel = client
|
||||
.channel('messaging', id: Uuid().v4(), extraData: {
|
||||
'members': [
|
||||
client.state.user.id,
|
||||
..._selectedUsers.map((e) => e.id),
|
||||
],
|
||||
'name': groupName,
|
||||
});
|
||||
await channel.watch();
|
||||
Navigator.of(context)
|
||||
..pop()
|
||||
..pushReplacement(
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return StreamChannel(
|
||||
child: ChannelPage(),
|
||||
channel: channel,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: _selectedUsers.length + 1,
|
||||
separatorBuilder: (_, __) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(0.1)
|
||||
: Colors.black.withOpacity(0.1),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.maxFinite,
|
||||
color: Colors.grey.shade50,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Text(
|
||||
'$_totalUsers ${_totalUsers > 1 ? 'Members' : 'Member'}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
itemBuilder: (_, index) {
|
||||
if (index == _selectedUsers.length) {
|
||||
return Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(0.1)
|
||||
: Colors.black.withOpacity(0.1),
|
||||
);
|
||||
}
|
||||
final user = _selectedUsers[index];
|
||||
return ListTile(
|
||||
key: ObjectKey(user),
|
||||
leading: UserAvatar(
|
||||
user: user,
|
||||
constraints: BoxConstraints.tightFor(
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
user.name,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 8,
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
Icons.clear_rounded,
|
||||
color: Colors.black,
|
||||
),
|
||||
padding: const EdgeInsets.all(0),
|
||||
splashRadius: 24,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_selectedUsers.remove(user);
|
||||
});
|
||||
if (_selectedUsers.isEmpty) {
|
||||
Navigator.pop(context, _selectedUsers);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: _selectedUsers.length + 1,
|
||||
separatorBuilder: (_, __) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(0.1)
|
||||
: Colors.black.withOpacity(0.1),
|
||||
),
|
||||
itemBuilder: (_, index) {
|
||||
if (index == _selectedUsers.length) {
|
||||
return Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.white.withOpacity(0.1)
|
||||
: Colors.black.withOpacity(0.1),
|
||||
);
|
||||
}
|
||||
final user = _selectedUsers[index];
|
||||
return ListTile(
|
||||
key: ObjectKey(user),
|
||||
leading: UserAvatar(
|
||||
user: user,
|
||||
constraints: BoxConstraints.tightFor(
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
user.name,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 8,
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
Icons.clear_rounded,
|
||||
color: Colors.black,
|
||||
),
|
||||
padding: const EdgeInsets.all(0),
|
||||
splashRadius: 24,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_selectedUsers.remove(user);
|
||||
});
|
||||
if (_selectedUsers.isEmpty) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
+17
-9
@@ -69,12 +69,14 @@ class ChannelListPage extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final user = StreamChat.of(context).user;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
title: Text(
|
||||
'Stream Chat',
|
||||
style: TextStyle(color: Colors.black),
|
||||
),
|
||||
appBar: ChannelListHeader(
|
||||
onNewChatButtonTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => NewChatScreen(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
drawer: _buildDrawer(context, user),
|
||||
drawerEdgeDragWidth: 50,
|
||||
@@ -141,7 +143,9 @@ class ChannelListPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.edit),
|
||||
leading: StreamSvgIcon.penWrite(
|
||||
color: Colors.black.withOpacity(.5),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
..pop()
|
||||
@@ -157,7 +161,9 @@ class ChannelListPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.group),
|
||||
leading: StreamSvgIcon.contacts(
|
||||
color: Colors.black.withOpacity(.5),
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.of(context)
|
||||
..pop()
|
||||
@@ -189,7 +195,9 @@ class ChannelListPage extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: Icon(StreamIcons.user),
|
||||
leading: StreamSvgIcon.user(
|
||||
color: Colors.black.withOpacity(.5),
|
||||
),
|
||||
title: Text(
|
||||
'Sign out',
|
||||
style: TextStyle(
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NeumorphicButton extends StatelessWidget {
|
||||
final Widget child;
|
||||
final Color backgroundColor;
|
||||
|
||||
const NeumorphicButton({
|
||||
Key key,
|
||||
@required this.child,
|
||||
this.backgroundColor = Colors.white,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: child,
|
||||
margin: EdgeInsets.all(8.0),
|
||||
height: 40,
|
||||
width: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey[700],
|
||||
offset: Offset(0, 1.0),
|
||||
blurRadius: 0.5,
|
||||
spreadRadius: 0,
|
||||
),
|
||||
BoxShadow(
|
||||
color: Colors.white,
|
||||
offset: Offset.zero,
|
||||
blurRadius: 0.5,
|
||||
spreadRadius: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
import 'chips_input_text_field.dart';
|
||||
import 'main.dart';
|
||||
import 'neumorphic_button.dart';
|
||||
import 'new_group_chat_screen.dart';
|
||||
|
||||
class NewChatScreen extends StatefulWidget {
|
||||
@@ -164,8 +163,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
child: Icon(
|
||||
StreamIcons.close,
|
||||
child: StreamSvgIcon.close(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
@@ -193,10 +191,12 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
NeumorphicButton(
|
||||
child: Icon(
|
||||
StreamIcons.group,
|
||||
color: Color(0xFF006CFF),
|
||||
StreamNeumorphicButton(
|
||||
child: Center(
|
||||
child: StreamSvgIcon.contacts(
|
||||
color: Color(0xFF006CFF),
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
@@ -289,8 +289,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Icon(
|
||||
StreamIcons.search,
|
||||
child: StreamSvgIcon.search(
|
||||
size: 96,
|
||||
color: Colors.grey,
|
||||
),
|
||||
|
||||
@@ -47,10 +47,12 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: UsersBloc(
|
||||
child: Scaffold(
|
||||
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
|
||||
body: NestedScrollView(
|
||||
floatHeaderSlivers: true,
|
||||
headerSliverBuilder:
|
||||
@@ -74,8 +76,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||
actions: [
|
||||
if (_selectedUsers.isNotEmpty)
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
StreamIcons.arrow_right,
|
||||
icon: StreamSvgIcon.right(
|
||||
color: Color(0xFF006CFF),
|
||||
),
|
||||
onPressed: () async {
|
||||
@@ -116,8 +117,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(
|
||||
StreamIcons.search,
|
||||
prefixIcon: StreamSvgIcon.search(
|
||||
color: Colors.black,
|
||||
size: 24,
|
||||
),
|
||||
@@ -181,8 +181,8 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(0.0),
|
||||
child: Icon(
|
||||
StreamIcons.close,
|
||||
child: StreamSvgIcon.close(
|
||||
color: Colors.black,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -288,8 +288,7 @@ class _NewGroupChatScreenState extends State<NewGroupChatScreen> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Icon(
|
||||
StreamIcons.search,
|
||||
child: StreamSvgIcon.search(
|
||||
size: 96,
|
||||
color: Colors.grey,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: example
|
||||
description: A new Flutter project.
|
||||
version: 1.0.66+68
|
||||
version: 1.0.72+74
|
||||
|
||||
environment:
|
||||
sdk: ">=2.2.2 <3.0.0"
|
||||
|
||||
Reference in New Issue
Block a user