TTs whisper

This commit is contained in:
2026-06-18 13:45:32 +02:00
parent 0e7fbbfdca
commit 9a23863320
57 changed files with 10430 additions and 253 deletions

View File

@@ -1,3 +1,4 @@
import { Picker } from "@react-native-picker/picker";
import { router } from "expo-router";
import { useEffect, useState } from "react";
import {
@@ -16,11 +17,20 @@ import {
loadRecorderSettings,
saveRecorderSettings,
} from "@/lib/recorder-settings";
import { AVAILABLE_LOCALES, t, type Locale, getStrings } from "@/lib/translations";
function localeLabel(locale: Locale) {
if (locale === "ca") return "Catal\u00e0";
if (locale === "en") return "English";
return locale;
}
export default function SettingsScreen() {
const [backendUrl, setBackendUrl] = useState("");
const [authToken, setAuthToken] = useState("");
const [fieldName, setFieldName] = useState("file");
const [language, setLanguage] = useState<Locale>("ca");
const [strings, setStrings] = useState(() => getStrings("ca"));
useEffect(() => {
let isMounted = true;
@@ -36,9 +46,11 @@ export default function SettingsScreen() {
setBackendUrl(settings.backendUrl);
setAuthToken(settings.authToken);
setFieldName(settings.fieldName);
setLanguage(settings.language);
setStrings(getStrings(settings.language));
} catch {
if (isMounted) {
Alert.alert("Settings error", "Could not load backend settings.");
Alert.alert(strings.loadError, strings.loadError);
}
}
}
@@ -50,19 +62,28 @@ export default function SettingsScreen() {
};
}, []);
const langStrings = getStrings(language);
async function handleSave() {
try {
await saveRecorderSettings({
authToken,
backendUrl,
fieldName,
language,
});
setStrings(getStrings(language));
router.back();
} catch {
Alert.alert("Save failed", "Could not save backend settings.");
Alert.alert(langStrings.saveError, langStrings.saveError);
}
}
function handleLanguageChange(val: Locale) {
setLanguage(val);
setStrings(getStrings(val));
}
return (
<SafeAreaView style={styles.safeArea}>
<KeyboardAvoidingView
@@ -76,54 +97,73 @@ export default function SettingsScreen() {
>
<View style={styles.headerRow}>
<Pressable onPress={() => router.back()} style={styles.navButton}>
<Text style={styles.navButtonText}>Back</Text>
<Text style={styles.navButtonText}>{langStrings.back}</Text>
</Pressable>
<Text style={styles.title}>Settings</Text>
<Text style={styles.title}>{langStrings.settingsTitle}</Text>
<Pressable onPress={handleSave} style={styles.navButton}>
<Text style={styles.navButtonText}>Save</Text>
<Text style={styles.navButtonText}>{langStrings.save}</Text>
</Pressable>
</View>
<View style={styles.panel}>
<Text style={styles.label}>Backend URL</Text>
<Text style={styles.label}>{langStrings.backendUrl}</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
keyboardType="url"
onChangeText={setBackendUrl}
placeholder="https://api.example.com/upload"
placeholder={langStrings.urlPlaceholder}
placeholderTextColor="#8f8a7c"
style={styles.input}
value={backendUrl}
/>
<Text style={styles.label}>Bearer token</Text>
<Text style={styles.label}>{langStrings.bearerToken}</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
onChangeText={setAuthToken}
placeholder="Optional"
placeholder={langStrings.tokenOptional}
placeholderTextColor="#8f8a7c"
secureTextEntry
style={styles.input}
value={authToken}
/>
<Text style={styles.label}>Form field name</Text>
<Text style={styles.label}>{langStrings.formFieldName}</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
onChangeText={setFieldName}
placeholder="file"
placeholder={langStrings.fieldNamePlaceholder}
placeholderTextColor="#8f8a7c"
style={styles.input}
value={fieldName}
/>
<Text style={styles.helperText}>
The recording is uploaded as multipart field `{fieldName.trim() || "file"}`.
{t("helperText", language, fieldName.trim() || "file")}
</Text>
</View>
<View style={styles.panel}>
<Text style={styles.label}>{langStrings.languageTitle}</Text>
<View style={styles.pickerWrapper}>
<Picker
selectedValue={language}
onValueChange={handleLanguageChange}
style={styles.picker}
>
{AVAILABLE_LOCALES.map((loc) => (
<Picker.Item
key={loc}
label={localeLabel(loc)}
value={loc}
/>
))}
</Picker>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
@@ -199,4 +239,14 @@ const styles = StyleSheet.create({
fontSize: 13,
lineHeight: 18,
},
pickerWrapper: {
backgroundColor: "#f7f0e0",
borderColor: "#d9ccb5",
borderRadius: 16,
borderWidth: 1,
overflow: "hidden",
},
picker: {
height: 50,
},
});