@@ -5,6 +5,96 @@ import '../api/model/model.dart';
55import '../model/emoji.dart' ;
66import 'content.dart' ;
77
8+ /// A widget showing an emoji.
9+ class EmojiWidget extends StatelessWidget {
10+ const EmojiWidget ({
11+ super .key,
12+ required this .emojiDisplay,
13+ required this .squareDimension,
14+ this .squareDimensionScaler = TextScaler .noScaling,
15+ this .imagePlaceholderStyle = EmojiImagePlaceholderStyle .square,
16+ this .neverAnimateImage = false ,
17+ this .buildCustomTextEmoji,
18+ });
19+
20+ final EmojiDisplay emojiDisplay;
21+
22+ /// The base width and height to use for the emoji square.
23+ ///
24+ /// This will be scaled by [squareDimensionScaler] .
25+ ///
26+ /// This is ignored when using the plain-text emoji style.
27+ final double squareDimension;
28+
29+ /// A [TextScaler] to apply to [squareDimension] .
30+ ///
31+ /// Defaults to [TextScaler.noScaling] .
32+ ///
33+ /// This is ignored when using the plain-text emoji style.
34+ final TextScaler squareDimensionScaler;
35+
36+ final EmojiImagePlaceholderStyle imagePlaceholderStyle;
37+
38+ /// Whether to show an animated emoji in its still (non-animated) variant
39+ /// only, even if device settings permit animation.
40+ ///
41+ /// Defaults to false.
42+ final bool neverAnimateImage;
43+
44+ /// An optional callback to specify a custom plain-text emoji style.
45+ ///
46+ /// If this is not passed, a simple [Text] widget with no added styling
47+ /// is used.
48+ final Widget Function ()? buildCustomTextEmoji;
49+
50+ Widget _buildTextEmoji () {
51+ return buildCustomTextEmoji? .call ()
52+ ?? Text (textEmojiForEmojiName (emojiDisplay.emojiName));
53+ }
54+
55+ ImageErrorWidgetBuilder _getImageErrorBuilder (double effectiveSize) {
56+ return (_, _, _) => switch (imagePlaceholderStyle) {
57+ EmojiImagePlaceholderStyle .square => SizedBox .square (dimension: effectiveSize),
58+ EmojiImagePlaceholderStyle .nothing => SizedBox .shrink (),
59+ EmojiImagePlaceholderStyle .text => _buildTextEmoji (),
60+ };
61+ }
62+
63+ @override
64+ Widget build (BuildContext context) {
65+ final effectiveSquareDimension = squareDimensionScaler.scale (squareDimension);
66+
67+ final emojiDisplay = this .emojiDisplay;
68+ return switch (emojiDisplay) {
69+ ImageEmojiDisplay () => ImageEmojiWidget (
70+ emojiDisplay: emojiDisplay,
71+ size: squareDimension,
72+ textScaler: squareDimensionScaler,
73+ errorBuilder: _getImageErrorBuilder (effectiveSquareDimension)),
74+ UnicodeEmojiDisplay () => UnicodeEmojiWidget (
75+ size: squareDimension,
76+ emojiDisplay: emojiDisplay),
77+ TextEmojiDisplay () => _buildTextEmoji (),
78+ };
79+ }
80+ }
81+
82+ /// In [EmojiWidget] , how to present an image emoji when we don't have the image.
83+ enum EmojiImagePlaceholderStyle {
84+ /// A square of [EmojiWidget.squareDimension]
85+ /// scaled by [EmojiWidget.squareDimensionScaler] .
86+ square,
87+
88+ /// A [SizedBox.shrink] .
89+ nothing,
90+
91+ /// A plain-text emoji.
92+ ///
93+ /// See [EmojiWidget.buildCustomTextEmoji] for how plain-text emojis are
94+ /// styled.
95+ text,
96+ }
97+
898class UnicodeEmojiWidget extends StatelessWidget {
999 const UnicodeEmojiWidget ({
10100 super .key,
@@ -91,7 +181,6 @@ class UnicodeEmojiWidget extends StatelessWidget {
91181 }
92182}
93183
94-
95184class ImageEmojiWidget extends StatelessWidget {
96185 const ImageEmojiWidget ({
97186 super .key,
0 commit comments