summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/gui/app.go29
-rw-r--r--internal/processor/processor.go28
2 files changed, 47 insertions, 10 deletions
diff --git a/internal/gui/app.go b/internal/gui/app.go
index f9d941d..666c763 100644
--- a/internal/gui/app.go
+++ b/internal/gui/app.go
@@ -127,6 +127,11 @@ type Config struct {
TranslationProvider translation.Provider
PhoneticProvider phonetic.Provider
AutoPlay bool // Whether to automatically play audio when generated or navigated to
+
+ // Injectable dependencies — when non-nil, New() uses them directly instead of
+ // constructing new instances from the provider/key fields above.
+ PhoneticFetcher *phonetic.Fetcher
+ Translator *translation.Translator
}
const (
@@ -221,12 +226,24 @@ func New(config *Config) *Application {
// Set up audio configuration
app.audioConfig = audioConfigForApp(config)
- app.phoneticFetcher = phonetic.NewFetcher(&phonetic.Config{
- Provider: config.PhoneticProvider,
- OpenAIKey: config.OpenAIKey,
- GoogleAPIKey: config.GoogleAPIKey,
- })
- app.translator = translation.NewTranslator(translationConfigForApp(config))
+
+ // Use injected phonetic fetcher when provided; otherwise construct from config fields.
+ if config.PhoneticFetcher != nil {
+ app.phoneticFetcher = config.PhoneticFetcher
+ } else {
+ app.phoneticFetcher = phonetic.NewFetcher(&phonetic.Config{
+ Provider: config.PhoneticProvider,
+ OpenAIKey: config.OpenAIKey,
+ GoogleAPIKey: config.GoogleAPIKey,
+ })
+ }
+
+ // Use injected translator when provided; otherwise construct from config fields.
+ if config.Translator != nil {
+ app.translator = config.Translator
+ } else {
+ app.translator = translation.NewTranslator(translationConfigForApp(config))
+ }
app.setupUI()
diff --git a/internal/processor/processor.go b/internal/processor/processor.go
index 54c99c3..c79e892 100644
--- a/internal/processor/processor.go
+++ b/internal/processor/processor.go
@@ -714,19 +714,39 @@ func (p *Processor) guiConfigForRunMode() *gui.Config {
imageProvider = gui.DefaultConfig().ImageProvider
}
+ openAIKey := cli.GetOpenAIKey()
+ googleAPIKey := cli.GetGoogleAPIKey()
+ translationProvider := translation.Provider(viper.GetString("translation.provider"))
+ phoneticProvider := phonetic.Provider(viper.GetString("phonetic.provider"))
+
+ // Construct and inject phonetic/translation dependencies at the composition root
+ // so gui.New() receives ready-to-use instances rather than raw config strings.
+ phoneticFetcher := phonetic.NewFetcher(&phonetic.Config{
+ Provider: phoneticProvider,
+ OpenAIKey: openAIKey,
+ GoogleAPIKey: googleAPIKey,
+ })
+ translator := translation.NewTranslator(&translation.Config{
+ Provider: translationProvider,
+ OpenAIKey: openAIKey,
+ GeminiModel: viper.GetString("translation.gemini_model"),
+ })
+
return &gui.Config{
AudioFormat: p.effectiveAudioFormat(),
AudioProvider: p.audioProviderName(),
ImageProvider: imageProvider,
- OpenAIKey: cli.GetOpenAIKey(),
- GoogleAPIKey: cli.GetGoogleAPIKey(),
+ OpenAIKey: openAIKey,
+ GoogleAPIKey: googleAPIKey,
NanoBananaModel: p.nanoBananaModelForRunMode(),
NanoBananaTextModel: p.nanoBananaTextModelForRunMode(),
GeminiTTSModel: p.geminiTTSModel(),
GeminiVoice: p.geminiVoice(),
- TranslationProvider: translation.Provider(viper.GetString("translation.provider")),
- PhoneticProvider: phonetic.Provider(viper.GetString("phonetic.provider")),
+ TranslationProvider: translationProvider,
+ PhoneticProvider: phoneticProvider,
AutoPlay: !p.flags.NoAutoPlay, // Invert the flag (--no-auto-play disables auto-play)
+ PhoneticFetcher: phoneticFetcher,
+ Translator: translator,
}
}