diff --git a/packages/stream_chat_flutter/lib/src/reaction_icon.dart b/packages/stream_chat_flutter/lib/src/reaction_icon.dart index 66e19fe7..4466e154 100644 --- a/packages/stream_chat_flutter/lib/src/reaction_icon.dart +++ b/packages/stream_chat_flutter/lib/src/reaction_icon.dart @@ -1,9 +1,14 @@ +/// Reaction icon data class ReactionIcon { - final String type; - final String assetName; - + /// Constructor for creating [ReactionIcon] ReactionIcon({ required this.type, required this.assetName, }); + + /// Type of reaction + final String type; + + /// Asset to display for reaction + final String assetName; } diff --git a/packages/stream_chat_flutter/lib/src/reaction_picker.dart b/packages/stream_chat_flutter/lib/src/reaction_picker.dart index aaa2c040..1308876d 100644 --- a/packages/stream_chat_flutter/lib/src/reaction_picker.dart +++ b/packages/stream_chat_flutter/lib/src/reaction_picker.dart @@ -3,23 +3,24 @@ import 'dart:math'; import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/material.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; - -import '../stream_chat_flutter.dart'; -import 'extension.dart'; +import 'package:stream_chat_flutter/src/extension.dart'; +import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/reaction_picker.png) /// ![screenshot](https://raw.githubusercontent.com/GetStream/stream-chat-flutter/master/screenshots/reaction_picker_paint.png) /// /// It shows a reaction picker /// -/// Usually you don't use this widget as it's one of the default widgets used by [MessageWidget.onMessageActions]. - +/// Usually you don't use this widget as it's one of the default widgets used +/// by [MessageWidget.onMessageActions]. class ReactionPicker extends StatefulWidget { + /// Constructor for creating a [ReactionPicker] widget const ReactionPicker({ Key? key, required this.message, }) : super(key: key); + /// Message to attach the reaction to final Message message; @override @@ -39,7 +40,7 @@ class _ReactionPickerState extends State animations.add( EzAnimation.tween( Tween(begin: 0.0, end: 1.0), - Duration(milliseconds: 500), + const Duration(milliseconds: 500), curve: Curves.easeInOutBack, ), ); @@ -51,108 +52,104 @@ class _ReactionPickerState extends State return TweenAnimationBuilder( tween: Tween(begin: 0, end: 1), curve: Curves.easeInOutBack, - duration: Duration(milliseconds: 500), - builder: (context, val, wid) { - return Transform.scale( - scale: val, - child: Material( - borderRadius: BorderRadius.circular(24), - color: StreamChatTheme.of(context).colorTheme.white, - clipBehavior: Clip.hardEdge, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - 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; - final index = reactionIcons.indexOf(reactionIcon); + duration: const Duration(milliseconds: 500), + builder: (context, val, wid) => Transform.scale( + scale: val, + child: Material( + borderRadius: BorderRadius.circular(24), + color: StreamChatTheme.of(context).colorTheme.white, + clipBehavior: Clip.hardEdge, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + 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; + final index = reactionIcons.indexOf(reactionIcon); - return ConstrainedBox( - constraints: BoxConstraints.tightFor( - height: 24, - width: 24, - ), - child: RawMaterialButton( - elevation: 0, - shape: ContinuousRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - constraints: BoxConstraints.tightFor( + return ConstrainedBox( + constraints: const BoxConstraints.tightFor( height: 24, width: 24, ), - onPressed: () { - if (ownReactionIndex != -1) { - removeReaction( - context, - widget - .message.ownReactions![ownReactionIndex], - ); - } else { - sendReaction( - context, - reactionIcon.type, - ); - } - }, - child: AnimatedBuilder( - animation: animations[index], - builder: (context, val) { - return Transform.scale( - scale: animations[index].value, - child: StreamSvgIcon( - assetName: reactionIcon.assetName, - height: max( - 0, - animations[index].value * 24.0, - ), - width: max( - 0, - animations[index].value * 24.0, - ), - color: ownReactionIndex != -1 - ? StreamChatTheme.of(context) - .colorTheme - .accentBlue - : Theme.of(context) - .iconTheme - .color! - .withOpacity(.5), - ), + child: RawMaterialButton( + elevation: 0, + shape: ContinuousRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + constraints: const BoxConstraints.tightFor( + height: 24, + width: 24, + ), + onPressed: () { + if (ownReactionIndex != -1) { + removeReaction( + context, + widget.message + .ownReactions![ownReactionIndex], ); - }), - ), - ); - }) - .insertBetween(SizedBox( - width: 16, - )) - .toList(), + } else { + sendReaction( + context, + reactionIcon.type, + ); + } + }, + child: AnimatedBuilder( + animation: animations[index], + builder: (context, val) => Transform.scale( + scale: animations[index].value, + child: StreamSvgIcon( + assetName: reactionIcon.assetName, + height: max( + 0, + animations[index].value * 24.0, + ), + width: max( + 0, + animations[index].value * 24.0, + ), + color: ownReactionIndex != -1 + ? StreamChatTheme.of(context) + .colorTheme + .accentBlue + : Theme.of(context) + .iconTheme + .color! + .withOpacity(.5), + ), + )), + ), + ); + }) + .insertBetween(const SizedBox( + width: 16, + )) + .toList(), + ), ), ), - ), - ); - }); + )); } void triggerAnimations() async { - for (var a in animations) { + for (final a in animations) { a.start(); - await Future.delayed(Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 100)); } } void pop() async { - for (var a in animations) { + for (final a in animations) { a.stop(); } Navigator.of(context).pop(); @@ -176,7 +173,7 @@ class _ReactionPickerState extends State @override void dispose() { - for (var a in animations) { + for (final a in animations) { a.dispose(); } super.dispose();