fix issues. Remove babel.

This commit is contained in:
Jordan 2025-02-01 08:58:03 -08:00
parent 5c5cf48f6e
commit 718d8e034f
17 changed files with 4268 additions and 6422 deletions

View File

@ -1,57 +0,0 @@
import React, { useEffect } from 'react';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { ThemeProvider, DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
import Settings from '@/components/Settings';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from '.';
import { LanguageSelection } from '@/components/LanguageSelection';
import { language_matrix_entry } from '../i18n/api';
import ConversationThread from '@/components/ConversationThread';
const Stack = createNativeStackNavigator();
export default function _layout() {
const [loaded] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
});
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
}
}, [loaded]);
if (!loaded) {
return null;
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Welcome'}}
/>
<Stack.Screen
name="LanguageSelection"
component={LanguageSelection}
/>
<Stack.Screen
name="Conversation"
component={ConversationThread}
/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
settingsIconContainer: {
marginLeft: 16,
},
});

View File

@ -1,45 +0,0 @@
import { LanguageSelection } from '@/components/LanguageSelection';
import { useState } from 'react';
import { Button, Text, View } from 'react-native';
import { Image, StyleSheet, Platform } from 'react-native';
import { Conversation, Speaker } from '../lib/conversation';
import { language_matrix_entry, Translator } from '../i18n/api';
import ConversationThread from '@/components/ConversationThread';
import { NavigationContainerProps, NavigationProp, ParamListBase } from '@react-navigation/native';
export default function HomeScreen({navigation} : {navigation: NavigationProp<ParamListBase>}) {
const [language, setLanguage] = useState<language_matrix_entry | undefined>()
const [conversation, setConversation] = useState<Conversation | undefined>();
return (
conversation ? <ConversationThread conversation={conversation} /> :
<View>
<Button
title="Settings"
onPress={() =>
navigation.navigate('Settings')
}
/>
</View>
);
}
const styles = StyleSheet.create({
titleContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
stepContainer: {
gap: 8,
marginBottom: 8,
},
reactLogo: {
height: 178,
width: 290,
bottom: 0,
left: 0,
position: 'absolute',
},
});

View File

@ -1,25 +0,0 @@
import { Link, Stack } from 'expo-router';
import { StyleSheet } from 'react-native';
import { ThemedText } from '@/components/ThemedText';
import { Text } from 'react-native';
export default function NotFoundScreen() {
return (
<>
<Text>Not Found</Text>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
link: {
marginTop: 15,
paddingVertical: 15,
},
});

View File

@ -1,38 +1,17 @@
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router'; import { Stack } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import { StatusBar } from 'expo-status-bar';
import { useEffect } from 'react';
import 'react-native-reanimated';
import { useColorScheme } from '@/hooks/useColorScheme';
// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
const colorScheme = useColorScheme();
const [loaded] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
});
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
}
}, [loaded]);
if (!loaded) {
return null;
}
export default function Layout() {
return ( return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> <Stack
<Stack> screenOptions={{
<Stack.Screen name="(screens)" options={{ headerShown: false }} /> headerStyle: {
<Stack.Screen name="+not-found" /> backgroundColor: '#f4511e',
</Stack> },
</ThemeProvider> headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
/>
); );
} }

67
app/index.tsx Normal file
View File

@ -0,0 +1,67 @@
import { LanguageSelection } from "@/components/LanguageSelection";
import { Link, Stack } from "expo-router";
import { useState } from "react";
import { Image, Text, View, StyleSheet } from "react-native";
import { Translator, language_matrix_entry } from "./i18n/api";
import ConversationThread from "@/components/ConversationThread";
import { Conversation } from "./lib/conversation";
function LogoTitle() {
return (
<Image
style={styles.image}
source={{ uri: "https://reactnative.dev/img/tiny_logo.png" }}
/>
);
}
export default function Home() {
const [lang, setLang] = useState<language_matrix_entry | undefined>();
const [conversation, setConversation] = useState<Conversation | undefined>();
function onLangSelected(lang: language_matrix_entry | undefined) {
console.log("Language %s selected", lang?.code);
setLang(lang);
if (!lang?.code) return;
setConversation(
new Conversation(
new Translator("en", lang.code),
{ id: "host", language: "en" },
{ id: "guest", language: lang.code }
)
);
}
return (
<View style={styles.container}>
<Stack.Screen
options={{
title: "My home",
headerStyle: { backgroundColor: "#f4511e" },
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold",
},
}}
/>
<Text>Home Screen</Text>
{conversation ? (
<ConversationThread conversation={conversation} />
) : (
<LanguageSelection onLangSelected={onLangSelected} />
)}
)
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "flex-start",
},
image: {
width: 50,
height: 50,
},
});

