react-native-ajora
Version:
The most complete AI agent UI for React Native
115 lines • 4.45 kB
JavaScript
import React from "react";
import { Linking, StyleSheet, View, } from "react-native";
import ParsedText from "react-native-parsed-text";
import { useChatContext } from "./AjoraContext";
import { error } from "./logging";
import RichText from "./richText/RichText";
const WWW_URL_PATTERN = /^www\./i;
const { textStyle } = StyleSheet.create({
textStyle: {
fontSize: 16,
lineHeight: 20,
marginTop: 2,
marginBottom: 2,
marginLeft: 0,
marginRight: 0,
},
});
const styles = {
left: StyleSheet.create({
container: {},
text: {
color: "black",
...textStyle,
},
link: {
color: "black",
textDecorationLine: "underline",
},
}),
right: StyleSheet.create({
container: {
paddingVertical: 0,
},
text: {
color: "white",
...textStyle,
marginTop: 0,
marginBottom: 0,
lineHeight: 16,
},
link: {
color: "white",
textDecorationLine: "underline",
},
}),
};
const DEFAULT_OPTION_TITLES = ["Call", "Text", "Cancel"];
export function MessageText({ currentMessage = {}, optionTitles = DEFAULT_OPTION_TITLES, position = "left", containerStyle, textStyle, linkStyle: linkStyleProp, customTextStyle, parsePatterns, textProps, }) {
const { actionSheet } = useChatContext();
// TODO: React.memo
// const shouldComponentUpdate = (nextProps: MessageTextProps<TMessage>) => {
// return (
// !!currentMessage &&
// !!nextProps.currentMessage &&
// currentMessage.text !== nextProps.currentMessage.text
// )
// }
const onUrlPress = (url) => {
// When someone sends a message that includes a website address beginning with "www." (omitting the scheme),
// react-native-parsed-text recognizes it as a valid url, but Linking fails to open due to the missing scheme.
if (WWW_URL_PATTERN.test(url))
onUrlPress(`https://${url}`);
else
Linking.openURL(url).catch((e) => {
error(e, "No handler for URL:", url);
});
};
const onPhonePress = (phone) => {
const options = optionTitles && optionTitles.length > 0
? optionTitles.slice(0, 3)
: DEFAULT_OPTION_TITLES;
const cancelButtonIndex = options.length - 1;
actionSheet().showActionSheetWithOptions({
options,
cancelButtonIndex,
}, (buttonIndex) => {
switch (buttonIndex) {
case 0:
Linking.openURL(`tel:${phone}`).catch((e) => {
error(e, "No handler for telephone");
});
break;
case 1:
Linking.openURL(`sms:${phone}`).catch((e) => {
error(e, "No handler for text");
});
break;
}
});
};
const onEmailPress = (email) => Linking.openURL(`mailto:${email}`).catch((e) => error(e, "No handler for mailto"));
const linkStyle = [styles[position].link, linkStyleProp?.[position]];
return (<View style={[styles[position].container, containerStyle?.[position]]}>
<ParsedText style={[styles[position].text, textStyle?.[position], customTextStyle]} parse={[
...(parsePatterns
? parsePatterns(linkStyle)
: []),
{ type: "url", style: linkStyle, onPress: onUrlPress },
{ type: "phone", style: linkStyle, onPress: onPhonePress },
{ type: "email", style: linkStyle, onPress: onEmailPress },
]} childrenProps={{ ...textProps }}>
<RichText text={currentMessage.parts
?.filter((part) => part.text)
.map((part) => part.text)
.join(" ") || ""} compact={position === "right"} textColor={String(textStyle?.[position]?.color ||
customTextStyle?.color ||
styles[position].text.color)} fontSize={textStyle?.[position]?.fontSize ||
customTextStyle?.fontSize ||
styles[position].text.fontSize} lineHeight={textStyle?.[position]?.lineHeight ||
customTextStyle?.lineHeight ||
styles[position].text.lineHeight}/>
</ParsedText>
</View>);
}
//# sourceMappingURL=MessageText.js.map