react-native-ajora
Version:
The most complete AI agent UI for React Native
93 lines • 3.4 kB
JavaScript
import React, { useMemo, useCallback } from "react";
import { StyleSheet, TouchableOpacity, View, } from "react-native";
import Color from "./Color";
import { TEST_ID } from "./Constant";
import { MaterialIcons } from "@expo/vector-icons";
import { useChatContext } from "./AjoraContext";
const styles = StyleSheet.create({
container: {
height: 44,
justifyContent: "flex-end",
},
text: {
color: Color.primary,
fontWeight: "600",
fontSize: 17,
backgroundColor: Color.backgroundTransparent,
marginBottom: 12,
marginLeft: 10,
marginRight: 10,
},
});
export const Send = ({ text, containerStyle, alwaysShowSend = false, disabled = false, sendButtonProps, onSend, }) => {
const { ajora } = useChatContext();
const { submitQuery, activeThreadId, stopStreaming, isComplete, attachement, isRecording, setIsRecording, } = ajora;
const handleOnPress = useCallback(() => {
if (!isComplete) {
// Abort/stop current streaming
stopStreaming();
return;
}
// If no text or attachment, start recording
if (!attachement && !text) {
setIsRecording(true);
return;
}
let message = {
_id: Math.round(Math.random() * 1000000).toString(),
role: "user",
thread_id: activeThreadId || "",
parts: [],
createdAt: new Date().toISOString(),
};
if (text) {
message.parts.push({ text: text.trim() });
}
if (attachement) {
message.parts.push({
fileData: {
// displayName: attachement.displayName,
fileUri: attachement.fileUri,
mimeType: attachement.mimeType,
},
});
}
// Call onSend to trigger input clearing and other side effects
if (onSend) {
onSend([message], true);
}
else {
// Fallback to direct submitQuery if onSend is not provided
submitQuery({
type: "text",
message,
});
}
}, [
text,
submitQuery,
activeThreadId,
onSend,
isComplete,
stopStreaming,
attachement,
setIsRecording,
]);
const showSend = useMemo(() => {
// Show button when there is text/attachment to send, when alwaysShowSend, when streaming (to show abort), or when recording
const hasText = !!(text && text.trim().length > 0);
return (alwaysShowSend || hasText || !!attachement?.isUploaded || !isComplete
// ||
// isRecording
);
}, [alwaysShowSend, text, isComplete, attachement, isRecording]);
if (!showSend) {
return null;
}
return (<TouchableOpacity testID={TEST_ID.SEND_TOUCHABLE} accessible accessibilityLabel={isRecording ? "stop recording" : "send"} style={[styles.container, containerStyle]} onPress={handleOnPress} accessibilityRole="button" disabled={disabled} {...sendButtonProps}>
<View style={{ justifyContent: "center", padding: 10 }}>
<MaterialIcons size={28} color={Color.primary} name={isRecording ? "stop" : isComplete ? "arrow-upward" : "stop"}/>
</View>
</TouchableOpacity>);
};
//# sourceMappingURL=Send.js.map