igrate example

This commit is contained in:
Salvatore Giordano
2021-04-30 14:59:50 +02:00
parent 34888d0fff
commit 3283f008eb
13 changed files with 64 additions and 55 deletions
@@ -61,8 +61,8 @@ class MyApp extends StatelessWidget {
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
builder: (context, widget) { builder: (context, widget) {
return StreamChat( return StreamChat(
child: widget,
client: client, client: client,
child: widget,
); );
}, },
home: StreamChannel( home: StreamChannel(
@@ -80,7 +80,7 @@ class MyApp extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
/// Creates the page that shows the list of messages /// Creates the page that shows the list of messages
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -25,8 +25,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
builder: (context, child) => StreamChat( builder: (context, child) => StreamChat(
child: child,
client: client, client: client,
child: child,
), ),
home: SplitView(), home: SplitView(),
); );
@@ -39,7 +39,7 @@ class SplitView extends StatefulWidget {
} }
class _SplitViewState extends State<SplitView> { class _SplitViewState extends State<SplitView> {
Channel selectedChannel; Channel? selectedChannel;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -47,6 +47,7 @@ class _SplitViewState extends State<SplitView> {
direction: Axis.horizontal, direction: Axis.horizontal,
children: <Widget>[ children: <Widget>[
Flexible( Flexible(
flex: 1,
child: ChannelListPage( child: ChannelListPage(
onTap: (channel) { onTap: (channel) {
setState(() { setState(() {
@@ -54,15 +55,15 @@ class _SplitViewState extends State<SplitView> {
}); });
}, },
), ),
flex: 1,
), ),
Flexible( Flexible(
flex: 2,
child: Scaffold( child: Scaffold(
body: selectedChannel != null body: selectedChannel != null
? StreamChannel( ? StreamChannel(
key: ValueKey(selectedChannel.cid), key: ValueKey(selectedChannel!.cid),
channel: selectedChannel!,
child: ChannelPage(), child: ChannelPage(),
channel: selectedChannel,
) )
: Center( : Center(
child: Text( child: Text(
@@ -71,7 +72,6 @@ class _SplitViewState extends State<SplitView> {
), ),
), ),
), ),
flex: 2,
), ),
], ],
); );
@@ -79,7 +79,7 @@ class _SplitViewState extends State<SplitView> {
} }
class ChannelListPage extends StatelessWidget { class ChannelListPage extends StatelessWidget {
final void Function(Channel) onTap; final void Function(Channel)? onTap;
ChannelListPage({this.onTap}); ChannelListPage({this.onTap});
@@ -90,12 +90,12 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
onChannelTap: onTap != null onChannelTap: onTap != null
? (channel, _) { ? (channel, _) {
onTap(channel); onTap!(channel);
} }
: null, : null,
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user.id], [StreamChat.of(context).user!.id],
), ),
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
@@ -109,7 +109,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -55,8 +55,8 @@ class MyApp extends StatelessWidget {
return MaterialApp( return MaterialApp(
builder: (context, widget) { builder: (context, widget) {
return StreamChat( return StreamChat(
child: widget,
client: client, client: client,
child: widget,
); );
}, },
home: StreamChannel( home: StreamChannel(
@@ -69,7 +69,7 @@ class MyApp extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -73,7 +73,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -1,4 +1,5 @@
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
@@ -43,8 +44,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
builder: (context, child) => StreamChat( builder: (context, child) => StreamChat(
child: child,
client: client, client: client,
child: child,
), ),
home: ChannelListPage(), home: ChannelListPage(),
); );
@@ -59,7 +60,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user.id], [StreamChat.of(context).user!.id],
), ),
channelPreviewBuilder: _channelPreviewBuilder, channelPreviewBuilder: _channelPreviewBuilder,
// sort: [SortOption('last_message_at')], // sort: [SortOption('last_message_at')],
@@ -73,13 +74,12 @@ class ChannelListPage extends StatelessWidget {
} }
Widget _channelPreviewBuilder(BuildContext context, Channel channel) { Widget _channelPreviewBuilder(BuildContext context, Channel channel) {
final lastMessage = channel.state.messages.reversed.firstWhere( final lastMessage = channel.state?.messages.reversed.firstWhereOrNull(
(message) => !message.isDeleted, (message) => !message.isDeleted,
orElse: () => null,
); );
final subtitle = (lastMessage == null ? 'nothing yet' : lastMessage.text); final subtitle = (lastMessage == null ? 'nothing yet' : lastMessage.text!);
final opacity = channel.state.unreadCount > .0 ? 1.0 : 0.5; final opacity = (channel.state?.unreadCount ?? 0) > 0 ? 1.0 : 0.5;
return ListTile( return ListTile(
onTap: () { onTap: () {
@@ -87,8 +87,8 @@ class ChannelListPage extends StatelessWidget {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (_) => StreamChannel( builder: (_) => StreamChannel(
child: ChannelPage(),
channel: channel, channel: channel,
child: ChannelPage(),
), ),
), ),
); );
@@ -98,7 +98,7 @@ class ChannelListPage extends StatelessWidget {
), ),
title: ChannelName( title: ChannelName(
textStyle: textStyle:
StreamChatTheme.of(context).channelPreviewTheme.title.copyWith( StreamChatTheme.of(context).channelPreviewTheme.title!.copyWith(
color: StreamChatTheme.of(context) color: StreamChatTheme.of(context)
.colorTheme .colorTheme
.black .black
@@ -106,10 +106,10 @@ class ChannelListPage extends StatelessWidget {
), ),
), ),
subtitle: Text(subtitle), subtitle: Text(subtitle),
trailing: channel.state.unreadCount > 0 trailing: channel.state!.unreadCount! > 0
? CircleAvatar( ? CircleAvatar(
radius: 10, radius: 10,
child: Text(channel.state.unreadCount.toString()), child: Text(channel.state!.unreadCount.toString()),
) )
: SizedBox(), : SizedBox(),
); );
@@ -118,7 +118,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -33,8 +33,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
builder: (context, child) => StreamChat( builder: (context, child) => StreamChat(
child: child,
client: client, client: client,
child: child,
), ),
home: Container( home: Container(
child: ChannelListPage(), child: ChannelListPage(),
@@ -51,7 +51,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user.id], [StreamChat.of(context).user!.id],
), ),
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
@@ -66,7 +66,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -92,10 +92,10 @@ class ChannelPage extends StatelessWidget {
} }
class ThreadPage extends StatelessWidget { class ThreadPage extends StatelessWidget {
final Message parent; final Message? parent;
ThreadPage({ ThreadPage({
Key key, Key? key,
this.parent, this.parent,
}) : super(key: key); }) : super(key: key);
@@ -103,7 +103,7 @@ class ThreadPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: ThreadHeader( appBar: ThreadHeader(
parent: parent, parent: parent!,
), ),
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
@@ -38,8 +38,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
builder: (context, child) => StreamChat( builder: (context, child) => StreamChat(
child: child,
client: client, client: client,
child: child,
), ),
home: ChannelListPage(), home: ChannelListPage(),
); );
@@ -54,7 +54,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user.id], [StreamChat.of(context).user!.id],
), ),
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
@@ -69,7 +69,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -95,7 +95,7 @@ class ChannelPage extends StatelessWidget {
List<Message> messages, List<Message> messages,
) { ) {
final message = details.message; final message = details.message;
final isCurrentUser = StreamChat.of(context).user.id == message.user.id; final isCurrentUser = StreamChat.of(context).user!.id == message.user!.id;
final textAlign = isCurrentUser ? TextAlign.right : TextAlign.left; final textAlign = isCurrentUser ? TextAlign.right : TextAlign.left;
final color = isCurrentUser ? Colors.blueGrey : Colors.blue; final color = isCurrentUser ? Colors.blueGrey : Colors.blue;
@@ -110,11 +110,11 @@ class ChannelPage extends StatelessWidget {
), ),
child: ListTile( child: ListTile(
title: Text( title: Text(
message.text, message.text!,
textAlign: textAlign, textAlign: textAlign,
), ),
subtitle: Text( subtitle: Text(
message.user.extraData['name'], message.user!.extraData['name'] as String,
textAlign: textAlign, textAlign: textAlign,
), ),
), ),
@@ -64,9 +64,9 @@ class MyApp extends StatelessWidget {
theme: themeData, theme: themeData,
builder: (context, child) { builder: (context, child) {
return StreamChat( return StreamChat(
child: child,
client: client, client: client,
streamChatThemeData: customTheme, streamChatThemeData: customTheme,
child: child,
); );
}, },
home: ChannelListPage(), home: ChannelListPage(),
@@ -82,7 +82,7 @@ class ChannelListPage extends StatelessWidget {
child: ChannelListView( child: ChannelListView(
filter: Filter.in_( filter: Filter.in_(
'members', 'members',
[StreamChat.of(context).user.id], [StreamChat.of(context).user!.id],
), ),
sort: [SortOption('last_message_at')], sort: [SortOption('last_message_at')],
pagination: PaginationParams( pagination: PaginationParams(
@@ -97,7 +97,7 @@ class ChannelListPage extends StatelessWidget {
class ChannelPage extends StatelessWidget { class ChannelPage extends StatelessWidget {
const ChannelPage({ const ChannelPage({
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -123,10 +123,10 @@ class ChannelPage extends StatelessWidget {
} }
class ThreadPage extends StatelessWidget { class ThreadPage extends StatelessWidget {
final Message parent; final Message? parent;
ThreadPage({ ThreadPage({
Key key, Key? key,
this.parent, this.parent,
}) : super(key: key); }) : super(key: key);
@@ -134,7 +134,7 @@ class ThreadPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: ThreadHeader( appBar: ThreadHeader(
parent: parent, parent: parent!,
), ),
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
@@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
@@ -28,7 +28,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0 cupertino_icons: ^1.0.2
collection: ^1.15.0
dependency_overrides: dependency_overrides:
stream_chat: stream_chat:
@@ -21,7 +21,12 @@ class GiphyAttachment extends AttachmentWidget {
this.onShowMessage, this.onShowMessage,
this.onReturnAction, this.onReturnAction,
this.onAttachmentTap, this.onAttachmentTap,
}) : super(key: key, message: message, attachment: attachment, size: size); }) : super(
key: key,
message: message,
attachment: attachment,
size: size,
);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -173,6 +178,7 @@ class GiphyAttachment extends AttachmentWidget {
.black .black
.withOpacity(0.5), .withOpacity(0.5),
), ),
maxLines: 1,
), ),
), ),
), ),
@@ -177,7 +177,7 @@ class MediaThumbnailProvider extends ImageProvider<MediaThumbnailProvider> {
@override @override
ImageStreamCompleter load(key, decode) { ImageStreamCompleter load(key, decode) {
return MultiFrameImageStreamCompleter( return MultiFrameImageStreamCompleter(
codec: _loadAsync(key, decode) as Future<ui.Codec>, codec: _loadAsync(key, decode),
scale: 1.0, scale: 1.0,
informationCollector: () sync* { informationCollector: () sync* {
yield ErrorDescription('Id: ${media.id}'); yield ErrorDescription('Id: ${media.id}');
@@ -185,11 +185,10 @@ class MediaThumbnailProvider extends ImageProvider<MediaThumbnailProvider> {
); );
} }
Future<ui.Codec?> _loadAsync( Future<ui.Codec> _loadAsync(
MediaThumbnailProvider key, DecoderCallback decode) async { MediaThumbnailProvider key, DecoderCallback decode) async {
assert(key == this); assert(key == this);
final bytes = await media.thumbData; final bytes = await media.thumbData;
if (bytes?.isNotEmpty != true) return null;
return await decode(bytes!); return await decode(bytes!);
} }
@@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
@@ -610,7 +609,7 @@ class MessageInputState extends State<MessageInput> {
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Container( child: Container(
constraints: BoxConstraints.tight(Size(64, 24)), constraints: BoxConstraints.tight(Size(84, 24)),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
color: theme.colorTheme.accentBlue, color: theme.colorTheme.accentBlue,
@@ -1105,10 +1104,14 @@ class MessageInputState extends State<MessageInput> {
} }
void _addAttachment(AssetEntity medium) async { void _addAttachment(AssetEntity medium) async {
final mediaFile = await (medium.originFile.timeout( final mediaFile = await medium.originFile.timeout(
Duration(seconds: 5), Duration(seconds: 5),
onTimeout: () => medium.originFile, onTimeout: () => medium.originFile,
) as FutureOr<File>); );
if (mediaFile == null) {
return;
}
var file = AttachmentFile( var file = AttachmentFile(
path: mediaFile.path, path: mediaFile.path,
@@ -446,7 +446,7 @@ class _MessageWidgetState extends State<MessageWidget>
transform: Matrix4.rotationY(widget.reverse ? pi : 0), transform: Matrix4.rotationY(widget.reverse ? pi : 0),
child: FractionallySizedBox( child: FractionallySizedBox(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
widthFactor: 0.75, widthFactor: 0.78,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,