Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 1x 2x 2x 2x 2x 2x 2x 2x | import React, { useEffect } from "react";
import Animated, {
Easing,
FadeInDown,
FadeOutUp,
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
} from "react-native-reanimated";
import { makeStyles } from "@repo/ui/themes/makeStyles";
/**
* Placeholder for the welcome description while the thread is being created.
*
* The sentence itself belongs to the agent — it states what this actor may
* actually do, which the client cannot know before the thread exists. Showing
* a shimmer rather than a stand-in sentence keeps the client from claiming
* anything on the agent's behalf, and matches how the chips below already
* announce that they are still loading.
*/
export const WelcomeTextSkeleton = () => {
const styles = useStyles();
const opacity = useSharedValue(0.4);
useEffect(() => {
opacity.value = withRepeat(
withTiming(1, { duration: 750, easing: Easing.inOut(Easing.ease) }),
-1,
true,
);
}, [opacity]);
const animStyle = useAnimatedStyle(() => ({ opacity: opacity.value }));
return (
<Animated.View
entering={FadeInDown.duration(200)}
exiting={FadeOutUp.duration(220)}
style={styles.container}
>
<Animated.View style={[styles.line, animStyle]} />
</Animated.View>
);
};
const useStyles = makeStyles((theme) => ({
container: {
width: "100%",
alignItems: "center",
},
line: {
// Sized to the description's own line box so the heading above does not
// jump when the real sentence replaces this.
height: 20,
width: "70%",
borderRadius: 6,
backgroundColor: theme.isNewTheme
? theme.colors.background.surface
: theme.colors.background.tertiary,
},
}));
|