Merge branch 'feature/new-ui' into feature/image-detail
This commit is contained in:
@@ -119,8 +119,6 @@ PODS:
|
||||
- nanopb/encode (1.30906.0)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- "permission_handler (5.0.1+1)":
|
||||
- Flutter
|
||||
- photo_manager (0.0.1):
|
||||
- Flutter
|
||||
- PromisesObjC (1.2.11)
|
||||
@@ -178,7 +176,6 @@ DEPENDENCIES:
|
||||
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
|
||||
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
|
||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
@@ -238,8 +235,6 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/image_picker/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
permission_handler:
|
||||
:path: ".symlinks/plugins/permission_handler/ios"
|
||||
photo_manager:
|
||||
:path: ".symlinks/plugins/photo_manager/ios"
|
||||
shared_preferences:
|
||||
@@ -283,7 +278,6 @@ SPEC CHECKSUMS:
|
||||
image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
|
||||
photo_manager: f7c619c2cc8c2adb8d85c63363babac477de9c67
|
||||
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
|
||||
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
|
||||
|
||||
@@ -157,9 +157,8 @@ class ChooseUserPage extends StatelessWidget {
|
||||
}
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
Routes.CHANNEL_LIST,
|
||||
ModalRoute.withName(Routes.CHANNEL_LIST),
|
||||
arguments: client,
|
||||
Routes.HOME,
|
||||
ModalRoute.withName(Routes.HOME),
|
||||
);
|
||||
},
|
||||
leading: UserAvatar(
|
||||
|
||||
@@ -132,7 +132,7 @@ class _GroupChatDetailsScreenState extends State<GroupChatDetailsScreen> {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
Routes.CHANNEL_PAGE,
|
||||
ModalRoute.withName(Routes.CHANNEL_LIST),
|
||||
ModalRoute.withName(Routes.HOME),
|
||||
arguments: channel,
|
||||
);
|
||||
},
|
||||
|
||||
+235
-26
@@ -12,6 +12,8 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'notifications_service.dart';
|
||||
import 'routes/app_routes.dart';
|
||||
import 'routes/routes.dart';
|
||||
import 'search_text_field.dart';
|
||||
import 'dart:async';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@@ -58,15 +60,55 @@ class MyApp extends StatelessWidget {
|
||||
//TODO change to system once dark theme is implemented
|
||||
themeMode: ThemeMode.light,
|
||||
onGenerateRoute: AppRoutes.generateRoute,
|
||||
initialRoute: client.state.user == null
|
||||
? Routes.CHOOSE_USER
|
||||
: Routes.CHANNEL_LIST,
|
||||
initialRoute:
|
||||
client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelListPage extends StatelessWidget {
|
||||
class HomePage extends StatefulWidget {
|
||||
@override
|
||||
_HomePageState createState() => _HomePageState();
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> {
|
||||
int _currentIndex = 0;
|
||||
|
||||
bool _isSelected(int index) => _currentIndex == index;
|
||||
|
||||
List<BottomNavigationBarItem> get _navBarItems {
|
||||
return <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: Stack(
|
||||
overflow: Overflow.visible,
|
||||
children: [
|
||||
StreamSvgIcon.message(
|
||||
color: _isSelected(0) ? Colors.black : Colors.grey,
|
||||
),
|
||||
Positioned(
|
||||
top: -3,
|
||||
right: -16,
|
||||
child: UnreadIndicator(),
|
||||
),
|
||||
],
|
||||
),
|
||||
label: 'Chats',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Stack(
|
||||
overflow: Overflow.visible,
|
||||
children: [
|
||||
StreamSvgIcon.mentions(
|
||||
color: _isSelected(1) ? Colors.black : Colors.grey,
|
||||
),
|
||||
],
|
||||
),
|
||||
label: 'Mentions',
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final user = StreamChat.of(context).user;
|
||||
@@ -78,28 +120,22 @@ class ChannelListPage extends StatelessWidget {
|
||||
),
|
||||
drawer: _buildDrawer(context, user),
|
||||
drawerEdgeDragWidth: 50,
|
||||
body: ChannelsBloc(
|
||||
child: ChannelListView(
|
||||
onStartChatPressed: () {
|
||||
Navigator.pushNamed(context, Routes.NEW_CHAT);
|
||||
},
|
||||
swipeToAction: true,
|
||||
filter: {
|
||||
'members': {
|
||||
'\$in': [user.id],
|
||||
},
|
||||
'draft': {
|
||||
r'$ne': true,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
'presence': true,
|
||||
},
|
||||
pagination: PaginationParams(
|
||||
limit: 20,
|
||||
),
|
||||
channelWidget: ChannelPage(),
|
||||
),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
currentIndex: _currentIndex,
|
||||
items: _navBarItems,
|
||||
type: BottomNavigationBarType.fixed,
|
||||
selectedItemColor: Colors.black,
|
||||
unselectedItemColor: Colors.grey,
|
||||
onTap: (index) {
|
||||
setState(() => _currentIndex = index);
|
||||
},
|
||||
),
|
||||
body: IndexedStack(
|
||||
index: _currentIndex,
|
||||
children: [
|
||||
ChannelListPage(),
|
||||
UserMentionPage(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -207,6 +243,178 @@ class ChannelListPage extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class UserMentionPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Text('On Pause Right Now!'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelListPage extends StatefulWidget {
|
||||
@override
|
||||
_ChannelListPageState createState() => _ChannelListPageState();
|
||||
}
|
||||
|
||||
class _ChannelListPageState extends State<ChannelListPage> {
|
||||
TextEditingController _controller;
|
||||
|
||||
String _channelQuery = '';
|
||||
|
||||
bool _isSearchActive = false;
|
||||
|
||||
Timer _debounce;
|
||||
|
||||
void _channelQueryListener() {
|
||||
if (_debounce?.isActive ?? false) _debounce.cancel();
|
||||
_debounce = Timer(const Duration(milliseconds: 350), () {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_channelQuery = _controller.text;
|
||||
_isSearchActive = _channelQuery.isNotEmpty;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = TextEditingController()..addListener(_channelQueryListener);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller?.removeListener(_channelQueryListener);
|
||||
_controller?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final user = StreamChat.of(context).user;
|
||||
return ChannelsBloc(
|
||||
child: MessageSearchBloc(
|
||||
child: Column(
|
||||
children: [
|
||||
SearchTextField(
|
||||
controller: _controller,
|
||||
showCloseButton: _isSearchActive,
|
||||
),
|
||||
Expanded(
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onPanDown: (_) => FocusScope.of(context).unfocus(),
|
||||
child: _isSearchActive
|
||||
? MessageSearchListView(
|
||||
messageQuery: _channelQuery,
|
||||
filters: {
|
||||
'members': {
|
||||
r'$in': [user.id]
|
||||
}
|
||||
},
|
||||
sortOptions: [
|
||||
SortOption(
|
||||
'created_at',
|
||||
direction: SortOption.ASC,
|
||||
),
|
||||
],
|
||||
paginationParams: PaginationParams(limit: 20),
|
||||
onItemTap: (message) {},
|
||||
)
|
||||
: ChannelListView(
|
||||
onStartChatPressed: () {
|
||||
Navigator.pushNamed(context, Routes.NEW_CHAT);
|
||||
},
|
||||
swipeToAction: true,
|
||||
filter: {
|
||||
'members': {
|
||||
r'$in': [user.id],
|
||||
},
|
||||
},
|
||||
options: {
|
||||
'presence': true,
|
||||
},
|
||||
pagination: PaginationParams(
|
||||
limit: 20,
|
||||
),
|
||||
channelWidget: ChannelPage(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelQuerySearchResultPage extends StatelessWidget {
|
||||
final Stream<List<Message>> searchResultStream;
|
||||
|
||||
const ChannelQuerySearchResultPage({
|
||||
Key key,
|
||||
@required this.searchResultStream,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<List<Message>>(
|
||||
initialData: const <Message>[],
|
||||
stream: searchResultStream,
|
||||
builder: (context, snapshot) {
|
||||
final result = snapshot.data;
|
||||
return Column(
|
||||
children: [
|
||||
if (result.isNotEmpty)
|
||||
Container(
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Colors.black.withOpacity(0.02),
|
||||
Colors.white.withOpacity(0.05),
|
||||
],
|
||||
stops: [0, 1],
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Text(
|
||||
'${result.length} results',
|
||||
style: TextStyle(
|
||||
color: Colors.black.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: result.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
leading: UserAvatar(),
|
||||
title: Text(result[index].toJson().toString()),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelPage extends StatelessWidget {
|
||||
const ChannelPage({
|
||||
Key key,
|
||||
@@ -215,6 +423,7 @@ class ChannelPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color.fromRGBO(252, 252, 252, 1),
|
||||
appBar: ChannelHeader(
|
||||
showTypingIndicator: false,
|
||||
),
|
||||
|
||||
@@ -338,7 +338,7 @@ class _NewChatScreenState extends State<NewChatScreen> {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
Routes.CHANNEL_PAGE,
|
||||
ModalRoute.withName(Routes.CHANNEL_LIST),
|
||||
ModalRoute.withName(Routes.HOME),
|
||||
arguments: channel,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ void showLocalNotification(Message message, ChannelModel channel) async {
|
||||
}
|
||||
|
||||
Future backgroundHandler(Map<String, dynamic> notification) async {
|
||||
final messageId = notification['data']['message_id'];
|
||||
print('new notification ${notification}');
|
||||
final messageId = notification['data']['id'];
|
||||
|
||||
final notificationData =
|
||||
await NotificationService.getAndStoreMessage(messageId);
|
||||
|
||||
@@ -13,11 +13,11 @@ class AppRoutes {
|
||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
final args = settings.arguments;
|
||||
switch (settings.name) {
|
||||
case Routes.CHANNEL_LIST:
|
||||
case Routes.HOME:
|
||||
return MaterialPageRoute(
|
||||
settings: const RouteSettings(name: Routes.CHANNEL_LIST),
|
||||
settings: const RouteSettings(name: Routes.HOME),
|
||||
builder: (_) {
|
||||
return ChannelListPage();
|
||||
return HomePage();
|
||||
});
|
||||
case Routes.CHOOSE_USER:
|
||||
return MaterialPageRoute(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// Define all the route names here
|
||||
class Routes {
|
||||
static const String CHANNEL_LIST = '/channel_list';
|
||||
static const String HOME = '/home';
|
||||
static const String CHOOSE_USER = '/choose_user';
|
||||
static const String ADVANCED_OPTIONS = '/advance_options';
|
||||
static const String CHANNEL_PAGE = '/channel_page';
|
||||
|
||||
@@ -78,7 +78,7 @@ class SearchTextField extends StatelessWidget {
|
||||
Future.microtask(
|
||||
() => [
|
||||
controller.clear(),
|
||||
onChanged(''),
|
||||
if (onChanged != null) onChanged(''),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: example
|
||||
description: A new Flutter project.
|
||||
version: 1.0.79+81
|
||||
version: 1.0.87+89
|
||||
|
||||
environment:
|
||||
sdk: ">=2.2.2 <3.0.0"
|
||||
|
||||
Reference in New Issue
Block a user