Skip to content

Instantly share code, notes, and snippets.

@nhancv
Last active January 6, 2021 23:51
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Flutter custom chat emoji text (custom icon text font)
import 'package:nft/services/safety/base_stateful.dart';
import 'package:flutter/material.dart';
/// Use
/// const WChatText(text: 'hello:heart.86ac068::smile.48f82f2::fire.9f77c64:'),
class WChatText extends StatefulWidget {
const WChatText({Key key, @required this.text}) : super(key: key);
final String text;
@override
_WChatTextState createState() => _WChatTextState();
}
class _WChatTextState extends BaseStateful<WChatText> {
@override
Widget build(BuildContext context) {
super.build(context);
return Container(
child: RichText(
text: _buildEmojiTextSpan(_standardizeText(widget.text)),
),
);
}
// Standardize text
// hello:heart.86ac068::smile.48f82f2::fire.9f77c64:
// =>
// hello\ue901\ue902\ue900
String _standardizeText(String text) {
text = text?.replaceAll(RegExp(r':fire.\w+:'), '\ue900');
text = text?.replaceAll(RegExp(r':heart.\w+:'), '\ue901');
text = text?.replaceAll(RegExp(r':smile.\w+:'), '\ue902');
return text;
}
// Get emoji color from code
Color _getEmojiColor(int emojiCode) {
switch (emojiCode) {
case 0xe900:
return const Color(0xFFFFD243);
case 0xe901:
return const Color(0xFFFF39AF);
case 0xe902:
return const Color(0xFF2CD7FF);
}
return null;
}
// Build text span
TextSpan _buildEmojiTextSpan(String text) {
if (text == null) {
return const TextSpan();
}
final List<TextSpan> children = <TextSpan>[];
// integer Unicode code points
final Runes runes = text.runes;
final List<int> chunk = <int>[];
for (int i = 0; i < runes.length; i++) {
final int code = runes.elementAt(i);
// print('code ${code.toRadixString(16)}');
// we assume that everything that is not
// in Extended-ASCII set is an emoji...
final bool isEmoji = code > 255;
if (!isEmoji) {
chunk.add(code);
}
if (isEmoji || i == runes.length - 1) {
children.add(
TextSpan(
text: String.fromCharCodes(chunk),
style: const TextStyle(),
),
);
chunk.clear();
if (isEmoji) {
children.add(
TextSpan(
text: String.fromCharCode(code),
style: TextStyle(
fontFamily: 'nft',
color: _getEmojiColor(code),
),
),
);
}
}
}
return TextSpan(children: children);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment