add typing indicator widget
This commit is contained in:
@@ -3,13 +3,13 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
|||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final client = Client(
|
final client = Client(
|
||||||
'b67pax5b2wdq',
|
's2dxdhpxd94g',
|
||||||
logLevel: Level.INFO,
|
logLevel: Level.INFO,
|
||||||
);
|
);
|
||||||
|
|
||||||
await client.setUser(
|
await client.setUser(
|
||||||
User(id: 'falling-mountain-7'),
|
User(id: 'super-band-9'),
|
||||||
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiZmFsbGluZy1tb3VudGFpbi03In0.AKgRXHMQQMz6vJAKszXdY8zMFfsAgkoUeZHlI-Szz9E',
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoic3VwZXItYmFuZC05In0.0L6lGoeLwkz0aZRUcpZKsvaXtNEDHBcezVTZ0oPq40A',
|
||||||
);
|
);
|
||||||
|
|
||||||
runApp(MyApp(client));
|
runApp(MyApp(client));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:stream_chat/stream_chat.dart';
|
|||||||
|
|
||||||
import '../stream_chat_flutter.dart';
|
import '../stream_chat_flutter.dart';
|
||||||
import 'channel_name.dart';
|
import 'channel_name.dart';
|
||||||
|
import 'typing_indicator.dart';
|
||||||
|
|
||||||
/// 
|
/// 
|
||||||
/// 
|
/// 
|
||||||
@@ -88,7 +89,19 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
final typings = snapshot.data;
|
final typings = snapshot.data;
|
||||||
final opacity = channel.state.unreadCount > 0 ? 1.0 : 0.5;
|
final opacity = channel.state.unreadCount > 0 ? 1.0 : 0.5;
|
||||||
return typings.isNotEmpty
|
return typings.isNotEmpty
|
||||||
? _buildTypings(typings, context, opacity)
|
? TypingIndicator(
|
||||||
|
typings: typings,
|
||||||
|
style: StreamChatTheme.of(context)
|
||||||
|
.channelPreviewTheme
|
||||||
|
.subtitle
|
||||||
|
.copyWith(
|
||||||
|
color: StreamChatTheme.of(context)
|
||||||
|
.channelPreviewTheme
|
||||||
|
.subtitle
|
||||||
|
.color
|
||||||
|
.withOpacity(opacity),
|
||||||
|
),
|
||||||
|
)
|
||||||
: _buildLastMessage(context, opacity);
|
: _buildLastMessage(context, opacity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -141,18 +154,4 @@ class ChannelPreview extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Text _buildTypings(List<User> typings, BuildContext context, double opacity) {
|
|
||||||
return Text(
|
|
||||||
'${typings.map((u) => u.extraData.containsKey('name') ? u.extraData['name'] : u.id).join(',')} ${typings.length == 1 ? 'is' : 'are'} typing...',
|
|
||||||
maxLines: 1,
|
|
||||||
style: StreamChatTheme.of(context).channelPreviewTheme.subtitle.copyWith(
|
|
||||||
color: StreamChatTheme.of(context)
|
|
||||||
.channelPreviewTheme
|
|
||||||
.subtitle
|
|
||||||
.color
|
|
||||||
.withOpacity(opacity),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class MessageWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MessageWidgetState extends State<MessageWidget>
|
class _MessageWidgetState extends State<MessageWidget>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
|
||||||
final Map<String, ChangeNotifier> _videoControllers = {};
|
final Map<String, ChangeNotifier> _videoControllers = {};
|
||||||
final Map<String, ChangeNotifier> _chuwieControllers = {};
|
final Map<String, ChangeNotifier> _chuwieControllers = {};
|
||||||
|
|
||||||
@@ -126,8 +126,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
row = row.reversed.toList();
|
row = row.reversed.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
child = AnimatedContainer(
|
child = Container(
|
||||||
duration: Duration(milliseconds: 300),
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||||
margin: EdgeInsets.only(
|
margin: EdgeInsets.only(
|
||||||
top: isLastUser ? 5 : 24,
|
top: isLastUser ? 5 : 24,
|
||||||
@@ -674,9 +673,7 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: widget.message.reactionCounts?.isNotEmpty == true ? 4.0 : 0,
|
vertical: widget.message.reactionCounts?.isNotEmpty == true ? 4.0 : 0,
|
||||||
),
|
),
|
||||||
child: AnimatedContainer(
|
child: Container(
|
||||||
duration: Duration(milliseconds: 300),
|
|
||||||
curve: Curves.decelerate,
|
|
||||||
padding: widget.message.reactionCounts?.isNotEmpty == true
|
padding: widget.message.reactionCounts?.isNotEmpty == true
|
||||||
? const EdgeInsets.all(8)
|
? const EdgeInsets.all(8)
|
||||||
: EdgeInsets.zero,
|
: EdgeInsets.zero,
|
||||||
@@ -685,7 +682,12 @@ class _MessageWidgetState extends State<MessageWidget>
|
|||||||
borderRadius: BorderRadius.all(Radius.circular(14))),
|
borderRadius: BorderRadius.all(Radius.circular(14))),
|
||||||
child: (widget.message.reactionCounts != null &&
|
child: (widget.message.reactionCounts != null &&
|
||||||
widget.message.reactionCounts.isNotEmpty)
|
widget.message.reactionCounts.isNotEmpty)
|
||||||
? _buildReactionRow()
|
? AnimatedSize(
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
vsync: this,
|
||||||
|
curve: Curves.easeInQuad,
|
||||||
|
child: _buildReactionRow(),
|
||||||
|
)
|
||||||
: SizedBox(),
|
: SizedBox(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
|
||||||
|
/// Widget to show the current list of typing users
|
||||||
|
class TypingIndicator extends StatelessWidget {
|
||||||
|
const TypingIndicator({
|
||||||
|
Key key,
|
||||||
|
@required this.typings,
|
||||||
|
this.style,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
/// Style of the text widget
|
||||||
|
final TextStyle style;
|
||||||
|
|
||||||
|
/// List of typing users
|
||||||
|
final List<User> typings;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text(
|
||||||
|
'${typings.map((u) => u.name).join(',')} ${typings.length == 1 ? 'is' : 'are'} typing...',
|
||||||
|
maxLines: 1,
|
||||||
|
style: style,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,3 +13,4 @@ export 'src/stream_channel.dart';
|
|||||||
export 'src/stream_chat.dart';
|
export 'src/stream_chat.dart';
|
||||||
export 'src/stream_chat_theme.dart';
|
export 'src/stream_chat_theme.dart';
|
||||||
export 'src/thread_header.dart';
|
export 'src/thread_header.dart';
|
||||||
|
export 'src/typing_indicator.dart';
|
||||||
|
|||||||
Reference in New Issue
Block a user