diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-02 07:16:49 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-02 07:16:49 +0300 |
| commit | e96cc2578595a0ec22a07819cd0eb1b0b0c711f7 (patch) | |
| tree | 0df43845dedeb27ba2afaadfb5a821aeee7a713b /internal/gui/audio_paths.go | |
| parent | faa2465955445ac1cb1461eb70a98280d32fbf9a (diff) | |
Harden GUI audio loading for Gemini
Diffstat (limited to 'internal/gui/audio_paths.go')
| -rw-r--r-- | internal/gui/audio_paths.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/internal/gui/audio_paths.go b/internal/gui/audio_paths.go new file mode 100644 index 0000000..baee232 --- /dev/null +++ b/internal/gui/audio_paths.go @@ -0,0 +1,74 @@ +package gui + +import ( + "os" + "path/filepath" + "strings" + "time" +) + +var supportedAudioExtensions = map[string]struct{}{ + ".aac": {}, + ".flac": {}, + ".mp3": {}, + ".opus": {}, + ".wav": {}, +} + +func (a *Application) resolveSingleAudioFile(wordDir string) string { + return resolveAudioFileByBaseName(wordDir, "audio") +} + +func (a *Application) resolveBgBgAudioFiles(wordDir string) (string, string) { + return resolveAudioFileByBaseName(wordDir, "audio_front"), resolveAudioFileByBaseName(wordDir, "audio_back") +} + +func (a *Application) hasAnyAudioFile(wordDir string) bool { + single := a.resolveSingleAudioFile(wordDir) + if single != "" { + return true + } + + front, back := a.resolveBgBgAudioFiles(wordDir) + return front != "" || back != "" +} + +func resolveAudioFileByBaseName(wordDir, baseName string) string { + entries, err := os.ReadDir(wordDir) + if err != nil { + return "" + } + + prefix := baseName + "." + var resolved string + var resolvedModTime time.Time + + for _, entry := range entries { + if entry.IsDir() { + continue + } + + name := entry.Name() + if !strings.HasPrefix(name, prefix) { + continue + } + + ext := strings.ToLower(filepath.Ext(name)) + if _, ok := supportedAudioExtensions[ext]; !ok { + continue + } + + info, err := entry.Info() + if err != nil { + continue + } + + candidate := filepath.Join(wordDir, name) + if resolved == "" || info.ModTime().After(resolvedModTime) || (info.ModTime().Equal(resolvedModTime) && candidate < resolved) { + resolved = candidate + resolvedModTime = info.ModTime() + } + } + + return resolved +} |
