Commit 077101c7 authored by Malith Anjana's avatar Malith Anjana

finalize the chatbot

parent 19284a8a
...@@ -51,11 +51,11 @@ const App = () => { ...@@ -51,11 +51,11 @@ const App = () => {
component={Chatbot} component={Chatbot}
options={{headerShown:false}} options={{headerShown:false}}
/> />
<Stack.Screen {/* <Stack.Screen
name="VoiceConversation" name="VoiceConversation"
component={VoiceConversation} component={VoiceConversation}
options={{headerShown:false}} options={{headerShown:false}}
/> /> */}
</Stack.Navigator> </Stack.Navigator>
</NavigationContainer> </NavigationContainer>
......
import axios from "axios"; import axios from "axios";
const RASA_BASE = "http://192.168.170.35:5005/webhooks/rest/webhook/" const RASA_BASE = "http://127.0.0.1:5005/webhooks/rest/webhook/"
const SENTI_BASE = "http://127.0.0.1:8000/chats/" const SENTI_BASE = "http://127.0.0.1:8000/"
export async function sendToRasa (body){ export async function sendToRasa (body){
return axios({ return axios({
...@@ -11,9 +11,17 @@ export async function sendToRasa (body){ ...@@ -11,9 +11,17 @@ export async function sendToRasa (body){
}) })
} }
export async function predict (body){
return axios({
url:`${SENTI_BASE}/test`,
method: "POST",
data: body
})
}
export async function getChats (id){ export async function getChats (id){
return axios({ return axios({
url:SENTI_BASE + id, url:`${SENTI_BASE}/chats/${id}`,
method:"GET" method:"GET"
}) })
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native"; ...@@ -4,7 +4,7 @@ import { View, Text, StyleSheet, TouchableOpacity, Image } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome5"; import Icon from "react-native-vector-icons/FontAwesome5";
import { COLOR } from '../../themes'; import { COLOR } from '../../themes';
export const ChatHeader = () => { export const ChatHeader = ({onPress}) => {
const navigation = useNavigation(); const navigation = useNavigation();
return ( return (
<View style={styles.container}> <View style={styles.container}>
...@@ -29,9 +29,9 @@ export const ChatHeader = () => { ...@@ -29,9 +29,9 @@ export const ChatHeader = () => {
color={COLOR.white} color={COLOR.white}
/> />
</TouchableOpacity> */} </TouchableOpacity> */}
<TouchableOpacity style={{ paddingHorizontal: 20 }}> <TouchableOpacity onPress={onPress} style={{ paddingHorizontal: 20 }}>
<Icon <Icon
name="ellipsis-v" name="file-contract"
size={30} size={30}
color={COLOR.white} color={COLOR.white}
/> />
......
import axios from 'axios'; import axios from 'axios';
import React, { useCallback, useEffect, useState } from 'react' import React, { useCallback, useEffect, useState } from 'react'
import { Text, View } from 'react-native' import { Text, View, Animated, StyleSheet, TouchableOpacity, Image, Modal} from 'react-native'
import { Bubble, GiftedChat, Send } from 'react-native-gifted-chat'; import { Bubble, GiftedChat, InputToolbar, Send } from 'react-native-gifted-chat';
import { getChats, sendToRasa } from '../api'; import { getChats, predict, sendToRasa } from '../api';
import { ChatHeader } from '../components/chatbot/ChatHeader' import { ChatHeader } from '../components/chatbot/ChatHeader'
import uuid from 'react-native-uuid'; import uuid from 'react-native-uuid';
import {IMAGE} from '../assets/images/chatbotImage' import {IMAGE} from '../assets/images/chatbotImage'
import { COLOR, FONT } from '../themes'; import { COLOR, FONT } from '../themes';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import { unixConvertion } from '../assets/utils/UnixConverter'; import { unixConvertion } from '../assets/utils/UnixConverter';
import { AlanView } from '@alan-ai/alan-sdk-react-native'; import { useRef } from 'react';
export const Chatbot = () => { export const Chatbot = () => {
const [messages, setMessages] = useState([]); const [messages, setMessages] = useState([]);
const [start, setStart] = useState(true);
const [end, setEnd] = useState(false);
const [predictResult, setPredictResault] = useState("");
const [visible, setVisible] = useState(false);
//Control the popup modal
const ModalPoup = ({visible, children}) => {
const [showModal, setShowModal] = useState(visible);
const scaleValue = useRef(new Animated.Value(0)).current;
useEffect(() => {
toggleModal();
}, [visible]);
const toggleModal = () => {
if (visible) {
setShowModal(true);
Animated.spring(scaleValue, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}).start();
} else {
setTimeout(() => setShowModal(false), 200);
Animated.timing(scaleValue, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}).start();
}
};
return (
<Modal transparent visible={showModal}>
<View style={styles.modalBackGround}>
<Animated.View
style={[styles.modalContainer, {transform: [{scale: scaleValue}]}]}>
{children}
</Animated.View>
</View>
</Modal>
);
};
const BOT_USER = { const BOT_USER = {
_id: 2, _id: 2,
...@@ -26,15 +70,17 @@ export const Chatbot = () => { ...@@ -26,15 +70,17 @@ export const Chatbot = () => {
const BOT_MSG = [{ const BOT_MSG = [{
_id: uuid.v4(), _id: uuid.v4(),
text: `Hi! I am the FAQ bot 🤖 from TEST.\n\nHow may I help you with today?`, text: `Hi! I am the AI chatbot 🤖 \n\nHow may I help you with today?`,
createdAt: new Date(), createdAt: new Date(),
user: BOT_USER user: BOT_USER
}] }]
useEffect(() => { useEffect(() => {
getChatForUser(); getChatForUser();
setStart(true);
}, []) }, [])
//get chat for specific user
const getChatForUser=async() => { const getChatForUser=async() => {
try{ try{
const res = await getChats(USER._id) const res = await getChats(USER._id)
...@@ -77,6 +123,7 @@ const getChatForUser=async() => { ...@@ -77,6 +123,7 @@ const getChatForUser=async() => {
const onSend = useCallback(async(msg = []) => { const onSend = useCallback(async(msg = []) => {
console.log(msg[0].text); console.log(msg[0].text);
setMessages(previousMessages => (GiftedChat.append(previousMessages, msg))); setMessages(previousMessages => (GiftedChat.append(previousMessages, msg)));
try{ try{
...@@ -95,6 +142,12 @@ const getChatForUser=async() => { ...@@ -95,6 +142,12 @@ const getChatForUser=async() => {
} }
) )
setMessages(prev=> prev.concat(reply)); setMessages(prev=> prev.concat(reply));
//send for prediction
const prediction = await predict({"start": start, "text":msg[0].text, "end":end});
console.log(prediction.data.overall);
setPredictResault(prediction.data.overall)
setStart(false);
} }
catch(err){ catch(err){
console.log(err) console.log(err)
...@@ -146,8 +199,38 @@ const getChatForUser=async() => { ...@@ -146,8 +199,38 @@ const getChatForUser=async() => {
return ( return (
<View style={{flex:1}}> <View style={{flex:1}}>
<ChatHeader/> {/* Popup Modal */}
<AlanView projectid={'900e11c36e836f117bff78fe3fac34872e956eca572e1d8b807a3e2338fdd0dc/stage'}/> <ModalPoup visible={visible}>
<View style={{alignItems: 'center'}}>
<View style={styles.header}>
<TouchableOpacity onPress={() => setVisible(false)}>
<Image
source={require('../assets/images/close.png')}
style={{height: 30, width: 30}}
/>
</TouchableOpacity>
</View>
</View>
<View style={{alignItems: 'center'}}>
<Image
source={require('../assets/images/chatbot.png')}
style={{height: 150, width: 150, marginVertical: 10}}
/>
</View>
<Text style={{marginVertical: 10, fontSize: 22, textAlign: 'center', color:COLOR.greyFont, fontFamily:FONT.SemiBold}}>
Completed
</Text>
<Text style={{fontSize: 15, textAlign: 'center', color:COLOR.greyFont, fontFamily:FONT.Regular}}>
Overall Emotion: {predictResult.overalEmotion}
</Text>
<Text style={{fontSize: 15, textAlign: 'center', color:COLOR.greyFont, fontFamily:FONT.Regular}}>
Overall Score: {predictResult.overalScore}
</Text>
</ModalPoup>
<ChatHeader onPress={() => setVisible(true)}/>
<GiftedChat <GiftedChat
messages={messages.reverse()} messages={messages.reverse()}
onSend={msg => onSend(msg)} onSend={msg => onSend(msg)}
...@@ -157,7 +240,40 @@ const getChatForUser=async() => { ...@@ -157,7 +240,40 @@ const getChatForUser=async() => {
renderBubble={renderBubble} renderBubble={renderBubble}
renderSend={renderSend} renderSend={renderSend}
scrollToBottom scrollToBottom
textStyle={{color:'black'}}
renderInputToolbar={(props)=>{
return <InputToolbar {...props}
containerStyle={{borderTopWidth:1.5, borderTopColor:COLOR.primary}}
textInputStyle={{color:COLOR.greyFont}}/>
}}
/> />
</View> </View>
) )
} }
const styles = StyleSheet.create({
modalBackGround: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
width: '80%',
backgroundColor: 'white',
paddingHorizontal: 20,
paddingVertical: 30,
borderRadius: 20,
elevation: 20,
},
header: {
width: '100%',
height: 40,
alignItems: 'flex-end',
justifyContent: 'center',
},
});
\ No newline at end of file
...@@ -11,7 +11,7 @@ export const Home = () => { ...@@ -11,7 +11,7 @@ export const Home = () => {
<View style={styles.container}> <View style={styles.container}>
<Text style={{fontSize:20, fontFamily:FONT.Regular}}>Home</Text> <Text style={{fontSize:20, fontFamily:FONT.Regular}}>Home</Text>
<Button title="Chatbot" onPress={()=> navigation.navigate('Chatbot')}/> <Button title="Chatbot" onPress={()=> navigation.navigate('Chatbot')}/>
<Button title="Alan" onPress={()=> navigation.navigate('VoiceConversation')}/> {/* <Button title="Alan" onPress={()=> navigation.navigate('VoiceConversation')}/> */}
</View> </View>
); );
}; };
......
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {View, Text, ScrollView, TouchableHighlight, Image, StyleSheet, TextInput, TouchableOpacity} from 'react-native'; import {
import Voice from '@react-native-voice/voice'; View,
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' StyleSheet,
import { COLOR } from '../themes'; TextInput,
TouchableOpacity,
ScrollView,
Text,
ToastAndroid,
ImageBackground,
} from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import {COLOR, FONT} from '../themes';
import Voice from '`@react-native-community/voice`';
import {sendToRasa} from '../api/';
import {IMAGE} from '../assets/images/chatbotImage';
import Tts from 'react-native-tts';
import Lottie from 'lottie-react-native';
import {LogBox} from 'react-native';
export function VoiceConversation() { export function VoiceConversation() {
const [result, setResult] = useState('') LogBox.ignoreLogs(['new NativeEventEmitter']); // Ignore log notification by message
LogBox.ignoreAllLogs(); //Ignore all log notifications
Tts.setDefaultRate(0.4);
useEffect(() => { const [pitch, setPitch] = useState('');
Voice.onSpeechStart = onSpeechStartHandler; const [error, setError] = useState('');
Voice.onSpeechEnd = onSpeechEndHandler; const [end, setEnd] = useState(true);
Voice.onSpeechResults = onSpeechResultsHandler; const [started, setStarted] = useState(false);
const [reply, setReply] = useState('Hey, How are you?');
const [results, setResults] = useState(['Hi']);
const [partialResults, setPartialResults] = useState([]);
return()=>{ const BOT_USER = {
Voice.destroy().then(Voice.removeAllListeners); _id: 2,
} name: 'FAQ Bot',
}, []) avatar: IMAGE.chatbot,
};
const USER = {
_id: 1,
name: 'USER',
};
const onSpeechStartHandler = (e) =>{ const onSpeechStart = e => {
console,log("e>>>>", e) setStarted(true);
} };
const onSpeechEnd = () => {
setStarted(false);
setEnd(true);
setStarted(false);
};
const onSpeechError = e => {
setError(JSON.stringify(e.error));
};
const onSpeechResults = e => {
console.log(e.value[0]);
setResults(e.value[0]);
getReply(e.value[0]);
};
const onSpeechPartialResults = e => {
setPartialResults(e.value);
};
const onSpeechVolumeChanged = e => {
setPitch(e.value);
};
const onSpeechEndHandler = (e)=>{ useEffect(() => {
console,log("start handler", e) Voice.onSpeechStart = onSpeechStart;
} Voice.onSpeechEnd = onSpeechEnd;
Voice.onSpeechError = onSpeechError;
Voice.onSpeechResults = onSpeechResults;
Voice.onSpeechPartialResults = onSpeechPartialResults;
Voice.onSpeechVolumeChanged = onSpeechVolumeChanged;
const onSpeechResultsHandler = (e)=>{ return () => {
console,log("Result handler", e) stopSpeechRecognizing();
} };
}, []);
const startRecording = async() =>{ const getReply = async text => {
try{ console.log('hit');
await Voice.start('en-Us'); try {
console.log("hit") const res = await sendToRasa({message: text, sender: USER._id});
console.log(res)
if(res.data.length>0){
setReply(res.data[0].text);
Tts.getInitStatus().then(() => {
Tts.speak(res.data[0].text, {
androidParams: {
KEY_PARAM_PAN: -1,
KEY_PARAM_VOLUME: 0.5,
KEY_PARAM_STREAM: 'STREAM_MUSIC',
},
});
});
}else{
Tts.getInitStatus().then(() => {
Tts.speak("Cannot understand you", {
androidParams: {
KEY_PARAM_PAN: -1,
KEY_PARAM_VOLUME: 0.5,
KEY_PARAM_STREAM: 'STREAM_MUSIC',
},
});
});
} }
catch(err){ Tts.addEventListener('tts-finish', (event) => startSpeechRecognizing());
console.log('error raised', err) } catch (err) {
ToastAndroid.show(err, ToastAndroid.LONG);
} }
};
const startSpeechRecognizing = async () => {
setPitch('');
setError('');
setStarted(true);
// setReply('');
setResults([]);
setPartialResults([]);
setEnd(false);
try {
await Voice.start('en-US', {
EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS: 10000,
});
} catch (e) {
console.error(e);
} }
};
const stopRecording = async() =>{ const stopSpeechRecognizing = async () => {
try{ try {
await Voice.stop(); await Voice.stop();
setStarted(false);
} catch (e) {
console.error(e);
} }
catch(err){ };
console.log('error raised', err)
}
}
return ( return (
<View style={styles.container}> <View style={styles.container}>
<TextInput value={result} placeholder='your text here'> <ImageBackground style={styles.image}
</TextInput> resizeMode='cover'
<TouchableOpacity onPress={startRecording}> source={require('../assets/images/voice_background.jpg')}
<MaterialCommunityIcons name='microphone' size={40} color={COLOR.primary}/> imageStyle={{opacity:0.25}}
</TouchableOpacity> >
<TouchableOpacity onPress={stopRecording}> <View style={styles.hBox1}>
<MaterialCommunityIcons name='stop' size={40} color={COLOR.primary}/> <Text style={{fontFamily:FONT.SemiBold, fontSize:30,padding:5, backgroundColor:'white', borderRadius:50}}>Start the Conversation</Text>
</View>
<View style={styles.hBox2}>
{/* {partialResults.map((result, index) => {
return (
<Text key={`partial-result-${index}`} style={styles.message}>
{results}
</Text>
);
})} */}
<Text style={[styles.message, {color: COLOR.primary, padding:5, backgroundColor:'white', borderRadius:50}]}>{reply}</Text>
</View>
<View style={styles.hBox3}>
<Text style={styles.message}>Hi</Text>
<TouchableOpacity onPress={startSpeechRecognizing}>
<View style={{position: 'relative', alignItems:'center', paddingBottom:10}}>
{started ? (
<Lottie
style={styles.checkAnimation}
source={require('../assets/lottie/mic_animation.json')}
autoPlay
resizeMode="cover"
loop={true}
speed={1}
/>
) : (
<View style={{borderRadius:140, width:'100%', backgroundColor: COLOR.primary}}>
<MaterialCommunityIcons
name="microphone"
color={COLOR.white}
size={90}
/>
</View>
)}
</View>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</ImageBackground>
</View>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container:{ checkAnimation: {
width: '95%',
height: '95%',
marginLeft: 7,
marginTop: 10,
},
container: {
flex: 1,
padding: 20,
backgroundColor:'white',
flexDirection: 'column',
},
hBox1: {
flex: 2,
alignItems:'center',
// backgroundColor: 'red',
},
hBox2: {
flex: 3,
// backgroundColor: 'darkorange',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
},
hBox3: {
flex: 2,
// backgroundColor: 'green',
justifyContent: 'center',
alignItems: 'center',
},
message: {
fontFamily: FONT.SemiBold,
fontSize: 30,
color: 'black',
},
image:{
flex:1, flex:1,
justifyContent:'center', justifyContent:'center'
alignSelf:'center'
} }
}) });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment