From 730152379886f1a7dd7c36d68918706c82ad718d Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 2 Apr 2026 22:03:06 +0300 Subject: task 00e: inject phonetic.Fetcher and translation.Translator into gui.New() Add PhoneticFetcher and Translator fields to gui.Config so callers can inject ready-to-use instances. gui.New() uses the injected values when non-nil and falls back to constructing from provider/key fields otherwise. The processor composition root now builds both dependencies and sets them on gui.Config, keeping construction logic out of gui.New(). Co-Authored-By: Claude Sonnet 4.6 --- internal/gui/app.go | 29 +++++++++++++++++++++++------ internal/processor/processor.go | 28 ++++++++++++++++++++++++---- 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, } } -- cgit v1.2.3