diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-02 22:18:09 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-02 22:18:09 +0300 |
| commit | 373a10660bdd1faf27d22073380e5e897870ab12 (patch) | |
| tree | 3d1e8a8b375aa509c0b4b2b540058cc3a4b3e200 /internal/processor | |
| parent | bd23c3f3e53bced44b5ecf0b0c6a74a3cc2f9875 (diff) | |
task zy: move GUI application launch out of Processor into cmd/main.go [SoC]
Replace Processor.RunGUIMode() with a standalone runGUIMode() function in
the composition root (cmd/main.go) that calls proc.GUIConfig() to get the
GUI settings and then owns the gui.New()/Run() lifecycle. The processor
package still imports gui for the gui.Config return type; complete removal
of that import is deferred to task 000 (god-object decomposition) where
the Processor itself will be split up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/processor')
| -rw-r--r-- | internal/processor/processor.go | 46 | ||||
| -rw-r--r-- | internal/processor/processor_test.go | 14 |
2 files changed, 18 insertions, 42 deletions
diff --git a/internal/processor/processor.go b/internal/processor/processor.go index c79e892..40487b9 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -16,7 +16,6 @@ import ( "codeberg.org/snonux/totalrecall/internal/audio" "codeberg.org/snonux/totalrecall/internal/batch" "codeberg.org/snonux/totalrecall/internal/cli" - appconfig "codeberg.org/snonux/totalrecall/internal/config" "codeberg.org/snonux/totalrecall/internal/gui" "codeberg.org/snonux/totalrecall/internal/image" "codeberg.org/snonux/totalrecall/internal/phonetic" @@ -32,11 +31,11 @@ type Processor struct { randomIntn func(n int) int } -var newOpenAIImageClient = func(config *image.OpenAIConfig) image.ImageSearcher { +var newOpenAIImageClient = func(config *image.OpenAIConfig) image.ImageClient { return image.NewOpenAIClient(config) } -var newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageSearcher { +var newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageClient { return image.NewNanoBananaClient(config) } @@ -681,34 +680,11 @@ func (p *Processor) GenerateAnkiFile() (string, error) { return outputPath, nil } -// RunGUIMode launches the GUI application -func (p *Processor) RunGUIMode() error { - guiConfig := p.guiConfigForRunMode() - - // Only set OutputDir if it was explicitly provided via flag - // Check if the outputDir is different from the default - home, err := appconfig.HomeDir() - if err != nil { - fmt.Fprintf(os.Stderr, "Warning: %v\n", err) - } - defaultOutputDir := filepath.Join(home, "Downloads") - if p.flags.OutputDir != defaultOutputDir { - // User explicitly set a different output directory - guiConfig.OutputDir = p.flags.OutputDir - } - if guiConfig.GoogleAPIKey == "" { - guiConfig.GoogleAPIKey = cli.GetGoogleAPIKey() - } - // Otherwise, gui.New will use its own default (XDG state directory) - - // Create and run GUI application - app := gui.New(guiConfig) - app.Run() - - return nil -} - -func (p *Processor) guiConfigForRunMode() *gui.Config { +// GUIConfig returns a gui.Config populated from the processor's flags and +// Viper settings. Callers (typically cmd/main.go) use this to construct the +// GUI application so that gui.New() lives outside the processor package and +// the processor→gui dependency is limited to the Config type only. +func (p *Processor) GUIConfig() *gui.Config { imageProvider := p.flags.ImageAPI if !p.flags.ImageAPISpecified { imageProvider = gui.DefaultConfig().ImageProvider @@ -790,7 +766,7 @@ func (p *Processor) nanoBananaTextModelForRunMode() string { return image.DefaultNanoBananaTextModel } -func (p *Processor) newImageSearcher() (image.ImageSearcher, error) { +func (p *Processor) newImageSearcher() (image.ImageClient, error) { provider := p.imageProviderForRunMode() switch provider { @@ -815,7 +791,7 @@ func (p *Processor) imageProviderForRunMode() string { return strings.ToLower(strings.TrimSpace(p.flags.ImageAPI)) } -func (p *Processor) newOpenAIImageSearcher() (image.ImageSearcher, error) { +func (p *Processor) newOpenAIImageSearcher() (image.ImageClient, error) { openaiConfig := &image.OpenAIConfig{ APIKey: cli.GetOpenAIKey(), Model: p.flags.OpenAIImageModel, @@ -844,7 +820,7 @@ func (p *Processor) newOpenAIImageSearcher() (image.ImageSearcher, error) { return newOpenAIImageClient(openaiConfig), nil } -func (p *Processor) newNanoBananaImageSearcher() (image.ImageSearcher, error) { +func (p *Processor) newNanoBananaImageSearcher() (image.ImageClient, error) { nanoBananaConfig := &image.NanoBananaConfig{ APIKey: cli.GetGoogleAPIKey(), Model: p.flags.NanoBananaModel, @@ -865,7 +841,7 @@ func (p *Processor) newNanoBananaImageSearcher() (image.ImageSearcher, error) { return newNanoBananaImageClient(nanoBananaConfig), nil } -func (p *Processor) saveImagePrompt(wordDir string, searcher image.ImageSearcher) { +func (p *Processor) saveImagePrompt(wordDir string, searcher image.ImageClient) { type promptGetter interface { GetLastPrompt() string } diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index db03266..cfa4545 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -274,7 +274,7 @@ func TestGUIConfigForRunModeUsesNanoBananaDefaultWhenImageAPIIsNotSpecified(t *t flags.ImageAPISpecified = false p := NewProcessor(flags) - guiConfig := p.guiConfigForRunMode() + guiConfig := p.GUIConfig() if guiConfig.ImageProvider != gui.DefaultConfig().ImageProvider { t.Fatalf("guiConfig.ImageProvider = %q, want GUI default %q", guiConfig.ImageProvider, gui.DefaultConfig().ImageProvider) } @@ -314,7 +314,7 @@ func TestGUIConfigForRunModeHonorsExplicitImageAPI(t *testing.T) { flags.ImageAPISpecified = true p := NewProcessor(flags) - guiConfig := p.guiConfigForRunMode() + guiConfig := p.GUIConfig() if guiConfig.ImageProvider != "openai" { t.Fatalf("guiConfig.ImageProvider = %q, want %q", guiConfig.ImageProvider, "openai") } @@ -348,7 +348,7 @@ func TestGUIConfigForRunModeHonorsExplicitNanoBananaModelFlags(t *testing.T) { flags.NanoBananaTextModelSpecified = true p := NewProcessor(flags) - guiConfig := p.guiConfigForRunMode() + guiConfig := p.GUIConfig() if guiConfig.NanoBananaModel != "flag-image-model" { t.Fatalf("guiConfig.NanoBananaModel = %q, want %q", guiConfig.NanoBananaModel, "flag-image-model") } @@ -1218,7 +1218,7 @@ func TestDownloadImagesWithTranslationUsesNanoBananaConfigAndSavesPrompt(t *test originalConstructor := newNanoBananaImageClient stubSearcher := &stubImageSearcher{} capturedConfig := new(image.NanoBananaConfig) - newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageSearcher { + newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageClient { *capturedConfig = *config return stubSearcher } @@ -1274,7 +1274,7 @@ func TestDownloadImagesWithTranslationPersistsPromptWhenDownloadFails(t *testing originalConstructor := newNanoBananaImageClient stubSearcher := &stubImageSearcher{downloadErr: errors.New("download failed")} - newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageSearcher { + newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageClient { return stubSearcher } t.Cleanup(func() { @@ -1323,7 +1323,7 @@ func TestDownloadImagesWithTranslationUsesConfiguredNanoBananaWhenImageAPINotSpe originalConstructor := newNanoBananaImageClient stubSearcher := &stubImageSearcher{} capturedConfig := new(image.NanoBananaConfig) - newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageSearcher { + newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageClient { *capturedConfig = *config return stubSearcher } @@ -1429,7 +1429,7 @@ func TestNewNanoBananaImageSearcherExplicitDefaultWinsOverConfig(t *testing.T) { originalConstructor := newNanoBananaImageClient capturedConfig := new(image.NanoBananaConfig) - newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageSearcher { + newNanoBananaImageClient = func(config *image.NanoBananaConfig) image.ImageClient { *capturedConfig = *config return &stubImageSearcher{} } |
