Skip to content

Commit 85db2af

Browse files
sm-sayedichrisbobbe
andcommitted
content: Add UserStatusEmoji widget
Co-authored-by: Chris Bobbe <[email protected]>
1 parent 3df6507 commit 85db2af

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

lib/widgets/content.dart

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import '../generated/l10n/zulip_localizations.dart';
1414
import '../model/avatar_url.dart';
1515
import '../model/binding.dart';
1616
import '../model/content.dart';
17+
import '../model/emoji.dart';
1718
import '../model/internal_link.dart';
1819
import '../model/katex.dart';
1920
import '../model/presence.dart';
2021
import 'actions.dart';
2122
import 'code_block.dart';
2223
import 'dialog.dart';
24+
import 'emoji.dart';
2325
import 'icons.dart';
2426
import 'inset_shadow.dart';
2527
import 'lightbox.dart';
@@ -1940,6 +1942,92 @@ class _PresenceCircleState extends State<PresenceCircle> with PerAccountStoreAwa
19401942
}
19411943
}
19421944

1945+
/// A user status emoji to be displayed in different parts of the app.
1946+
///
1947+
/// Use [padding] to control the padding of status emoji from neighboring
1948+
/// widgets.
1949+
/// When there is no status emoji to be shown, the padding will be omitted too.
1950+
///
1951+
/// Use [neverAnimate] to forcefully disable the animation for animated emojis.
1952+
/// Defaults to true.
1953+
class UserStatusEmoji extends StatelessWidget {
1954+
const UserStatusEmoji({
1955+
super.key,
1956+
required this.userId,
1957+
required this.size,
1958+
this.padding = EdgeInsets.zero,
1959+
this.neverAnimate = true,
1960+
});
1961+
1962+
final int userId;
1963+
final double size;
1964+
final EdgeInsetsGeometry padding;
1965+
final bool neverAnimate;
1966+
1967+
static const double _spanPadding = 4;
1968+
1969+
/// Creates a [WidgetSpan] with a [UserStatusEmoji], for use in rich text;
1970+
/// before or after a text span.
1971+
///
1972+
/// Use [position] to tell the emoji span where it is located relative to
1973+
/// another span, so that it can adjust the necessary padding from it.
1974+
static InlineSpan asWidgetSpan({
1975+
required int userId,
1976+
required double fontSize,
1977+
required TextScaler textScaler,
1978+
StatusEmojiPosition position = StatusEmojiPosition.after,
1979+
bool neverAnimate = true,
1980+
}) {
1981+
final (double paddingStart, double paddingEnd) = switch (position) {
1982+
StatusEmojiPosition.before => (0, _spanPadding),
1983+
StatusEmojiPosition.after => (_spanPadding, 0),
1984+
};
1985+
final size = textScaler.scale(fontSize);
1986+
return WidgetSpan(
1987+
alignment: PlaceholderAlignment.middle,
1988+
child: UserStatusEmoji(userId: userId, size: size,
1989+
padding: EdgeInsetsDirectional.only(start: paddingStart, end: paddingEnd),
1990+
neverAnimate: neverAnimate));
1991+
}
1992+
1993+
@override
1994+
Widget build(BuildContext context) {
1995+
final store = PerAccountStoreWidget.of(context);
1996+
final emoji = store.getUserStatus(userId).emoji;
1997+
1998+
final placeholder = SizedBox.shrink();
1999+
if (emoji == null) return placeholder;
2000+
2001+
final emojiDisplay = store.emojiDisplayFor(
2002+
emojiType: emoji.reactionType,
2003+
emojiCode: emoji.emojiCode,
2004+
emojiName: emoji.emojiName)
2005+
// Web doesn't seem to respect the emojiset user settings for user status.
2006+
// .resolve(store.userSettings)
2007+
;
2008+
return switch (emojiDisplay) {
2009+
UnicodeEmojiDisplay() => Padding(
2010+
padding: padding,
2011+
child: UnicodeEmojiWidget(size: size, emojiDisplay: emojiDisplay)),
2012+
ImageEmojiDisplay() => Padding(
2013+
padding: padding,
2014+
child: ImageEmojiWidget(
2015+
size: size,
2016+
emojiDisplay: emojiDisplay,
2017+
neverAnimate: neverAnimate,
2018+
// If image emoji fails to load, show nothing.
2019+
errorBuilder: (_, _, _) => placeholder)),
2020+
// The user-status feature doesn't support a :text_emoji:-style display.
2021+
// Also, if an image emoji's URL string doesn't parse, it'll fall back to
2022+
// a :text_emoji:-style display. We show nothing for this case.
2023+
TextEmojiDisplay() => placeholder,
2024+
};
2025+
}
2026+
}
2027+
2028+
/// The position of the status emoji span relative to another text span.
2029+
enum StatusEmojiPosition { before, after }
2030+
19432031
//
19442032
// Small helpers.
19452033
//

0 commit comments

Comments
 (0)