summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-01-21 22:41:08 +0200
committerPaul Buetow <paul@buetow.org>2026-01-21 22:41:08 +0200
commit5f9f32f089fcc3cd827db4d707003acefa2a8cca (patch)
tree5b295dbc88ac8fefb9661fffd442ebc846af269f /internal
parent962dd1f77c0b38bf5333e3328ba136ff6c456285 (diff)
Fix: Auto-play only regenerated audio (front or back, not both) for bg-bg cardsv0.8.0
- Removed duplicate fyne.KeyA handler that was triggering both front and back audio - Added SetAudioFileNoAutoPlay() method for controlled playback - Front audio (a key) now auto-plays only front audio - Back audio (A key) now auto-plays only back audio - Refactored startPlayback to use startPlaybackForFile for better control - Fixed icon reset when playback finishes for each audio type separately
Diffstat (limited to 'internal')
-rw-r--r--internal/gui/app.go100
-rw-r--r--internal/gui/audio_player.go95
-rw-r--r--internal/gui/generator.go14
-rw-r--r--internal/gui/navigation.go35
-rw-r--r--internal/version.go2
5 files changed, 209 insertions, 37 deletions
diff --git a/internal/gui/app.go b/internal/gui/app.go
index 7d48f75..ea4d840 100644
--- a/internal/gui/app.go
+++ b/internal/gui/app.go
@@ -1032,14 +1032,23 @@ func (a *Application) onRegenerateRandomImage() {
// onRegenerateAudio regenerates front audio (or single audio for en-bg cards)
func (a *Application) onRegenerateAudio() {
+ fmt.Printf("DEBUG: ████████████████████████████████████████████████████████████████\n")
+ fmt.Printf("DEBUG: ████ ENTERED onRegenerateAudio() - REGENERATING FRONT AUDIO\n")
+ fmt.Printf("DEBUG: ████████████████████████████████████████████████████████████████\n")
+ fmt.Printf("DEBUG (onRegenerateAudio): Starting front audio regeneration\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+
// Only disable the audio-related buttons
a.regenerateAudioBtn.Disable()
a.regenerateAllBtn.Disable()
isBgBg := a.currentCardType == "bg-bg"
if isBgBg {
+ fmt.Printf("DEBUG (onRegenerateAudio): Card type is bg-bg, regenerating FRONT audio only\n")
a.showProgress("Regenerating front audio...")
} else {
+ fmt.Printf("DEBUG (onRegenerateAudio): Card type is en-bg, regenerating single audio\n")
a.showProgress("Regenerating audio...")
}
@@ -1052,6 +1061,7 @@ func (a *Application) onRegenerateAudio() {
// Store the word we're generating for
wordForGeneration := a.currentWord
+ fmt.Printf("DEBUG (onRegenerateAudio): In goroutine - wordForGeneration: %s\n", wordForGeneration)
a.startOperation(wordForGeneration)
defer a.endOperation(wordForGeneration)
@@ -1083,7 +1093,10 @@ func (a *Application) onRegenerateAudio() {
fyne.Do(func() {
a.mu.Lock()
if a.currentWord == wordForGeneration {
- a.audioPlayer.SetAudioFile(audioFile)
+ // Set front audio WITHOUT auto-play initially
+ a.audioPlayer.SetAudioFileNoAutoPlay(audioFile)
+ // Then explicitly play ONLY the front audio
+ a.audioPlayer.Play()
}
a.mu.Unlock()
})
@@ -1126,7 +1139,17 @@ func (a *Application) onRegenerateAudio() {
// onRegenerateBackAudio regenerates back audio for bg-bg cards
func (a *Application) onRegenerateBackAudio() {
+ fmt.Printf("DEBUG: ████████████████████████████████████████████████████████████████\n")
+ fmt.Printf("DEBUG: ████ ENTERED onRegenerateBackAudio() - REGENERATING BACK AUDIO\n")
+ fmt.Printf("DEBUG: ████████████████████████████████████████████████████████████████\n")
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Starting back audio regeneration\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+ fmt.Printf(" - currentTranslation (state var): %s\n", a.currentTranslation)
+ fmt.Printf(" - translationEntry.Text (UI field): %s\n", a.translationEntry.Text)
+
if a.currentCardType != "bg-bg" {
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Not a bg-bg card, returning\n")
return
}
@@ -1141,17 +1164,30 @@ func (a *Application) onRegenerateBackAudio() {
defer a.wg.Done()
defer a.decrementProcessing()
+ // CRITICAL: Get translation from state variable first
translation := a.currentTranslation
+ fmt.Printf("DEBUG (onRegenerateBackAudio): In goroutine - translation from a.currentTranslation: %s\n", translation)
+ fmt.Printf("DEBUG (onRegenerateBackAudio): In goroutine - translation UI field: %s\n", a.translationEntry.Text)
+
if translation == "" {
+ fmt.Printf("DEBUG (onRegenerateBackAudio): WARNING - translation state was empty, falling back to UI field\n")
translation = strings.TrimSpace(a.translationEntry.Text)
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Using UI field translation: %s\n", translation)
}
+
wordForGeneration := a.currentWord
-
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Final decision - will generate back audio for: %s\n", translation)
+ fmt.Printf("DEBUG (onRegenerateBackAudio): (NOT for word: %s)\n", wordForGeneration)
+
+ // For back audio, we need to use the main context, not create a new card context
+ // because the front audio regeneration already has an active context for this word.
+ // Creating a new context would cancel the front audio operation.
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Using main context (not creating new card context)\n")
+ fmt.Printf("DEBUG (onRegenerateBackAudio): This prevents cancelling ongoing front audio operation\n")
+
a.startOperation(wordForGeneration)
defer a.endOperation(wordForGeneration)
- cardCtx, _ := a.getOrCreateCardContext(wordForGeneration)
-
cardDir, err := a.ensureCardDirectory(wordForGeneration)
if err != nil {
fyne.Do(func() {
@@ -1160,7 +1196,17 @@ func (a *Application) onRegenerateBackAudio() {
return
}
- audioFile, err := a.generateAudioBack(cardCtx, translation, cardDir)
+ fmt.Printf("DEBUG (onRegenerateBackAudio): Calling generateAudioBack with:\n")
+ fmt.Printf(" - ctx: a.ctx (main app context)\n")
+ fmt.Printf(" - translation: %s\n", translation)
+ fmt.Printf(" - cardDir: %s\n", cardDir)
+
+ audioFile, err := a.generateAudioBack(a.ctx, translation, cardDir)
+
+ fmt.Printf("DEBUG (onRegenerateBackAudio): generateAudioBack returned:\n")
+ fmt.Printf(" - err: %v\n", err)
+ fmt.Printf(" - audioFile: %s\n", audioFile)
+
if err != nil {
fyne.Do(func() {
a.showError(fmt.Errorf("Back audio regeneration failed: %w", err))
@@ -1174,6 +1220,8 @@ func (a *Application) onRegenerateBackAudio() {
a.mu.Lock()
if a.currentWord == wordForGeneration {
a.audioPlayer.SetBackAudioFile(audioFile)
+ // Auto-play the regenerated back audio
+ a.audioPlayer.PlayBack()
}
a.mu.Unlock()
})
@@ -2427,12 +2475,30 @@ func (a *Application) setupKeyboardShortcuts() {
a.onRegenerateRandomImage()
}
case 'a', 'а': // a = regenerate front audio
+ fmt.Printf("DEBUG: ╔════════════════════════════════════════════════════════════════\n")
+ fmt.Printf("DEBUG: ║ KEY PRESSED: 'a' (lowercase, regenerate FRONT audio)\n")
+ fmt.Printf("DEBUG: ╚════════════════════════════════════════════════════════════════\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+ fmt.Printf(" - regenerateAudioBtn.Disabled(): %v\n", a.regenerateAudioBtn.Disabled())
+ fmt.Printf(" - CALLING: onRegenerateAudio() for FRONT audio\n")
if !a.regenerateAudioBtn.Disabled() {
a.onRegenerateAudio()
}
case 'A', 'А': // A = regenerate back audio (for bg-bg cards)
- if a.currentCardType == "bg-bg" && !a.regenerateAudioBtn.Disabled() {
+ fmt.Printf("DEBUG: ╔════════════════════════════════════════════════════════════════\n")
+ fmt.Printf("DEBUG: ║ KEY PRESSED: 'A' (uppercase, regenerate BACK audio)\n")
+ fmt.Printf("DEBUG: ╚════════════════════════════════════════════════════════════════\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+ fmt.Printf(" - currentTranslation: %s\n", a.currentTranslation)
+ fmt.Printf(" - translationEntry.Text: %s\n", a.translationEntry.Text)
+ fmt.Printf(" - regenerateAudioBtn.Disabled(): %v\n", a.regenerateAudioBtn.Disabled())
+ if a.currentCardType == "bg-bg" {
+ fmt.Printf(" - CALLING: onRegenerateBackAudio() for BACK audio\n")
a.onRegenerateBackAudio()
+ } else {
+ fmt.Printf("DEBUG: Skipping back audio regen - not a bg-bg card\n")
}
case 'р', 'Р': // р = r
if !a.regenerateAllBtn.Disabled() {
@@ -2443,12 +2509,24 @@ func (a *Application) setupKeyboardShortcuts() {
a.onDelete()
}
case 'p', 'п': // p = play front audio
+ fmt.Printf("DEBUG: Key pressed 'p' (play front audio)\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+ fmt.Printf(" - currentAudioFile: %s\n", a.currentAudioFile)
if a.currentAudioFile != "" {
a.audioPlayer.Play()
+ } else {
+ fmt.Printf("DEBUG: No front audio file to play\n")
}
case 'P', 'П': // P = play back audio (for bg-bg cards)
+ fmt.Printf("DEBUG: Key pressed 'P' (play back audio)\n")
+ fmt.Printf(" - currentWord: %s\n", a.currentWord)
+ fmt.Printf(" - currentCardType: %s\n", a.currentCardType)
+ fmt.Printf(" - currentAudioFileBack: %s\n", a.currentAudioFileBack)
if a.currentAudioFileBack != "" {
a.audioPlayer.PlayBack()
+ } else {
+ fmt.Printf("DEBUG: No back audio file to play\n")
}
case 'ж', 'Ж': // ж = x
a.onExportToAnki()
@@ -2562,11 +2640,11 @@ func (a *Application) handleShortcutKey(key fyne.KeyName) {
}
a.onRegenerateRandomImage()
- case fyne.KeyA: // Regenerate Audio
- if a.regenerateAudioBtn.Disabled() {
- return
- }
- a.onRegenerateAudio()
+ case fyne.KeyA: // Regenerate Audio (handled by custom OnTypedRune for proper case sensitivity)
+ // NOTE: This handler is disabled to use character-based handler instead
+ // For bg-bg cards: shift+A = back audio, a = front audio
+ // For en-bg cards: a/A = regenerate audio
+ // See handleTypedRune for actual implementation
case fyne.KeyR: // Regenerate All
if a.regenerateAllBtn.Disabled() {
diff --git a/internal/gui/audio_player.go b/internal/gui/audio_player.go
index 4846615..8ab7f76 100644
--- a/internal/gui/audio_player.go
+++ b/internal/gui/audio_player.go
@@ -96,8 +96,19 @@ func (p *AudioPlayer) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(p.container)
}
-// SetAudioFile sets the audio file to play
+// SetAudioFile sets the audio file to play and optionally auto-plays it
func (p *AudioPlayer) SetAudioFile(audioFile string) {
+ p.setAudioFileInternal(audioFile, true) // Enable auto-play
+}
+
+// SetAudioFileNoAutoPlay sets the audio file without auto-playing
+// Used when regenerating audio on bg-bg cards - we only want to play when explicitly requested
+func (p *AudioPlayer) SetAudioFileNoAutoPlay(audioFile string) {
+ p.setAudioFileInternal(audioFile, false) // Disable auto-play
+}
+
+// setAudioFileInternal is the internal implementation for setting audio files
+func (p *AudioPlayer) setAudioFileInternal(audioFile string, allowAutoPlay bool) {
p.audioFile = audioFile
p.isPlaying = false
@@ -139,8 +150,8 @@ func (p *AudioPlayer) SetAudioFile(audioFile string) {
statusText := fmt.Sprintf("Audio: %s%s", filepath.Base(audioFile), p.voiceInfo)
p.statusLabel.SetText(statusText)
- // Auto-play if enabled
- if p.autoPlayEnabled != nil && *p.autoPlayEnabled {
+ // Auto-play if enabled and allowed
+ if allowAutoPlay && p.autoPlayEnabled != nil && *p.autoPlayEnabled {
// Small delay to ensure UI is ready
go func() {
// Wait a tiny bit for UI to be ready
@@ -166,6 +177,9 @@ func (p *AudioPlayer) SetBackAudioFile(audioFile string) {
p.playBackLabel.Show()
// Update front label now that we know it's bg-bg
p.playButtonLabel.SetText("Front")
+ // NOTE: Do NOT auto-play back audio
+ // Back audio regeneration just prepares the file
+ // User should press 'P' to listen to it
} else {
p.isBgBg = false
p.playBackButton.Disable()
@@ -221,18 +235,28 @@ func (p *AudioPlayer) SetAutoPlayEnabled(autoPlayEnabled *bool) {
// onPlay handles play button click
func (p *AudioPlayer) onPlay() {
+ fmt.Printf("DEBUG (onPlay): Starting playback\n")
+ fmt.Printf(" - audioFile: %s\n", p.audioFile)
+ fmt.Printf(" - audioFileBack: %s\n", p.audioFileBack)
+ fmt.Printf(" - isBgBg: %v\n", p.isBgBg)
+ fmt.Printf(" - isPlaying: %v\n", p.isPlaying)
+
if p.audioFile == "" {
+ fmt.Printf("DEBUG (onPlay): No audioFile set, returning\n")
return
}
if p.isPlaying {
// Pause functionality - just stop for now
+ fmt.Printf("DEBUG (onPlay): Already playing, stopping\n")
p.onStop()
return
}
// Start playing
+ fmt.Printf("DEBUG (onPlay): About to start playback for: %s\n", filepath.Base(p.audioFile))
if err := p.startPlayback(); err != nil {
+ fmt.Printf("DEBUG (onPlay): Error starting playback: %v\n", err)
p.statusLabel.SetText(fmt.Sprintf("Error: %v", err))
return
}
@@ -241,35 +265,40 @@ func (p *AudioPlayer) onPlay() {
p.playButton.SetIcon(theme.MediaPauseIcon())
p.stopButton.Enable()
p.statusLabel.SetText(fmt.Sprintf("Playing: %s%s", filepath.Base(p.audioFile), p.voiceInfo))
+ fmt.Printf("DEBUG (onPlay): Playback started successfully\n")
}
// onPlayBack handles back audio button click (for bg-bg cards)
func (p *AudioPlayer) onPlayBack() {
+ fmt.Printf("DEBUG (onPlayBack): Starting back audio playback\n")
+ fmt.Printf(" - audioFile: %s\n", p.audioFile)
+ fmt.Printf(" - audioFileBack: %s\n", p.audioFileBack)
+ fmt.Printf(" - isBgBg: %v\n", p.isBgBg)
+ fmt.Printf(" - isPlaying: %v\n", p.isPlaying)
+
if p.audioFileBack == "" {
+ fmt.Printf("DEBUG (onPlayBack): No audioFileBack set, returning\n")
return
}
if p.isPlaying {
+ fmt.Printf("DEBUG (onPlayBack): Already playing, stopping first\n")
p.onStop()
}
- // Temporarily swap audio files to play the back audio
- originalFile := p.audioFile
- p.audioFile = p.audioFileBack
-
- if err := p.startPlayback(); err != nil {
+ // Start playback using back audio file directly
+ fmt.Printf("DEBUG (onPlayBack): About to start playback for back audio: %s\n", filepath.Base(p.audioFileBack))
+ if err := p.startPlaybackForFile(p.audioFileBack); err != nil {
+ fmt.Printf("DEBUG (onPlayBack): Error starting playback: %v\n", err)
p.statusLabel.SetText(fmt.Sprintf("Error: %v", err))
- p.audioFile = originalFile
return
}
p.isPlaying = true
- p.playButton.SetIcon(theme.MediaPauseIcon())
+ p.playBackButton.SetIcon(theme.MediaPauseIcon()) // Back button, not front
p.stopButton.Enable()
p.statusLabel.SetText(fmt.Sprintf("Playing back audio: %s", filepath.Base(p.audioFileBack)))
-
- // Restore original file after playback starts
- p.audioFile = originalFile
+ fmt.Printf("DEBUG (onPlayBack): Back audio playback started successfully\n")
}
// onStop handles stop button click
@@ -280,7 +309,12 @@ func (p *AudioPlayer) onStop() {
}
p.isPlaying = false
- p.playButton.SetIcon(theme.MediaPlayIcon())
+ // Set correct button icon based on which audio was playing
+ if p.isBgBg && p.audioFileBack != "" {
+ p.playBackButton.SetIcon(theme.MediaPlayIcon()) // Back button if it was playing
+ } else {
+ p.playButton.SetIcon(theme.MediaPlayIcon()) // Front button otherwise
+ }
p.stopButton.Disable()
p.statusLabel.SetText(fmt.Sprintf("Stopped: %s%s", filepath.Base(p.audioFile), p.voiceInfo))
}
@@ -304,32 +338,39 @@ func (p *AudioPlayer) PlayBack() {
}
// startPlayback starts audio playback using platform-specific commands
+// This plays the front audio file (p.audioFile)
func (p *AudioPlayer) startPlayback() error {
+ return p.startPlaybackForFile(p.audioFile)
+}
+
+// startPlaybackForFile starts playback of a specific audio file
+// This allows playing either front or back audio without modifying state
+func (p *AudioPlayer) startPlaybackForFile(audioFile string) error {
var cmd *exec.Cmd
switch runtime.GOOS {
case "darwin": // macOS
- cmd = exec.Command("afplay", p.audioFile)
+ cmd = exec.Command("afplay", audioFile)
case "linux":
// Try multiple commands in order of preference
// mpg123 first since it handles MP3 files best
if _, err := exec.LookPath("mpg123"); err == nil {
- cmd = exec.Command("mpg123", "-q", p.audioFile) // -q for quiet mode
+ cmd = exec.Command("mpg123", "-q", audioFile) // -q for quiet mode
} else if _, err := exec.LookPath("ffplay"); err == nil {
- cmd = exec.Command("ffplay", "-nodisp", "-autoexit", "-loglevel", "quiet", p.audioFile)
+ cmd = exec.Command("ffplay", "-nodisp", "-autoexit", "-loglevel", "quiet", audioFile)
} else if _, err := exec.LookPath("play"); err == nil {
// SoX play command
- cmd = exec.Command("play", "-q", p.audioFile)
+ cmd = exec.Command("play", "-q", audioFile)
} else if _, err := exec.LookPath("paplay"); err == nil {
- cmd = exec.Command("paplay", p.audioFile)
+ cmd = exec.Command("paplay", audioFile)
} else if _, err := exec.LookPath("aplay"); err == nil {
- cmd = exec.Command("aplay", "-q", p.audioFile)
+ cmd = exec.Command("aplay", "-q", audioFile)
} else {
return fmt.Errorf("no audio player found. Install mpg123, ffplay, sox, paplay, or aplay")
}
case "windows":
// Use Windows Media Player
- cmd = exec.Command("cmd", "/c", "start", "/min", p.audioFile)
+ cmd = exec.Command("cmd", "/c", "start", "/min", audioFile)
default:
return fmt.Errorf("unsupported platform: %s", runtime.GOOS)
}
@@ -338,15 +379,23 @@ func (p *AudioPlayer) startPlayback() error {
p.playCmd = cmd
// Start playback in background
+ // Capture whether this is playing back audio or front audio for proper icon reset
+ isPlayingBack := audioFile == p.audioFileBack
go func() {
err := cmd.Run()
if err == nil {
// Playback finished normally
fyne.Do(func() {
p.isPlaying = false
- p.playButton.SetIcon(theme.MediaPlayIcon())
+ // Reset correct button icon based on which audio was playing
+ if isPlayingBack {
+ p.playBackButton.SetIcon(theme.MediaPlayIcon())
+ p.statusLabel.SetText(fmt.Sprintf("Finished: %s", filepath.Base(p.audioFileBack)))
+ } else {
+ p.playButton.SetIcon(theme.MediaPlayIcon())
+ p.statusLabel.SetText(fmt.Sprintf("Finished: %s%s", filepath.Base(p.audioFile), p.voiceInfo))
+ }
p.stopButton.Disable()
- p.statusLabel.SetText(fmt.Sprintf("Finished: %s%s", filepath.Base(p.audioFile), p.voiceInfo))
})
}
}()
diff --git a/internal/gui/generator.go b/internal/gui/generator.go
index a3a0a4d..4569191 100644
--- a/internal/gui/generator.go
+++ b/internal/gui/generator.go
@@ -154,7 +154,10 @@ func (a *Application) generateAudio(ctx context.Context, word string, cardDir st
// generateAudioFront generates front audio for a bg-bg card
func (a *Application) generateAudioFront(ctx context.Context, word string, cardDir string) (string, error) {
+ fmt.Printf("DEBUG (generateAudioFront): Called with word: %s, cardDir: %s\n", word, cardDir)
+
if cardDir == "" {
+ fmt.Printf("DEBUG (generateAudioFront): Card directory not provided, returning error\n")
return "", fmt.Errorf("card directory not provided")
}
@@ -170,14 +173,18 @@ func (a *Application) generateAudioFront(ctx context.Context, word string, cardD
provider, err := audio.NewProvider(&audioConfig)
if err != nil {
+ fmt.Printf("DEBUG (generateAudioFront): Failed to create audio provider: %v\n", err)
return "", err
}
+ fmt.Printf("DEBUG (generateAudioFront): Generating front audio for '%s' with voice: %s, speed: %.2f\n", word, voice, speed)
fmt.Printf("Generating front audio for '%s' with voice: %s, speed: %.2f\n", word, voice, speed)
frontFile := filepath.Join(cardDir, fmt.Sprintf("audio_front.%s", a.config.AudioFormat))
+ fmt.Printf("DEBUG (generateAudioFront): Will write to: %s\n", frontFile)
if err := provider.GenerateAudio(ctx, word, frontFile); err != nil {
return "", fmt.Errorf("failed to generate front audio: %w", err)
}
+ fmt.Printf("DEBUG (generateAudioFront): Successfully wrote front audio to: %s\n", frontFile)
// Update metadata
metadataFile := filepath.Join(cardDir, "audio_metadata.txt")
@@ -191,7 +198,10 @@ func (a *Application) generateAudioFront(ctx context.Context, word string, cardD
// generateAudioBack generates back audio for a bg-bg card
func (a *Application) generateAudioBack(ctx context.Context, text string, cardDir string) (string, error) {
+ fmt.Printf("DEBUG (generateAudioBack): Called with text: %s, cardDir: %s\n", text, cardDir)
+
if cardDir == "" {
+ fmt.Printf("DEBUG (generateAudioBack): Card directory not provided, returning error\n")
return "", fmt.Errorf("card directory not provided")
}
@@ -207,14 +217,18 @@ func (a *Application) generateAudioBack(ctx context.Context, text string, cardDi
provider, err := audio.NewProvider(&audioConfig)
if err != nil {
+ fmt.Printf("DEBUG (generateAudioBack): Failed to create audio provider: %v\n", err)
return "", err
}
+ fmt.Printf("DEBUG (generateAudioBack): Generating back audio for '%s' with voice: %s, speed: %.2f\n", text, voice, speed)
fmt.Printf("Generating back audio for '%s' with voice: %s, speed: %.2f\n", text, voice, speed)
backFile := filepath.Join(cardDir, fmt.Sprintf("audio_back.%s", a.config.AudioFormat))
+ fmt.Printf("DEBUG (generateAudioBack): Will write to: %s\n", backFile)
if err := provider.GenerateAudio(ctx, text, backFile); err != nil {
return "", fmt.Errorf("failed to generate back audio: %w", err)
}
+ fmt.Printf("DEBUG (generateAudioBack): Successfully wrote back audio to: %s\n", backFile)
return backFile, nil
}
diff --git a/internal/gui/navigation.go b/internal/gui/navigation.go
index 1755397..79703de 100644
--- a/internal/gui/navigation.go
+++ b/internal/gui/navigation.go
@@ -377,13 +377,29 @@ func (a *Application) loadExistingFiles(word string) {
if data, err := os.ReadFile(translationFile); err == nil {
// Parse translation from "word = translation" format
content := string(data)
+ fmt.Printf("DEBUG (loadExistingFiles): Read translation.txt: %s\n", content)
parts := strings.Split(content, "=")
+ fmt.Printf("DEBUG (loadExistingFiles): Split into %d parts\n", len(parts))
if len(parts) >= 2 {
- a.currentTranslation = strings.TrimSpace(parts[1])
+ translation := strings.TrimSpace(parts[1])
+ fmt.Printf("DEBUG (loadExistingFiles): Extracted translation (part 1, after '='): %s\n", translation)
+
+ // CRITICAL: Set the state BEFORE SetText so it's available when needed
+ a.currentTranslation = translation
+ fmt.Printf("DEBUG (loadExistingFiles): Set a.currentTranslation state variable to: %s\n", a.currentTranslation)
+
fyne.Do(func() {
- a.translationEntry.SetText(a.currentTranslation)
+ a.translationEntry.SetText(translation)
+ fmt.Printf("DEBUG (loadExistingFiles): Set translationEntry UI field to: %s\n", translation)
+
+ // CRITICAL: After SetText, verify the state is correct
+ fmt.Printf("DEBUG (loadExistingFiles): After SetText, a.currentTranslation is: %s\n", a.currentTranslation)
})
+ } else {
+ fmt.Printf("DEBUG (loadExistingFiles): Translation file did not have '=' separator\n")
}
+ } else {
+ fmt.Printf("DEBUG (loadExistingFiles): Could not read translation.txt: %v\n", err)
}
// Load image prompt file
@@ -413,46 +429,61 @@ func (a *Application) loadExistingFiles(word string) {
// Load card type and audio files
cardType := internal.LoadCardType(wordDir)
a.currentCardType = string(cardType)
+ fmt.Printf("DEBUG (loadExistingFiles): Loaded card type: %s (isBgBg: %v)\n", cardType, cardType.IsBgBg())
// Update UI card type selector
fyne.Do(func() {
if cardType.IsBgBg() {
+ fmt.Printf("DEBUG (loadExistingFiles): Setting UI to bg-bg (Bulgarian → Bulgarian)\n")
a.cardTypeSelect.SetSelected("Bulgarian → Bulgarian")
} else {
+ fmt.Printf("DEBUG (loadExistingFiles): Setting UI to en-bg (English → Bulgarian)\n")
a.cardTypeSelect.SetSelected("English → Bulgarian")
}
})
// Load audio file(s)
if cardType.IsBgBg() {
+ fmt.Printf("DEBUG (loadExistingFiles): Loading audio files for bg-bg card\n")
// For bg-bg cards, load both front and back audio
frontAudio := filepath.Join(wordDir, fmt.Sprintf("audio_front.%s", a.config.AudioFormat))
backAudio := filepath.Join(wordDir, fmt.Sprintf("audio_back.%s", a.config.AudioFormat))
if _, err := os.Stat(frontAudio); err == nil {
a.currentAudioFile = frontAudio
+ fmt.Printf("DEBUG (loadExistingFiles): Found front audio: %s\n", frontAudio)
fyne.Do(func() {
a.audioPlayer.SetAudioFile(frontAudio)
})
+ } else {
+ fmt.Printf("DEBUG (loadExistingFiles): Front audio not found: %s\n", frontAudio)
}
if _, err := os.Stat(backAudio); err == nil {
a.currentAudioFileBack = backAudio
+ fmt.Printf("DEBUG (loadExistingFiles): Found back audio: %s\n", backAudio)
fyne.Do(func() {
a.audioPlayer.SetBackAudioFile(backAudio)
})
+ } else {
+ fmt.Printf("DEBUG (loadExistingFiles): Back audio not found: %s\n", backAudio)
}
} else {
+ fmt.Printf("DEBUG (loadExistingFiles): Loading audio files for en-bg card\n")
// For en-bg cards, load standard audio file
audioFile := filepath.Join(wordDir, fmt.Sprintf("audio.%s", a.config.AudioFormat))
if _, err := os.Stat(audioFile); err == nil {
a.currentAudioFile = audioFile
+ fmt.Printf("DEBUG (loadExistingFiles): Found audio: %s\n", audioFile)
fyne.Do(func() {
a.audioPlayer.SetAudioFile(audioFile)
})
+ } else {
+ fmt.Printf("DEBUG (loadExistingFiles): Audio not found: %s\n", audioFile)
}
// Hide back audio button for en-bg cards
a.currentAudioFileBack = ""
+ fmt.Printf("DEBUG (loadExistingFiles): Clearing back audio for en-bg card\n")
fyne.Do(func() {
a.audioPlayer.SetBackAudioFile("")
})
diff --git a/internal/version.go b/internal/version.go
index 17deabe..7f93254 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -1,3 +1,3 @@
package internal
-const Version = "0.7.5"
+const Version = "0.8.0"