summaryrefslogtreecommitdiff
path: root/internal/gui/persistence.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-06 10:47:33 +0300
committerPaul Buetow <paul@buetow.org>2026-04-06 10:47:33 +0300
commit95dd36d28d18615ad3f8dd7122a404850dcb39f8 (patch)
tree14c56ec1252d8bfe81faa46ea512d9aff8308da5 /internal/gui/persistence.go
parent05bddac137607102f12c1c464db34a1e10707af6 (diff)
refactor: decompose gui.Application god object into focused services
Extract CardService (file I/O, persistence, card directory management) and GenerationOrchestrator (audio/image/phonetics generation) from the 2852-line Application struct. Application is now thin UI event-wiring. Also split all functions over 50 lines into focused helpers throughout app.go. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/gui/persistence.go')
-rw-r--r--internal/gui/persistence.go105
1 files changed, 17 insertions, 88 deletions
diff --git a/internal/gui/persistence.go b/internal/gui/persistence.go
index 0919974..e97a379 100644
--- a/internal/gui/persistence.go
+++ b/internal/gui/persistence.go
@@ -2,110 +2,39 @@ package gui
import (
"fmt"
- "os"
- "path/filepath"
-
- "fyne.io/fyne/v2"
-
- "codeberg.org/snonux/totalrecall/internal"
)
-// ensureWordDirectoryAndMetadata creates a new card directory and writes word metadata.
+// ensureWordDirectoryAndMetadata creates a new card directory and writes word
+// metadata. Delegates to CardService.
func (a *Application) ensureWordDirectoryAndMetadata(word string) (string, error) {
- cardID := internal.GenerateCardID(word)
- wordDir := filepath.Join(a.config.OutputDir, cardID)
- if err := os.MkdirAll(wordDir, 0755); err != nil {
- return "", fmt.Errorf("failed to create card directory: %w", err)
- }
-
- metadataFile := filepath.Join(wordDir, "word.txt")
- if err := os.WriteFile(metadataFile, []byte(word), 0644); err != nil {
- return "", fmt.Errorf("failed to save word metadata: %w", err)
- }
-
- return wordDir, nil
+ return a.getCardService().EnsureWordDirectoryAndMetadata(word)
}
-// ensureCardDirectory ensures a card directory exists for the given word and returns its path.
+// ensureCardDirectory ensures a card directory exists for the given word.
+// Delegates to CardService.
func (a *Application) ensureCardDirectory(word string) (string, error) {
- wordDir := a.findCardDirectory(word)
- if wordDir != "" {
- return wordDir, nil
- }
-
- return a.ensureWordDirectoryAndMetadata(word)
+ return a.getCardService().EnsureCardDirectory(word)
}
-// saveTranslation saves the current translation to a file.
+// saveTranslation saves the current translation to disk.
+// Delegates to CardService.
func (a *Application) saveTranslation() {
- if a.currentWord == "" || a.currentTranslation == "" {
- return
- }
-
- wordDir := a.findCardDirectory(a.currentWord)
- if wordDir == "" {
- newWordDir, err := a.ensureWordDirectoryAndMetadata(a.currentWord)
- if err != nil {
- a.showError(err)
- return
- }
- wordDir = newWordDir
- }
-
- translationFile := filepath.Join(wordDir, "translation.txt")
- content := fmt.Sprintf("%s = %s\n", a.currentWord, a.currentTranslation)
- if err := os.WriteFile(translationFile, []byte(content), 0644); err != nil {
- a.showError(fmt.Errorf("failed to save translation: %w", err))
+ if err := a.getCardService().SaveTranslation(a.currentWord, a.currentTranslation); err != nil {
+ a.showError(err)
}
}
-// saveImagePrompt saves the current image prompt to a file.
+// saveImagePrompt is retained for compatibility but is currently a no-op.
+// The image prompt is saved by the image generation callback when the image
+// is generated, so there is no need to save it separately here.
func (a *Application) saveImagePrompt() {
- // With timestamp-based card IDs, we can't update existing prompts.
- // The prompt is saved when the image is generated.
- // This function is kept for compatibility but does nothing.
+ // No-op: the prompt is saved as soon as it is generated via the callback.
}
-// savePhoneticInfo saves the phonetic information to a file.
+// savePhoneticInfo saves the current phonetic information to disk.
+// Delegates to CardService.
func (a *Application) savePhoneticInfo() {
- phoneticText := a.currentPhonetic
- if a.currentWord == "" || phoneticText == "" || phoneticText == "Failed to fetch phonetic information" {
- return
- }
-
- wordDir := a.findCardDirectory(a.currentWord)
- if wordDir == "" {
- newWordDir, err := a.ensureWordDirectoryAndMetadata(a.currentWord)
- if err != nil {
- a.showError(err)
- return
- }
- wordDir = newWordDir
- }
-
- phoneticFile := filepath.Join(wordDir, "phonetic.txt")
- if err := os.WriteFile(phoneticFile, []byte(phoneticText), 0644); err != nil {
+ if err := a.getCardService().SavePhoneticInfo(a.currentWord, a.currentPhonetic); err != nil {
a.showError(fmt.Errorf("failed to save phonetic info: %w", err))
}
}
-
-// loadPhoneticInfo loads phonetic information from a file if it exists.
-func (a *Application) loadPhoneticInfo(word string) {
- wordDir := a.findCardDirectory(word)
- if wordDir == "" {
- return
- }
-
- phoneticFile := filepath.Join(wordDir, "phonetic.txt")
- if data, err := os.ReadFile(phoneticFile); err == nil {
- phoneticText := string(data)
- a.currentPhonetic = phoneticText
- fyne.Do(func() {
- if phoneticText != "" {
- a.audioPlayer.SetPhonetic(phoneticText)
- } else {
- a.audioPlayer.SetPhonetic("")
- }
- })
- }
-}