Gate READY on download completion; move audio to ~/.radiantwave/audio

State machine now uses DOWNLOADING_ASSETS before READY. Downloads closing
the DownloadDone channel signals checkState() to proceed. Download failure
sets downloadFailed flag which prevents READY. Audio files moved from
~/.local/share/rhemawave/audio to ~/.radiantwave/audio/.

Regression tests in application_test.go (linux build-tagged due to
network package D-Bus init). Version 0.6.
This commit is contained in:
NeilClack
2026-07-11 13:43:05 -05:00
parent 2cc5071731
commit 3f8144a708
7 changed files with 252 additions and 26 deletions
+10 -3
View File
@@ -13,7 +13,7 @@ import (
"rhemawavetech.com/rhemawave/internal/shaderManager"
)
var GitVersion = "Audio-Bug-Fix 0.5"
var GitVersion = "Audio-Bug-Fix 0.6"
type Home struct {
Base
@@ -31,6 +31,7 @@ type Home struct {
hasLicenseInfo bool
baseFontSize int
isDownloadComplete bool
downloadFailed bool
}
// Init performs basic page initialization and creation of static assets.
@@ -172,8 +173,13 @@ func (p *Home) Update(dt float32) error {
case progressUpdate, ok = <-p.Context.MessageChannel:
gotUpdate = true
if !ok {
p.setMessage("Status: READY", colors.Green)
p.isDownloadComplete = true
if p.downloadFailed {
p.setMessage("Download failed — restart to retry", colors.Red)
} else {
p.setMessage("Status: READY", colors.Green)
p.isDownloadComplete = true
close(p.Context.DownloadDone)
}
return nil
}
default:
@@ -187,6 +193,7 @@ drained:
}
if progressUpdate.Err != nil {
p.downloadFailed = true
p.setMessage(fmt.Sprintf("Error: %s", progressUpdate.Err.Error()), colors.Red)
return nil
}
+1
View File
@@ -25,6 +25,7 @@ type PageCtx struct {
DbPtr *gorm.DB
W, H int32
MessageChannel chan download.DownloadStatus
DownloadDone chan struct{} // closed when downloads finish (success or failure)
NavigateTo func(pageType)
Msg string // Message to be displayed by MessagePage
Inst string // Instructions to be displayed on MessagePage
+11 -6
View File
@@ -291,7 +291,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
if err := p.Context.DbPtr.Where("Selected = ?", true).First(&selectedAudio).Error; err != nil {
selectedAudio = db.AudioFile{
Name: "OriginalAudio",
Path: filepath.Join(config.AssetsDir, "audio", "OriginalAudio.wav"),
Path: filepath.Join(audioDir(), "OriginalAudio.wav"),
Selected: true,
Order: 0,
}
@@ -420,14 +420,19 @@ func (p *ScrollerPage) loadProclamations() error {
return nil
}
// audioPathForFrequency builds the on-disk path for a solfeggio frequency's
// audio file, e.g. 396 -> "<AssetsDir>/audio/396Hz.wav".
func (p *ScrollerPage) audioPathForFrequency(freq int) string {
config, err := db.GetConfig(p.Context.DbPtr)
// audioDir returns the path to the audio files directory (~/.radiantwave/audio).
func audioDir() string {
home, err := os.UserHomeDir()
if err != nil {
panic(err)
}
return filepath.Join(config.AssetsDir, "audio", fmt.Sprintf("%dHz.wav", freq))
return filepath.Join(home, ".radiantwave", "audio")
}
// audioPathForFrequency builds the on-disk path for a solfeggio frequency's
// audio file, e.g. 396 -> "~/.radiantwave/audio/396Hz.wav".
func (p *ScrollerPage) audioPathForFrequency(freq int) string {
return filepath.Join(audioDir(), fmt.Sprintf("%dHz.wav", freq))
}
// switchAudioForFrequency swaps the currently playing track to match freq.