diff --git a/__mocks__/api.ts b/__mocks__/api.ts
new file mode 100644
index 0000000..7cddfdc
--- /dev/null
+++ b/__mocks__/api.ts
@@ -0,0 +1,38 @@
+// __mocks__/api.ts
+
+import { language_matrix, language_matrix_entry } from "@/app/i18n/api";
+
+// Import the actual API module to extend its functionality
+const origApi = jest.requireActual('@/app/i18n/api.ts');
+
+class LanguageServer {
+ constructor(...args: any[]) { }
+ fetchLanguages(): language_matrix {
+ return {
+ "en" : { code: "en", name: "English", targets: ['fr', 'es'] },
+ "fr" : { code: "fr", name: "French", targets: ["en", "es"] },
+ "es": { code: "es", name: "Spanish", targets: ['fr', 'en'] },
+ }
+ }
+}
+
+class Translator {
+ constructor(...args : any []) {}
+ translate(message : string, target : string) {
+ return message;
+ }
+}
+
+class CachedTranslator extends Translator{
+
+}
+
+module.exports = {
+ ...origApi,
+ LanguageServer,
+ Translator,
+ CachedTranslator,
+ // Mock the specific functions you want to override
+ fetchData: jest.fn(() => Promise.resolve({ data: 'mocked data' })),
+ // Add more mock implementations as needed
+};
\ No newline at end of file
diff --git a/app/i18n/api.ts b/app/i18n/api.ts
index e25701b..c81a3a7 100644
--- a/app/i18n/api.ts
+++ b/app/i18n/api.ts
@@ -83,6 +83,12 @@ export class Translator {
console.log(data)
return data.translatedText
}
+
+ static async getDefault(defaultTarget: string | undefined = undefined) {
+ const settings = await Settings.getDefault();
+ const source = await settings.getHostLanguage();
+ return new Translator(source, defaultTarget, await LanguageServer.getDefault())
+ }
}
export class CachedTranslator extends Translator {
diff --git a/app/index.tsx b/app/index.tsx
index 8095b75..96f6119 100644
--- a/app/index.tsx
+++ b/app/index.tsx
@@ -4,6 +4,7 @@ import { Image, Text, View, StyleSheet, Button, Pressable } from "react-native";
import { LanguageServer, Translator, language_matrix_entry } from "./i18n/api";
import { Conversation } from "./lib/conversation";
import { LanguageSelection } from "@/components/LanguageSelection";
+import { Link } from 'expo-router';
function LogoTitle() {
return (
diff --git a/components/ConversationThread.tsx b/components/ConversationThread.tsx
index b2ff8e0..6972f58 100644
--- a/components/ConversationThread.tsx
+++ b/components/ConversationThread.tsx
@@ -67,6 +67,7 @@ const ConversationThread = ({ route } : {route?: Route<"Conversation", {conversa
return cachedTranslator ? (
+ Conversation Thread
translator?: Translator
- onLangSelected? : (lang : language_matrix_entry) => any
+ onLangSelected?: (lang: language_matrix_entry) => any
}) {
const [languages, setLanguages] = useState();
const [languagesLoaded, setLanguagesLoaded] = useState(false);
- const translator = props.translator || new CachedTranslator("en")
+ const languageServer = new LanguageServer(LIBRETRANSLATE_BASE_URL);
+ const translator = props.translator || new CachedTranslator("en", undefined, languageServer);
function onLangSelected(language: language_matrix_entry) {
props.onLangSelected && props.onLangSelected(language)
@@ -28,7 +30,7 @@ export function LanguageSelection(props: {
const fetchData = async () => {
try {
// Replace with your actual async data fetching logic
- const languages = await translator.fetchLanguages();
+ const languages = await languageServer.fetchLanguages();
setLanguages(languages);
setLanguagesLoaded(true);
} catch (error) {
@@ -41,20 +43,25 @@ export function LanguageSelection(props: {
}, []);
return (
-
-
-
- {(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map(
- ([lang, lang_entry]) => {
- return (
-
- );
+
+
+ Settings
+
+
+
+
+ {(languages && languagesLoaded) ? Object.entries(languages).filter((l) => (LANG_FLAGS as any)[l[0]] !== undefined).map(
+ ([lang, lang_entry]) => {
+ return (
+
+ );
+ }
+ ) : Waiting...
}
- ) : Waiting...
- }
-
-
-
+
+
+
+
)
}
diff --git a/components/TTNavStack.tsx b/components/TTNavStack.tsx
index ceb1a9a..f9130c4 100644
--- a/components/TTNavStack.tsx
+++ b/components/TTNavStack.tsx
@@ -2,16 +2,38 @@ import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import SettingsComponent from '@/components/Settings';
import { LanguageSelection } from '@/components/LanguageSelection';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { createNativeStackNavigator, NativeStackNavigationProp } from '@react-navigation/native-stack';
+import {
+ useNavigation,
+} from '@react-navigation/native'
import ConversationThread from '@/components/ConversationThread';
+import { language_matrix_entry, Translator } from '@/app/i18n/api';
+import { useRouter } from 'expo-router';
+import { Conversation } from '@/app/lib/conversation';
+import { Settings } from '@/app/lib/settings';
+import { RootStackParamList } from '@/navigation.types';
const Stack = createNativeStackNavigator();
export default function TTNavStack() {
+
+
+ async function onLangSelected(lang: language_matrix_entry) {
+ const nav = useNavigation>();
+ const settings = await Settings.getDefault();
+ const hostLanguage = await settings.getHostLanguage();
+ const conversation = new Conversation(
+ (await Translator.getDefault(lang.code)),
+ { id: "host", language: hostLanguage },
+ { "id": "guest", language: lang.code, }
+ )
+ nav.navigate("Conversation", { conversation, })
+ }
+
return (
-
+ } />
diff --git a/components/__tests__/index.spec.tsx b/components/__tests__/index.spec.tsx
index b551182..b576561 100644
--- a/components/__tests__/index.spec.tsx
+++ b/components/__tests__/index.spec.tsx
@@ -1,17 +1,11 @@
import {dirname, resolve} from 'path'
import React from 'react';
-import { fireEvent, render, screen } from '@testing-library/react-native';
-import { NavigationContainer } from '@react-navigation/native';
+import { act, fireEvent, render, screen } from '@testing-library/react-native';
import { createStackNavigator } from '@react-navigation/stack';
-import TTNavStack from '../TTNavStack';
-// Mock the expo-file-system/next module
-jest.mock('expo-file-system/next', () => ({
- File: jest.fn(),
- Paths: {
- join: jest.fn(),
- },
-}));
+jest.mock("@/app/i18n/api", () => require("../../__mocks__/api.ts"));
+
+import TTNavStack from '../TTNavStack';
const Stack = createStackNavigator();
@@ -23,15 +17,19 @@ describe('Navigation', () => {
it('Navigates to ConversationThread on language selection', async () => {
render();
- const languageSelectionText = await screen.findByText("Language Selection");
- fireEvent.press(languageSelectionText);
+ const languageSelectionText = await screen.findByText(/I Speak French\./i);
+ act(() => {
+ fireEvent.press(languageSelectionText);
+ })
expect(await screen.findByText("Conversation Thread")).toBeOnTheScreen();
});
it('Navigates to Settings on settings selection', async () => {
render();
const settingsButton = await screen.findByText("Settings");
- fireEvent.press(settingsButton);
+ act(() => {
+ fireEvent.press(settingsButton)
+ })
expect(await screen.findByText("Settings")).toBeOnTheScreen();
});
});
\ No newline at end of file
diff --git a/navigation.types.ts b/navigation.types.ts
new file mode 100644
index 0000000..05bc7c2
--- /dev/null
+++ b/navigation.types.ts
@@ -0,0 +1,11 @@
+// navigation.types.ts
+
+import { ParamListBase } from '@react-navigation/native';
+import { Conversation } from '@/app/lib/conversation';
+
+export type RootStackParamList = {
+ LanguageSelection: undefined;
+ ConversationThread: undefined;
+ Settings: undefined;
+ Conversation: { conversation: Conversation };
+};
\ No newline at end of file