Feat: Settings for learning lang (#641)
* refactor settings * refactor constants * add settings for native/learning language * setup langugage for transcribe * use 2 letter code for echogarden * AI commands support multiple language * update languages constant * fix sentry error * fix context menu * show camdict when only learning English * add en-GB * recording assess support multiple languages * fix ai command * refactor
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { useContext } from "react";
|
||||
import { MediaPlayerProviderContext } from "@renderer/context";
|
||||
import {
|
||||
AppSettingsProviderContext,
|
||||
MediaPlayerProviderContext,
|
||||
} from "@renderer/context";
|
||||
import { TabsContent, Separator } from "@renderer/components/ui";
|
||||
import { t } from "i18next";
|
||||
import { TimelineEntry } from "echogarden/dist/utilities/Timeline";
|
||||
@@ -38,6 +41,7 @@ const SelectedWords = (props: {
|
||||
const { selectedIndices, caption } = props;
|
||||
|
||||
const { transcription, ipaMappings } = useContext(MediaPlayerProviderContext);
|
||||
const { learningLanguage } = useContext(AppSettingsProviderContext);
|
||||
|
||||
const word = selectedIndices
|
||||
.map((index) => caption.timeline[index]?.text || "")
|
||||
@@ -92,8 +96,12 @@ const SelectedWords = (props: {
|
||||
})}
|
||||
</div>
|
||||
|
||||
<Separator className="my-2" />
|
||||
<CamdictLookupResult word={word} />
|
||||
{learningLanguage.startsWith("en") && (
|
||||
<>
|
||||
<Separator className="my-2" />
|
||||
<CamdictLookupResult word={word} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Separator className="my-2" />
|
||||
<AiLookupResult
|
||||
|
||||
@@ -5,9 +5,12 @@ export * from "./appearance";
|
||||
export * from "./hotkeys";
|
||||
export * from "./hotkeys-settings";
|
||||
|
||||
export * from "./language-settings";
|
||||
export * from "./native-language-settings";
|
||||
export * from "./learning-language-settings";
|
||||
|
||||
export * from "./default-engine-settings";
|
||||
export * from "./openai-settings";
|
||||
export * from "./language-settings";
|
||||
export * from "./library-settings";
|
||||
export * from "./whisper-settings";
|
||||
export * from "./google-generative-ai-settings";
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { t } from "i18next";
|
||||
import {
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectItem,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
} from "@renderer/components/ui";
|
||||
import { AppSettingsProviderContext } from "@renderer/context";
|
||||
import { useContext } from "react";
|
||||
import { LANGUAGES } from "@/constants";
|
||||
|
||||
export const LearningLanguageSettings = () => {
|
||||
const { learningLanguage, switchLearningLanguage } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex items-start justify-between py-4">
|
||||
<div className="">
|
||||
<div className="mb-2">{t("learningLanguage")}</div>
|
||||
<div className="text-sm text-muted-foreground mb-2">
|
||||
{LANGUAGES.find((lang) => lang.code === learningLanguage)?.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="flex items-center justify-end space-x-2 mb-2">
|
||||
<Select
|
||||
value={learningLanguage}
|
||||
onValueChange={(value) => {
|
||||
switchLearningLanguage(value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="text-xs">
|
||||
<SelectValue>
|
||||
{LANGUAGES.find((lang) => lang.code === learningLanguage)?.name}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{LANGUAGES.map((lang) => (
|
||||
<SelectItem
|
||||
className="text-xs"
|
||||
value={lang.code}
|
||||
key={lang.code}
|
||||
>
|
||||
{lang.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
import { t } from "i18next";
|
||||
import {
|
||||
Select,
|
||||
SelectTrigger,
|
||||
SelectItem,
|
||||
SelectValue,
|
||||
SelectContent,
|
||||
} from "@renderer/components/ui";
|
||||
import { AppSettingsProviderContext } from "@renderer/context";
|
||||
import { useContext } from "react";
|
||||
import { LANGUAGES } from "@/constants";
|
||||
|
||||
export const NativeLanguageSettings = () => {
|
||||
const { nativeLanguage, switchNativeLanguage } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex items-start justify-between py-4">
|
||||
<div className="">
|
||||
<div className="mb-2">{t("nativeLanguage")}</div>
|
||||
<div className="text-sm text-muted-foreground mb-2">
|
||||
{LANGUAGES.find((lang) => lang.code === nativeLanguage)?.name}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="flex items-center justify-end space-x-2 mb-2">
|
||||
<Select
|
||||
value={nativeLanguage}
|
||||
onValueChange={(value) => {
|
||||
switchNativeLanguage(value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="text-xs">
|
||||
<SelectValue>
|
||||
{LANGUAGES.find((lang) => lang.code === nativeLanguage)?.name}
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{LANGUAGES.map((lang) => (
|
||||
<SelectItem
|
||||
className="text-xs"
|
||||
value={lang.code}
|
||||
key={lang.code}
|
||||
>
|
||||
{lang.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -14,6 +14,8 @@ import {
|
||||
GoogleGenerativeAiSettings,
|
||||
ResetSettings,
|
||||
ResetAllSettings,
|
||||
NativeLanguageSettings,
|
||||
LearningLanguageSettings,
|
||||
} from "@renderer/components";
|
||||
import { useState } from "react";
|
||||
import { Tooltip } from "react-tooltip";
|
||||
@@ -29,6 +31,10 @@ export const Preferences = () => {
|
||||
<div className="font-semibold mb-4 capitilized">
|
||||
{t("basicSettings")}
|
||||
</div>
|
||||
<NativeLanguageSettings />
|
||||
<Separator />
|
||||
<LearningLanguageSettings />
|
||||
<Separator />
|
||||
<WhisperSettings />
|
||||
<Separator />
|
||||
<DefaultEngineSettings />
|
||||
@@ -108,8 +114,9 @@ export const Preferences = () => {
|
||||
key={tab.value}
|
||||
variant={activeTab === tab.value ? "default" : "ghost"}
|
||||
size="sm"
|
||||
className={`capitilized w-full justify-start mb-2 ${activeTab === tab.value ? "" : "hover:bg-muted"
|
||||
}`}
|
||||
className={`capitilized w-full justify-start mb-2 ${
|
||||
activeTab === tab.value ? "" : "hover:bg-muted"
|
||||
}`}
|
||||
onClick={() => setActiveTab(tab.value)}
|
||||
>
|
||||
<span className="text-sm">{tab.label}</span>
|
||||
|
||||
@@ -21,12 +21,12 @@ export const RecordingDetail = (props: { recording: RecordingType }) => {
|
||||
}>();
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const { EnjoyApp, learningLanguage } = useContext(AppSettingsProviderContext);
|
||||
const [assessing, setAssessing] = useState(false);
|
||||
|
||||
const assess = () => {
|
||||
setAssessing(true);
|
||||
EnjoyApp.recordings.assess(recording.id).finally(() => {
|
||||
EnjoyApp.recordings.assess(recording.id, learningLanguage).finally(() => {
|
||||
setAssessing(false);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ import { t } from "i18next";
|
||||
import { md5 } from "js-md5";
|
||||
|
||||
export const LookupWidget = () => {
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const { EnjoyApp, learningLanguage } = useContext(AppSettingsProviderContext);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selected, setSelected] = useState<{
|
||||
word: string;
|
||||
@@ -82,8 +82,12 @@ export const LookupWidget = () => {
|
||||
{selected?.word}
|
||||
</div>
|
||||
<div className="px-4">
|
||||
<CamdictLookupResult word={selected?.word} />
|
||||
<Separator className="my-2" />
|
||||
{learningLanguage.startsWith("en") && (
|
||||
<>
|
||||
<CamdictLookupResult word={selected?.word} />
|
||||
<Separator className="my-2" />
|
||||
</>
|
||||
)}
|
||||
<AiLookupResult
|
||||
word={selected?.word}
|
||||
context={selected?.context}
|
||||
|
||||
Reference in New Issue
Block a user