Skip to content

Instantly share code, notes, and snippets.

@kkemple
Created September 25, 2019 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkemple/13a19b1342610c5e548b1acd8ef365a9 to your computer and use it in GitHub Desktop.
Save kkemple/13a19b1342610c5e548b1acd8ef365a9 to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from "react";
import {
TouchableOpacity,
View,
KeyboardAvoidingView,
Modal,
ScrollView,
StyleSheet,
StatusBar
} from "react-native";
import { Input, ListItem } from "react-native-elements";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { Predictions } from "aws-amplify";
import { SafeAreaView } from "react-navigation";
import styled from "@emotion/native";
import Colors from "../constants/Colors";
const options = {
en: {
title: "English",
voice: "Salli"
},
fr: {
title: "French",
voice: "Chantal"
},
es: {
title: "Spanish",
voice: "Penelope"
},
pt: {
title: "Portugese",
voice: "Vitoria"
},
zh: {
title: "Chinese",
voice: "Zhiyu"
},
ar: {
title: "Arabic",
voice: "Zeina"
},
da: {
title: "Danish",
voice: "Naja"
},
nl: {
title: "Dutch",
voice: "Lotte"
},
hi: {
title: "Hindi",
voice: "Aditi"
},
it: {
title: "Italian",
voice: "Carla"
},
ja: {
title: "Japanese",
voice: "Mizuki"
},
ko: {
title: "Korean",
voice: "Seoyeon"
},
no: {
title: "Norwegian",
voice: "Liv"
},
pl: {
title: "Polish",
voice: "Ewa"
},
ru: {
title: "Russian",
voice: "Tatyana"
},
sv: {
title: "Swedish",
voice: "Astrid"
},
tr: {
title: "Turkish",
voice: "Filiz"
}
};
const suggestions = [
"Does this go to ",
"Do you speak ",
"Where is the bathroom?",
"Check, please!",
"Do you take credit cards?",
"Is tip included?",
"Please",
"Thank you",
"Excuse me",
"Call the ambulance",
"I am hurt",
"I need a hospital",
"Call the police"
];
const ListenButton = styled.TouchableOpacity`
align-items: center;
background-color: ${Colors.grey["0"]};
border-radius: 32px;
bottom: 16px;
box-shadow: 1px 1px 1px ${Colors.shadow};
height: 64px;
justify-content: center;
margin: 8px;
position: absolute;
right: 16px;
width: 64px;
`;
const Container = styled.View`
flex: 1;
padding: 24px;
justify-content: flex-start;
`;
const LanguageOptions = styled.View`
justify-content: flex-start;
align-items: center;
flex-direction: row;
padding-horizontal: 10px;
`;
const LanguageOption = styled.TouchableOpacity``;
const LanguageOptionText = styled.Text`
text-align: center;
font-family: montserrat-bold;
color: ${Colors.primary["500"]};
`;
const LanguageContainer = styled.View`
padding: 10px;
flex: 1;
`;
const TranslatedText = styled.Text`
color: ${Colors.primary["600"]};
font-family: "montserrat-extra-bold";
font-size: 24px;
`;
export default function TranslateScreen() {
const [showSuggestionsPicker, setShowSuggestionsPicker] = useState(false);
const [showFromLanguagePicker, setShowFromLanguagePicker] = useState(false);
const [showToLanguagePicker, setShowToLanguagePicker] = useState(false);
const [selectedFromLanguage, setSelectedFromLanguage] = useState("en");
const [selectedToLanguage, setSelectedToLanguage] = useState("es");
const [textToTranslate, setTextToTranslate] = useState("");
const [translatedText, setTranslatedText] = useState("");
const playAudio = async () => {
try {
const result = await Predictions.convert({
textToSpeech: {
source: {
text: translatedText,
language: selectedToLanguage
},
voiceId: options[selectedToLanguage].voice
}
});
// const response = await fetch(`${result.speech.url}`, {
// responseType: "arrayBuffer"
// });
// const blob = await response.blob();
// const localUri = `${FileSystem.cacheDirectory}${uuid()}.mp3`;
// await FileSystem.writeAsStringAsync(localUri, blob);
// const { sound: soundObject, status } = await Audio.Sound.createAsync(
// { uri: localUri },
// { shouldPlay: true }
// );
console.log({ result });
} catch (error) {
console.log(error);
}
};
useEffect(() => {
const translate = async () => {
try {
if (textToTranslate.length < 2) {
setTranslatedText("");
return;
}
const result = await Predictions.convert({
translateText: {
source: {
text: textToTranslate,
language: selectedFromLanguage
},
targetLanguage: selectedToLanguage
}
});
setTranslatedText(result.text);
} catch (error) {
console.log(error);
}
};
translate();
}, [
textToTranslate,
setTextToTranslate,
selectedFromLanguage,
selectedToLanguage,
setSelectedToLanguage,
setSelectedFromLanguage
]);
return (
<React.Fragment>
<StatusBar barStyle="dark-content" />
<KeyboardAvoidingView style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1 }}>
<Container>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 16
}}
>
<View>
<LanguageOptions>
<LanguageOption
onPress={() => setShowFromLanguagePicker(true)}
>
<LanguageOptionText>
{options[selectedFromLanguage].title}
</LanguageOptionText>
</LanguageOption>
<View style={{ paddingHorizontal: 8 }}>
<MaterialCommunityIcons
style={{ marginBottom: -2 }}
size={16}
name="arrow-right"
color={Colors.primary["500"]}
/>
</View>
<LanguageOption onPress={() => setShowToLanguagePicker(true)}>
<LanguageOptionText>
{options[selectedToLanguage].title}
</LanguageOptionText>
</LanguageOption>
</LanguageOptions>
</View>
<View>
<LanguageOption onPress={() => setShowSuggestionsPicker(true)}>
<LanguageOptionText>
Suggested{" "}
<MaterialCommunityIcons
name="chevron-down"
color={Colors.primary["500"]}
/>
</LanguageOptionText>
</LanguageOption>
</View>
</View>
<View>
<Input
autoFocus
multiline
blurOnSubmit
returnKeyType="done"
placeholder="Translate"
value={textToTranslate}
onChangeText={text => setTextToTranslate(text)}
inputContainerStyle={styles.inputContainerStyle}
inputStyle={styles.inputStyle}
/>
</View>
<View style={{ flex: 1 }}>
<LanguageContainer>
<TranslatedText>{translatedText}</TranslatedText>
</LanguageContainer>
</View>
{/* <ListenButton onPress={playAudio}>
<Icon
size={28}
name="ear-hearing"
type="material-community"
color={Colors.primary["500"]}
/>
</ListenButton> */}
</Container>
</SafeAreaView>
</KeyboardAvoidingView>
<Modal visible={showFromLanguagePicker} animationType="slide">
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{ paddingVertical: 24 }}
>
{Object.keys(options).map(option => (
<TouchableOpacity
key={option}
onPress={() => {
setSelectedFromLanguage(option);
setShowFromLanguagePicker(false);
}}
>
<ListItem
titleStyle={{
fontFamily: "montserrat-bold",
color: Colors.primary["500"]
}}
bottomDivider
title={options[option].title}
/>
</TouchableOpacity>
))}
</ScrollView>
</SafeAreaView>
</Modal>
<Modal visible={showToLanguagePicker} animationType="slide">
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{ paddingVertical: 24 }}
>
{Object.keys(options).map(option => (
<TouchableOpacity
key={option}
onPress={() => {
setSelectedToLanguage(option);
setShowToLanguagePicker(false);
}}
>
<ListItem
titleStyle={{
fontFamily: "montserrat-bold",
color: Colors.primary["500"]
}}
bottomDivider
title={options[option].title}
/>
</TouchableOpacity>
))}
</ScrollView>
</SafeAreaView>
</Modal>
<Modal visible={showSuggestionsPicker} animationType="slide">
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{ paddingVertical: 24 }}
>
{suggestions.map(option => (
<TouchableOpacity
key={option}
onPress={() => {
setTextToTranslate(option);
setShowSuggestionsPicker(false);
}}
>
<ListItem
titleStyle={{
fontFamily: "montserrat-bold",
color: Colors.primary["500"]
}}
bottomDivider
title={option}
/>
</TouchableOpacity>
))}
</ScrollView>
</SafeAreaView>
</Modal>
</React.Fragment>
);
}
TranslateScreen.navigationOptions = {
header: null
};
const styles = StyleSheet.create({
inputContainerStyle: {
borderBottomWidth: 1,
borderBottomColor: Colors.primary["300"],
paddingVertical: 8,
alignItems: "flex-start"
},
inputStyle: {
fontSize: 24,
color: Colors.primary["600"],
fontFamily: "montserrat-bold",
paddingTop: 0,
alignSelf: "flex-start",
minHeight: 20
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment