fix: use grapheme cluster count instead of UTF-16 code units for animation resume index#9
Closed
WilliamRWalsh wants to merge 1 commit intohooshyar:mainfrom
Closed
Conversation
…ation resume index In `_resumeCharacterByCharacterTyping` and `_resumeCharacterByCharacterTypingFromOldText`, `_displayedText.length` returns the count of UTF-16 code units, but the value is used as an index into `Characters().toList()` which is indexed by grapheme clusters. For characters that occupy multiple UTF-16 code units (e.g. emoji like 👍 which is a surrogate pair), the index overshoots, causing the character immediately after the emoji to be skipped when the animation resumes after new text is appended. The fix replaces `_displayedText.length` with `_displayedText.characters.length` in these two methods so the index correctly counts grapheme clusters.
Author
|
Hey @hooshyar! Thanks for making this package! Let me know if you need more information about this change 🙏 |
Owner
|
Thanks for the fix @WilliamRWalsh! Great catch on the grapheme cluster vs UTF-16 code unit issue. We've applied this fix directly to main (along with tests for emoji text). Since the changes are identical, I'm going to close this PR. Your contribution is credited in the commit. Appreciate it! 🎉 |
hooshyar
added a commit
that referenced
this pull request
Apr 12, 2026
- Add 7 custom builder parameters (imageBuilder, onLinkTap, codeBuilder, latexBuilder, sourceTagBuilder, highlightBuilder, linkBuilder) to StreamingTextMarkdown and all named constructors (closes #10) - Fix emoji character skipping: use grapheme cluster count instead of UTF-16 code units for animation resume index (closes PR #9) - Add tests for emoji text and custom builders - Rewrite CLAUDE.md for accuracy and conciseness Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_resumeCharacterByCharacterTypingand_resumeCharacterByCharacterTypingFromOldText,_displayedText.lengthreturns UTF-16 code units, but is used as an index intoCharacters().toList()which is indexed by grapheme clusters. For emoji (e.g. 👍, which is 2 UTF-16 code units but 1 grapheme), the index overshoots, skipping the next character._displayedText.lengthwith_displayedText.characters.lengthin these two methods.Reproduction
"Great 👍 Keep going")Changes
Two lines in
lib/src/streaming/streaming_text.dart:_resumeCharacterByCharacterTyping_displayedText.length_displayedText.characters.length_resumeCharacterByCharacterTypingFromOldText_displayedText.length_displayedText.characters.length