summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-07-16 13:13:38 +0300
committerPaul Buetow <paul@buetow.org>2025-07-16 13:13:38 +0300
commit7187e7464f16a9d2991ba2da3c672fdb3cf5de72 (patch)
tree208d8e301dc55512a078f836f4f0c9ad2a927427 /cmd
parentb105333c061ea165b3b79317415cbb8b9cfb7c75 (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.go32
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)