| Age | Commit message (Collapse) | Author |
|
Two issues prevented the IPA from being fully displayed:
1. audio_player.go: switched the bottom bar from NewHBox to NewBorder so the
phonetic label fills the centre column instead of being squeezed to its
minimum width between the stop button and the status label. Also enabled
TextWrapWord so very long IPA strings wrap rather than being clipped.
2. phonetic/fetcher.go: raised MaxOutputTokens from 50 to 200 so Gemini 2.5
Flash has enough budget to emit the full IPA bracket pair without truncation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- audio/fallbacks.go: lowercase error string per Go convention
- gui/app.go: remove empty else branch in keyboard shortcut handler
- audio/provider_test.go: remove unused mockProvider type
- update test assertions in voices_test.go and processor_test.go to match
the corrected lowercase error string
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- startFileCheckTicker: add wg.Add(1)/wg.Done() so the app shutdown handler
waits for the ticker goroutine to exit (it already uses ctx.Done() to stop).
- post-delete cleanup goroutine: add wg.Add(1)/wg.Done() and a ctx.Done()
case so a shutdown during the 5-second polling window terminates cleanly
instead of leaking the goroutine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
config, extract shared card-dir logic
task 00d: remove package-level var test seams from processor and gui packages;
factory functions (newAudioProvider, newOpenAIImageClient, newNanoBananaImageClient)
are now struct fields on Processor and Application, initialized with production
defaults in constructors and replaced in tests without global mutation.
task 006: add viperConfig struct captured once in NewProcessor; no method body
calls viper.GetString/IsSet/GetFloat64 directly any more — all config-file values
are accessed via p.viperCfg fields.
task 007: extract FindCardDirectory and FindOrCreateCardDirectory into
internal/utils.go; both Processor.findCardDirectory and
Application.findCardDirectory now delegate to the shared implementation,
which also handles the legacy _word.txt backward-compat fallback.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Extend audio.Provider with Voices() []string and BuildAttribution() string
so all provider-specific behaviour is encapsulated in the implementation
rather than scattered as switch-cases across callers.
Add package-level VoicesFor(name) and BuildAttributionFor(name, params)
for callers (processor, GUI) that need these before constructing a
Provider instance. Add AttributionParamsFrom(config, word, ...) so
callers can build AttributionParams from the flat Config without a manual
provider switch. Implement both new interface methods in OpenAIProvider
and GeminiProvider. Update all Provider mock/fake types in tests.
Migrate audioVoicesForProvider() and saveAudioAttribution() in both
processor.go and gui/generator.go to use the new package-level helpers,
replacing the 10+ duplicated switch blocks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
audio_player.go: use time.AfterFunc instead of goroutine+sleep for the
100ms auto-play delay — no goroutine is blocked waiting.
app.go (setupUI, setupTooltips): replace goroutine+sleep with time.AfterFunc
for both 500ms tooltip initialization delays.
navigation.go: replace fixed 500ms sleep in the delete-cleanup goroutine with
a ticker+select loop that polls hasActiveOperations(). The goroutine now
proceeds as soon as all in-flight operations for the deleted word finish
(or after a 5-second safety timeout), rather than waiting a fixed interval
that may be too short or too long.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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 <noreply@anthropic.com>
|
|
shared prompt
- task 00g: fix gofmt violations (trailing whitespace, missing newlines,
indentation) in 8 files; all pass gofmt -l now
- task 00k: remove unused ProviderWithFallback and its tests (YAGNI — no
production caller existed; voice-level fallback via RunWithVoiceFallbacks
already covers the real use case)
- task 00h: replace private splitLines/trimSpace/isSpace helpers in
internal/batch/processor.go with strings.Split+ReplaceAll and
strings.TrimSpace from the stdlib; remove the now-redundant tests
- task 008: extract buildEducationalPrompt into internal/image/prompt.go so
the prompt-assembly policy (scene truncation cascade, char limit) lives in
one place; both OpenAIClient and NanoBananaClient delegate to it
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 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
|
|
|
|
Add console debug output to understand which side (front/back) is being
regenerated for audio A and P key presses.
|
|
- Remove Space key handler from handleShortcutKey
Space is not needed - use P/Shift+P instead
- Clarify hotkeys help text
p/п = play front audio
P/П = play back audio (bg-bg only)
The SetOnTypedRune handler already correctly handles case-sensitive
keys (p vs P, a vs A) for both playback and regeneration.
|
|
- Add Space key as primary hotkey to play back audio (bg-bg cards only)
More intuitive than Shift+P for playing the second audio
- Change back audio button icon from MediaSkipNextIcon to MediaPlayIcon
Both front and back buttons now use the same play icon for consistency
- Update hotkeys help dialog to document Space key
Mark P/П as legacy (kept for backward compatibility)
This makes the UI more consistent and the Space key is more natural
for playing the back audio without using Shift.
|
|
Now that the root cause is fixed in the processor, remove the debug
logging that was added for troubleshooting.
|
|
- Add debug logging to navigation.go to diagnose audio file loading issues
Prints paths being checked and whether files are found
- Improve AudioPlayer UI for Bulgarian-Bulgarian cards:
- Add labels showing 'Front' and 'Back' for bg-bg audio buttons
- Labels only show when audio files are actually loaded
- Better visual distinction between the two playable audios
- Reorganized button layout with VBox for cleaner appearance
- Track bg-bg state in AudioPlayer (isBgBg field)
- Automatically set when back audio file is loaded
- Used to determine when to show labels
This makes it clearer that Bulgarian-Bulgarian cards have two independently
playable audio outputs, and helps debug why audio isn't being loaded.
|
|
- Fix scanExistingWords() to detect cards with audio_front/audio_back files
Previously only checked for audio.mp3, missing Bulgarian-Bulgarian cards
- Fix checkForMissingFiles() to also look for bg-bg audio files
Now checks both audio.mp3 (en-bg) and audio_front.mp3 (bg-bg)
- Add check for back audio file in checkForMissingFiles()
Ensures SetBackAudioFile is called when audio_back is loaded later
This fixes the issue where opening an existing Bulgarian-Bulgarian card
would not load the audio files, leaving the play buttons non-functional.
|
|
|
|
cards
- Fix race condition where images, audio, and phonetic info could be saved to wrong flashcard when navigating quickly between cards
- Add pre-determined card directory that's passed to all background operations
- Track active operations per word to prevent deletion during generation
- Block deletion of cards that are queued or being processed
- Show appropriate error messages when deletion is blocked
This ensures files are always saved to the correct card directory and prevents data loss from deleting cards with active operations.
🤖 Generated with [opencode](https://opencode.ai)
Co-Authored-By: opencode <noreply@opencode.ai>
|
|
- Add 'в' and 'В' (Cyrillic) key handling for archive functionality
- Ensures archive works with both Latin 'v' and Cyrillic 'в' keyboards
🤖 Generated with [opencode](https://opencode.ai)
Co-Authored-By: opencode <noreply@opencode.ai>
|
|
- Add 'v' hotkey for archive all cards functionality
- Change regenerate image icon to ColorPaletteIcon (artistic palette)
- Change random image icon to ViewRefreshIcon (refresh symbol)
- Update help dialog to include archive hotkey in Export & Archive section
- Add hotkey hint to archive button tooltip
🤖 Generated with [opencode](https://opencode.ai)
Co-Authored-By: opencode <noreply@opencode.ai>
|
|
- Move totalrecall.desktop, install-icon.sh, and config.yaml.example to assets/ directory
- Update all references in README.md and install-icon.sh
- Add file organization guidelines to AGENTS.md
- Clean up root directory structure
🤖 Generated with [opencode](https://opencode.ai)
Co-Authored-By: opencode <noreply@opencode.ai>
|
|
|
|
- Add file.Sync() after image download to ensure data is flushed to disk
- Add double-checking in UI updates to prevent wrong card updates
- Fix background job completion to reload files when user navigates back
- Add file size validation in image display widget
- Improve error messages for image loading failures
This fixes two issues:
1. 'png: invalid format: not enough pixel data' error when navigating during generation
2. Images not updating when navigating back to a card after background generation completes
|
|
🤖 Generated with [opencode](https://opencode.ai)
Co-Authored-By: opencode <noreply@opencode.ai>
|