Skip to content

Conversation

@rjmarsan
Copy link

We don't use the "phrases" concept anymore and we'd like to sync markdown decorations. This generalizes well and removes some stale code. hopefully fixes some bugs along the way.


Layout(content = {
val alpha = rememberMarkdownFade(richTextRenderOptions, markdownAnimationState)
Layout(modifier = Modifier.alpha(alpha.value), content = {
Copy link

@rz-openai rz-openai Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using .graphicsLayer { } block to defer animated value reads to the draw phase would improve perf

mutableFloatStateOf(if (richTextRenderOptions.animate) 0f else 1f)
}
LaunchedEffect(Unit) {
targetAlpha.value = 1f

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this code was just moved, but we would skip a recomposition step by using a simple animate call to update the state value instead of animateFloatAsState, and also prevents us from creating something like an Animatable in cases we don't need to animate.

}
// Remove animation right away, in case it had split at an inappropriate unicode point.
animations.remove(phraseIndex)
fun updateText(newText: AnnotatedString) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only called in the launched effect? Maybe we should inline it?

animations.remove(phraseIndex)
fun updateText(newText: AnnotatedString) {
val currentText = lastText.value
if (newText.text == currentText.text) return
Copy link

@rz-openai rz-openai Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about letting the launched effect key on the text value instead?

val startIndex = commonPrefixLength(currentText.text, newText.text)
lastText.value = newText
textToRender.value = newText
animations.clear()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we clear the other animations? Maybe they are still running, and they won't draw their updates anymore.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah reverting this for now

fun updateText(newText: AnnotatedString) {
val currentText = lastText.value
if (newText.text == currentText.text) return
val startIndex = commonPrefixLength(currentText.text, newText.text)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we might kind of lose our on the granular animation now, but it would feel snappier in general since text would come in faster after delays?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i don't like these changes once i tried them in prod, backing them out

)
)
LaunchedEffect(Unit) {
markdownAnimationState.addAnimation(richTextRenderOptions)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to unregister it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addAnimation only ticks the delay counter up, we don't need to unregister it globally

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha

@rjmarsan
Copy link
Author

going through these comments and moving them to #43

@rjmarsan rjmarsan closed this Aug 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants