feat: Added file and image screens, group info details

This commit is contained in:
Deven Joshi
2020-12-17 19:42:07 +05:30
parent d2a115be6f
commit 7c24e7b202
6 changed files with 364 additions and 15 deletions
+135 -1
View File
@@ -1,7 +1,52 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/lazy_load_scroll_view.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
class ChannelFileDisplayScreen extends StatelessWidget {
class ChannelFileDisplayScreen extends StatefulWidget {
/// The sorting used for the channels matching the filters.
/// Sorting is based on field and direction, multiple sorting options can be provided.
/// You can sort based on last_updated, last_message_at, updated_at, created_at or member_count.
/// Direction can be ascending or descending.
final List<SortOption> sortOptions;
/// Pagination parameters
/// limit: the number of users to return (max is 30)
/// offset: the offset (max is 1000)
/// message_limit: how many messages should be included to each channel
final PaginationParams paginationParams;
ChannelFileDisplayScreen({
this.sortOptions,
this.paginationParams,
});
@override
_ChannelFileDisplayScreenState createState() =>
_ChannelFileDisplayScreenState();
}
class _ChannelFileDisplayScreenState extends State<ChannelFileDisplayScreen> {
@override
void initState() {
super.initState();
final messageSearchBloc = MessageSearchBloc.of(context);
messageSearchBloc.search(
filter: {
'cid': {
r'$in': ['messaging:${StreamChannel.of(context).channel.id}']
}
},
messageFilter: {
'attachments.type': {
r'$in': ['file'],
},
},
sort: widget.sortOptions,
pagination: widget.paginationParams,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -31,6 +76,95 @@ class ChannelFileDisplayScreen extends StatelessWidget {
),
backgroundColor: StreamChatTheme.of(context).primaryColor,
),
body: _buildMediaGrid(),
);
}
Widget _buildMediaGrid() {
final messageSearchBloc = MessageSearchBloc.of(context);
return StreamBuilder<List<GetMessageResponse>>(
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(
child: CircularProgressIndicator(
backgroundColor: StreamChatTheme.of(context).accentColor,
),
);
}
if (snapshot.data.isEmpty) {
return Center(
child: Text('Nothing here...'),
);
}
Map<Attachment, Message> media = {};
for (var item in snapshot.data) {
item.message.attachments
.where((e) => e.type == 'file')
.forEach((e) {
media[e] = item.message;
});
}
return LazyLoadScrollView(
onEndOfPage: () => messageSearchBloc.search(
filter: {
'cid': {
r'$in': ['messaging:${StreamChannel.of(context).channel.id}']
}
},
messageFilter: {
'attachments.type': {
r'$in': ['file']
},
},
sort: widget.sortOptions,
pagination: widget.paginationParams.copyWith(
offset: messageSearchBloc.messageResponses?.length ?? 0,
),
),
child: ListView.builder(
itemBuilder: (context, position) {
var channel = StreamChannel.of(context).channel;
return Padding(
padding: const EdgeInsets.all(1.0),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: FullScreenMedia(
mediaAttachments: [
media.keys.toList()[position],
],
message: media.values.toList()[position],
sentAt: media.values.toList()[position].createdAt,
userName: media.values.toList()[position].user.name,
),
),
),
);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: FileAttachment(
attachment: media.keys.toList()[position],
),
),
),
);
},
itemCount: media.length,
),
);
},
stream: messageSearchBloc.messagesStream,
);
}
}
+146 -1
View File
@@ -1,7 +1,50 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/lazy_load_scroll_view.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:video_player/video_player.dart';
class ChannelMediaDisplayScreen extends StatefulWidget {
/// The sorting used for the channels matching the filters.
/// Sorting is based on field and direction, multiple sorting options can be provided.
/// You can sort based on last_updated, last_message_at, updated_at, created_at or member_count.
/// Direction can be ascending or descending.
final List<SortOption> sortOptions;
/// Pagination parameters
/// limit: the number of users to return (max is 30)
/// offset: the offset (max is 1000)
/// message_limit: how many messages should be included to each channel
final PaginationParams paginationParams;
ChannelMediaDisplayScreen({this.sortOptions, this.paginationParams});
@override
_ChannelMediaDisplayScreenState createState() =>
_ChannelMediaDisplayScreenState();
}
class _ChannelMediaDisplayScreenState extends State<ChannelMediaDisplayScreen> {
@override
void initState() {
super.initState();
final messageSearchBloc = MessageSearchBloc.of(context);
messageSearchBloc.search(
filter: {
'cid': {
r'$in': ['messaging:${StreamChannel.of(context).channel.id}']
}
},
messageFilter: {
'attachments.type': {
r'$in': ['image', 'video']
},
},
sort: widget.sortOptions,
pagination: widget.paginationParams,
);
}
class ChannelMediaDisplayScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -31,6 +74,108 @@ class ChannelMediaDisplayScreen extends StatelessWidget {
),
backgroundColor: StreamChatTheme.of(context).primaryColor,
),
body: _buildMediaGrid(),
);
}
Widget _buildMediaGrid() {
final messageSearchBloc = MessageSearchBloc.of(context);
return StreamBuilder<List<GetMessageResponse>>(
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(
child: CircularProgressIndicator(
backgroundColor: StreamChatTheme.of(context).accentColor,
),
);
}
if (snapshot.data.isEmpty) {
return Center(
child: Text('Nothing here...'),
);
}
List<_AssetPackage> media = [];
for (var item in snapshot.data) {
item.message.attachments
.where((e) => e.type == 'image' || e.type == 'video')
.forEach((e) {
VideoPlayerController controller;
if(e.type == 'video') {
controller = VideoPlayerController.network(e.assetUrl);
controller.initialize();
}
media.add(_AssetPackage(e, item.message, controller));
});
}
return LazyLoadScrollView(
onEndOfPage: () => messageSearchBloc.search(
filter: {
'cid': {
r'$in': ['messaging:${StreamChannel.of(context).channel.id}']
}
},
messageFilter: {
'attachments.type': {
r'$in': ['image', 'video']
},
},
sort: widget.sortOptions,
pagination: widget.paginationParams.copyWith(
offset: messageSearchBloc.messageResponses?.length ?? 0,
),
),
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemBuilder: (context, position) {
var channel = StreamChannel.of(context).channel;
return Padding(
padding: const EdgeInsets.all(1.0),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: FullScreenMedia(
mediaAttachments: [
media[position].attachment,
],
message: media[position].message,
sentAt: media[position].message.createdAt,
userName: media[position].message.user.name,
),
),
),
);
},
child: media[position].attachment.type == 'image' ? CachedNetworkImage(
imageUrl: media[position].attachment.imageUrl,
fit: BoxFit.cover,
) : VideoPlayer(media[position].videoPlayer),
),
);
},
itemCount: media.length,
),
);
},
stream: messageSearchBloc.messagesStream,
);
}
}
class _AssetPackage {
Attachment attachment;
Message message;
VideoPlayerController videoPlayer;
_AssetPackage(this.attachment, this.message, this.videoPlayer);
}
+40 -6
View File
@@ -174,10 +174,27 @@ class _ChatInfoScreenState extends State<ChatInfoScreen> {
),
trailing: StreamSvgIcon.right(),
onTap: () {
final channel = StreamChannel.of(context).channel;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChannelMediaDisplayScreen()));
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: MessageSearchBloc(
child: ChannelMediaDisplayScreen(
sortOptions: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
paginationParams: PaginationParams(limit: 20),
),
),
),
),
);
},
),
OptionListTile(
@@ -188,10 +205,27 @@ class _ChatInfoScreenState extends State<ChatInfoScreen> {
),
trailing: StreamSvgIcon.right(),
onTap: () {
final channel = StreamChannel.of(context).channel;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChannelFileDisplayScreen()));
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: MessageSearchBloc(
child: ChannelFileDisplayScreen(
sortOptions: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
paginationParams: PaginationParams(limit: 20),
),
),
),
),
);
},
),
OptionListTile(
+40 -6
View File
@@ -361,10 +361,27 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
),
trailing: StreamSvgIcon.right(),
onTap: () {
var channel = StreamChannel.of(context).channel;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChannelMediaDisplayScreen()));
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: MessageSearchBloc(
child: ChannelMediaDisplayScreen(
sortOptions: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
paginationParams: PaginationParams(limit: 20),
),
),
),
),
);
},
),
OptionListTile(
@@ -375,10 +392,27 @@ class _GroupInfoScreenState extends State<GroupInfoScreen> {
),
trailing: StreamSvgIcon.right(),
onTap: () {
var channel = StreamChannel.of(context).channel;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChannelFileDisplayScreen()));
context,
MaterialPageRoute(
builder: (context) => StreamChannel(
channel: channel,
child: MessageSearchBloc(
child: ChannelFileDisplayScreen(
sortOptions: [
SortOption(
'created_at',
direction: SortOption.ASC,
),
],
paginationParams: PaginationParams(limit: 20),
),
),
),
),
);
},
),
OptionListTile(
+2
View File
@@ -55,6 +55,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
/// Calls [Client.search] updating [queryMessagesLoading] stream
Future<void> search({
Map<String, dynamic> filter,
Map<String, dynamic> messageFilter,
List<SortOption> sort,
String query,
PaginationParams pagination,
@@ -78,6 +79,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
sort,
query,
pagination,
messageFilters: messageFilter,
);
if (clear) {
+1 -1
View File
@@ -28,7 +28,7 @@ dependencies:
file_picker: ^2.0.12
image_picker: ^0.6.7+2
flutter_keyboard_visibility: ^3.3.0
stream_chat: ^0.2.14
stream_chat: ^0.2.19
mime: ^0.9.6+3
video_compress: ^2.1.1
visibility_detector: ^0.1.5