Skip to content

Commit

Permalink
fix: auto-resizing textboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
Vali-98 committed Nov 16, 2024
1 parent aca821f commit 1ff281b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 77 deletions.
77 changes: 32 additions & 45 deletions app/components/ChatMenu/ChatWindow/ChatText.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Chats, MarkdownStyle } from '@globals'
import React, { useEffect, useRef } from 'react'
import { Animated, Easing, LayoutChangeEvent } from 'react-native'
import { View } from 'react-native'
import Markdown from 'react-native-markdown-display'
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'

type ChatTextProps = {
nowGenerating: boolean
Expand All @@ -15,57 +16,43 @@ const ChatText: React.FC<ChatTextProps> = ({ nowGenerating, id }) => {
.swipe ?? ''
)

const animatedHeight = useRef(new Animated.Value(-1)).current
const height = useRef(-1)

const handleAnimateHeight = (newheight: number) => {
animatedHeight.stopAnimation(() =>
Animated.timing(animatedHeight, {
toValue: newheight,
duration: 200,
useNativeDriver: false,
easing: Easing.inOut((x) => x * x),
}).start()
)
}

const handleContentSizeChange = (event: LayoutChangeEvent) => {
const newHeight = event.nativeEvent.layout.height
const animHeight = useSharedValue(-1)
const targetHeight = useSharedValue(-1)
const heightStyle = useAnimatedStyle(() =>
animHeight.value < 0
? {}
: {
height: withTiming(animHeight.value, { duration: 100 }),
}
)
const viewRef = useRef<View>(null)
const updateHeight = () => {
const oveflowPadding = 12

if (height.current === -1) {
height.current = newHeight
animatedHeight.setValue(newHeight)
return
if (viewRef.current) {
viewRef.current.measure((x, y, width, measuredHeight) => {
const newHeight = measuredHeight
if (targetHeight.value === newHeight) return
animHeight.value = newHeight
targetHeight.value = newHeight
})
}

if (height.current === newHeight) return
height.current = newHeight
handleAnimateHeight(newHeight)
}

useEffect(() => {
if (!nowGenerating && height.current !== -1) {
handleAnimateHeight(height.current)
} else if (nowGenerating && !mes) {
// NOTE: this assumes that mes is empty due to a swipe and may break, but unlikely
height.current = 0
handleAnimateHeight(height.current)
}
}, [nowGenerating])
requestAnimationFrame(() => updateHeight())
}, [mes])

return (
<Animated.View
onLayout={handleContentSizeChange}
style={{
height: __DEV__ ? 'auto' : animatedHeight, // dev fix for slow emulator animations
overflow: 'scroll',
}}>
<Markdown
markdownit={MarkdownStyle.Rules}
rules={MarkdownStyle.RenderRules}
style={MarkdownStyle.Styles}>
{mes.trim()}
</Markdown>
<Animated.View style={[heightStyle, { overflow: 'scroll' }]}>
<View style={{ minHeight: 10 }} ref={viewRef}>
<Markdown
markdownit={MarkdownStyle.Rules}
rules={MarkdownStyle.RenderRules}
style={MarkdownStyle.Styles}>
{mes.trim()}
</Markdown>
</View>
</Animated.View>
)
}
Expand Down
82 changes: 50 additions & 32 deletions app/components/ChatMenu/ChatWindow/ChatTextLast.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useInference } from '@constants/Chat'
import { Chats, Style, MarkdownStyle } from '@globals'
import React, { useEffect, useRef } from 'react'
import { Easing, LayoutChangeEvent, Animated, View, StyleSheet, Platform } from 'react-native'
import { useEffect, useRef } from 'react'
import { LayoutChangeEvent, View } from 'react-native'
import Markdown from 'react-native-markdown-display'
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
//@ts-expect-error
import AnimatedEllipsis from 'rn-animated-ellipsis'
import { useShallow } from 'zustand/react/shallow'
Expand Down Expand Up @@ -31,6 +32,7 @@ const ChatTextLast: React.FC<ChatTextProps> = ({ nowGenerating, id }) => {
}))
)

/*
const animatedHeight = useRef(new Animated.Value(-1)).current
const height = useRef(-1)
const handleAnimateHeight = (newheight: number) => {
Expand Down Expand Up @@ -69,38 +71,54 @@ const ChatTextLast: React.FC<ChatTextProps> = ({ nowGenerating, id }) => {
height.current = 0
handleAnimateHeight(height.current)
}
}, [nowGenerating])
}, [nowGenerating])*/

const animHeight = useSharedValue(-1)
const targetHeight = useSharedValue(-1)
const heightStyle = useAnimatedStyle(() =>
animHeight.value < 0
? {}
: {
height: withTiming(animHeight.value, { duration: 100 }),
}
)
const viewRef = useRef<View>(null)
const updateHeight = () => {
const oveflowPadding = 12
const showPadding = nowGenerating && buffer !== ''

if (viewRef.current) {
viewRef.current.measure((x, y, width, measuredHeight) => {
const newHeight = measuredHeight + (showPadding ? oveflowPadding : 0)
if (targetHeight.value === newHeight) return
animHeight.value = newHeight
targetHeight.value = newHeight
})
}
}

useEffect(() => {
requestAnimationFrame(() => updateHeight())
}, [buffer, mes])

return (
<Animated.View
style={{
height: animatedHeight,
overflow: 'scroll',
}}>
{swipeId === currentSwipeId && nowGenerating && buffer === '' && (
<AnimatedEllipsis
style={{
color: Style.getColor('primary-text2'),
fontSize: 20,
}}
/>
)}
<Markdown
markdownit={MarkdownStyle.Rules}
rules={{
...MarkdownStyle.RenderRules,
body: (node: any, children: any, parent: any, styles: any) => (
<View
key={node.key}
style={styles._VIEW_SAFE_body}
onLayout={handleContentSizeChange}>
{children}
</View>
),
}}
style={MarkdownStyle.Styles}>
{nowGenerating && swipeId === currentSwipeId ? buffer.trim() : mes.trim()}
</Markdown>
<Animated.View style={[heightStyle, { overflow: 'scroll' }]}>
<View style={{ minHeight: 10 }} ref={viewRef}>
{swipeId === currentSwipeId && nowGenerating && buffer === '' && (
<AnimatedEllipsis
style={{
color: Style.getColor('primary-text2'),
fontSize: 20,
}}
/>
)}
<Markdown
markdownit={MarkdownStyle.Rules}
rules={MarkdownStyle.RenderRules}
style={MarkdownStyle.Styles}>
{nowGenerating && swipeId === currentSwipeId ? buffer.trim() : mes.trim()}
</Markdown>
</View>
</Animated.View>
)
}
Expand Down

0 comments on commit 1ff281b

Please sign in to comment.