View File

@ -30,8 +30,8 @@ export class Message {
export class Conversation extends Array<Message> { export class Conversation extends Array<Message> {
public onAddMessage? : (conversation : Conversation) => Promise<any>; public onAddMessage? : (conversation : Conversation) => any;
public onTranslationDone? : (conversation : Conversation) => Promise<any>; public onTranslationDone? : (conversation : Conversation) => any;
constructor ( constructor (
private translator : Translator, private translator : Translator,

18
app/settings.tsx Normal file
View File

@ -0,0 +1,18 @@
import {StyleSheet, Text, View} from "react-native";
export type SettingsScreenProps = {
};
export const SettingsScreen = (props: SettingsScreenProps) => {
return (
<View style={styles.wrapper}>
<Text>Settings Here</Text>
</View>
)
};
export const styles = StyleSheet.create({
wrapper: {
}
});

View File

@ -1,6 +0,0 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};

View File

@ -10,31 +10,22 @@ interface ConversationThreadProps {
conversation: Conversation; conversation: Conversation;
} }
const ConversationThread = ({ language, navigation }: { language: language_matrix_entry, navigation: NavigationProp<ParamListBase> }) => { const ConversationThread = (p : ConversationThreadProps) => {
const [messages, setMessages] = useState<Message[]>([]); const [messages, setMessages] = useState<Message[]>([]);
useEffect(async () => {
const db = await getDb();
const curs = await db.executeSql("SELECT host_language FROM settings LIMIT 1");
})
const translator = new Translator()
const conversation = new Conversation()
useEffect(() => { useEffect(() => {
const updateMessages = () => { const updateMessages = (c : Conversation) => {
setMessages([...conversation]); setMessages([...c]);
}; };
conversation.on('messageAdded', updateMessages); p.conversation.onAddMessage = updateMessages;
conversation.on('messageUpdated', updateMessages); p.conversation.onTranslationDone = updateMessages;
return () => { return () => {
conversation.off('messageAdded', updateMessages); p.conversation.onAddMessage = undefined;
conversation.off('messageUpdated', updateMessages); p.conversation.onTranslationDone = undefined;
}; };
}, [conversation]); }, [p.conversation]);
const renderMessages = () => ( const renderMessages = () => (
messages.map((message, index) => ( messages.map((message, index) => (

View File

@ -10,8 +10,9 @@ import { NavigationProp, ParamListBase } from "@react-navigation/native";
export function LanguageSelection(props: { export function LanguageSelection(props: {
navigation: NavigationProp<ParamListBase> navigation?: NavigationProp<ParamListBase>
translator?: Translator translator?: Translator
onLangSelected? : (lang : language_matrix_entry) => any
}) { }) {
const [languages, setLanguages] = useState<language_matrix | undefined>(); const [languages, setLanguages] = useState<language_matrix | undefined>();
const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false); const [languagesLoaded, setLanguagesLoaded] = useState<boolean>(false);
@ -19,7 +20,7 @@ export function LanguageSelection(props: {
const translator = props.translator || new CachedTranslator("en") const translator = props.translator || new CachedTranslator("en")
function onLangSelected(language: language_matrix_entry) { function onLangSelected(language: language_matrix_entry) {
props.navigation.navigate("Conversation", { language, }) props.onLangSelected && props.onLangSelected(language)
} }
@ -45,9 +46,7 @@ export function LanguageSelection(props: {
{(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map( {(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map(
([lang, lang_entry]) => { ([lang, lang_entry]) => {
return ( return (
<View style={styles.column}> <ISpeakButton language={lang_entry} key={lang_entry.code} onLangSelected={onLangSelected} />
<ISpeakButton language={lang_entry} key={lang_entry.code} onLangSelected={onLangSelected} />
</View>
); );
} }
) : <Text>Waiting...</Text> ) : <Text>Waiting...</Text>
@ -63,8 +62,6 @@ const styles = StyleSheet.create({
flex: 1, flex: 1,
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'wrap', flexWrap: 'wrap',
flexBasis: "auto",
flexGrow: 1,
padding: 8, padding: 8,
}, },
}) })

View File

@ -76,7 +76,7 @@ const ISpeakButton = (props : ISpeakButtonProps) => {
return ( return (
title ? ( title ? (
<TouchableOpacity style={styles.button}> <TouchableOpacity style={styles.button} onPress={() => props.onLangSelected && props.onLangSelected(props.language)}>
<View> <View>
<View style={styles.flag}> <View style={styles.flag}>
{countries && {countries &&
@ -105,7 +105,8 @@ const styles = StyleSheet.create({
borderWidth: 1, borderWidth: 1,
borderStyle: "solid", borderStyle: "solid",
height: 110, height: 110,
alignContent: 'flex-start', alignSelf: "flex-start",
margin: 8,
}, },
flag: { flag: {
}, },

View File

@ -6,7 +6,6 @@ import { SafeAreaView } from "react-native-safe-area-context";
type MessageProps = { type MessageProps = {
message: Message; message: Message;
translator: Translator;
} }
const MessageBubble = (props: MessageProps) => { const MessageBubble = (props: MessageProps) => {
@ -20,7 +19,7 @@ const MessageBubble = (props: MessageProps) => {
props.message.onTextDone = async (message: Message) => { props.message.onTextDone = async (message: Message) => {
setIsTranslating(true); setIsTranslating(true);
await props.message.translate(props.translator) await props.message.translate()
} }
props.message.onTranslationDone = (message: Message) => { props.message.onTranslationDone = (message: Message) => {

View File

@ -1 +1 @@
export const LIBRETRANSLATE_BASE_URL = process.env.LIBRETRANSALTE_BASE_URL || "http://localhost:5000" export const LIBRETRANSLATE_BASE_URL = process.env.LIBRETRANSALTE_BASE_URL || "https://translate.flossboxin.org.in" || "http://localhost:5000"

View File

@ -10,18 +10,6 @@ const jestConfig = {
moduleNameMapper: { moduleNameMapper: {
'@': "<rootDir>" '@': "<rootDir>"
}, },
transformIgnorePatterns: [
'node_modules/(?!' +
[
'@cspotcode',
'node-fetch',
'fetch-blob',
'data-uri-to-buffer',
'jest-runtime',
'formdata-polyfill'
].join('|') +
')',
],
} }
export default jestConfig export default jestConfig

View File

@ -7,19 +7,18 @@
"reset-project": "node ./scripts/reset-project.js", "reset-project": "node ./scripts/reset-project.js",
"android": "expo start --android", "android": "expo start --android",
"ios": "expo start --ios", "ios": "expo start --ios",
"web": "expo start --localhost --web", "web": "expo start --offline --web",
"test": "jest --watchAll", "test": "jest --watchAll",
"lint": "expo lint" "lint": "expo lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.26.7", "@babel/runtime": "^7.26.7",
"@expo/vector-icons": "^14.0.2", "@expo/vector-icons": "^14.0.4",
"@mmomtchev/react-native-settings": "^1.1.0", "@mmomtchev/react-native-settings": "^1.1.0",
"@react-native-async-storage/async-storage": "^2.1.0", "@react-native-async-storage/async-storage": "^2.1.0",
"@react-navigation/bottom-tabs": "^7.2.0", "@react-navigation/bottom-tabs": "^7.2.0",
"@react-navigation/native": "^7.0.14", "@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0", "@react-navigation/native-stack": "^7.2.0",
"expo": "~52.0.28",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.5", "expo-constants": "~17.0.5",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
@ -28,7 +27,7 @@
"expo-router": "~4.0.17", "expo-router": "~4.0.17",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.1", "expo-symbols": "~0.2.2",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
@ -37,7 +36,7 @@
"react-native-cache": "^2.0.3", "react-native-cache": "^2.0.3",
"react-native-country-flag": "^2.0.2", "react-native-country-flag": "^2.0.2",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
"react-native-reanimated": "~3.16.1", "react-native-reanimated": "~3.16.7",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0", "react-native-screens": "~4.4.0",
"react-native-sqlite-storage": "^6.0.1", "react-native-sqlite-storage": "^6.0.1",
@ -45,21 +44,22 @@
"react-native-webview": "13.12.5" "react-native-webview": "13.12.5"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.26.7",
"@babel/preset-typescript": "^7.26.0", "@babel/preset-typescript": "^7.26.0",
"@jest/globals": "^29.7.0", "@jest/globals": "^29.7.0",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.14",
"@types/react": "~18.3.12", "@types/react": "~18.3.18",
"@types/react-native-sqlite-storage": "^6.0.5", "@types/react-native-sqlite-storage": "^6.0.5",
"@types/react-test-renderer": "^18.3.0", "@types/react-test-renderer": "^18.3.1",
"babel-jest": "^29.7.0", "babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"jest": "^29.2.1", "expo": "~52.0.28",
"jest": "^29.7.0",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"metro-react-native-babel-preset": "^0.77.0", "metro-react-native-babel-preset": "^0.77.0",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"ts-jest": "^29.2.5", "ts-jest": "^29.2.5",
"typescript": "^5.3.3" "typescript": "^5.7.3"
}, },
"private": true "private": true
} }

10343
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff