summaryrefslogtreecommitdiff
path: root/internal/gui/generator.go
AgeCommit message (Collapse)Author
2026-04-03tasks 00d, 006, 007: move test seams to struct fields, centralize Viper ↡Paul Buetow
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>
2026-04-02task zz: add Voices()/BuildAttribution() to Provider interface [OCP]Paul Buetow
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>
2026-04-02task 002: restore Gemini warning outputPaul Buetow
2026-04-02task 002: centralize Gemini voice fallbacksPaul Buetow
2026-04-02task 001: remove committed debug printf tracesPaul Buetow
2026-04-02Release v0.9.0v0.9.0Paul Buetow
2026-04-02Fix verification gate lint and test issuesPaul Buetow
2026-04-02Centralize audio sidecar generationPaul Buetow
2026-04-02Align GUI and CLI provider wiringPaul Buetow
2026-04-02Fix GUI selector sync and audio metadata modelPaul Buetow
2026-04-02Fix GUI audio reload and bg-bg session statePaul Buetow
2026-04-02Harden GUI audio loading for GeminiPaul Buetow
2026-04-01Wire Gemini audio into GUIPaul Buetow
2026-04-01zg: add bg-bg consumer coveragePaul Buetow
2026-04-01zg: add consumer coverage for shared voice listsPaul Buetow
2026-04-01zg: extract shared audio voice listsPaul Buetow
2026-04-01z9: wire Nano Banana into GUIPaul Buetow
2026-04-01zt: route GUI translations through shared translatorPaul Buetow
2026-03-08refactor(task-376): share audio attribution builderPaul Buetow
2026-03-08test(task-374): fix errcheck issues in tests and support codePaul Buetow
2026-03-08fix: complete code-quality task queue (373-378)Paul Buetow
2026-01-21Fix: Auto-play only regenerated audio (front or back, not both) for bg-bg cardsv0.8.0Paul Buetow
- 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
2026-01-21improve: better audio player UI and debugging for bg-bg cardsPaul Buetow
- 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.
2025-07-22Fix race conditions in background processing and prevent deletion of active ↡Paul Buetow
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>
2025-07-21more on thisPaul Buetow
2025-07-20feat: make GUI default mode and always use random voicev0.6.1Paul Buetow
- GUI mode now launches by default when no arguments provided - Updated .desktop file to remove unnecessary --gui flag - Updated README to reflect GUI as default mode - Audio generation always uses random voice and speed (0.90-1.00) - No more defaulting to "alloy" voice for first generation - Bump version to 0.6.1 πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19feat: improve flashcard storage and audio regenerationv0.6.0Paul Buetow
- Change default card storage from ~/Downloads to ~/.local/state/totalrecall/cards/ - Keep .apkg exports in ~/Downloads for user convenience - Fix audio regeneration to use random voice and speed (0.9-1.0) - Fix GNOME dock icon by updating StartupWMClass to "Totalrecall" - Fix navigation to properly find cards in new XDG state directory - Ensure config defaults are properly filled when using GUI mode - Bump version to 0.6.0 πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19fix: set default audio speed to 1.0 for alloy voicePaul Buetow
Changed the default speed from 0.98 to 1.0 for initial audio generation to match the standard playback speed. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19fix: use default voice for initial generation, random for regenerationPaul Buetow
- Initial audio generation uses "alloy" voice with 0.98 speed - Regeneration uses random voice selection for variety - This ensures consistent initial experience while allowing variety on regeneration πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19fix: always use random voice selection for audio generationPaul Buetow
Previously, random voice was only used for regeneration. Now all audio generation uses a random voice from the available OpenAI voices for more variety in pronunciation. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19feat: add context cancellation for card operationsPaul Buetow
- Add per-card context tracking to cancel ongoing operations - Cancel audio/image generation when card is deleted - Keep delete button enabled during generation for cancellation - Add cleanup hook to remove recreated directories after deletion This allows users to cancel in-progress card generation by deleting the card, preventing orphaned API calls and file creation. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19feat: update default voice to alloy with speed 0.98Paul Buetow
- Changed default voice from 'nova' to 'alloy' - Changed default speed from 0.9 to 0.98 for better clarity - GUI now uses default voice/speed for first generation - Regeneration still uses random voice/speed for variety πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18feat: multiple improvements to GUI and codebasePaul Buetow
- Add random voice speed between 0.90-1.00 for more natural audio - Display voice and speed info in GUI audio player - Implement automatic retry loading for missing files (checks every 2 seconds) - Fix voice/speed info persistence during audio playback - Remove image caching functionality for cleaner codebase - Rename prompt.txt to image_prompt.txt for clarity - Fix GUI to recognize newly added cards during runtime (rescan on navigation) - Update README to reflect removed image cache These changes improve the user experience by making the audio more natural, providing better feedback about audio generation parameters, and ensuring the GUI stays synchronized with externally added cards. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18fix: ensure single directory per card with consistent IDPaul Buetow
- Fixed issue where multiple directories were created for the same word - Added findCardDirectory to check for existing directories before creating new ones - Updated all file creation functions to reuse existing card directories - Applied fix to both GUI and CLI code - Added phonetic fetching to processing counter in generateMaterials - Now each card gets one directory with all its files πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18fix: use timestamp+hash naming for directories in CLI to match GUIPaul Buetow
- Updated CLI code to use internal.GenerateCardID() for directory names - Changed file naming to match GUI: word.txt, translation.txt, audio.mp3, image.jpg/png - Created internal/utils.go with shared GenerateCardID and SanitizeFilename functions - Fixed all references to use the new naming system consistently - Ensures both CLI and GUI use the same directory and file naming convention πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18feat: major refactor - APKG export support and subdirectory organizationPaul Buetow
Major Features: - Added native .apkg (Anki package) export format with embedded media - Reorganized file structure to use subdirectories per word - Enhanced GUI export dialog with format selection (APKG/CSV) APKG Export Implementation: - Created apkg_generator.go with full SQLite-based Anki package generation - Includes custom card templates with professional CSS styling - Front side: Image + English word - Back side: Image + Bulgarian word + Audio + Notes - All media files automatically embedded in package - Custom deck names supported via --deck-name flag Directory Structure Changes: - Each word now gets its own subdirectory (e.g., anki_cards/ябълка/) - All related files (audio, images, translations, prompts) stored together - Cleaner organization and easier management - Prevents file naming conflicts GUI Updates: - Export dialog no longer shows file browser, exports directly to anki_cards - Format selection between APKG (recommended) and CSV (legacy) - Fixed navigation to properly load image prompts from subdirectories - Delete function now moves entire word directory to trash CLI Updates: - --anki flag now generates APKG by default - --anki-csv flag for legacy CSV format - All file generation uses subdirectory structure Bug Fixes: - Fixed handling of multi-word entries (e.g., "ΠΊΠ°Ρ€Ρ‚ΠΎΡ„ ΠΊΠ°Ρ€Ρ‚ΠΎΡ„ΠΈ") - Fixed GenerateFromDirectory to properly handle words with underscores - Fixed phonetic files being treated as separate cards - Fixed image prompt preservation during navigation Breaking Changes: - File structure changed from flat to subdirectory-based - Existing files need to be reorganized into subdirectories πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-17fix: prevent UI element mix-ups during concurrent processing and rapid ↡Paul Buetow
navigation - Fixed one-way translation bug: English to Bulgarian no longer triggers reverse translation - Prevent mix-ups when rapidly entering new words while previous words are processing - Ensure all UI elements update only for their associated job: * Bulgarian/English text fields protected by job ID checks * Phonetic info saved to disk immediately and UI updates restricted * Audio file associations protected from background job interference * Image prompts saved immediately and UI updates controlled - Add mutex protection for thread-safe UI updates - Disconnect from background jobs when user starts typing new input - Save all generated data to disk immediately, not just on UI update - Improve navigation to properly load all associated data from disk This ensures correct flashcard generation even with rapid word entry and navigation. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-17add phoenetic alphabetPaul Buetow
2025-07-17feat: add manual translation editing and bidirectional translationPaul Buetow
- Replace translation label with editable entry field - Move translation field next to Bulgarian input for better UX - Add bidirectional translation support: - Bulgarian β†’ English: auto-translate when only Bulgarian provided - English β†’ Bulgarian: auto-translate when only English provided - No translation when both fields are filled - Show translations immediately upon generation - Auto-save translations when edited - Keep input fields populated during processing πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-16Remove Pixabay and Unsplash image search supportPaul Buetow
- Delete Pixabay and Unsplash implementation files - Remove API key configuration for both services - Update CLI and GUI to only support OpenAI DALL-E - Update documentation to reflect OpenAI as sole image provider - Fix tests to handle nil client in OpenAI implementation - Simplify configuration examples The application now exclusively uses OpenAI DALL-E for image generation, providing AI-generated educational images with creative art styles. πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-16only one img per cardPaul Buetow
2025-07-16feat: add custom image prompt support and keyboard shortcutsPaul Buetow
- Add text area next to image display for custom image generation prompts - Users can specify their own prompts or leave empty for auto-generation - Display the used prompt in the text area after generation - Load prompts from attribution files when navigating to existing cards - Add keyboard shortcuts for all GUI buttons: - G: Generate, N: New Word, I: Regenerate Image, A: Regenerate Audio - R: Regenerate All, D: Delete, P: Play audio - Left/Right arrows: Navigate between words - Y/N: Confirm/cancel delete dialog - Update UI layout with equal 50/50 split between image and prompt - Enable text wrapping in prompt text area - Add 25% chance to ask OpenAI for creative photo style suggestions - Fix concurrent processing to properly use custom prompts πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-16feat: add Fyne GUI mode with interactive flashcard managementPaul Buetow
- 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>