From 404ec4c89d43bb9b39505be13931e7c0d39aae87 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 13:26:26 +0530 Subject: [PATCH 01/26] feat: Added reaction modal animations --- lib/src/message_actions_modal.dart | 116 ++++++++++++++---------- lib/src/reaction_picker.dart | 139 ++++++++++++++++++++--------- pubspec.yaml | 1 + 3 files changed, 168 insertions(+), 88 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 16c48e25..049f1be7 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -95,58 +95,78 @@ class MessageActionsModal extends StatelessWidget { messageTheme: messageTheme, ), ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showUserAvatar: showUserAvatar, - showTimestamp: false, - translateUserAvatar: false, - showReactionPickerIndicator: true, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, - ), + TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + builder: (context, val, snapshot) { + return Transform.scale( + scale: val, + child: IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), + messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showUserAvatar: showUserAvatar, + showTimestamp: false, + translateUserAvatar: false, + showReactionPickerIndicator: true, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, + ), + ), + ); + } ), SizedBox( height: 8, ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, - ), - child: Material( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: ListTile.divideTiles( - context: context, - tiles: [ - if (showReply && - (message.status == - MessageSendingStatus.SENT || - message.status == null) && - message.parentId == null) - _buildReplyButton(context), - if (showEditMessage) _buildEditMessage(context), - if (showDeleteMessage) - _buildDeleteButton(context), - if (showCopyMessage) _buildCopyButton(context), - ], - ).toList(), - ), - ), + TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + builder: (context, val, wid) { + return Transform( + transform: Matrix4.identity()..scale(val)..rotateZ(-1.0 + val), + alignment: Alignment.topRight, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 48.0, + ), + child: Material( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: ListTile.divideTiles( + context: context, + tiles: [ + if (showReply && + (message.status == + MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildReplyButton(context), + if (showEditMessage) _buildEditMessage(context), + if (showDeleteMessage) + _buildDeleteButton(context), + if (showCopyMessage) _buildCopyButton(context), + ], + ).toList(), + ), + ), + ), + ); + } ) ], ), diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index e7d302e6..1946e9ff 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -1,4 +1,6 @@ +import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/physics.dart'; import '../stream_chat_flutter.dart'; @@ -8,7 +10,8 @@ import '../stream_chat_flutter.dart'; /// It shows a reaction picker /// /// Usually you don't use this widget as it's one of the default widgets used by [MessageWidget.onMessageActions]. -class ReactionPicker extends StatelessWidget { + +class ReactionPicker extends StatefulWidget { const ReactionPicker({ Key key, @required this.message, @@ -18,59 +21,115 @@ class ReactionPicker extends StatelessWidget { final Message message; final MessageTheme messageTheme; + @override + _ReactionPickerState createState() => _ReactionPickerState(); +} + +class _ReactionPickerState extends State { + List animations = []; + @override Widget build(BuildContext context) { final reactionIcons = StreamChatTheme.of(context).reactionIcons; - return Material( - color: messageTheme.reactionsBackgroundColor, - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(24), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: reactionIcons.map((reactionIcon) { - final ownReactionIndex = message.ownReactions?.indexWhere( - (reaction) => reaction.type == reactionIcon.type) ?? - -1; - return IconButton( - iconSize: 24, - icon: Icon( - reactionIcon.iconData, - color: ownReactionIndex != -1 - ? StreamChatTheme.of(context).accentColor - : Theme.of(context).iconTheme.color.withOpacity(.5), + + if (animations.isEmpty && reactionIcons.isNotEmpty) { + reactionIcons.forEach((element) { + animations.add( + EzAnimation.sequence([ + SequenceItem(0.0, 1.4), + SequenceItem(1.4, 1.0), + ], Duration(milliseconds: 500)), + ); + }); + + triggerAnimations(); + } + + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + curve: Curves.easeInOutExpo, + duration: Duration(milliseconds: 500), + builder: (context, val, wid) { + return Transform.scale( + scale: val, + child: Material( + color: widget.messageTheme.reactionsBackgroundColor, + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: reactionIcons.map((reactionIcon) { + final ownReactionIndex = widget.message.ownReactions + ?.indexWhere((reaction) => + reaction.type == reactionIcon.type) ?? + -1; + var index = reactionIcons.indexOf(reactionIcon); + + return IconButton( + iconSize: 24, + icon: AnimatedBuilder( + animation: animations[index], + builder: (context, val) { + return Transform( + transform: Matrix4.identity() + ..scale(animations[index].value, + animations[index].value) + ..rotateZ(1.0 - animations[index].value), + child: Icon( + reactionIcon.iconData, + size: animations[index].value * 24.0, + color: ownReactionIndex != -1 + ? StreamChatTheme.of(context).accentColor + : Theme.of(context) + .iconTheme + .color + .withOpacity(.5), + ), + ); + }), + onPressed: () { + if (ownReactionIndex != -1) { + removeReaction( + context, + widget.message.ownReactions[ownReactionIndex], + ); + } else { + sendReaction( + context, + reactionIcon.type, + ); + } + }, + ); + }).toList(), + ), ), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - message.ownReactions[ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, ); - }).toList(), - ), - ); + }); + } + + void triggerAnimations() async { + for (var a in animations) { + a.start(); + await Future.delayed(Duration(milliseconds: 100)); + } } /// Add a reaction to the message void sendReaction(BuildContext context, String reactionType) { - StreamChannel.of(context).channel.sendReaction(message, reactionType); + StreamChannel.of(context) + .channel + .sendReaction(widget.message, reactionType); Navigator.of(context).pop(); } /// Remove a reaction from the message void removeReaction(BuildContext context, Reaction reaction) { - StreamChannel.of(context).channel.deleteReaction(message, reaction); + StreamChannel.of(context).channel.deleteReaction(widget.message, reaction); Navigator.of(context).pop(); } } diff --git a/pubspec.yaml b/pubspec.yaml index 1716bab1..689a54b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: media_gallery: ^0.1.5 permission_handler: ^5.0.1+1 transparent_image: ^1.0.0 + ezanimation: ^0.4.0 flutter: assets: From f9231e93b3059be68cece526288555d5e63e7cba Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 13:38:15 +0530 Subject: [PATCH 02/26] feat: Added reaction list modal animations --- lib/src/message_reactions_modal.dart | 146 +++++++++++++++------------ 1 file changed, 82 insertions(+), 64 deletions(-) diff --git a/lib/src/message_reactions_modal.dart b/lib/src/message_reactions_modal.dart index d68bd769..db5d8710 100644 --- a/lib/src/message_reactions_modal.dart +++ b/lib/src/message_reactions_modal.dart @@ -86,27 +86,35 @@ class MessageReactionsModal extends StatelessWidget { messageTheme: messageTheme, ), ), - IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, - ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showUserAvatar: showUserAvatar, - showReplyIndicator: false, - showTimestamp: false, - translateUserAvatar: false, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, - showReactionPickerIndicator: true, - ), - ), + TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + builder: (context, val, snapshot) { + return Transform.scale( + scale: val, + child: IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), + messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showUserAvatar: showUserAvatar, + showReplyIndicator: false, + showTimestamp: false, + translateUserAvatar: false, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, + showReactionPickerIndicator: true, + ), + ), + ); + }), SizedBox( height: 16, ), @@ -178,50 +186,60 @@ class MessageReactionsModal extends StatelessWidget { BuildContext context, ) { final isCurrentUser = reaction.user.id == currentUser.id; - return ConstrainedBox( - constraints: BoxConstraints.loose(Size( - 64, - 98, - )), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Stack( - children: [ - UserAvatar( - onTap: onUserAvatarTap, - user: reaction.user, - constraints: BoxConstraints.tightFor( - height: 64, - width: 64, - ), - borderRadius: BorderRadius.circular(32), - ), - Positioned( - child: Align( - alignment: Alignment.centerLeft, - child: ReactionBubble( - reactions: [reaction], - borderColor: messageTheme.reactionsBorderColor, - backgroundColor: messageTheme.reactionsBackgroundColor, - highlightOwnReactions: false, + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + builder: (context, val, snapshot) { + return Transform.scale( + scale: val, + child: ConstrainedBox( + constraints: BoxConstraints.loose(Size( + 64, + 98, + )), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Stack( + children: [ + UserAvatar( + onTap: onUserAvatarTap, + user: reaction.user, + constraints: BoxConstraints.tightFor( + height: 64, + width: 64, + ), + borderRadius: BorderRadius.circular(32), + ), + Positioned( + child: Align( + alignment: Alignment.centerLeft, + child: ReactionBubble( + reactions: [reaction], + borderColor: messageTheme.reactionsBorderColor, + backgroundColor: + messageTheme.reactionsBackgroundColor, + highlightOwnReactions: false, + ), + ), + bottom: 4, + left: isCurrentUser ? 0 : null, + right: isCurrentUser ? 0 : null, + ), + ], ), - ), - bottom: 4, - left: isCurrentUser ? 0 : null, - right: isCurrentUser ? 0 : null, + Text( + reaction.user.name, + style: Theme.of(context).textTheme.subtitle2, + textAlign: TextAlign.center, + ), + ], ), - ], - ), - Text( - reaction.user.name, - style: Theme.of(context).textTheme.subtitle2, - textAlign: TextAlign.center, - ), - ], - ), - ); + ), + ); + }); } } From c70c49d54d33c6f40404579ba1c382ca3d333dce Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 15:07:42 +0530 Subject: [PATCH 03/26] feat: Added animations for giphy and mentions --- lib/src/message_input.dart | 302 ++++++++++++++++++++----------------- 1 file changed, 165 insertions(+), 137 deletions(-) diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index cd96119a..01c531de 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -536,86 +536,101 @@ class MessageInputState extends State { bottom: size.height + MediaQuery.of(context).viewInsets.bottom, left: 0, right: 0, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Card( - elevation: 2.0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - color: StreamChatTheme.of(context).primaryColor, - clipBehavior: Clip.antiAlias, - child: Container( - constraints: BoxConstraints.loose(Size.fromHeight(400)), - decoration: BoxDecoration( - color: StreamChatTheme.of(context).primaryColor, - borderRadius: BorderRadius.circular(8.0)), - child: ListView( - padding: const EdgeInsets.all(0), - shrinkWrap: true, - children: [ - if (commands.isNotEmpty) - Padding( - padding: const EdgeInsets.only(left: 8.0, top: 8.0), - child: Row( + child: TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutExpo, + builder: (context, val, wid) { + return Transform.scale( + alignment: Alignment.center, + scale: val, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Card( + elevation: 2.0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + color: StreamChatTheme.of(context).primaryColor, + clipBehavior: Clip.antiAlias, + child: Container( + constraints: BoxConstraints.loose(Size.fromHeight(400)), + decoration: BoxDecoration( + color: StreamChatTheme.of(context).primaryColor, + borderRadius: BorderRadius.circular(8.0)), + child: ListView( + padding: const EdgeInsets.all(0), + shrinkWrap: true, children: [ - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8.0), - child: Icon( - StreamIcons.lightning, - color: StreamChatTheme.of(context).accentColor, + if (commands.isNotEmpty) + Padding( + padding: + const EdgeInsets.only(left: 8.0, top: 8.0), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0), + child: Icon( + StreamIcons.lightning, + color: StreamChatTheme.of(context) + .accentColor, + ), + ), + Text( + 'Instant Commands', + style: TextStyle( + color: Colors.black.withOpacity(.5), + ), + ) + ], + ), ), - ), - Text( - 'Instant Commands', - style: TextStyle( - color: Colors.black.withOpacity(.5), - ), - ) + ...commands + .map( + (c) => ListTile( + leading: c.name == 'giphy' + ? _buildGiphyIcon() + : null, + title: Text.rich( + TextSpan( + text: '${c.name.capitalize()}', + style: TextStyle( + fontWeight: FontWeight.bold), + children: [ + TextSpan( + text: ' /${c.name} ${c.args}', + style: TextStyle( + fontWeight: FontWeight.w300, + ), + ), + ], + ), + ), + trailing: CircleAvatar( + backgroundColor: + StreamChatTheme.of(context).accentColor, + child: Icon( + StreamIcons.lightning, + color: Colors.white, + size: 12.5, + ), + maxRadius: 12, + ), + //subtitle: Text(c.description), + onTap: () { + _setCommand(c); + }, + ), + ) + .toList(), ], ), ), - ...commands - .map( - (c) => ListTile( - leading: c.name == 'giphy' ? _buildGiphyIcon() : null, - title: Text.rich( - TextSpan( - text: '${c.name.capitalize()}', - style: TextStyle(fontWeight: FontWeight.bold), - children: [ - TextSpan( - text: ' /${c.name} ${c.args}', - style: TextStyle( - fontWeight: FontWeight.w300, - ), - ), - ], - ), - ), - trailing: CircleAvatar( - backgroundColor: - StreamChatTheme.of(context).accentColor, - child: Icon( - StreamIcons.lightning, - color: Colors.white, - size: 12.5, - ), - maxRadius: 12, - ), - //subtitle: Text(c.description), - onTap: () { - _setCommand(c); - }, - ), - ) - .toList(), - ], - ), - ), - ), - ), + ), + ), + ); + }), ); }); } @@ -925,71 +940,84 @@ class MessageInputState extends State { bottom: size.height + MediaQuery.of(context).viewInsets.bottom, left: 0, right: 0, - child: Card( - margin: EdgeInsets.all(8.0), - elevation: 2.0, - color: StreamChatTheme.of(context).primaryColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - clipBehavior: Clip.antiAlias, - child: Container( - constraints: BoxConstraints.loose(Size.fromHeight(400)), - decoration: BoxDecoration( - color: StreamChatTheme.of(context).primaryColor, - ), - child: FutureBuilder>( - future: queryMembers ?? Future.value(members), - initialData: members, - builder: (context, snapshot) { - return ListView( - padding: const EdgeInsets.all(0), - shrinkWrap: true, - children: snapshot.data - .map((m) => ListTile( - leading: UserAvatar( - constraints: BoxConstraints.tight( - Size( - 40, - 40, - ), - ), - user: m.user, - ), - title: Text( - '${m.user.name}', - style: TextStyle(fontWeight: FontWeight.bold), - ), - subtitle: Text('@${m.userId}'), - trailing: Icon( - StreamIcons.at_mention, - color: StreamChatTheme.of(context).accentColor, - ), - onTap: () { - _mentionedUsers.add(m.user); + child: TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutExpo, + builder: (context, val, wid) { + return Transform.scale( + scale: val, + child: Card( + margin: EdgeInsets.all(8.0), + elevation: 2.0, + color: StreamChatTheme.of(context).primaryColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + clipBehavior: Clip.antiAlias, + child: Container( + constraints: BoxConstraints.loose(Size.fromHeight(400)), + decoration: BoxDecoration( + color: StreamChatTheme.of(context).primaryColor, + ), + child: FutureBuilder>( + future: queryMembers ?? Future.value(members), + initialData: members, + builder: (context, snapshot) { + return ListView( + padding: const EdgeInsets.all(0), + shrinkWrap: true, + children: snapshot.data + .map((m) => ListTile( + leading: UserAvatar( + constraints: BoxConstraints.tight( + Size( + 40, + 40, + ), + ), + user: m.user, + ), + title: Text( + '${m.user.name}', + style: TextStyle( + fontWeight: FontWeight.bold), + ), + subtitle: Text('@${m.userId}'), + trailing: Icon( + StreamIcons.at_mention, + color: StreamChatTheme.of(context) + .accentColor, + ), + onTap: () { + _mentionedUsers.add(m.user); - splits[splits.length - 1] = m.user.name; - final rejoin = splits.join('@'); + splits[splits.length - 1] = m.user.name; + final rejoin = splits.join('@'); - textEditingController.value = TextEditingValue( - text: rejoin + - textEditingController.text.substring( - textEditingController - .selection.start), - selection: TextSelection.collapsed( - offset: rejoin.length, - ), - ); + textEditingController.value = + TextEditingValue( + text: rejoin + + textEditingController.text + .substring( + textEditingController + .selection.start), + selection: TextSelection.collapsed( + offset: rejoin.length, + ), + ); - _mentionsOverlay?.remove(); - _mentionsOverlay = null; - }, - )) - .toList(), - ); - }), - ), - ), + _mentionsOverlay?.remove(); + _mentionsOverlay = null; + }, + )) + .toList(), + ); + }), + ), + ), + ); + }), ); }); } From e952d350c54ebc9951cd3bc5b85adfdc8228455e Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 18:10:23 +0530 Subject: [PATCH 04/26] fix: Stop animation before pop --- lib/src/reaction_picker.dart | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 1946e9ff..d661621e 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -119,17 +119,24 @@ class _ReactionPickerState extends State { } } + void pop() async { + for (var a in animations) { + a.stop(); + } + Navigator.of(context).pop(); + } + /// Add a reaction to the message void sendReaction(BuildContext context, String reactionType) { StreamChannel.of(context) .channel .sendReaction(widget.message, reactionType); - Navigator.of(context).pop(); + pop(); } /// Remove a reaction from the message void removeReaction(BuildContext context, Reaction reaction) { StreamChannel.of(context).channel.deleteReaction(widget.message, reaction); - Navigator.of(context).pop(); + pop(); } } From 5b06e9c257ce5875fe40382b4343ef520346c4d9 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 18:16:03 +0530 Subject: [PATCH 05/26] fix: Stop animation before pop --- lib/src/reaction_picker.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index d661621e..802e8eb3 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -122,6 +122,7 @@ class _ReactionPickerState extends State { void pop() async { for (var a in animations) { a.stop(); + a.dispose(); } Navigator.of(context).pop(); } From ee5cec3c4566cdde3c46125fd6bafc0dc1bbb4e5 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 18:27:12 +0530 Subject: [PATCH 06/26] fix: Stop animation before pop --- lib/src/reaction_picker.dart | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 802e8eb3..71ddcbb5 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -25,7 +25,8 @@ class ReactionPicker extends StatefulWidget { _ReactionPickerState createState() => _ReactionPickerState(); } -class _ReactionPickerState extends State { +class _ReactionPickerState extends State + with TickerProviderStateMixin { List animations = []; @override @@ -35,10 +36,14 @@ class _ReactionPickerState extends State { if (animations.isEmpty && reactionIcons.isNotEmpty) { reactionIcons.forEach((element) { animations.add( - EzAnimation.sequence([ - SequenceItem(0.0, 1.4), - SequenceItem(1.4, 1.0), - ], Duration(milliseconds: 500)), + EzAnimation.sequence( + [ + SequenceItem(0.0, 1.4), + SequenceItem(1.4, 1.0), + ], + Duration(milliseconds: 500), + vsync: this, + ), ); }); From b0b05e165cfa18591673ad57cabfb0730f38d308 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Fri, 20 Nov 2020 18:30:50 +0530 Subject: [PATCH 07/26] fix: Stop animation before pop --- lib/src/reaction_picker.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 71ddcbb5..8d337498 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -127,7 +127,7 @@ class _ReactionPickerState extends State void pop() async { for (var a in animations) { a.stop(); - a.dispose(); + //a.dispose(); } Navigator.of(context).pop(); } From 0ba45d82beb88ca2e49a9b0534e8522806096299 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 23 Nov 2020 15:46:38 +0530 Subject: [PATCH 08/26] fix: Fixed dispose errors --- lib/src/reaction_picker.dart | 9 ++++++++- pubspec.yaml | 2 +- test/src/message_action_modal_test.dart | 1 + test/src/message_reaction_modal_test.dart | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 8d337498..83698e46 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -127,7 +127,6 @@ class _ReactionPickerState extends State void pop() async { for (var a in animations) { a.stop(); - //a.dispose(); } Navigator.of(context).pop(); } @@ -145,4 +144,12 @@ class _ReactionPickerState extends State StreamChannel.of(context).channel.deleteReaction(widget.message, reaction); pop(); } + + @override + void dispose() { + for (var a in animations) { + a?.dispose(); + } + super.dispose(); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 689a54b8..85f164b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,7 @@ dependencies: media_gallery: ^0.1.5 permission_handler: ^5.0.1+1 transparent_image: ^1.0.0 - ezanimation: ^0.4.0 + ezanimation: ^0.4.1 flutter: assets: diff --git a/test/src/message_action_modal_test.dart b/test/src/message_action_modal_test.dart index 1427edd6..b186ab91 100644 --- a/test/src/message_action_modal_test.dart +++ b/test/src/message_action_modal_test.dart @@ -40,6 +40,7 @@ void main() { ); await tester.pump(); + await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); expect(find.byIcon(StreamIcons.sorting_up), findsOneWidget); expect(find.byIcon(StreamIcons.edit), findsOneWidget); diff --git a/test/src/message_reaction_modal_test.dart b/test/src/message_reaction_modal_test.dart index e270793e..4cf3dafa 100644 --- a/test/src/message_reaction_modal_test.dart +++ b/test/src/message_reaction_modal_test.dart @@ -87,6 +87,7 @@ void main() { ); await tester.pump(); + await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsNWidgets(2)); expect(find.byIcon(StreamIcons.love_reaction), findsNWidgets(2)); From cb4bd6849d0dfc9ece7c2d5982bb247ac2c1b308 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 23 Nov 2020 16:05:16 +0530 Subject: [PATCH 09/26] fmt --- lib/src/message_actions_modal.dart | 129 +++++++++++++++-------------- 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 049f1be7..8b53a973 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -96,78 +96,81 @@ class MessageActionsModal extends StatelessWidget { ), ), TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - builder: (context, val, snapshot) { - return Transform.scale( - scale: val, - child: IgnorePointer( - child: MessageWidget( - key: Key('MessageWidget'), - reverse: reverse, - message: message.copyWith( - text: message.text.length > 200 - ? '${message.text.substring(0, 200)}...' - : message.text, + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + builder: (context, val, snapshot) { + return Transform.scale( + scale: val, + child: IgnorePointer( + child: MessageWidget( + key: Key('MessageWidget'), + reverse: reverse, + message: message.copyWith( + text: message.text.length > 200 + ? '${message.text.substring(0, 200)}...' + : message.text, + ), + messageTheme: messageTheme, + showReactions: false, + showUsername: false, + showReplyIndicator: false, + showUserAvatar: showUserAvatar, + showTimestamp: false, + translateUserAvatar: false, + showReactionPickerIndicator: true, + showSendingIndicator: DisplayWidget.gone, + shape: messageShape, ), - messageTheme: messageTheme, - showReactions: false, - showUsername: false, - showReplyIndicator: false, - showUserAvatar: showUserAvatar, - showTimestamp: false, - translateUserAvatar: false, - showReactionPickerIndicator: true, - showSendingIndicator: DisplayWidget.gone, - shape: messageShape, ), - ), - ); - } - ), + ); + }), SizedBox( height: 8, ), TweenAnimationBuilder( - tween: Tween(begin: 0.0, end: 1.0), - duration: Duration(milliseconds: 300), - curve: Curves.easeInOut, - builder: (context, val, wid) { - return Transform( - transform: Matrix4.identity()..scale(val)..rotateZ(-1.0 + val), - alignment: Alignment.topRight, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 48.0, - ), - child: Material( - clipBehavior: Clip.hardEdge, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), + tween: Tween(begin: 0.0, end: 1.0), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + builder: (context, val, wid) { + return Transform( + transform: Matrix4.identity() + ..scale(val) + ..rotateZ(-1.0 + val), + alignment: Alignment.topRight, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 48.0, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: ListTile.divideTiles( - context: context, - tiles: [ - if (showReply && - (message.status == - MessageSendingStatus.SENT || - message.status == null) && - message.parentId == null) - _buildReplyButton(context), - if (showEditMessage) _buildEditMessage(context), - if (showDeleteMessage) - _buildDeleteButton(context), - if (showCopyMessage) _buildCopyButton(context), - ], - ).toList(), + child: Material( + clipBehavior: Clip.hardEdge, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.stretch, + children: ListTile.divideTiles( + context: context, + tiles: [ + if (showReply && + (message.status == + MessageSendingStatus.SENT || + message.status == null) && + message.parentId == null) + _buildReplyButton(context), + if (showEditMessage) + _buildEditMessage(context), + if (showDeleteMessage) + _buildDeleteButton(context), + if (showCopyMessage) + _buildCopyButton(context), + ], + ).toList(), + ), ), ), - ), - ); - } - ) + ); + }) ], ), ), From 162971636e5be112929cf4c3bc73310879e08af8 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 23 Nov 2020 16:13:13 +0530 Subject: [PATCH 10/26] fix: Fixed tests --- test/src/message_action_modal_test.dart | 1 + test/src/message_reaction_modal_test.dart | 2 ++ 2 files changed, 3 insertions(+) diff --git a/test/src/message_action_modal_test.dart b/test/src/message_action_modal_test.dart index b186ab91..97709e70 100644 --- a/test/src/message_action_modal_test.dart +++ b/test/src/message_action_modal_test.dart @@ -85,6 +85,7 @@ void main() { ); await tester.pump(); + await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); expect(find.byIcon(StreamIcons.sorting_up), findsNothing); expect(find.byIcon(StreamIcons.edit), findsNothing); diff --git a/test/src/message_reaction_modal_test.dart b/test/src/message_reaction_modal_test.dart index 4cf3dafa..622b57c3 100644 --- a/test/src/message_reaction_modal_test.dart +++ b/test/src/message_reaction_modal_test.dart @@ -39,6 +39,8 @@ void main() { ), ); + await tester.pump(Duration(milliseconds: 1000)); + expect(find.byKey(Key('MessageWidget')), findsOneWidget); expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsOneWidget); }, From 525991f24b64448094e236c32a60321d8b67a6db Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Mon, 23 Nov 2020 16:36:50 +0530 Subject: [PATCH 11/26] feat : ChannelListHeader --- example/lib/group_chat_details_screen.dart | 3 +- example/lib/main.dart | 8 +- example/lib/new_chat_screen.dart | 3 +- lib/src/channel_list_header.dart | 158 ++++++++++++++++++ .../src/stream_neumorphic_button.dart | 4 +- lib/stream_chat_flutter.dart | 2 + 6 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 lib/src/channel_list_header.dart rename example/lib/neumorphic_button.dart => lib/src/stream_neumorphic_button.dart (90%) diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index 6aff5711..5fca35b4 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -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 selectedUsers; @@ -103,7 +102,7 @@ class _GroupChatDetailsScreenState extends State { ), ), actions: [ - NeumorphicButton( + StreamNeumorphicButton( child: IconButton( padding: const EdgeInsets.all(0), icon: Icon(StreamIcons.check), diff --git a/example/lib/main.dart b/example/lib/main.dart index a7d5e473..7592cfab 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -69,13 +69,7 @@ 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(), drawer: _buildDrawer(context, user), drawerEdgeDragWidth: 50, body: ChannelsBloc( diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index 9ec2ca7e..deff2a3c 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -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 { @@ -193,7 +192,7 @@ class _NewChatScreenState extends State { padding: const EdgeInsets.symmetric(vertical: 8), child: Row( children: [ - NeumorphicButton( + StreamNeumorphicButton( child: Icon( StreamIcons.group, color: Color(0xFF006CFF), diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart new file mode 100644 index 00000000..94266045 --- /dev/null +++ b/lib/src/channel_list_header.dart @@ -0,0 +1,158 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/src/stream_neumorphic_button.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; + +import 'stream_chat.dart'; + +typedef TitleBuilder = Widget Function( + BuildContext context, + ConnectionStatus status, + Client client, +); + +class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { + const ChannelListHeader({ + Key key, + this.client, + this.titleBuilder, + }) : super(key: key); + + final Client client; + + final TitleBuilder titleBuilder; + + @override + Widget build(BuildContext context) { + final _client = client ?? StreamChat.of(context).client; + final user = _client.state.user; + return AppBar( + brightness: Theme.of(context).brightness, + elevation: 1, + backgroundColor: + StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, + centerTitle: true, + leading: Center( + child: UserAvatar( + user: user, + onTap: (_) => Scaffold.of(context).openDrawer(), + constraints: BoxConstraints.tightFor( + height: 40, + width: 40, + ), + ), + ), + actions: [ + StreamNeumorphicButton( + child: IconButton( + icon: ValueListenableBuilder( + valueListenable: _client.wsConnectionStatus, + builder: (context, status, child) { + var color; + switch (status) { + case ConnectionStatus.connected: + color = Color(0xFF006CFF); + break; + case ConnectionStatus.connecting: + color = Colors.grey; + break; + case ConnectionStatus.disconnected: + color = Colors.grey; + break; + } + return Icon( + StreamIcons.pen_write, + color: color, + ); + }, + ), + onPressed: () {}, + ), + ) + ], + title: ValueListenableBuilder( + valueListenable: _client.wsConnectionStatus, + builder: (context, status, child) { + if (titleBuilder != null) { + return titleBuilder(context, status, _client); + } + switch (status) { + case ConnectionStatus.connected: + return _buildConnectedTitleState(); + case ConnectionStatus.connecting: + return _buildConnectingTitleState(); + case ConnectionStatus.disconnected: + return _buildDisconnectedTitleState(_client); + default: + return Offstage(); + } + }, + ), + ); + } + + Widget _buildConnectedTitleState() => Text( + 'Stream Chat', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ); + + Widget _buildConnectingTitleState() { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 16, + width: 16, + child: Center( + child: CircularProgressIndicator(), + ), + ), + SizedBox(width: 10), + Text( + 'Searching for Network', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ) + ], + ); + } + + Widget _buildDisconnectedTitleState(Client client) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Offline...', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + TextButton( + onPressed: () => client.connect(), + child: Text( + 'Try Again', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF006CFF), + ), + ), + ), + ], + ); + } + + @override + Size get preferredSize => Size.fromHeight(kToolbarHeight); +} diff --git a/example/lib/neumorphic_button.dart b/lib/src/stream_neumorphic_button.dart similarity index 90% rename from example/lib/neumorphic_button.dart rename to lib/src/stream_neumorphic_button.dart index 69454fb2..bf3e8e97 100644 --- a/example/lib/neumorphic_button.dart +++ b/lib/src/stream_neumorphic_button.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -class NeumorphicButton extends StatelessWidget { +class StreamNeumorphicButton extends StatelessWidget { final Widget child; final Color backgroundColor; - const NeumorphicButton({ + const StreamNeumorphicButton({ Key key, @required this.child, this.backgroundColor = Colors.white, diff --git a/lib/stream_chat_flutter.dart b/lib/stream_chat_flutter.dart index 91ac68c8..1399bf08 100644 --- a/lib/stream_chat_flutter.dart +++ b/lib/stream_chat_flutter.dart @@ -33,3 +33,5 @@ export 'src/video_attachment.dart'; export 'src/users_bloc.dart'; export 'src/user_list_view.dart'; export 'src/user_item.dart'; +export 'src/stream_neumorphic_button.dart'; +export 'src/channel_list_header.dart'; From a30565e0e1784d031efc82ceda1c5242dacc6585 Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Mon, 23 Nov 2020 17:40:41 +0530 Subject: [PATCH 12/26] [ChannelListHeader] Refactor, Add support for trailing, leading widget taps. --- lib/src/channel_list_header.dart | 111 ++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 31 deletions(-) diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 94266045..147f9340 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -7,22 +7,57 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'stream_chat.dart'; -typedef TitleBuilder = Widget Function( +typedef _TitleBuilder = Widget Function( BuildContext context, ConnectionStatus status, Client client, ); +/// +/// It shows the current [Client] status. +/// +/// ```dart +/// class MyApp extends StatelessWidget { +/// final Client client; +/// +/// MyApp(this.client); +/// +/// @override +/// Widget build(BuildContext context) { +/// return MaterialApp( +/// home: StreamChat( +/// client: client, +/// child: Scaffold( +/// appBar: ChannelListHeader(), +/// ), +/// ), +/// ); +/// } +/// } +/// ``` +/// +/// Usually you would use this widget as an [AppBar] inside a [Scaffold]. +/// However you can also use it as a normal widget. +/// +/// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelTheme.channelHeaderTheme] property. +/// Modify it to change the widget appearance. class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { + /// Instantiates a ChannelListHeader const ChannelListHeader({ Key key, this.client, this.titleBuilder, + this.onUserAvatarTap, + this.onNewChatButtonTap, }) : super(key: key); final Client client; - final TitleBuilder titleBuilder; + final _TitleBuilder titleBuilder; + + final Function(User) onUserAvatarTap; + + final VoidCallback onNewChatButtonTap; @override Widget build(BuildContext context) { @@ -37,7 +72,8 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { leading: Center( child: UserAvatar( user: user, - onTap: (_) => Scaffold.of(context).openDrawer(), + onTap: onUserAvatarTap ?? (_) => Scaffold.of(context).openDrawer(), + borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( height: 40, width: 40, @@ -68,7 +104,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { ); }, ), - onPressed: () {}, + onPressed: onNewChatButtonTap, ), ) ], @@ -80,11 +116,11 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { } switch (status) { case ConnectionStatus.connected: - return _buildConnectedTitleState(); + return _buildConnectedTitleState(context); case ConnectionStatus.connecting: - return _buildConnectingTitleState(); + return _buildConnectingTitleState(context); case ConnectionStatus.disconnected: - return _buildDisconnectedTitleState(_client); + return _buildDisconnectedTitleState(context, _client); default: return Offstage(); } @@ -93,16 +129,19 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { ); } - Widget _buildConnectedTitleState() => Text( + Widget _buildConnectedTitleState(BuildContext context) => Text( 'Stream Chat', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, - ), + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title + .copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ); - Widget _buildConnectingTitleState() { + Widget _buildConnectingTitleState(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -116,37 +155,47 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { SizedBox(width: 10), Text( 'Searching for Network', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ) + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title + .copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), ], ); } - Widget _buildDisconnectedTitleState(Client client) { + Widget _buildDisconnectedTitleState(BuildContext context, Client client) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Offline...', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, - ), + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title + .copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ), TextButton( onPressed: () => client.connect(), child: Text( 'Try Again', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Color(0xFF006CFF), - ), + style: StreamChatTheme.of(context) + .channelTheme + .channelHeaderTheme + .title + .copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Color(0xFF006CFF), + ), ), ), ], From 942250d517971c28bbaed7eb4ac3d374e1b2b1f2 Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Mon, 23 Nov 2020 17:49:42 +0530 Subject: [PATCH 13/26] [ChannelListHeader] Add docComments --- lib/src/channel_list_header.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 147f9340..b44097c2 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -39,6 +39,9 @@ typedef _TitleBuilder = Widget Function( /// Usually you would use this widget as an [AppBar] inside a [Scaffold]. /// However you can also use it as a normal widget. /// +/// The widget by default uses the inherited [Client] to fetch information about the status. +/// However you can also pass your own [Client] if you don't have it in the widget tree. +/// /// The widget components render the ui based on the first ancestor of type [StreamChatTheme] and on its [ChannelTheme.channelHeaderTheme] property. /// Modify it to change the widget appearance. class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { @@ -51,12 +54,17 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { this.onNewChatButtonTap, }) : super(key: key); + /// Pass this if you don't have a [Client] in your widget tree. final Client client; + /// Use this to build your own title as per different [ConnectionStatus] final _TitleBuilder titleBuilder; + /// Callback to call when pressing the user avatar button. + /// By default it calls Scaffold.of(context).openDrawer() final Function(User) onUserAvatarTap; + /// Callback to call when pressing the new chat button. final VoidCallback onNewChatButtonTap; @override From f789975844b69f1aca1b96a46ccb735813268834 Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Mon, 23 Nov 2020 17:51:37 +0530 Subject: [PATCH 14/26] Open new chat screen page when new chat button is pressed. --- example/lib/main.dart | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 7592cfab..9bcf63b5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -69,7 +69,15 @@ class ChannelListPage extends StatelessWidget { Widget build(BuildContext context) { final user = StreamChat.of(context).user; return Scaffold( - appBar: ChannelListHeader(), + appBar: ChannelListHeader( + onNewChatButtonTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => NewChatScreen(), + ), + ); + }, + ), drawer: _buildDrawer(context, user), drawerEdgeDragWidth: 50, body: ChannelsBloc( From d68c02066e51ebe3a3cb0220f9fa6651f835a316 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 23 Nov 2020 17:00:51 +0100 Subject: [PATCH 15/26] change reconnection logic --- lib/src/channel_list_header.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index b44097c2..0df8ea06 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -192,7 +192,10 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { ), ), TextButton( - onPressed: () => client.connect(), + onPressed: () async { + await client.disconnect(); + return client.connect(); + }, child: Text( 'Try Again', style: StreamChatTheme.of(context) From f61d42bf3a61f926b2621bde1786e25355ce3dda Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Tue, 24 Nov 2020 12:44:34 +0530 Subject: [PATCH 16/26] [Channel List Header] Hide online status from user avatar --- lib/src/channel_list_header.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 0df8ea06..6a838265 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -80,6 +80,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { leading: Center( child: UserAvatar( user: user, + showOnlineStatus: false, onTap: onUserAvatarTap ?? (_) => Scaffold.of(context).openDrawer(), borderRadius: BorderRadius.circular(20), constraints: BoxConstraints.tightFor( From b20caeee8fa0606926e61f96afc27209de1ced60 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Mon, 23 Nov 2020 13:15:37 +0100 Subject: [PATCH 17/26] add cacheextent and placeholder --- images/placeholder.png | Bin 0 -> 981 bytes lib/src/media_list_view.dart | 12 ++++++++---- lib/src/message_input.dart | 5 +++++ 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 images/placeholder.png diff --git a/images/placeholder.png b/images/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..deca84745564e52a2d1da32eb4bbd07eb7c46323 GIT binary patch literal 981 zcmeAS@N?(olHy`uVBq!ia0vp^WgyJK1|(&drwalp&H|6fVg?3oVGw3ym^DWND9BhG z5$Qp10} zV<*^{94~dnZrOafvSGr3pN3VB-W6$97Fx*29X+v8$4#hP^k|an#)v?jFcDfaueHv& z{WeUl|M=&Gq>T|a{a3R>BNmEO?~ObCv}mDl6!Xs6XP2$HUbB2+o{K=2GV_iP=bnH5 ztjuEUI5pYWb8eHN@+kvHWwG#Dx0Q@(@BY^5>s)AgH1EpOBG2$84hmemrOw=XTNW*` zK=8Iz;ECv*o!SR@)*jA(UH>CIp!Jc|u`J_^*aDwWo6=^c)0|;5j0GF58rQsHXX566KN&V}x*mGyeR|fHeh>9+s-;{<9=%p(+?%ACR-6CXCV1%_uQ%E& z8J9RYv2rS$guG6c>!;yYhSk6(mtnbQ<%!p?S zCI3<^g^pg*u9|9Od?o3**W7)4JBwAW07WA5jo&)jCucukGn+-4 zTvoxv#YyR<^dg^EL>~9$Bd*{7bP0l+XkK+2Exx literal 0 HcmV?d00001 diff --git a/lib/src/media_list_view.dart b/lib/src/media_list_view.dart index cd414fa9..371428d4 100644 --- a/lib/src/media_list_view.dart +++ b/lib/src/media_list_view.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:media_gallery/media_gallery.dart'; import 'package:stream_chat_flutter/src/stream_icons.dart'; -import 'package:transparent_image/transparent_image.dart'; class MediaListView extends StatefulWidget { final List selectedIds; @@ -26,8 +25,10 @@ class _MediaListViewState extends State { return GridView.builder( itemCount: _media.length, controller: _scrollController, - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + ), + cacheExtent: 1000, itemBuilder: ( context, position, @@ -42,7 +43,10 @@ class _MediaListViewState extends State { aspectRatio: 1.0, child: FadeInImage( fadeInDuration: Duration(milliseconds: 300), - placeholder: MemoryImage(kTransparentImage), + placeholder: AssetImage( + 'images/placeholder.png', + package: 'stream_chat_flutter', + ), image: MediaThumbnailProvider( media: media, highQuality: true, diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 8b77a5cf..af4b8979 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -201,6 +201,11 @@ class MessageInputState extends State { onPanUpdate: (details) { if (details.delta.dy > 0) { _focusNode.unfocus(); + if (_openFilePickerSection) { + setState(() { + _openFilePickerSection = false; + }); + } } }, child: Column( From 5ec2b20a0d6b1658bfe98e2903e3cba6848218c5 Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Tue, 24 Nov 2020 14:55:37 +0530 Subject: [PATCH 18/26] [Channel List Header] Replace pen_write icon with correct svg icon. --- images/icon_pen-write.svg | 5 +++++ lib/src/channel_list_header.dart | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 images/icon_pen-write.svg diff --git a/images/icon_pen-write.svg b/images/icon_pen-write.svg new file mode 100644 index 00000000..b2711dad --- /dev/null +++ b/images/icon_pen-write.svg @@ -0,0 +1,5 @@ + + + diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 6a838265..7ae84eec 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -1,6 +1,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/stream_neumorphic_button.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -107,8 +108,11 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { color = Colors.grey; break; } - return Icon( - StreamIcons.pen_write, + return SvgPicture.asset( + 'images/icon_pen-write.svg', + package: 'stream_chat_flutter', + width: 24.0, + height: 24.0, color: color, ); }, From 92b88c505eac8de6165b19cadb0702cd59fb730b Mon Sep 17 00:00:00 2001 From: xsahil03x Date: Tue, 24 Nov 2020 15:33:48 +0530 Subject: [PATCH 19/26] Minor fix --- lib/src/channel_list_header.dart | 2 +- images/icon_pen-write.svg => svgs/icon_pen_write.svg | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename images/icon_pen-write.svg => svgs/icon_pen_write.svg (100%) diff --git a/lib/src/channel_list_header.dart b/lib/src/channel_list_header.dart index 7ae84eec..0a01733b 100644 --- a/lib/src/channel_list_header.dart +++ b/lib/src/channel_list_header.dart @@ -109,7 +109,7 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { break; } return SvgPicture.asset( - 'images/icon_pen-write.svg', + 'svgs/icon_pen_write.svg', package: 'stream_chat_flutter', width: 24.0, height: 24.0, diff --git a/images/icon_pen-write.svg b/svgs/icon_pen_write.svg similarity index 100% rename from images/icon_pen-write.svg rename to svgs/icon_pen_write.svg From f1b7c6f39fee0fc6e91b397b81bd2bea802c4d02 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 12:52:54 +0100 Subject: [PATCH 20/26] use StreamSvgIcon widget --- example/lib/advanced_options_page.dart | 4 +- example/lib/chips_input_text_field.dart | 13 +- example/lib/choose_user_page.dart | 4 +- example/lib/group_chat_details_screen.dart | 4 +- example/lib/main.dart | 15 +- example/lib/new_chat_screen.dart | 15 +- example/lib/new_group_chat_screen.dart | 25 +- example/pubspec.yaml | 2 +- fonts/stream-icons.ttf | Bin 52024 -> 0 bytes lib/src/back_button.dart | 12 +- lib/src/channel_bottom_sheet.dart | 17 +- lib/src/channel_list_view.dart | 16 +- lib/src/channel_preview.dart | 8 +- lib/src/giphy_attachment.dart | 36 +- lib/src/media_list_view.dart | 9 +- lib/src/message_actions_modal.dart | 25 +- lib/src/message_input.dart | 158 ++- lib/src/message_list_view.dart | 5 +- lib/src/reaction_bubble.dart | 27 +- lib/src/reaction_icon.dart | 6 +- lib/src/reaction_picker.dart | 9 +- lib/src/stream_chat_theme.dart | 11 +- lib/src/stream_icons.dart | 1184 -------------------- lib/src/stream_svg_icon.dart | 40 + lib/src/thread_header.dart | 13 +- lib/src/user_item.dart | 8 +- lib/stream_chat_flutter.dart | 8 +- lib/svgs/Empty State_Camera.svg | 3 + lib/svgs/Empty State_Files.svg | 3 + lib/svgs/Empty State_No channel.svg | 3 + lib/svgs/Empty State_Search.svg | 3 + lib/svgs/Empty State_picture.svg | 3 + lib/svgs/Giphy icon.svg | 8 + lib/svgs/Icon_LOL_reaction.svg | 3 + lib/svgs/Icon_Thread_Reply.svg | 3 + lib/svgs/Icon_User_add.svg | 3 + lib/svgs/Icon_User_deselect.svg | 3 + lib/svgs/Icon_arrow_right.svg | 3 + lib/svgs/Icon_attach.svg | 3 + lib/svgs/Icon_camera.svg | 3 + lib/svgs/Icon_check.svg | 3 + lib/svgs/Icon_check_all.svg | 3 + lib/svgs/Icon_check_big.svg | 3 + lib/svgs/Icon_check_send.svg | 3 + lib/svgs/Icon_circle_right.svg | 3 + lib/svgs/Icon_circle_up.svg | 3 + lib/svgs/Icon_close.svg | 3 + lib/svgs/Icon_close_black.svg | 3 + lib/svgs/Icon_close_sml.svg | 3 + lib/svgs/Icon_cloud_download.svg | 3 + lib/svgs/Icon_contacts.svg | 3 + lib/svgs/Icon_copy.svg | 3 + lib/svgs/Icon_curve_line_left_up.svg | 3 + lib/svgs/Icon_curve_line_left_up_big.svg | 3 + lib/svgs/Icon_delete.svg | 3 + lib/svgs/Icon_down.svg | 3 + lib/svgs/Icon_download.svg | 3 + lib/svgs/Icon_edit.svg | 3 + lib/svgs/Icon_empty_circle_left.svg | 3 + lib/svgs/Icon_error.svg | 3 + lib/svgs/Icon_eye-off.svg | 3 + lib/svgs/Icon_grid.svg | 3 + lib/svgs/Icon_left.svg | 3 + lib/svgs/Icon_lightning-command runner.svg | 3 + lib/svgs/Icon_love_reaction.svg | 3 + lib/svgs/Icon_message.svg | 3 + lib/svgs/Icon_mute.svg | 3 + lib/svgs/Icon_pen-write.svg | 3 + lib/svgs/Icon_record.svg | 3 + lib/svgs/Icon_right.svg | 3 + lib/svgs/Icon_search.svg | 3 + lib/svgs/Icon_smile.svg | 3 + lib/svgs/Icon_thumbs_down_reaction.svg | 3 + lib/svgs/Icon_thumbs_up_reaction.svg | 3 + lib/svgs/Icon_time.svg | 3 + lib/svgs/Icon_user.svg | 3 + lib/svgs/Icon_user_delete.svg | 3 + lib/svgs/Icon_wut_reaction.svg | 3 + lib/svgs/STREAM MARK 1.svg | 10 + lib/svgs/UI_Reverse Pagination Loading.svg | 14 + lib/svgs/eye-line_big.svg | 3 + lib/svgs/files.svg | 3 + lib/svgs/filetype_7z.svg | 7 + lib/svgs/filetype_CSV.svg | 7 + lib/svgs/filetype_DOC.svg | 12 + lib/svgs/filetype_DOCX.svg | 12 + lib/svgs/filetype_Generic.svg | 11 + lib/svgs/filetype_MD.svg | 7 + lib/svgs/filetype_ODT.svg | 7 + lib/svgs/filetype_PDF.svg | 7 + lib/svgs/filetype_PPT.svg | 12 + lib/svgs/filetype_PPTX-1.svg | 12 + lib/svgs/filetype_PPTX.svg | 12 + lib/svgs/filetype_RAR.svg | 7 + lib/svgs/filetype_RTF.svg | 7 + lib/svgs/filetype_TAR.svg | 7 + lib/svgs/filetype_TXT.svg | 7 + lib/svgs/filetype_XLS.svg | 12 + lib/svgs/filetype_XLSX.svg | 12 + lib/svgs/filetype_ZIP.svg | 7 + lib/svgs/filetype_html.svg | 8 + lib/svgs/giphy icon blue.svg | 3 + lib/svgs/icon_SHARE.svg | 3 + lib/svgs/icon_delete_grey.svg | 4 + lib/svgs/icon_mentions.svg | 3 + lib/svgs/mentions.svg | 3 + lib/svgs/pictures.svg | 3 + lib/svgs/settings.svg | 3 + lib/svgs/share_arrow.svg | 3 + pubspec.yaml | 5 +- 110 files changed, 673 insertions(+), 1392 deletions(-) delete mode 100644 fonts/stream-icons.ttf delete mode 100644 lib/src/stream_icons.dart create mode 100644 lib/src/stream_svg_icon.dart create mode 100644 lib/svgs/Empty State_Camera.svg create mode 100644 lib/svgs/Empty State_Files.svg create mode 100644 lib/svgs/Empty State_No channel.svg create mode 100644 lib/svgs/Empty State_Search.svg create mode 100644 lib/svgs/Empty State_picture.svg create mode 100644 lib/svgs/Giphy icon.svg create mode 100644 lib/svgs/Icon_LOL_reaction.svg create mode 100644 lib/svgs/Icon_Thread_Reply.svg create mode 100644 lib/svgs/Icon_User_add.svg create mode 100644 lib/svgs/Icon_User_deselect.svg create mode 100644 lib/svgs/Icon_arrow_right.svg create mode 100644 lib/svgs/Icon_attach.svg create mode 100644 lib/svgs/Icon_camera.svg create mode 100644 lib/svgs/Icon_check.svg create mode 100644 lib/svgs/Icon_check_all.svg create mode 100644 lib/svgs/Icon_check_big.svg create mode 100644 lib/svgs/Icon_check_send.svg create mode 100644 lib/svgs/Icon_circle_right.svg create mode 100644 lib/svgs/Icon_circle_up.svg create mode 100644 lib/svgs/Icon_close.svg create mode 100644 lib/svgs/Icon_close_black.svg create mode 100644 lib/svgs/Icon_close_sml.svg create mode 100644 lib/svgs/Icon_cloud_download.svg create mode 100644 lib/svgs/Icon_contacts.svg create mode 100644 lib/svgs/Icon_copy.svg create mode 100644 lib/svgs/Icon_curve_line_left_up.svg create mode 100644 lib/svgs/Icon_curve_line_left_up_big.svg create mode 100644 lib/svgs/Icon_delete.svg create mode 100644 lib/svgs/Icon_down.svg create mode 100644 lib/svgs/Icon_download.svg create mode 100644 lib/svgs/Icon_edit.svg create mode 100644 lib/svgs/Icon_empty_circle_left.svg create mode 100644 lib/svgs/Icon_error.svg create mode 100644 lib/svgs/Icon_eye-off.svg create mode 100644 lib/svgs/Icon_grid.svg create mode 100644 lib/svgs/Icon_left.svg create mode 100644 lib/svgs/Icon_lightning-command runner.svg create mode 100644 lib/svgs/Icon_love_reaction.svg create mode 100644 lib/svgs/Icon_message.svg create mode 100644 lib/svgs/Icon_mute.svg create mode 100644 lib/svgs/Icon_pen-write.svg create mode 100644 lib/svgs/Icon_record.svg create mode 100644 lib/svgs/Icon_right.svg create mode 100644 lib/svgs/Icon_search.svg create mode 100644 lib/svgs/Icon_smile.svg create mode 100644 lib/svgs/Icon_thumbs_down_reaction.svg create mode 100644 lib/svgs/Icon_thumbs_up_reaction.svg create mode 100644 lib/svgs/Icon_time.svg create mode 100644 lib/svgs/Icon_user.svg create mode 100644 lib/svgs/Icon_user_delete.svg create mode 100644 lib/svgs/Icon_wut_reaction.svg create mode 100644 lib/svgs/STREAM MARK 1.svg create mode 100644 lib/svgs/UI_Reverse Pagination Loading.svg create mode 100644 lib/svgs/eye-line_big.svg create mode 100644 lib/svgs/files.svg create mode 100644 lib/svgs/filetype_7z.svg create mode 100644 lib/svgs/filetype_CSV.svg create mode 100644 lib/svgs/filetype_DOC.svg create mode 100644 lib/svgs/filetype_DOCX.svg create mode 100644 lib/svgs/filetype_Generic.svg create mode 100644 lib/svgs/filetype_MD.svg create mode 100644 lib/svgs/filetype_ODT.svg create mode 100644 lib/svgs/filetype_PDF.svg create mode 100644 lib/svgs/filetype_PPT.svg create mode 100644 lib/svgs/filetype_PPTX-1.svg create mode 100644 lib/svgs/filetype_PPTX.svg create mode 100644 lib/svgs/filetype_RAR.svg create mode 100644 lib/svgs/filetype_RTF.svg create mode 100644 lib/svgs/filetype_TAR.svg create mode 100644 lib/svgs/filetype_TXT.svg create mode 100644 lib/svgs/filetype_XLS.svg create mode 100644 lib/svgs/filetype_XLSX.svg create mode 100644 lib/svgs/filetype_ZIP.svg create mode 100644 lib/svgs/filetype_html.svg create mode 100644 lib/svgs/giphy icon blue.svg create mode 100644 lib/svgs/icon_SHARE.svg create mode 100644 lib/svgs/icon_delete_grey.svg create mode 100644 lib/svgs/icon_mentions.svg create mode 100644 lib/svgs/mentions.svg create mode 100644 lib/svgs/pictures.svg create mode 100644 lib/svgs/settings.svg create mode 100644 lib/svgs/share_arrow.svg diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index c84ef58e..57ed1f06 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -44,8 +44,8 @@ class _AdvancedOptionsPageState extends State { ), ), leading: IconButton( - icon: Icon( - StreamIcons.left, + icon: StreamSvgIcon( + assetName: 'Icon_left.svg', color: Colors.black, ), onPressed: () { diff --git a/example/lib/chips_input_text_field.dart b/example/lib/chips_input_text_field.dart index 317a68f7..0310de5b 100644 --- a/example/lib/chips_input_text_field.dart +++ b/example/lib/chips_input_text_field.dart @@ -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 = Widget Function(BuildContext context, T chip); typedef OnChipAdded = void Function(T chip); @@ -130,12 +130,13 @@ class ChipInputTextFieldState extends State> { Align( alignment: Alignment.bottomCenter, child: IconButton( - icon: Icon( - _chips.isEmpty - ? StreamIcons.user - : StreamIcons.user_add, + icon: StreamSvgIcon( + assetName: _chips.isEmpty + ? 'Icon_user.svg' + : 'Icon_User_add.svg', color: Colors.black.withOpacity(0.5), - size: 24, + height: 24, + width: 24, ), onPressed: !_pauseItemAddition ? null : resumeItemAddition, diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 4583a2a6..0a0d67b9 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -196,8 +196,8 @@ class ChooseUserPage extends StatelessWidget { ); }, leading: CircleAvatar( - child: Icon( - StreamIcons.settings, + child: StreamSvgIcon( + assetName: 'settings.svg', color: Colors.black, ), backgroundColor: diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index 6aff5711..d5c65a9e 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -106,7 +106,9 @@ class _GroupChatDetailsScreenState extends State { NeumorphicButton( child: IconButton( padding: const EdgeInsets.all(0), - icon: Icon(StreamIcons.check), + icon: StreamSvgIcon( + assetName: 'Icon_check.svg', + ), color: Color(0xFF006CFF), onPressed: _isGroupNameEmpty ? null diff --git a/example/lib/main.dart b/example/lib/main.dart index a7d5e473..1984c3dd 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -141,7 +141,10 @@ class ChannelListPage extends StatelessWidget { ), ), ListTile( - leading: Icon(StreamIcons.edit), + leading: StreamSvgIcon( + assetName: 'Icon_pen-write.svg', + color: Colors.black.withOpacity(.5), + ), onTap: () { Navigator.of(context) ..pop() @@ -157,7 +160,10 @@ class ChannelListPage extends StatelessWidget { ), ), ListTile( - leading: Icon(StreamIcons.group), + leading: StreamSvgIcon( + assetName: 'Icon_contacts.svg', + color: Colors.black.withOpacity(.5), + ), onTap: () { Navigator.of(context) ..pop() @@ -189,7 +195,10 @@ class ChannelListPage extends StatelessWidget { ), ); }, - leading: Icon(StreamIcons.user), + leading: StreamSvgIcon( + assetName: 'Icon_user.svg', + color: Colors.black.withOpacity(.5), + ), title: Text( 'Sign out', style: TextStyle( diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index 9ec2ca7e..6f8e53cd 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -164,8 +164,8 @@ class _NewChatScreenState extends State { ), ), Positioned( - child: Icon( - StreamIcons.close, + child: StreamSvgIcon( + assetName: 'Icon_close.svg', color: Colors.white, ), ), @@ -194,8 +194,8 @@ class _NewChatScreenState extends State { child: Row( children: [ NeumorphicButton( - child: Icon( - StreamIcons.group, + child: StreamSvgIcon( + assetName: 'Icon_contacts.svg', color: Color(0xFF006CFF), ), ), @@ -289,9 +289,10 @@ class _NewChatScreenState extends State { children: [ Padding( padding: const EdgeInsets.all(24), - child: Icon( - StreamIcons.search, - size: 96, + child: StreamSvgIcon( + assetName: 'Icon_search.svg', + height: 96, + width: 96, color: Colors.grey, ), ), diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index b75e7510..3d7c418a 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -65,8 +65,8 @@ class _NewGroupChatScreenState extends State { actions: [ if (_selectedUsers.isNotEmpty) IconButton( - icon: Icon( - StreamIcons.arrow_right, + icon: StreamSvgIcon( + assetName: 'Icon_right.svg', color: Color(0xFF006CFF), ), onPressed: () { @@ -101,10 +101,11 @@ class _NewGroupChatScreenState extends State { child: TextField( controller: _controller, decoration: InputDecoration( - prefixIcon: Icon( - StreamIcons.search, + prefixIcon: StreamSvgIcon( + assetName: 'Icon_search.svg', color: Colors.black, - size: 24, + height: 24, + width: 24, ), hintText: 'Search', hintStyle: TextStyle( @@ -162,9 +163,10 @@ class _NewGroupChatScreenState extends State { ), child: Padding( padding: const EdgeInsets.all(0.0), - child: Icon( - StreamIcons.close, - size: 24, + child: StreamSvgIcon( + assetName: 'Icon_close.svg', + height: 24, + width: 24, ), ), ), @@ -260,9 +262,10 @@ class _NewGroupChatScreenState extends State { children: [ Padding( padding: const EdgeInsets.all(24), - child: Icon( - StreamIcons.search, - size: 96, + child: StreamSvgIcon( + assetName: 'Icon_search.svg', + height: 96, + width: 96, color: Colors.grey, ), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e5daa043..8700c861 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.66+68 +version: 1.0.67+69 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/fonts/stream-icons.ttf b/fonts/stream-icons.ttf deleted file mode 100644 index 80660da49b37da1994c6044eb58c4b76501db4ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52024 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 children: [ Padding( padding: const EdgeInsets.all(8.0), - child: Icon( - StreamIcons.message, - size: 136, + child: StreamSvgIcon( + assetName: 'Icon_message.svg', + height: 136, + width: 136, color: Color(0xffDBDBDB), ), ), @@ -517,7 +519,9 @@ class _ChannelListViewState extends State ), IconSlideAction( color: backgroundColor, - icon: StreamIcons.mute, + iconWidget: StreamSvgIcon( + assetName: 'Icon_mute.svg', + ), onTap: () async { if (!channel.isMuted) { await channel.mute(); @@ -529,7 +533,9 @@ class _ChannelListViewState extends State if (channel.isGroup && !channel.isDistinct) IconSlideAction( color: backgroundColor, - icon: StreamIcons.user_minus, + iconWidget: StreamSvgIcon( + assetName: 'Icon_User_deselect.svg', + ), onTap: () async { final confirm = await showConfirmationDialog( context, diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index ba3090c2..c61e469e 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:jiffy/jiffy.dart'; import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import '../stream_chat_flutter.dart'; import 'channel_name.dart'; @@ -152,9 +153,10 @@ class ChannelPreview extends StatelessWidget { return Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - Icon( - StreamIcons.mute, - size: 16, + StreamSvgIcon( + assetName: 'Icon_mute.svg', + height: 16, + width: 16, ), Text( ' Channel is muted', diff --git a/lib/src/giphy_attachment.dart b/lib/src/giphy_attachment.dart index df4708c5..0f3b9e7e 100644 --- a/lib/src/giphy_attachment.dart +++ b/lib/src/giphy_attachment.dart @@ -1,6 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import '../stream_chat_flutter.dart'; import 'attachment_error.dart'; @@ -111,10 +112,11 @@ class GiphyAttachment extends StatelessWidget { ), child: Row( children: [ - Icon( - StreamIcons.lightning, + StreamSvgIcon( + assetName: 'Icon_lightning-command runner.svg', color: StreamChatTheme.of(context).accentColor, - size: 16.0, + height: 16.0, + width: 16.0, ), Text( 'GIPHY', @@ -144,9 +146,10 @@ class GiphyAttachment extends StatelessWidget { child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), - icon: Icon( - StreamIcons.left, - size: 24.0, + icon: StreamSvgIcon( + assetName: 'Icon_left.svg', + height: 24.0, + width: 24.0, ), splashRadius: 16, onPressed: () { @@ -172,9 +175,10 @@ class GiphyAttachment extends StatelessWidget { child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), - icon: Icon( - StreamIcons.right, - size: 24.0, + icon: StreamSvgIcon( + assetName: 'Icon_right.svg', + height: 24.0, + width: 24.0, ), splashRadius: 16, onPressed: () { @@ -253,10 +257,11 @@ class GiphyAttachment extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - Icon( - StreamIcons.eye, + StreamSvgIcon( + assetName: 'Icon_eye-off.svg', color: Colors.black.withOpacity(0.5), - size: 16.0, + height: 16.0, + width: 16.0, ), SizedBox( width: 8.0, @@ -326,10 +331,11 @@ class GiphyAttachment extends StatelessWidget { ), child: Row( children: [ - Icon( - StreamIcons.lightning, + StreamSvgIcon( + assetName: 'Icon_lightning-command runner.svg', color: Colors.white, - size: 16, + height: 16, + width: 16, ), Text( 'GIPHY', diff --git a/lib/src/media_list_view.dart b/lib/src/media_list_view.dart index 371428d4..c4ae4981 100644 --- a/lib/src/media_list_view.dart +++ b/lib/src/media_list_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:media_gallery/media_gallery.dart'; -import 'package:stream_chat_flutter/src/stream_icons.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; class MediaListView extends StatefulWidget { final List selectedIds; @@ -71,9 +71,10 @@ class _MediaListViewState extends State { child: CircleAvatar( radius: 12, backgroundColor: Colors.white, - child: Icon( - StreamIcons.check, - size: 24, + child: StreamSvgIcon( + assetName: 'Icon_check.svg', + height: 24, + width: 24, color: Colors.black, ), ), diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index 8b53a973..d95b63ea 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -6,7 +6,7 @@ import 'package:flutter/services.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/reaction_picker.dart'; import 'package:stream_chat_flutter/src/stream_channel.dart'; -import 'package:stream_chat_flutter/src/stream_icons.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'message_input.dart'; import 'message_widget.dart'; @@ -188,8 +188,8 @@ class MessageActionsModal extends StatelessWidget { style: Theme.of(context).textTheme.headline6.copyWith(color: Colors.red), ), - leading: Icon( - StreamIcons.delete, + leading: StreamSvgIcon( + assetName: 'Icon_delete.svg', color: Colors.red, ), onTap: () { @@ -208,8 +208,8 @@ class MessageActionsModal extends StatelessWidget { 'Copy message', style: Theme.of(context).textTheme.headline6, ), - leading: Icon( - StreamIcons.copy, + leading: StreamSvgIcon( + assetName: 'Icon_copy.svg', color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () async { @@ -225,8 +225,8 @@ class MessageActionsModal extends StatelessWidget { 'Edit message', style: Theme.of(context).textTheme.headline6, ), - leading: Icon( - StreamIcons.edit, + leading: StreamSvgIcon( + assetName: 'Icon_edit.svg', color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () async { @@ -267,9 +267,10 @@ class MessageActionsModal extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( - icon: Icon( - StreamIcons.edit, - size: 22, + icon: StreamSvgIcon( + assetName: 'Icon_edit.svg', + height: 22, + width: 22, color: StreamChatTheme.of(context).primaryIconTheme.color, ), @@ -323,8 +324,8 @@ class MessageActionsModal extends StatelessWidget { 'Thread reply', style: Theme.of(context).textTheme.headline6, ), - leading: Icon( - StreamIcons.sorting_up, + leading: StreamSvgIcon( + assetName: 'Icon_Thread_Reply.svg', color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () { diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index af4b8979..a7d8db5e 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:io'; -import 'dart:math'; import 'package:emojis/emoji.dart'; import 'package:file_picker/file_picker.dart'; @@ -18,6 +17,7 @@ import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/media_list_view.dart'; import 'package:stream_chat_flutter/src/message_list_view.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/user_avatar.dart'; import 'package:stream_chat_flutter/src/video_thumbnail.dart'; import 'package:substring_highlight/substring_highlight.dart'; @@ -284,9 +284,10 @@ class MessageInputState extends State { crossFadeState: _sendAsDm ? CrossFadeState.showFirst : CrossFadeState.showSecond, - firstChild: Icon( - StreamIcons.check, - size: 16.0, + firstChild: StreamSvgIcon( + assetName: 'Icon_check.svg', + height: 16.0, + width: 16.0, color: Colors.white, ), secondChild: SizedBox( @@ -330,8 +331,8 @@ class MessageInputState extends State { _actionsShrunk = false; }); }, - icon: Icon( - StreamIcons.circle_left, + icon: StreamSvgIcon( + assetName: 'Icon_empty_circle_left.svg', color: StreamChatTheme.of(context).accentColor, ), ), @@ -403,8 +404,8 @@ class MessageInputState extends State { _chosenCommand?.name ?? "", style: TextStyle(color: Colors.white), ), - avatar: Icon( - StreamIcons.lightning, + avatar: StreamSvgIcon( + assetName: 'Icon_lightning-command runner.svg', color: Colors.white, ), ), @@ -579,9 +580,11 @@ class MessageInputState extends State { children: [ Padding( padding: const EdgeInsets.symmetric( - horizontal: 8.0), - child: Icon( - StreamIcons.lightning, + horizontal: 8.0, + ), + child: StreamSvgIcon( + assetName: + 'Icon_lightning-command runner.svg', color: StreamChatTheme.of(context) .accentColor, ), @@ -619,10 +622,12 @@ class MessageInputState extends State { trailing: CircleAvatar( backgroundColor: StreamChatTheme.of(context).accentColor, - child: Icon( - StreamIcons.lightning, + child: StreamSvgIcon( + assetName: + 'Icon_lightning-command runner.svg', color: Colors.white, - size: 12.5, + height: 12.5, + width: 12.5, ), maxRadius: 12, ), @@ -656,9 +661,10 @@ class MessageInputState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ IconButton( - icon: Icon( - StreamIcons.picture, - size: 24, + icon: StreamSvgIcon( + assetName: 'pictures.svg', + height: 24, + width: 24, color: _filePickerIndex == 0 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -670,9 +676,10 @@ class MessageInputState extends State { }, ), IconButton( - icon: Icon( - StreamIcons.folder, - size: 24, + icon: StreamSvgIcon( + assetName: 'files.svg', + height: 24, + width: 24, color: _filePickerIndex == 1 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -682,9 +689,8 @@ class MessageInputState extends State { }, ), IconButton( - icon: SvgPicture.asset( - 'svgs/icon_camera.svg', - package: 'stream_chat_flutter', + icon: StreamSvgIcon( + assetName: 'Icon_camera.svg', height: 24, width: 24, color: _filePickerIndex == 2 @@ -696,10 +702,11 @@ class MessageInputState extends State { }, ), IconButton( - icon: Icon( - StreamIcons.record, - size: 24, - color: _filePickerIndex == 2 + icon: StreamSvgIcon( + assetName: 'Icon_record.svg', + height: 24, + width: 24, + color: _filePickerIndex == 3 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), ), @@ -993,8 +1000,8 @@ class MessageInputState extends State { fontWeight: FontWeight.bold), ), subtitle: Text('@${m.userId}'), - trailing: Icon( - StreamIcons.at_mention, + trailing: StreamSvgIcon( + assetName: 'mentions.svg', color: StreamChatTheme.of(context) .accentColor, ), @@ -1091,8 +1098,8 @@ class MessageInputState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Icon( - StreamIcons.smile, + child: StreamSvgIcon( + assetName: 'Icon_smile.svg', color: StreamChatTheme.of(context).accentColor, ), ), @@ -1227,9 +1234,10 @@ class MessageInputState extends State { }, fillColor: Colors.black.withOpacity(.5), child: Center( - child: Icon( - StreamIcons.close, - size: 24, + child: StreamSvgIcon( + assetName: 'Icon_close.svg', + height: 24, + width: 24, color: Colors.white, ), ), @@ -1299,8 +1307,8 @@ class MessageInputState extends State { child: Padding( padding: const EdgeInsets.only(left: 4.0, right: 8.0, top: 8.0, bottom: 8.0), - child: Icon( - StreamIcons.lightning, + child: StreamSvgIcon( + assetName: 'Icon_lightning-command runner.svg', color: Color(0xFF000000).withAlpha(128), ), ), @@ -1323,8 +1331,8 @@ class MessageInputState extends State { child: Padding( padding: EdgeInsets.only(left: 8.0, right: padding, top: 8.0, bottom: 8.0), - child: Icon( - StreamIcons.attach, + child: StreamSvgIcon( + assetName: 'Icon_attach.svg', color: _openFilePickerSection ? StreamChatTheme.of(context).accentColor : Color(0xFF000000).withAlpha(128), @@ -1594,69 +1602,53 @@ class MessageInputState extends State { } Widget _buildIdleSendButton(BuildContext context) { - return IconTheme( - data: - StreamChatTheme.of(context).channelTheme.messageInputButtonIconTheme, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Center( - child: InkWell( - onTap: () { - sendMessage(); - }, - child: Icon( - _getIdleSendIcon(), - color: Colors.grey, - ), - )), - ), + return Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: InkWell( + onTap: () { + sendMessage(); + }, + child: StreamSvgIcon( + assetName: _getIdleSendIcon(), + color: Colors.grey, + ), + )), ); } Widget _buildSendButton(BuildContext context) { - return IconTheme( - data: - StreamChatTheme.of(context).channelTheme.messageInputButtonIconTheme, - child: Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - sendMessage(); - }, - child: _getSendIcon(), + return Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + sendMessage(); + }, + child: StreamSvgIcon( + assetName: _getSendIcon(), + color: StreamChatTheme.of(context).accentColor, ), ), ), ); } - IconData _getIdleSendIcon() { + String _getIdleSendIcon() { if (_commandEnabled) { - return StreamIcons.search; + return 'Icon_search.svg'; } else { - return StreamIcons.send_message; + return 'Icon_circle_up.svg'; } } - Widget _getSendIcon() { + String _getSendIcon() { if (widget.editMessage != null) { - return Icon( - StreamIcons.check_send, - color: StreamChatTheme.of(context).accentColor, - ); + return 'Icon_circle_right.svg'; } else if (_commandEnabled) { - return Icon( - StreamIcons.search, - color: StreamChatTheme.of(context).accentColor, - ); + return 'Icon_search.svg'; } else { - return Transform.rotate( - angle: -pi / 2, - child: Icon( - StreamIcons.send_message, - color: StreamChatTheme.of(context).accentColor, - )); + return 'Icon_circle_right.svg'; } } diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 4a5e445b..2954f043 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -6,6 +6,7 @@ import 'package:jiffy/jiffy.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:stream_chat/stream_chat.dart'; import 'package:stream_chat_flutter/src/message_widget.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/system_message.dart'; import 'package:visibility_detector/visibility_detector.dart'; @@ -374,8 +375,8 @@ class _MessageListViewState extends State { children: [ FloatingActionButton( backgroundColor: Colors.white, - child: Icon( - StreamIcons.down, + child: StreamSvgIcon( + assetName: 'Icon_down.svg', color: Colors.black, ), onPressed: () { diff --git a/lib/src/reaction_bubble.dart b/lib/src/reaction_bubble.dart index 83593afc..87dc7a92 100644 --- a/lib/src/reaction_bubble.dart +++ b/lib/src/reaction_bubble.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:stream_chat_flutter/src/reaction_icon.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; class ReactionBubble extends StatelessWidget { @@ -99,14 +100,24 @@ class ReactionBubble extends StatelessWidget { padding: const EdgeInsets.symmetric( horizontal: 4.0, ), - child: Icon( - reactionIcon?.iconData ?? Icons.help_outline_rounded, - size: 16, - color: (!highlightOwnReactions || - reaction.user.id == StreamChat.of(context).user.id) - ? StreamChatTheme.of(context).accentColor - : Colors.black.withOpacity(.5), - ), + child: reactionIcon != null + ? StreamSvgIcon( + assetName: reactionIcon.assetName, + width: 16, + height: 16, + color: (!highlightOwnReactions || + reaction.user.id == StreamChat.of(context).user.id) + ? StreamChatTheme.of(context).accentColor + : Colors.black.withOpacity(.5), + ) + : Icon( + Icons.help_outline_rounded, + size: 16, + color: (!highlightOwnReactions || + reaction.user.id == StreamChat.of(context).user.id) + ? StreamChatTheme.of(context).accentColor + : Colors.black.withOpacity(.5), + ), ); } diff --git a/lib/src/reaction_icon.dart b/lib/src/reaction_icon.dart index 5f885643..99b93328 100644 --- a/lib/src/reaction_icon.dart +++ b/lib/src/reaction_icon.dart @@ -1,11 +1,9 @@ -import 'package:flutter/material.dart'; - class ReactionIcon { final String type; - final IconData iconData; + final String assetName; ReactionIcon({ this.type, - this.iconData, + this.assetName, }); } diff --git a/lib/src/reaction_picker.dart b/lib/src/reaction_picker.dart index 83698e46..ff23b8a3 100644 --- a/lib/src/reaction_picker.dart +++ b/lib/src/reaction_picker.dart @@ -1,6 +1,6 @@ import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/physics.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import '../stream_chat_flutter.dart'; @@ -84,9 +84,10 @@ class _ReactionPickerState extends State ..scale(animations[index].value, animations[index].value) ..rotateZ(1.0 - animations[index].value), - child: Icon( - reactionIcon.iconData, - size: animations[index].value * 24.0, + child: StreamSvgIcon( + assetName: reactionIcon.assetName, + height: animations[index].value * 24.0, + width: animations[index].value * 24.0, color: ownReactionIndex != -1 ? StreamChatTheme.of(context).accentColor : Theme.of(context) diff --git a/lib/src/stream_chat_theme.dart b/lib/src/stream_chat_theme.dart index 967cbbbf..d5b2c1c2 100644 --- a/lib/src/stream_chat_theme.dart +++ b/lib/src/stream_chat_theme.dart @@ -5,7 +5,6 @@ import 'package:stream_chat_flutter/src/channel_header.dart'; import 'package:stream_chat_flutter/src/channel_preview.dart'; import 'package:stream_chat_flutter/src/message_input.dart'; import 'package:stream_chat_flutter/src/reaction_icon.dart'; -import 'package:stream_chat_flutter/src/stream_icons.dart'; import 'package:stream_chat_flutter/src/utils.dart'; /// Inherited widget providing the [StreamChatThemeData] to the widget tree @@ -353,23 +352,23 @@ class StreamChatThemeData { reactionIcons: [ ReactionIcon( type: 'love', - iconData: StreamIcons.love_reaction, + assetName: 'Icon_love_reaction.svg', ), ReactionIcon( type: 'thumbs_up', - iconData: StreamIcons.thumbs_up_reaction, + assetName: 'Icon_thumbs_up_reaction.svg', ), ReactionIcon( type: 'thumbs_down', - iconData: StreamIcons.thumbs_down_reaction, + assetName: 'Icon_thumbs_down_reaction.svg', ), ReactionIcon( type: 'lol', - iconData: StreamIcons.LOL_reaction, + assetName: 'Icon_LOL_reaction.svg', ), ReactionIcon( type: 'wut', - iconData: StreamIcons.wut_reaction, + assetName: 'Icon_wut_reaction.svg', ), ], ); diff --git a/lib/src/stream_icons.dart b/lib/src/stream_icons.dart deleted file mode 100644 index c8fc6493..00000000 --- a/lib/src/stream_icons.dart +++ /dev/null @@ -1,1184 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class StreamIcons { - StreamIcons._(); - - static const String _fontFamily = 'stream-icons'; - static const String _fontPackage = 'stream_chat_flutter'; - - static const IconData ambulance_car = IconData( - 0xe900, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData ambulance_signal = IconData( - 0xe901, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData ambulance = IconData( - 0xe902, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData apps = IconData( - 0xe903, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData archive = IconData( - 0xe904, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_down_left = IconData( - 0xe905, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_down = IconData( - 0xe906, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_drop_down = IconData( - 0xe907, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_drop_up = IconData( - 0xe908, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_left_up = IconData( - 0xe909, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_left = IconData( - 0xe90a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_right_down = IconData( - 0xe90b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_right = IconData( - 0xe90c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_up_right = IconData( - 0xe90d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData arrow_up = IconData( - 0xe90e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData at_mention = IconData( - 0xe90f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData atom = IconData( - 0xe910, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData attach = IconData( - 0xe911, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData attention = IconData( - 0xe912, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData basket = IconData( - 0xe913, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData blank_empty = IconData( - 0xe914, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData blank = IconData( - 0xe915, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData blood_add = IconData( - 0xe916, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData blood_delete = IconData( - 0xe917, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData brain = IconData( - 0xe918, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData building = IconData( - 0xe919, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData calculator = IconData( - 0xe91a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData calendar = IconData( - 0xe91b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData call_in = IconData( - 0xe91c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData call_out = IconData( - 0xe91d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData call = IconData( - 0xe91e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData camera = IconData( - 0xe91f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData car = IconData( - 0xe920, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData card = IconData( - 0xe921, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData cards = IconData( - 0xe922, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData cash = IconData( - 0xe923, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData chart_line = IconData( - 0xe924, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData chart = IconData( - 0xe925, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData check_all = IconData( - 0xe926, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData check_send = IconData( - 0xe927, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData check = IconData( - 0xe928, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData chemical = IconData( - 0xe929, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData circle_down = IconData( - 0xe92a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData circle_left = IconData( - 0xe92b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData circle_right = IconData( - 0xe92c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData circle_up = IconData( - 0xe92d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData close_circle = IconData( - 0xe92e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData close = IconData( - 0xe92f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData closed = IconData( - 0xe930, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData coin = IconData( - 0xe931, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData command_runner_rocket = IconData( - 0xe932, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData compass = IconData( - 0xe933, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData copy = IconData( - 0xe934, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData couch = IconData( - 0xe935, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_left_down = IconData( - 0xe936, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_down_left = IconData( - 0xe937, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_down_right = IconData( - 0xe938, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_left_up = IconData( - 0xe939, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_right_up = IconData( - 0xe93a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_up_left = IconData( - 0xe93b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_line_up_right = IconData( - 0xe93c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData curve_right_down = IconData( - 0xe93d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData daily_planner = IconData( - 0xe93e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData date = IconData( - 0xe93f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData delete = IconData( - 0xe940, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData desktop = IconData( - 0xe941, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData disabled = IconData( - 0xe942, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData dna = IconData( - 0xe943, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData doc = IconData( - 0xe944, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData documents = IconData( - 0xe945, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData down = IconData( - 0xe946, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData download_1 = IconData( - 0xe947, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData download = IconData( - 0xe948, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData edit = IconData( - 0xe949, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData emergency_call_add = IconData( - 0xe94a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData emergency_call = IconData( - 0xe94b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData emergency = IconData( - 0xe94c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData error = IconData( - 0xe94d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData exit = IconData( - 0xe94e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData experiment = IconData( - 0xe94f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData eye_off = IconData( - 0xe950, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData eye = IconData( - 0xe951, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData face = IconData( - 0xe952, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData female = IconData( - 0xe953, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData filter_hor = IconData( - 0xe954, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData filter = IconData( - 0xe955, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData first_aid = IconData( - 0xe956, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData flag = IconData( - 0xe957, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData flash = IconData( - 0xe958, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData folder = IconData( - 0xe959, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData form_edit = IconData( - 0xe95a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData grid = IconData( - 0xe95b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData group = IconData( - 0xe95c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData heart_1 = IconData( - 0xe95d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData heart_outline_add = IconData( - 0xe95e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData heart_outline_delete = IconData( - 0xe95f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData heart_pill = IconData( - 0xe960, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData heart = IconData( - 0xe961, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData help = IconData( - 0xe962, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData home_1 = IconData( - 0xe963, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData home = IconData( - 0xe964, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData hospital = IconData( - 0xe965, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData hourglass_empty = IconData( - 0xe966, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData hourglass_full = IconData( - 0xe967, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData hourglass = IconData( - 0xe968, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData insurance_outline = IconData( - 0xe969, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData insurance = IconData( - 0xe96a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData left_right = IconData( - 0xe96b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData left = IconData( - 0xe96c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData light = IconData( - 0xe96d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData lightning = IconData( - 0xe96e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData link = IconData( - 0xe96f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData location_map = IconData( - 0xe970, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData location = IconData( - 0xe971, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData LOL_reaction = IconData( - 0xe972, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData love_reaction = IconData( - 0xe973, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData love = IconData( - 0xe974, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData lungs = IconData( - 0xe975, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData mail_open = IconData( - 0xe976, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData mail = IconData( - 0xe977, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData male = IconData( - 0xe978, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_bed = IconData( - 0xe979, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_blank = IconData( - 0xe97a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_card_add = IconData( - 0xe97b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_card = IconData( - 0xe97c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_cross = IconData( - 0xe97d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData medical_load = IconData( - 0xe97e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData menu_point_1 = IconData( - 0xe97f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData menu_point_v = IconData( - 0xe980, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData menu_point = IconData( - 0xe981, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData menu = IconData( - 0xe982, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData message = IconData( - 0xe983, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData mic_1 = IconData( - 0xe984, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData mic = IconData( - 0xe985, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData minus_circle = IconData( - 0xe986, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData minus = IconData( - 0xe987, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData molecule = IconData( - 0xe988, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData money = IconData( - 0xe989, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData multiply_circle = IconData( - 0xe98a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData mute = IconData( - 0xe98b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData notification_off = IconData( - 0xe98c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData notification = IconData( - 0xe98d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData nurse = IconData( - 0xe98e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData open = IconData( - 0xe98f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData patch = IconData( - 0xe990, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData payment = IconData( - 0xe991, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pc_graph = IconData( - 0xe992, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pen_write = IconData( - 0xe993, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData photo = IconData( - 0xe994, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData picture = IconData( - 0xe995, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pie_chart_empty = IconData( - 0xe996, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pie_chart_line = IconData( - 0xe997, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pie_chart = IconData( - 0xe998, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pill = IconData( - 0xe999, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pin = IconData( - 0xe99a, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData plus_circle = IconData( - 0xe99b, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData plus = IconData( - 0xe99c, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData podium = IconData( - 0xe99d, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pointer_leftright = IconData( - 0xe99e, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pointer = IconData( - 0xe99f, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData potion_circle = IconData( - 0xe9a0, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData potion_health = IconData( - 0xe9a1, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData potion = IconData( - 0xe9a2, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData print = IconData( - 0xe9a3, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pulse = IconData( - 0xe9a4, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData pyramid = IconData( - 0xe9a5, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData radiation = IconData( - 0xe9a6, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData rating = IconData( - 0xe9a7, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData record = IconData( - 0xe9a8, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData refresh_back = IconData( - 0xe9a9, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData refresh = IconData( - 0xe9aa, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData reload_vert = IconData( - 0xe9ab, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData reload = IconData( - 0xe9ac, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData right = IconData( - 0xe9ad, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData roll = IconData( - 0xe9ae, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData sale = IconData( - 0xe9af, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData save_1 = IconData( - 0xe9b0, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData save_check = IconData( - 0xe9b1, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData save = IconData( - 0xe9b2, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData schedule_square = IconData( - 0xe9b3, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData schedule = IconData( - 0xe9b4, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData scissors = IconData( - 0xe9b5, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData search = IconData( - 0xe9b6, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData send_message = IconData( - 0xe9b7, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData settings = IconData( - 0xe9b8, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData share_1 = IconData( - 0xe9b9, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData share = IconData( - 0xe9ba, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData signboard = IconData( - 0xe9bb, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData smile_sad = IconData( - 0xe9bc, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData smile = IconData( - 0xe9bd, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData sorting_down = IconData( - 0xe9be, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData sorting_up = IconData( - 0xe9bf, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData sorting = IconData( - 0xe9c0, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData square_down = IconData( - 0xe9c1, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData square_left = IconData( - 0xe9c2, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData square_right = IconData( - 0xe9c3, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData square_up = IconData( - 0xe9c4, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData stand = IconData( - 0xe9c5, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData star = IconData( - 0xe9c6, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData stats = IconData( - 0xe9c7, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData stethoscope = IconData( - 0xe9c8, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData sticker = IconData( - 0xe9c9, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData storage = IconData( - 0xe9ca, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData strl_down = IconData( - 0xe9cb, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData strl_left = IconData( - 0xe9cc, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData strl_right = IconData( - 0xe9cd, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData strl_up = IconData( - 0xe9ce, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData syringe = IconData( - 0xe9cf, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData tablet = IconData( - 0xe9d0, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData target = IconData( - 0xe9d1, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData test_tube = IconData( - 0xe9d2, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData thumbs_down_reaction = IconData( - 0xe9d3, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData thumbs_up_reaction = IconData( - 0xe9d4, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData time_1 = IconData( - 0xe9d5, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData time_wait = IconData( - 0xe9d6, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData time = IconData( - 0xe9d7, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData tooth = IconData( - 0xe9d8, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData tube_full = IconData( - 0xe9d9, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData tv_check = IconData( - 0xe9da, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData tv_rating = IconData( - 0xe9db, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData unfold_less_h = IconData( - 0xe9dc, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData unfold_less = IconData( - 0xe9dd, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData unfold_more_h = IconData( - 0xe9de, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData unfold_more = IconData( - 0xe9df, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData unread = IconData( - 0xe9e0, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData up_down = IconData( - 0xe9e1, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData up = IconData( - 0xe9e2, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData upload = IconData( - 0xe9e3, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData user_add = IconData( - 0xe9e4, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData user_delete = IconData( - 0xe9e5, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData user_minus = IconData( - 0xe9e6, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData user = IconData( - 0xe9e7, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData voice = IconData( - 0xe9e8, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData world = IconData( - 0xe9e9, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); - static const IconData wut_reaction = IconData( - 0xe9ea, - fontFamily: _fontFamily, - fontPackage: _fontPackage, - ); -} diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart new file mode 100644 index 00000000..25571150 --- /dev/null +++ b/lib/src/stream_svg_icon.dart @@ -0,0 +1,40 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class StreamSvgIcon extends StatelessWidget { + final String assetName; + final double width; + final double height; + final Color color; + + const StreamSvgIcon({ + Key key, + this.assetName, + this.width, + this.height, + this.color, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return kIsWeb + ? Image.network( + 'packages/stream_chat_flutter/svgs/$assetName', + width: width, + height: height, + color: color, + fit: BoxFit.cover, + alignment: Alignment.center, + ) + : SvgPicture.asset( + 'lib/svgs/$assetName', + package: 'stream_chat_flutter', + width: width, + height: height, + fit: BoxFit.cover, + color: color, + alignment: Alignment.center, + ); + } +} diff --git a/lib/src/thread_header.dart b/lib/src/thread_header.dart index 993a3047..9ad71a47 100644 --- a/lib/src/thread_header.dart +++ b/lib/src/thread_header.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:stream_chat/stream_chat.dart'; -import 'package:stream_chat_flutter/src/back_button.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/thread_header.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/thread_header_paint.png) @@ -84,9 +84,16 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { child: showBackButton ? AspectRatio( aspectRatio: 1, - child: StreamBackButton( + child: IconButton( onPressed: onBackPressed, - icon: Icons.close, + icon: StreamSvgIcon( + assetName: 'Icon_close.svg', + height: 24, + width: 24, + color: Theme.of(context).brightness == Brightness.dark + ? Colors.white + : Colors.black, + ), ), ) : SizedBox(), diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index 06ab0848..8ddd3d99 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:jiffy/jiffy.dart'; import 'package:stream_chat/stream_chat.dart'; +import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/user_list_view.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -73,9 +74,10 @@ class UserItem extends StatelessWidget { ), trailing: selected ? CircleAvatar( - child: Icon( - StreamIcons.check, - size: 20, + child: StreamSvgIcon( + assetName: 'Icon_check.svg', + height: 20, + width: 20, ), radius: 10, ) diff --git a/lib/stream_chat_flutter.dart b/lib/stream_chat_flutter.dart index 91ac68c8..ce5edca7 100644 --- a/lib/stream_chat_flutter.dart +++ b/lib/stream_chat_flutter.dart @@ -23,13 +23,13 @@ export 'src/sending_indicator.dart'; export 'src/stream_channel.dart'; export 'src/stream_chat.dart'; export 'src/stream_chat_theme.dart'; -export 'src/stream_icons.dart'; export 'src/system_message.dart'; export 'src/thread_header.dart'; export 'src/typing_indicator.dart'; export 'src/user_avatar.dart'; +export 'src/user_item.dart'; +export 'src/stream_svg_icon.dart'; +export 'src/user_list_view.dart'; +export 'src/users_bloc.dart'; export 'src/utils.dart'; export 'src/video_attachment.dart'; -export 'src/users_bloc.dart'; -export 'src/user_list_view.dart'; -export 'src/user_item.dart'; diff --git a/lib/svgs/Empty State_Camera.svg b/lib/svgs/Empty State_Camera.svg new file mode 100644 index 00000000..170ff7d4 --- /dev/null +++ b/lib/svgs/Empty State_Camera.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Empty State_Files.svg b/lib/svgs/Empty State_Files.svg new file mode 100644 index 00000000..658bcb1d --- /dev/null +++ b/lib/svgs/Empty State_Files.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Empty State_No channel.svg b/lib/svgs/Empty State_No channel.svg new file mode 100644 index 00000000..d7979534 --- /dev/null +++ b/lib/svgs/Empty State_No channel.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Empty State_Search.svg b/lib/svgs/Empty State_Search.svg new file mode 100644 index 00000000..d0026388 --- /dev/null +++ b/lib/svgs/Empty State_Search.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Empty State_picture.svg b/lib/svgs/Empty State_picture.svg new file mode 100644 index 00000000..fc82db46 --- /dev/null +++ b/lib/svgs/Empty State_picture.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Giphy icon.svg b/lib/svgs/Giphy icon.svg new file mode 100644 index 00000000..a9419e59 --- /dev/null +++ b/lib/svgs/Giphy icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/svgs/Icon_LOL_reaction.svg b/lib/svgs/Icon_LOL_reaction.svg new file mode 100644 index 00000000..c0f1d6fc --- /dev/null +++ b/lib/svgs/Icon_LOL_reaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_Thread_Reply.svg b/lib/svgs/Icon_Thread_Reply.svg new file mode 100644 index 00000000..7482300d --- /dev/null +++ b/lib/svgs/Icon_Thread_Reply.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_User_add.svg b/lib/svgs/Icon_User_add.svg new file mode 100644 index 00000000..c9db7859 --- /dev/null +++ b/lib/svgs/Icon_User_add.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_User_deselect.svg b/lib/svgs/Icon_User_deselect.svg new file mode 100644 index 00000000..fc5129d7 --- /dev/null +++ b/lib/svgs/Icon_User_deselect.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_arrow_right.svg b/lib/svgs/Icon_arrow_right.svg new file mode 100644 index 00000000..dde29bcb --- /dev/null +++ b/lib/svgs/Icon_arrow_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_attach.svg b/lib/svgs/Icon_attach.svg new file mode 100644 index 00000000..e2369d21 --- /dev/null +++ b/lib/svgs/Icon_attach.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_camera.svg b/lib/svgs/Icon_camera.svg new file mode 100644 index 00000000..0bf3122d --- /dev/null +++ b/lib/svgs/Icon_camera.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_check.svg b/lib/svgs/Icon_check.svg new file mode 100644 index 00000000..49cf76be --- /dev/null +++ b/lib/svgs/Icon_check.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_check_all.svg b/lib/svgs/Icon_check_all.svg new file mode 100644 index 00000000..b477edde --- /dev/null +++ b/lib/svgs/Icon_check_all.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_check_big.svg b/lib/svgs/Icon_check_big.svg new file mode 100644 index 00000000..d42503bb --- /dev/null +++ b/lib/svgs/Icon_check_big.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_check_send.svg b/lib/svgs/Icon_check_send.svg new file mode 100644 index 00000000..e62c7099 --- /dev/null +++ b/lib/svgs/Icon_check_send.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_circle_right.svg b/lib/svgs/Icon_circle_right.svg new file mode 100644 index 00000000..1d20c031 --- /dev/null +++ b/lib/svgs/Icon_circle_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_circle_up.svg b/lib/svgs/Icon_circle_up.svg new file mode 100644 index 00000000..41ed17dd --- /dev/null +++ b/lib/svgs/Icon_circle_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_close.svg b/lib/svgs/Icon_close.svg new file mode 100644 index 00000000..0765c5c3 --- /dev/null +++ b/lib/svgs/Icon_close.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_close_black.svg b/lib/svgs/Icon_close_black.svg new file mode 100644 index 00000000..74eb480c --- /dev/null +++ b/lib/svgs/Icon_close_black.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_close_sml.svg b/lib/svgs/Icon_close_sml.svg new file mode 100644 index 00000000..63e0d016 --- /dev/null +++ b/lib/svgs/Icon_close_sml.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_cloud_download.svg b/lib/svgs/Icon_cloud_download.svg new file mode 100644 index 00000000..7b935f29 --- /dev/null +++ b/lib/svgs/Icon_cloud_download.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_contacts.svg b/lib/svgs/Icon_contacts.svg new file mode 100644 index 00000000..6db40129 --- /dev/null +++ b/lib/svgs/Icon_contacts.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_copy.svg b/lib/svgs/Icon_copy.svg new file mode 100644 index 00000000..83bd7aa5 --- /dev/null +++ b/lib/svgs/Icon_copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_curve_line_left_up.svg b/lib/svgs/Icon_curve_line_left_up.svg new file mode 100644 index 00000000..1c3c718c --- /dev/null +++ b/lib/svgs/Icon_curve_line_left_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_curve_line_left_up_big.svg b/lib/svgs/Icon_curve_line_left_up_big.svg new file mode 100644 index 00000000..4b6181b1 --- /dev/null +++ b/lib/svgs/Icon_curve_line_left_up_big.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_delete.svg b/lib/svgs/Icon_delete.svg new file mode 100644 index 00000000..3a63cfec --- /dev/null +++ b/lib/svgs/Icon_delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_down.svg b/lib/svgs/Icon_down.svg new file mode 100644 index 00000000..60ea59ee --- /dev/null +++ b/lib/svgs/Icon_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_download.svg b/lib/svgs/Icon_download.svg new file mode 100644 index 00000000..f42047ba --- /dev/null +++ b/lib/svgs/Icon_download.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_edit.svg b/lib/svgs/Icon_edit.svg new file mode 100644 index 00000000..7fc784fb --- /dev/null +++ b/lib/svgs/Icon_edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_empty_circle_left.svg b/lib/svgs/Icon_empty_circle_left.svg new file mode 100644 index 00000000..8f1e8329 --- /dev/null +++ b/lib/svgs/Icon_empty_circle_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_error.svg b/lib/svgs/Icon_error.svg new file mode 100644 index 00000000..af3df414 --- /dev/null +++ b/lib/svgs/Icon_error.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_eye-off.svg b/lib/svgs/Icon_eye-off.svg new file mode 100644 index 00000000..8f404ae2 --- /dev/null +++ b/lib/svgs/Icon_eye-off.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_grid.svg b/lib/svgs/Icon_grid.svg new file mode 100644 index 00000000..43bb0489 --- /dev/null +++ b/lib/svgs/Icon_grid.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_left.svg b/lib/svgs/Icon_left.svg new file mode 100644 index 00000000..5a4c5ced --- /dev/null +++ b/lib/svgs/Icon_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_lightning-command runner.svg b/lib/svgs/Icon_lightning-command runner.svg new file mode 100644 index 00000000..83045bbb --- /dev/null +++ b/lib/svgs/Icon_lightning-command runner.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_love_reaction.svg b/lib/svgs/Icon_love_reaction.svg new file mode 100644 index 00000000..4d946544 --- /dev/null +++ b/lib/svgs/Icon_love_reaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_message.svg b/lib/svgs/Icon_message.svg new file mode 100644 index 00000000..11eacefa --- /dev/null +++ b/lib/svgs/Icon_message.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_mute.svg b/lib/svgs/Icon_mute.svg new file mode 100644 index 00000000..d1d16aa7 --- /dev/null +++ b/lib/svgs/Icon_mute.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_pen-write.svg b/lib/svgs/Icon_pen-write.svg new file mode 100644 index 00000000..820d28bd --- /dev/null +++ b/lib/svgs/Icon_pen-write.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_record.svg b/lib/svgs/Icon_record.svg new file mode 100644 index 00000000..ff72859f --- /dev/null +++ b/lib/svgs/Icon_record.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_right.svg b/lib/svgs/Icon_right.svg new file mode 100644 index 00000000..6d42a1db --- /dev/null +++ b/lib/svgs/Icon_right.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_search.svg b/lib/svgs/Icon_search.svg new file mode 100644 index 00000000..0865a95e --- /dev/null +++ b/lib/svgs/Icon_search.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_smile.svg b/lib/svgs/Icon_smile.svg new file mode 100644 index 00000000..b803cf22 --- /dev/null +++ b/lib/svgs/Icon_smile.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_thumbs_down_reaction.svg b/lib/svgs/Icon_thumbs_down_reaction.svg new file mode 100644 index 00000000..9036ff72 --- /dev/null +++ b/lib/svgs/Icon_thumbs_down_reaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_thumbs_up_reaction.svg b/lib/svgs/Icon_thumbs_up_reaction.svg new file mode 100644 index 00000000..ff4dcc72 --- /dev/null +++ b/lib/svgs/Icon_thumbs_up_reaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_time.svg b/lib/svgs/Icon_time.svg new file mode 100644 index 00000000..59aa2c5d --- /dev/null +++ b/lib/svgs/Icon_time.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_user.svg b/lib/svgs/Icon_user.svg new file mode 100644 index 00000000..f50e33fc --- /dev/null +++ b/lib/svgs/Icon_user.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_user_delete.svg b/lib/svgs/Icon_user_delete.svg new file mode 100644 index 00000000..fb47f5e8 --- /dev/null +++ b/lib/svgs/Icon_user_delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/Icon_wut_reaction.svg b/lib/svgs/Icon_wut_reaction.svg new file mode 100644 index 00000000..f445ec29 --- /dev/null +++ b/lib/svgs/Icon_wut_reaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/STREAM MARK 1.svg b/lib/svgs/STREAM MARK 1.svg new file mode 100644 index 00000000..57ccef0f --- /dev/null +++ b/lib/svgs/STREAM MARK 1.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/lib/svgs/UI_Reverse Pagination Loading.svg b/lib/svgs/UI_Reverse Pagination Loading.svg new file mode 100644 index 00000000..dfc3754f --- /dev/null +++ b/lib/svgs/UI_Reverse Pagination Loading.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lib/svgs/eye-line_big.svg b/lib/svgs/eye-line_big.svg new file mode 100644 index 00000000..9eb20a58 --- /dev/null +++ b/lib/svgs/eye-line_big.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/files.svg b/lib/svgs/files.svg new file mode 100644 index 00000000..5d72fdd3 --- /dev/null +++ b/lib/svgs/files.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/filetype_7z.svg b/lib/svgs/filetype_7z.svg new file mode 100644 index 00000000..787f5f8c --- /dev/null +++ b/lib/svgs/filetype_7z.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_CSV.svg b/lib/svgs/filetype_CSV.svg new file mode 100644 index 00000000..d7395e78 --- /dev/null +++ b/lib/svgs/filetype_CSV.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_DOC.svg b/lib/svgs/filetype_DOC.svg new file mode 100644 index 00000000..4233055a --- /dev/null +++ b/lib/svgs/filetype_DOC.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_DOCX.svg b/lib/svgs/filetype_DOCX.svg new file mode 100644 index 00000000..3077f515 --- /dev/null +++ b/lib/svgs/filetype_DOCX.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_Generic.svg b/lib/svgs/filetype_Generic.svg new file mode 100644 index 00000000..3ec0f239 --- /dev/null +++ b/lib/svgs/filetype_Generic.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/lib/svgs/filetype_MD.svg b/lib/svgs/filetype_MD.svg new file mode 100644 index 00000000..560b7c61 --- /dev/null +++ b/lib/svgs/filetype_MD.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_ODT.svg b/lib/svgs/filetype_ODT.svg new file mode 100644 index 00000000..6e08875f --- /dev/null +++ b/lib/svgs/filetype_ODT.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_PDF.svg b/lib/svgs/filetype_PDF.svg new file mode 100644 index 00000000..c8306ca1 --- /dev/null +++ b/lib/svgs/filetype_PDF.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_PPT.svg b/lib/svgs/filetype_PPT.svg new file mode 100644 index 00000000..0541a496 --- /dev/null +++ b/lib/svgs/filetype_PPT.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_PPTX-1.svg b/lib/svgs/filetype_PPTX-1.svg new file mode 100644 index 00000000..a50efd64 --- /dev/null +++ b/lib/svgs/filetype_PPTX-1.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_PPTX.svg b/lib/svgs/filetype_PPTX.svg new file mode 100644 index 00000000..83339acc --- /dev/null +++ b/lib/svgs/filetype_PPTX.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_RAR.svg b/lib/svgs/filetype_RAR.svg new file mode 100644 index 00000000..ae0e14d0 --- /dev/null +++ b/lib/svgs/filetype_RAR.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_RTF.svg b/lib/svgs/filetype_RTF.svg new file mode 100644 index 00000000..e9266599 --- /dev/null +++ b/lib/svgs/filetype_RTF.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_TAR.svg b/lib/svgs/filetype_TAR.svg new file mode 100644 index 00000000..6796e1f7 --- /dev/null +++ b/lib/svgs/filetype_TAR.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_TXT.svg b/lib/svgs/filetype_TXT.svg new file mode 100644 index 00000000..263fdfbe --- /dev/null +++ b/lib/svgs/filetype_TXT.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_XLS.svg b/lib/svgs/filetype_XLS.svg new file mode 100644 index 00000000..eec9a05d --- /dev/null +++ b/lib/svgs/filetype_XLS.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_XLSX.svg b/lib/svgs/filetype_XLSX.svg new file mode 100644 index 00000000..6203aa27 --- /dev/null +++ b/lib/svgs/filetype_XLSX.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/lib/svgs/filetype_ZIP.svg b/lib/svgs/filetype_ZIP.svg new file mode 100644 index 00000000..daa24576 --- /dev/null +++ b/lib/svgs/filetype_ZIP.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/svgs/filetype_html.svg b/lib/svgs/filetype_html.svg new file mode 100644 index 00000000..9e3cb9cf --- /dev/null +++ b/lib/svgs/filetype_html.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/lib/svgs/giphy icon blue.svg b/lib/svgs/giphy icon blue.svg new file mode 100644 index 00000000..746e50a4 --- /dev/null +++ b/lib/svgs/giphy icon blue.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/icon_SHARE.svg b/lib/svgs/icon_SHARE.svg new file mode 100644 index 00000000..6a35ef8d --- /dev/null +++ b/lib/svgs/icon_SHARE.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/icon_delete_grey.svg b/lib/svgs/icon_delete_grey.svg new file mode 100644 index 00000000..10689df2 --- /dev/null +++ b/lib/svgs/icon_delete_grey.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/svgs/icon_mentions.svg b/lib/svgs/icon_mentions.svg new file mode 100644 index 00000000..ce6c6fa1 --- /dev/null +++ b/lib/svgs/icon_mentions.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/mentions.svg b/lib/svgs/mentions.svg new file mode 100644 index 00000000..05bdee3b --- /dev/null +++ b/lib/svgs/mentions.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/pictures.svg b/lib/svgs/pictures.svg new file mode 100644 index 00000000..64e6ca34 --- /dev/null +++ b/lib/svgs/pictures.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/settings.svg b/lib/svgs/settings.svg new file mode 100644 index 00000000..7dfab209 --- /dev/null +++ b/lib/svgs/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/svgs/share_arrow.svg b/lib/svgs/share_arrow.svg new file mode 100644 index 00000000..33b99c35 --- /dev/null +++ b/lib/svgs/share_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/pubspec.yaml b/pubspec.yaml index f8705c22..c441ca4f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,10 +46,7 @@ flutter: assets: - images/ - svgs/ - fonts: - - family: stream-icons - fonts: - - asset: fonts/stream-icons.ttf + - lib/svgs/ dev_dependencies: pedantic: ^1.9.0 From 800dd02aa27eb30f10ee8bbc8ac9b2f34d06e832 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 12:55:37 +0100 Subject: [PATCH 21/26] update tests --- test/src/message_action_modal_test.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/src/message_action_modal_test.dart b/test/src/message_action_modal_test.dart index 97709e70..5b0c1678 100644 --- a/test/src/message_action_modal_test.dart +++ b/test/src/message_action_modal_test.dart @@ -42,10 +42,10 @@ void main() { await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); - expect(find.byIcon(StreamIcons.sorting_up), findsOneWidget); - expect(find.byIcon(StreamIcons.edit), findsOneWidget); - expect(find.byIcon(StreamIcons.delete), findsOneWidget); - expect(find.byIcon(StreamIcons.copy), findsOneWidget); + expect(find.text('Thread reply'), findsOneWidget); + expect(find.text('Edit message'), findsOneWidget); + expect(find.text('Delete message'), findsOneWidget); + expect(find.text('Copy message'), findsOneWidget); }, ); testWidgets( @@ -87,10 +87,10 @@ void main() { await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); - expect(find.byIcon(StreamIcons.sorting_up), findsNothing); - expect(find.byIcon(StreamIcons.edit), findsNothing); - expect(find.byIcon(StreamIcons.delete), findsNothing); - expect(find.byIcon(StreamIcons.copy), findsNothing); + expect(find.text('Thread reply'), findsNothing); + expect(find.text('Edit message'), findsNothing); + expect(find.text('Delete message'), findsNothing); + expect(find.text('Copy message'), findsNothing); }, ); } From 93c324ac56f94ef0190a485a063b433fa7b2df8d Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 13:07:48 +0100 Subject: [PATCH 22/26] fix tests --- example/lib/new_chat_screen.dart | 10 +++++++--- example/pubspec.yaml | 2 +- lib/src/stream_svg_icon.dart | 6 ++++-- test/src/message_reaction_modal_test.dart | 9 ++++++--- test/src/reaction_bubble_test.dart | 12 ++++++++---- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index df4b7c3c..aeb4298e 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -193,9 +193,13 @@ class _NewChatScreenState extends State { child: Row( children: [ StreamNeumorphicButton( - child: StreamSvgIcon( - assetName: 'Icon_contacts.svg', - color: Color(0xFF006CFF), + child: Center( + child: StreamSvgIcon( + assetName: 'Icon_contacts.svg', + color: Color(0xFF006CFF), + height: 24, + width: 24, + ), ), ), SizedBox(width: 8), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bc892255..7cd6045a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.68+70 +version: 1.0.69+71 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart index 25571150..c0cf5d72 100644 --- a/lib/src/stream_svg_icon.dart +++ b/lib/src/stream_svg_icon.dart @@ -9,20 +9,21 @@ class StreamSvgIcon extends StatelessWidget { final Color color; const StreamSvgIcon({ - Key key, this.assetName, this.width, this.height, this.color, - }) : super(key: key); + }); @override Widget build(BuildContext context) { + final key = Key('StreamSvgIcon-$assetName'); return kIsWeb ? Image.network( 'packages/stream_chat_flutter/svgs/$assetName', width: width, height: height, + key: key, color: color, fit: BoxFit.cover, alignment: Alignment.center, @@ -30,6 +31,7 @@ class StreamSvgIcon extends StatelessWidget { : SvgPicture.asset( 'lib/svgs/$assetName', package: 'stream_chat_flutter', + key: key, width: width, height: height, fit: BoxFit.cover, diff --git a/test/src/message_reaction_modal_test.dart b/test/src/message_reaction_modal_test.dart index 622b57c3..d1c2a49c 100644 --- a/test/src/message_reaction_modal_test.dart +++ b/test/src/message_reaction_modal_test.dart @@ -42,7 +42,8 @@ void main() { await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); - expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsOneWidget); + expect(find.byKey(Key('StreamSvgIcon-Icon_thumbs_up_reaction.svg')), + findsOneWidget); }, ); @@ -91,8 +92,10 @@ void main() { await tester.pump(Duration(milliseconds: 1000)); expect(find.byKey(Key('MessageWidget')), findsOneWidget); - expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsNWidgets(2)); - expect(find.byIcon(StreamIcons.love_reaction), findsNWidgets(2)); + expect(find.byKey(Key('StreamSvgIcon-Icon_thumbs_up_reaction.svg')), + findsNWidgets(2)); + expect(find.byKey(Key('StreamSvgIcon-Icon_love_reaction.svg')), + findsNWidgets(2)); expect(find.text(testUserId), findsNWidgets(2)); }, ); diff --git a/test/src/reaction_bubble_test.dart b/test/src/reaction_bubble_test.dart index c524061c..6518dc94 100644 --- a/test/src/reaction_bubble_test.dart +++ b/test/src/reaction_bubble_test.dart @@ -25,7 +25,8 @@ void main() { ), ); - expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsNothing); + expect(find.byKey(Key('StreamSvgIcon-Icon_thumbs_up_reaction.svg')), + findsNothing); }, ); @@ -61,7 +62,8 @@ void main() { ), ); - expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsOneWidget); + expect(find.byKey(Key('StreamSvgIcon-Icon_thumbs_up_reaction.svg')), + findsOneWidget); }, ); testWidgets( @@ -100,8 +102,10 @@ void main() { ), ); - expect(find.byIcon(StreamIcons.thumbs_up_reaction), findsOneWidget); - expect(find.byIcon(StreamIcons.love_reaction), findsOneWidget); + expect(find.byKey(Key('StreamSvgIcon-Icon_thumbs_up_reaction.svg')), + findsOneWidget); + expect(find.byKey(Key('StreamSvgIcon-Icon_love_reaction.svg')), + findsOneWidget); }, ); } From 6b62eadaa4686dadc1a8780766c544cd0d2b7342 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 13:39:36 +0100 Subject: [PATCH 23/26] add factory constructor --- example/lib/advanced_options_page.dart | 3 +- example/lib/chips_input_text_field.dart | 17 +- example/lib/choose_user_page.dart | 3 +- example/lib/group_chat_details_screen.dart | 4 +- example/lib/main.dart | 9 +- example/lib/new_chat_screen.dart | 15 +- example/lib/new_group_chat_screen.dart | 21 +- example/pubspec.yaml | 2 +- lib/src/back_button.dart | 6 +- lib/src/channel_bottom_sheet.dart | 12 +- lib/src/channel_list_view.dart | 14 +- lib/src/channel_preview.dart | 6 +- lib/src/giphy_attachment.dart | 30 +- lib/src/media_list_view.dart | 6 +- lib/src/message_actions_modal.dart | 18 +- lib/src/message_input.dart | 65 ++-- lib/src/message_list_view.dart | 3 +- lib/src/stream_svg_icon.dart | 336 +++++++++++++++++++++ lib/src/thread_header.dart | 6 +- lib/src/user_item.dart | 6 +- lib/svgs/Icon_camera.svg | 4 +- lib/svgs/Icon_record.svg | 4 +- 22 files changed, 424 insertions(+), 166 deletions(-) diff --git a/example/lib/advanced_options_page.dart b/example/lib/advanced_options_page.dart index 57ed1f06..212a15a8 100644 --- a/example/lib/advanced_options_page.dart +++ b/example/lib/advanced_options_page.dart @@ -44,8 +44,7 @@ class _AdvancedOptionsPageState extends State { ), ), leading: IconButton( - icon: StreamSvgIcon( - assetName: 'Icon_left.svg', + icon: StreamSvgIcon.left( color: Colors.black, ), onPressed: () { diff --git a/example/lib/chips_input_text_field.dart b/example/lib/chips_input_text_field.dart index 0310de5b..19c5c761 100644 --- a/example/lib/chips_input_text_field.dart +++ b/example/lib/chips_input_text_field.dart @@ -130,14 +130,15 @@ class ChipInputTextFieldState extends State> { Align( alignment: Alignment.bottomCenter, child: IconButton( - icon: StreamSvgIcon( - assetName: _chips.isEmpty - ? 'Icon_user.svg' - : 'Icon_User_add.svg', - color: Colors.black.withOpacity(0.5), - height: 24, - width: 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, diff --git a/example/lib/choose_user_page.dart b/example/lib/choose_user_page.dart index 0a0d67b9..f1a53773 100644 --- a/example/lib/choose_user_page.dart +++ b/example/lib/choose_user_page.dart @@ -196,8 +196,7 @@ class ChooseUserPage extends StatelessWidget { ); }, leading: CircleAvatar( - child: StreamSvgIcon( - assetName: 'settings.svg', + child: StreamSvgIcon.settings( color: Colors.black, ), backgroundColor: diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index 3de87f2d..d11f377a 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -105,9 +105,7 @@ class _GroupChatDetailsScreenState extends State { StreamNeumorphicButton( child: IconButton( padding: const EdgeInsets.all(0), - icon: StreamSvgIcon( - assetName: 'Icon_check.svg', - ), + icon: StreamSvgIcon.check(), color: Color(0xFF006CFF), onPressed: _isGroupNameEmpty ? null diff --git a/example/lib/main.dart b/example/lib/main.dart index dcb4ac27..d2be225a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -143,8 +143,7 @@ class ChannelListPage extends StatelessWidget { ), ), ListTile( - leading: StreamSvgIcon( - assetName: 'Icon_pen-write.svg', + leading: StreamSvgIcon.penWrite( color: Colors.black.withOpacity(.5), ), onTap: () { @@ -162,8 +161,7 @@ class ChannelListPage extends StatelessWidget { ), ), ListTile( - leading: StreamSvgIcon( - assetName: 'Icon_contacts.svg', + leading: StreamSvgIcon.contacts( color: Colors.black.withOpacity(.5), ), onTap: () { @@ -197,8 +195,7 @@ class ChannelListPage extends StatelessWidget { ), ); }, - leading: StreamSvgIcon( - assetName: 'Icon_user.svg', + leading: StreamSvgIcon.user( color: Colors.black.withOpacity(.5), ), title: Text( diff --git a/example/lib/new_chat_screen.dart b/example/lib/new_chat_screen.dart index aeb4298e..690e831f 100644 --- a/example/lib/new_chat_screen.dart +++ b/example/lib/new_chat_screen.dart @@ -163,8 +163,7 @@ class _NewChatScreenState extends State { ), ), Positioned( - child: StreamSvgIcon( - assetName: 'Icon_close.svg', + child: StreamSvgIcon.close( color: Colors.white, ), ), @@ -194,11 +193,9 @@ class _NewChatScreenState extends State { children: [ StreamNeumorphicButton( child: Center( - child: StreamSvgIcon( - assetName: 'Icon_contacts.svg', + child: StreamSvgIcon.contacts( color: Color(0xFF006CFF), - height: 24, - width: 24, + size: 24, ), ), ), @@ -292,10 +289,8 @@ class _NewChatScreenState extends State { children: [ Padding( padding: const EdgeInsets.all(24), - child: StreamSvgIcon( - assetName: 'Icon_search.svg', - height: 96, - width: 96, + child: StreamSvgIcon.search( + size: 96, color: Colors.grey, ), ), diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index 3d7c418a..1db848a1 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -65,8 +65,7 @@ class _NewGroupChatScreenState extends State { actions: [ if (_selectedUsers.isNotEmpty) IconButton( - icon: StreamSvgIcon( - assetName: 'Icon_right.svg', + icon: StreamSvgIcon.right( color: Color(0xFF006CFF), ), onPressed: () { @@ -101,11 +100,9 @@ class _NewGroupChatScreenState extends State { child: TextField( controller: _controller, decoration: InputDecoration( - prefixIcon: StreamSvgIcon( - assetName: 'Icon_search.svg', + prefixIcon: StreamSvgIcon.search( color: Colors.black, - height: 24, - width: 24, + size: 24, ), hintText: 'Search', hintStyle: TextStyle( @@ -163,10 +160,8 @@ class _NewGroupChatScreenState extends State { ), child: Padding( padding: const EdgeInsets.all(0.0), - child: StreamSvgIcon( - assetName: 'Icon_close.svg', - height: 24, - width: 24, + child: StreamSvgIcon.close( + size: 24, ), ), ), @@ -262,10 +257,8 @@ class _NewGroupChatScreenState extends State { children: [ Padding( padding: const EdgeInsets.all(24), - child: StreamSvgIcon( - assetName: 'Icon_search.svg', - height: 96, - width: 96, + child: StreamSvgIcon.search( + size: 96, color: Colors.grey, ), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 7cd6045a..6e34335d 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.69+71 +version: 1.0.70+72 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/back_button.dart b/lib/src/back_button.dart index cd30c956..25c1c9da 100644 --- a/lib/src/back_button.dart +++ b/lib/src/back_button.dart @@ -33,10 +33,8 @@ class StreamBackButton extends StatelessWidget { Navigator.of(context).pop(); } }, - child: StreamSvgIcon( - assetName: 'Icon_left.svg', - height: 24, - width: 24, + child: StreamSvgIcon.left( + size: 24, color: Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black, diff --git a/lib/src/channel_bottom_sheet.dart b/lib/src/channel_bottom_sheet.dart index c3233ff4..c0e32509 100644 --- a/lib/src/channel_bottom_sheet.dart +++ b/lib/src/channel_bottom_sheet.dart @@ -72,10 +72,8 @@ class ChannelBottomSheet extends StatelessWidget { initialData: channel.isMuted, builder: (context, snapshot) { return ListTile( - leading: StreamSvgIcon( - assetName: 'Icon_mute.svg', - height: 22, - width: 22, + leading: StreamSvgIcon.mute( + size: 22, color: StreamChatTheme.of(context).primaryIconTheme.color, ), title: Text('Mute ${channel.isGroup ? 'group' : 'user'}'), @@ -94,10 +92,8 @@ class ChannelBottomSheet extends StatelessWidget { Divider(), if (channel.isGroup && !channel.isDistinct) ListTile( - leading: StreamSvgIcon( - assetName: 'Icon_User_deselect.svg', - height: 22, - width: 22, + leading: StreamSvgIcon.userRemove( + size: 22, color: Colors.black, ), title: Text('Leave Group'), diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 503e740d..bfd8e477 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -201,10 +201,8 @@ class _ChannelListViewState extends State children: [ Padding( padding: const EdgeInsets.all(8.0), - child: StreamSvgIcon( - assetName: 'Icon_message.svg', - height: 136, - width: 136, + child: StreamSvgIcon.message( + size: 136, color: Color(0xffDBDBDB), ), ), @@ -519,9 +517,7 @@ class _ChannelListViewState extends State ), IconSlideAction( color: backgroundColor, - iconWidget: StreamSvgIcon( - assetName: 'Icon_mute.svg', - ), + iconWidget: StreamSvgIcon.mute(), onTap: () async { if (!channel.isMuted) { await channel.mute(); @@ -533,9 +529,7 @@ class _ChannelListViewState extends State if (channel.isGroup && !channel.isDistinct) IconSlideAction( color: backgroundColor, - iconWidget: StreamSvgIcon( - assetName: 'Icon_User_deselect.svg', - ), + iconWidget: StreamSvgIcon.userRemove(), onTap: () async { final confirm = await showConfirmationDialog( context, diff --git a/lib/src/channel_preview.dart b/lib/src/channel_preview.dart index c61e469e..3c9eeace 100644 --- a/lib/src/channel_preview.dart +++ b/lib/src/channel_preview.dart @@ -153,10 +153,8 @@ class ChannelPreview extends StatelessWidget { return Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ - StreamSvgIcon( - assetName: 'Icon_mute.svg', - height: 16, - width: 16, + StreamSvgIcon.mute( + size: 16, ), Text( ' Channel is muted', diff --git a/lib/src/giphy_attachment.dart b/lib/src/giphy_attachment.dart index 0f3b9e7e..7abf7057 100644 --- a/lib/src/giphy_attachment.dart +++ b/lib/src/giphy_attachment.dart @@ -112,11 +112,9 @@ class GiphyAttachment extends StatelessWidget { ), child: Row( children: [ - StreamSvgIcon( - assetName: 'Icon_lightning-command runner.svg', + StreamSvgIcon.lightning( color: StreamChatTheme.of(context).accentColor, - height: 16.0, - width: 16.0, + size: 16.0, ), Text( 'GIPHY', @@ -146,10 +144,8 @@ class GiphyAttachment extends StatelessWidget { child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), - icon: StreamSvgIcon( - assetName: 'Icon_left.svg', - height: 24.0, - width: 24.0, + icon: StreamSvgIcon.left( + size: 24.0, ), splashRadius: 16, onPressed: () { @@ -175,10 +171,8 @@ class GiphyAttachment extends StatelessWidget { child: IconButton( padding: const EdgeInsets.all(0), constraints: BoxConstraints.tight(Size(32, 32)), - icon: StreamSvgIcon( - assetName: 'Icon_right.svg', - height: 24.0, - width: 24.0, + icon: StreamSvgIcon.right( + size: 24.0, ), splashRadius: 16, onPressed: () { @@ -257,11 +251,9 @@ class GiphyAttachment extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - StreamSvgIcon( - assetName: 'Icon_eye-off.svg', + StreamSvgIcon.eye( color: Colors.black.withOpacity(0.5), - height: 16.0, - width: 16.0, + size: 16.0, ), SizedBox( width: 8.0, @@ -331,11 +323,9 @@ class GiphyAttachment extends StatelessWidget { ), child: Row( children: [ - StreamSvgIcon( - assetName: 'Icon_lightning-command runner.svg', + StreamSvgIcon.lightning( color: Colors.white, - height: 16, - width: 16, + size: 16, ), Text( 'GIPHY', diff --git a/lib/src/media_list_view.dart b/lib/src/media_list_view.dart index c4ae4981..e8735d69 100644 --- a/lib/src/media_list_view.dart +++ b/lib/src/media_list_view.dart @@ -71,10 +71,8 @@ class _MediaListViewState extends State { child: CircleAvatar( radius: 12, backgroundColor: Colors.white, - child: StreamSvgIcon( - assetName: 'Icon_check.svg', - height: 24, - width: 24, + child: StreamSvgIcon.check( + size: 24, color: Colors.black, ), ), diff --git a/lib/src/message_actions_modal.dart b/lib/src/message_actions_modal.dart index d95b63ea..1967cd2b 100644 --- a/lib/src/message_actions_modal.dart +++ b/lib/src/message_actions_modal.dart @@ -188,8 +188,7 @@ class MessageActionsModal extends StatelessWidget { style: Theme.of(context).textTheme.headline6.copyWith(color: Colors.red), ), - leading: StreamSvgIcon( - assetName: 'Icon_delete.svg', + leading: StreamSvgIcon.delete( color: Colors.red, ), onTap: () { @@ -208,8 +207,7 @@ class MessageActionsModal extends StatelessWidget { 'Copy message', style: Theme.of(context).textTheme.headline6, ), - leading: StreamSvgIcon( - assetName: 'Icon_copy.svg', + leading: StreamSvgIcon.copy( color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () async { @@ -225,8 +223,7 @@ class MessageActionsModal extends StatelessWidget { 'Edit message', style: Theme.of(context).textTheme.headline6, ), - leading: StreamSvgIcon( - assetName: 'Icon_edit.svg', + leading: StreamSvgIcon.edit( color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () async { @@ -267,10 +264,8 @@ class MessageActionsModal extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( - icon: StreamSvgIcon( - assetName: 'Icon_edit.svg', - height: 22, - width: 22, + icon: StreamSvgIcon.edit( + size: 22, color: StreamChatTheme.of(context).primaryIconTheme.color, ), @@ -324,8 +319,7 @@ class MessageActionsModal extends StatelessWidget { 'Thread reply', style: Theme.of(context).textTheme.headline6, ), - leading: StreamSvgIcon( - assetName: 'Icon_Thread_Reply.svg', + leading: StreamSvgIcon.thread( color: StreamChatTheme.of(context).primaryIconTheme.color, ), onTap: () { diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index a7d8db5e..4b634ab7 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -284,10 +284,8 @@ class MessageInputState extends State { crossFadeState: _sendAsDm ? CrossFadeState.showFirst : CrossFadeState.showSecond, - firstChild: StreamSvgIcon( - assetName: 'Icon_check.svg', - height: 16.0, - width: 16.0, + firstChild: StreamSvgIcon.check( + size: 16.0, color: Colors.white, ), secondChild: SizedBox( @@ -331,8 +329,7 @@ class MessageInputState extends State { _actionsShrunk = false; }); }, - icon: StreamSvgIcon( - assetName: 'Icon_empty_circle_left.svg', + icon: StreamSvgIcon.emptyCircleLeft( color: StreamChatTheme.of(context).accentColor, ), ), @@ -404,8 +401,7 @@ class MessageInputState extends State { _chosenCommand?.name ?? "", style: TextStyle(color: Colors.white), ), - avatar: StreamSvgIcon( - assetName: 'Icon_lightning-command runner.svg', + avatar: StreamSvgIcon.lightning( color: Colors.white, ), ), @@ -582,9 +578,7 @@ class MessageInputState extends State { padding: const EdgeInsets.symmetric( horizontal: 8.0, ), - child: StreamSvgIcon( - assetName: - 'Icon_lightning-command runner.svg', + child: StreamSvgIcon.lightning( color: StreamChatTheme.of(context) .accentColor, ), @@ -622,12 +616,9 @@ class MessageInputState extends State { trailing: CircleAvatar( backgroundColor: StreamChatTheme.of(context).accentColor, - child: StreamSvgIcon( - assetName: - 'Icon_lightning-command runner.svg', + child: StreamSvgIcon.lightning( color: Colors.white, - height: 12.5, - width: 12.5, + size: 12.5, ), maxRadius: 12, ), @@ -661,10 +652,8 @@ class MessageInputState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ IconButton( - icon: StreamSvgIcon( - assetName: 'pictures.svg', - height: 24, - width: 24, + icon: StreamSvgIcon.pictures( + size: 24, color: _filePickerIndex == 0 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -676,10 +665,8 @@ class MessageInputState extends State { }, ), IconButton( - icon: StreamSvgIcon( - assetName: 'files.svg', - height: 24, - width: 24, + icon: StreamSvgIcon.files( + size: 24, color: _filePickerIndex == 1 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -689,10 +676,8 @@ class MessageInputState extends State { }, ), IconButton( - icon: StreamSvgIcon( - assetName: 'Icon_camera.svg', - height: 24, - width: 24, + icon: StreamSvgIcon.camera( + size: 24, color: _filePickerIndex == 2 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -702,10 +687,8 @@ class MessageInputState extends State { }, ), IconButton( - icon: StreamSvgIcon( - assetName: 'Icon_record.svg', - height: 24, - width: 24, + icon: StreamSvgIcon.record( + size: 24, color: _filePickerIndex == 3 ? StreamChatTheme.of(context).accentColor : Colors.black.withOpacity(0.5), @@ -1000,8 +983,7 @@ class MessageInputState extends State { fontWeight: FontWeight.bold), ), subtitle: Text('@${m.userId}'), - trailing: StreamSvgIcon( - assetName: 'mentions.svg', + trailing: StreamSvgIcon.mentions( color: StreamChatTheme.of(context) .accentColor, ), @@ -1098,8 +1080,7 @@ class MessageInputState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: StreamSvgIcon( - assetName: 'Icon_smile.svg', + child: StreamSvgIcon.smile( color: StreamChatTheme.of(context).accentColor, ), ), @@ -1234,10 +1215,8 @@ class MessageInputState extends State { }, fillColor: Colors.black.withOpacity(.5), child: Center( - child: StreamSvgIcon( - assetName: 'Icon_close.svg', - height: 24, - width: 24, + child: StreamSvgIcon.close( + size: 24, color: Colors.white, ), ), @@ -1307,8 +1286,7 @@ class MessageInputState extends State { child: Padding( padding: const EdgeInsets.only(left: 4.0, right: 8.0, top: 8.0, bottom: 8.0), - child: StreamSvgIcon( - assetName: 'Icon_lightning-command runner.svg', + child: StreamSvgIcon.lightning( color: Color(0xFF000000).withAlpha(128), ), ), @@ -1331,8 +1309,7 @@ class MessageInputState extends State { child: Padding( padding: EdgeInsets.only(left: 8.0, right: padding, top: 8.0, bottom: 8.0), - child: StreamSvgIcon( - assetName: 'Icon_attach.svg', + child: StreamSvgIcon.attach( color: _openFilePickerSection ? StreamChatTheme.of(context).accentColor : Color(0xFF000000).withAlpha(128), diff --git a/lib/src/message_list_view.dart b/lib/src/message_list_view.dart index 2954f043..1be1d0aa 100644 --- a/lib/src/message_list_view.dart +++ b/lib/src/message_list_view.dart @@ -375,8 +375,7 @@ class _MessageListViewState extends State { children: [ FloatingActionButton( backgroundColor: Colors.white, - child: StreamSvgIcon( - assetName: 'Icon_down.svg', + child: StreamSvgIcon.down( color: Colors.black, ), onPressed: () { diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart index c0cf5d72..6d97f2b6 100644 --- a/lib/src/stream_svg_icon.dart +++ b/lib/src/stream_svg_icon.dart @@ -39,4 +39,340 @@ class StreamSvgIcon extends StatelessWidget { alignment: Alignment.center, ); } + + factory StreamSvgIcon.settings({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'settings.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.down({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_down.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.attach({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_attach.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.smile({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_smile.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.mentions({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'mentions.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.record({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_record.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.camera({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_camera.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.files({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'files.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.pictures({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'pictures.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.left({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_left.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.user({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_user.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.userAdd({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_User_add.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.check({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_check.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.penWrite({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_pen-write.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.contacts({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_contacts.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.close({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_close.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.search({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_search.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.right({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_right.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.mute({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_mute.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.userRemove({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_User_deselect.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.lightning({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_lightning-command runner.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.emptyCircleLeft({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_empty_circle_left.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.message({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_message.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.thread({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_Thread_Reply.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.edit({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_edit.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.copy({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_copy.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.delete({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_delete.svg', + color: color, + width: size, + height: size, + ); + } + + factory StreamSvgIcon.eye({ + double size, + Color color, + }) { + return StreamSvgIcon( + assetName: 'Icon_eye-off.svg', + color: color, + width: size, + height: size, + ); + } } diff --git a/lib/src/thread_header.dart b/lib/src/thread_header.dart index 9ad71a47..c6cce13e 100644 --- a/lib/src/thread_header.dart +++ b/lib/src/thread_header.dart @@ -86,10 +86,8 @@ class ThreadHeader extends StatelessWidget implements PreferredSizeWidget { aspectRatio: 1, child: IconButton( onPressed: onBackPressed, - icon: StreamSvgIcon( - assetName: 'Icon_close.svg', - height: 24, - width: 24, + icon: StreamSvgIcon.close( + size: 24, color: Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black, diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index 8ddd3d99..03c275ac 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -74,10 +74,8 @@ class UserItem extends StatelessWidget { ), trailing: selected ? CircleAvatar( - child: StreamSvgIcon( - assetName: 'Icon_check.svg', - height: 20, - width: 20, + child: StreamSvgIcon.check( + size: 20, ), radius: 10, ) diff --git a/lib/svgs/Icon_camera.svg b/lib/svgs/Icon_camera.svg index 0bf3122d..a5a7d99d 100644 --- a/lib/svgs/Icon_camera.svg +++ b/lib/svgs/Icon_camera.svg @@ -1,3 +1,3 @@ - - + + diff --git a/lib/svgs/Icon_record.svg b/lib/svgs/Icon_record.svg index ff72859f..64d02895 100644 --- a/lib/svgs/Icon_record.svg +++ b/lib/svgs/Icon_record.svg @@ -1,3 +1,3 @@ - - + + From 987ad4e5baf4a9ec64880d9602ffaf97eacbb17b Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 13:44:42 +0100 Subject: [PATCH 24/26] fix search icon --- lib/src/stream_svg_icon.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/stream_svg_icon.dart b/lib/src/stream_svg_icon.dart index 6d97f2b6..2851df3a 100644 --- a/lib/src/stream_svg_icon.dart +++ b/lib/src/stream_svg_icon.dart @@ -25,7 +25,6 @@ class StreamSvgIcon extends StatelessWidget { height: height, key: key, color: color, - fit: BoxFit.cover, alignment: Alignment.center, ) : SvgPicture.asset( @@ -34,7 +33,6 @@ class StreamSvgIcon extends StatelessWidget { key: key, width: width, height: height, - fit: BoxFit.cover, color: color, alignment: Alignment.center, ); From 74e399bcc006900a1e5952f943f616c50366f512 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 13:48:58 +0100 Subject: [PATCH 25/26] fix icons --- example/lib/group_chat_details_screen.dart | 6 ++++-- example/lib/new_group_chat_screen.dart | 1 + example/pubspec.yaml | 2 +- lib/src/user_item.dart | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/example/lib/group_chat_details_screen.dart b/example/lib/group_chat_details_screen.dart index d11f377a..e8a88bac 100644 --- a/example/lib/group_chat_details_screen.dart +++ b/example/lib/group_chat_details_screen.dart @@ -105,8 +105,10 @@ class _GroupChatDetailsScreenState extends State { StreamNeumorphicButton( child: IconButton( padding: const EdgeInsets.all(0), - icon: StreamSvgIcon.check(), - color: Color(0xFF006CFF), + icon: StreamSvgIcon.check( + size: 24, + color: _isGroupNameEmpty ? Colors.grey : Color(0xFF006CFF), + ), onPressed: _isGroupNameEmpty ? null : () async { diff --git a/example/lib/new_group_chat_screen.dart b/example/lib/new_group_chat_screen.dart index 1db848a1..a11767c3 100644 --- a/example/lib/new_group_chat_screen.dart +++ b/example/lib/new_group_chat_screen.dart @@ -161,6 +161,7 @@ class _NewGroupChatScreenState extends State { child: Padding( padding: const EdgeInsets.all(0.0), child: StreamSvgIcon.close( + color: Colors.black, size: 24, ), ), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6e34335d..dab13883 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.70+72 +version: 1.0.71+73 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/user_item.dart b/lib/src/user_item.dart index 03c275ac..f12e3e61 100644 --- a/lib/src/user_item.dart +++ b/lib/src/user_item.dart @@ -76,6 +76,7 @@ class UserItem extends StatelessWidget { ? CircleAvatar( child: StreamSvgIcon.check( size: 20, + color: Colors.white, ), radius: 10, ) From dc7a436e96730405621e659a70d9ffbd23c2362b Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Tue, 24 Nov 2020 17:59:33 +0100 Subject: [PATCH 26/26] align with master --- example/ios/Podfile.lock | 2 +- example/pubspec.yaml | 2 +- lib/src/message_input.dart | 38 ++++++++++++++++++++++++-------------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 131e8aec..29b026b2 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -284,4 +284,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: eb001256612a59f8f9e4d083ad8b9671e69dd184 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.0 diff --git a/example/pubspec.yaml b/example/pubspec.yaml index dab13883..43eb867e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: example description: A new Flutter project. -version: 1.0.71+73 +version: 1.0.72+74 environment: sdk: ">=2.2.2 <3.0.0" diff --git a/lib/src/message_input.dart b/lib/src/message_input.dart index 4b634ab7..b4c79033 100644 --- a/lib/src/message_input.dart +++ b/lib/src/message_input.dart @@ -428,26 +428,36 @@ class MessageInputState extends State { ); } + Timer _debounce; void _onChanged(BuildContext context, String s) { - StreamChannel.of(context).channel.keyStroke().catchError((e) {}); + if (_debounce?.isActive == true) _debounce.cancel(); + _debounce = Timer( + const Duration(milliseconds: 350), + () { + if (!mounted) { + return; + } + StreamChannel.of(context).channel.keyStroke().catchError((e) {}); - setState(() { - _messageIsPresent = s.trim().isNotEmpty; - _actionsShrunk = s.trim().isNotEmpty; - }); + setState(() { + _messageIsPresent = s.trim().isNotEmpty; + _actionsShrunk = s.trim().isNotEmpty; + }); - _commandsOverlay?.remove(); - _commandsOverlay = null; - _mentionsOverlay?.remove(); - _mentionsOverlay = null; - _emojiOverlay?.remove(); - _emojiOverlay = null; + _commandsOverlay?.remove(); + _commandsOverlay = null; + _mentionsOverlay?.remove(); + _mentionsOverlay = null; + _emojiOverlay?.remove(); + _emojiOverlay = null; - _checkCommands(s.trim(), context); + _checkCommands(s.trim(), context); - _checkMentions(s, context); + _checkMentions(s, context); - _checkEmoji(s, context); + _checkEmoji(s, context); + }, + ); } String _getHint() {