diff options
| author | Paul Buetow <paul@buetow.org> | 2025-07-16 13:13:38 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-07-16 13:13:38 +0300 |
| commit | 7187e7464f16a9d2991ba2da3c672fdb3cf5de72 (patch) | |
| tree | 208d8e301dc55512a078f836f4f0c9ad2a927427 /cmd | |
| parent | b105333c061ea165b3b79317415cbb8b9cfb7c75 (diff) | |
feat: add Fyne GUI mode with interactive flashcard management
- Add --gui flag to launch interactive GUI mode
- Implement word navigation with prev/next buttons through existing cards
- Add delete functionality to remove unwanted flashcards
- Add fine-grained regeneration (image-only, audio-only, or both)
- Implement audio playback using mpg123 on Linux
- Auto-load first word on startup if cards exist
- Save translation files for navigation persistence
- Use DALL-E 2 with 512x512 images (half size)
- Update audio speed to 0.9 (from 0.8)
- Add comprehensive GUI documentation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/totalrecall/main.go | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/cmd/totalrecall/main.go b/cmd/totalrecall/main.go index 658301d..89d0ad9 100644 --- a/cmd/totalrecall/main.go +++ b/cmd/totalrecall/main.go @@ -17,6 +17,7 @@ import ( "codeberg.org/snonux/totalrecall/internal" "codeberg.org/snonux/totalrecall/internal/anki" "codeberg.org/snonux/totalrecall/internal/audio" + "codeberg.org/snonux/totalrecall/internal/gui" "codeberg.org/snonux/totalrecall/internal/image" ) @@ -34,6 +35,7 @@ var ( generateAnki bool listModels bool allVoices bool + guiMode bool // Audio provider flags removed - now only OpenAI // OpenAI flags openAIModel string @@ -84,13 +86,14 @@ func init() { rootCmd.Flags().BoolVar(&generateAnki, "anki", false, "Generate Anki import CSV file") rootCmd.Flags().BoolVar(&listModels, "list-models", false, "List available OpenAI models for the current API key") rootCmd.Flags().BoolVar(&allVoices, "all-voices", false, "Generate audio in all available voices (creates multiple files)") + rootCmd.Flags().BoolVar(&guiMode, "gui", false, "Launch interactive GUI mode") // Audio provider removed - now only OpenAI // OpenAI flags rootCmd.Flags().StringVar(&openAIModel, "openai-model", "gpt-4o-mini-tts", "OpenAI TTS model: tts-1, tts-1-hd, gpt-4o-mini-tts") rootCmd.Flags().StringVar(&openAIVoice, "openai-voice", "", "OpenAI voice: alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, shimmer, verse (default: random)") - rootCmd.Flags().Float64Var(&openAISpeed, "openai-speed", 0.8, "OpenAI speech speed (0.25 to 4.0, may be ignored by gpt-4o-mini-tts)") + rootCmd.Flags().Float64Var(&openAISpeed, "openai-speed", 0.9, "OpenAI speech speed (0.25 to 4.0, may be ignored by gpt-4o-mini-tts)") rootCmd.Flags().StringVar(&openAIInstruction, "openai-instruction", "", "Voice instructions for gpt-4o-mini-tts model (e.g., 'speak slowly with a Bulgarian accent')") // OpenAI Image Generation flags @@ -151,6 +154,11 @@ func runCommand(cmd *cobra.Command, args []string) error { return listAvailableModels() } + // Handle --gui flag + if guiMode { + return runGUIMode() + } + // Determine words to process var words []string @@ -309,7 +317,7 @@ func generateAudioWithVoice(word, voice string) error { if openAIVoice == "nova" && viper.IsSet("audio.openai_voice") { providerConfig.OpenAIVoice = viper.GetString("audio.openai_voice") } - if openAISpeed == 0.8 && viper.IsSet("audio.openai_speed") { + if openAISpeed == 0.9 && viper.IsSet("audio.openai_speed") { providerConfig.OpenAISpeed = viper.GetFloat64("audio.openai_speed") } if openAIInstruction == "" && viper.IsSet("audio.openai_instruction") { @@ -712,6 +720,26 @@ func saveAudioAttribution(word, audioFile string, config *audio.Config) error { return nil } +func runGUIMode() error { + // Create GUI configuration from command line flags and viper config + guiConfig := &gui.Config{ + OutputDir: outputDir, + AudioFormat: audioFormat, + ImageProvider: imageAPI, + ImagesPerWord: imagesPerWord, + EnableCache: viper.GetBool("cache.enable"), + OpenAIKey: getOpenAIKey(), + PixabayKey: viper.GetString("image.pixabay_key"), + UnsplashKey: viper.GetString("image.unsplash_key"), + } + + // Create and run GUI application + app := gui.New(guiConfig) + app.Run() + + return nil +} + func main() { if err := rootCmd.Execute(); err != nil { os.Exit(1) |
