166 lines
6.0 KiB
TypeScript
166 lines
6.0 KiB
TypeScript
// Import necessary packages
|
|
import React, { useState, useEffect } from "react";
|
|
import { View, Text, TextInput, StyleSheet, Pressable } from "react-native"; // Add Picker import
|
|
import { getDb } from "@/app/lib/db";
|
|
import { Settings } from "@/app/lib/settings";
|
|
import { LanguageServer } from "@/app/i18n/api";
|
|
import {Picker} from "@react-native-picker/picker"
|
|
import { longLang } from "@/app/i18n/lang";
|
|
import { LIBRETRANSLATE_BASE_URL } from "@/constants/api";
|
|
import { WHISPER_MODELS, downloadWhisperModel, download_status, getWhisperDownloadStatus, whisper_model_tag_t } from "@/app/lib/whisper";
|
|
|
|
type Language = {
|
|
code: string;
|
|
name: string;
|
|
};
|
|
|
|
type LanguageMatrix = {
|
|
[key: string]: Language;
|
|
};
|
|
|
|
const SettingsComponent: React.FC = () => {
|
|
const [hostLanguage, setHostLanguage] = useState<string | null>(null);
|
|
const [libretranslateBaseUrl, setLibretranslateBaseUrl] = useState<string | null>(null);
|
|
const [languages, setLanguages] = useState<undefined|LanguageMatrix>();
|
|
const [isLoaded, setIsLoaded] = useState<boolean>(false);
|
|
const [whisperModel, setWhisperModel] = useState<undefined|whisper_model_tag_t>()
|
|
const [downloadStatus, setDownloadStatus] = useState<undefined|download_status>();
|
|
|
|
useEffect(() => {
|
|
(async () => {
|
|
// Fetch the database connection
|
|
const db = await getDb();
|
|
const settings = new Settings(db);
|
|
|
|
// Get the current settings values
|
|
const hostLang = await settings.getHostLanguage();
|
|
const libretranslateUrl = await settings.getLibretranslateBaseUrl();
|
|
const langServer = new LanguageServer(libretranslateBaseUrl || LIBRETRANSLATE_BASE_URL);
|
|
const wModel = await settings.getWhisperModel()
|
|
|
|
// Fetch languages from API
|
|
const langData = await langServer.fetchLanguages();
|
|
setLanguages(langData);
|
|
setHostLanguage(hostLang || "en");
|
|
setLibretranslateBaseUrl(libretranslateUrl);
|
|
setWhisperModel(wModel);
|
|
setIsLoaded(true);
|
|
})();
|
|
|
|
// Check for whether a model is currently downloading and set the status.
|
|
setInterval(async () => {
|
|
if (!whisperModel) return null;
|
|
const dlStatus = await getWhisperDownloadStatus(whisperModel);
|
|
setDownloadStatus(dlStatus)
|
|
}, 200);
|
|
}, []);
|
|
|
|
const doReadownload = async () => {
|
|
if (!whisperModel) return;
|
|
await downloadWhisperModel(whisperModel, {force_redownload: true});
|
|
}
|
|
|
|
const doDownload = async () => {
|
|
if (!whisperModel) return;
|
|
await downloadWhisperModel(whisperModel)
|
|
}
|
|
|
|
const handleHostLanguageChange = async (value: string) => {
|
|
setHostLanguage(value);
|
|
|
|
// Fetch the database connection
|
|
const db = await getDb();
|
|
const settings = new Settings(db);
|
|
|
|
// Save the updated setting value
|
|
await settings.setHostLanguage(value);
|
|
};
|
|
|
|
const handleLibretranslateBaseUrlChange = async (value: string) => {
|
|
setLibretranslateBaseUrl(value);
|
|
|
|
// Fetch the database connection
|
|
const db = await getDb();
|
|
const settings = new Settings(db);
|
|
|
|
// Save the updated setting value
|
|
await settings.setLibretranslateBaseUrl(value);
|
|
};
|
|
|
|
return (
|
|
isLoaded ? <View style={styles.container}>
|
|
<Text style={styles.label}>Host Language:</Text>
|
|
<Picker
|
|
selectedValue={hostLanguage || ""}
|
|
style={{ height: 50, width: "100%" }}
|
|
onValueChange={handleHostLanguageChange}
|
|
accessibilityHint="language"
|
|
>
|
|
{languages && Object.keys(languages).map((langCode) => (
|
|
<Picker.Item key={langCode} label={longLang(langCode)} value={langCode} />
|
|
))}
|
|
</Picker>
|
|
|
|
<Text style={styles.label}>LibreTranslate Base URL:</Text>
|
|
<TextInput
|
|
style={styles.input}
|
|
value={libretranslateBaseUrl || ""}
|
|
onChangeText={handleLibretranslateBaseUrlChange}
|
|
accessibilityHint="libretranslate base url"
|
|
/>
|
|
<Picker
|
|
selectedValue={whisperModel || ""}
|
|
style={{ height: 50, width: "100%" }}
|
|
onValueChange={setWhisperModel}
|
|
accessibilityHint="language"
|
|
>
|
|
{Object.entries(WHISPER_MODELS).map(([key, {label}]) => (
|
|
<Picker.Item key={key} label={label} value={key} />
|
|
))}
|
|
</Picker>
|
|
{whisperModel && (
|
|
<View>
|
|
{
|
|
downloadStatus?.status === "complete" ? (
|
|
<Pressable onPress={doReadownload}>
|
|
Re-Download
|
|
</Pressable>
|
|
) : (
|
|
downloadStatus?.status === "in_progress" ? (
|
|
<Text>
|
|
{downloadStatus.bytes.done / downloadStatus.bytes.total * 100.0} % complete
|
|
{ downloadStatus.bytes.done } bytes of { downloadStatus.bytes.total }
|
|
</Text>
|
|
) : (
|
|
<Pressable onPress={doDownload}>
|
|
Download
|
|
</Pressable>
|
|
)
|
|
)
|
|
}
|
|
</View>
|
|
)}
|
|
</View> : <View><Text>Loading ...</Text></View>
|
|
);
|
|
};
|
|
|
|
// Create styles for the component
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
padding: 20,
|
|
},
|
|
label: {
|
|
fontSize: 16,
|
|
marginBottom: 8,
|
|
},
|
|
input: {
|
|
height: 40,
|
|
borderColor: "gray",
|
|
borderWidth: 1,
|
|
marginBottom: 20,
|
|
paddingHorizontal: 8,
|
|
},
|
|
});
|
|
|
|
export default SettingsComponent; |