@@ -5,6 +5,93 @@ 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+ @override
56+ Widget build (BuildContext context) {
57+ final emojiDisplay = this .emojiDisplay;
58+ return switch (emojiDisplay) {
59+ ImageEmojiDisplay () => ImageEmojiWidget (
60+ emojiDisplay: emojiDisplay,
61+ size: squareDimension,
62+ textScaler: squareDimensionScaler,
63+ errorBuilder: (_, _, _) => switch (imagePlaceholderStyle) {
64+ EmojiImagePlaceholderStyle .square =>
65+ SizedBox .square (dimension: squareDimensionScaler.scale (squareDimension)),
66+ EmojiImagePlaceholderStyle .nothing => SizedBox .shrink (),
67+ EmojiImagePlaceholderStyle .text => _buildTextEmoji (),
68+ },
69+ neverAnimate: neverAnimateImage),
70+ UnicodeEmojiDisplay () => UnicodeEmojiWidget (
71+ emojiDisplay: emojiDisplay,
72+ size: squareDimension,
73+ textScaler: squareDimensionScaler),
74+ TextEmojiDisplay () => _buildTextEmoji (),
75+ };
76+ }
77+ }
78+
79+ /// In [EmojiWidget] , how to present an image emoji when we don't have the image.
80+ enum EmojiImagePlaceholderStyle {
81+ /// A square of [EmojiWidget.squareDimension]
82+ /// scaled by [EmojiWidget.squareDimensionScaler] .
83+ square,
84+
85+ /// A [SizedBox.shrink] .
86+ nothing,
87+
88+ /// A plain-text emoji.
89+ ///
90+ /// See [EmojiWidget.buildCustomTextEmoji] for how plain-text emojis are
91+ /// styled.
92+ text,
93+ }
94+
895class UnicodeEmojiWidget extends StatelessWidget {
996 const UnicodeEmojiWidget ({
1097 super .key,
@@ -91,7 +178,6 @@ class UnicodeEmojiWidget extends StatelessWidget {
91178 }
92179}
93180
94-
95181class ImageEmojiWidget extends StatelessWidget {
96182 const ImageEmojiWidget ({
97183 super .key,
0 commit comments