Add downloading message to home screen.

Download files in the background and keep track of progress.
This commit is contained in:
NeilClack
2026-06-18 22:43:47 -05:00
parent 2af1aae885
commit ac86864c72
3 changed files with 78 additions and 42 deletions
+2 -1
View File
@@ -154,7 +154,8 @@ func Run() {
app.initializeManagers()
app.initializeAudio()
downloadProgressChan := make(chan download.DownloadStatus)
// Create a buffered channel so log writes don't slow down downloads.
downloadProgressChan := make(chan download.DownloadStatus, 1000)
app.PageRouter = page.NewRouter(page.PageCtx{
CfgPtr: app.Config.Load(),
+5 -4
View File
@@ -30,6 +30,7 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
// First, calculate the total size of files that need to be downloaded
totalSize := int64(0)
filesToDownload := []string{}
totalDownloaded := int64(0)
for _, filename := range filenames {
destPath := filepath.Join(destDir, filename)
@@ -62,13 +63,15 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
// Append it to the list to download
filesToDownload = append(filesToDownload, filename)
// And increase the total bytes to download
totalSize += resp.ContentLength
} else if err != nil {
logger.Error("unknown error: %v", err)
} else {
logger.Error("File %s exists, skipping...", filename)
totalDownloaded += fileStat.Size()
}
// Calculate the total of ALL files to give the illusion of
// "picking up where you left off" to the user
totalSize += resp.ContentLength
resp.Body.Close()
}
@@ -79,8 +82,6 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
Msg: "Starting download...",
}
totalDownloaded := int64(0)
// Download each file that doesn't exist
for _, filename := range filesToDownload {
url := urlBase + filename
+71 -37
View File
@@ -153,47 +153,81 @@ func (p *Home) HandleEvent(event *sdl.Event) error {
return nil
}
// Update updates animations and changing textures and other changes using `dt` which represents a time delta in float32.
func (p *Home) Update(dt float32) error {
select {
case progressUpdate, ok := <-p.Context.MessageChannel:
if !ok {
// Channel is closed, set message to READY
newMsg, err := NewStringItem("Status: READY", p.font, colors.Green)
if err != nil {
return err
var (
progressUpdate download.DownloadStatus
ok bool
gotUpdate bool
)
// Drain the channel, keeping only the newest update.
for {
select {
case progressUpdate, ok = <-p.Context.MessageChannel:
gotUpdate = true
if !ok {
// Channel was closed while draining.
newMsg, err := NewStringItem("Status: READY", p.font, colors.Green)
if err != nil {
return err
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
p.isDownloadComplete = true
return nil
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
p.isDownloadComplete = true
} else if progressUpdate.Err != nil {
// Handle error
newMsg, err := NewStringItem(fmt.Sprintf("Status: %s", progressUpdate.Err.Error), p.font, colors.Red)
if err != nil {
return err
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
} else {
// Update progress message
percentComplete := float64(progressUpdate.Cur) / float64(progressUpdate.Max) * 100
msg := fmt.Sprintf("Status: Downloading assets %.1f%% Complete", percentComplete)
newMsg, err := NewStringItem(msg, p.font, colors.White)
if err != nil {
return err
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
default:
goto drained
}
default:
// No update, do nothing
}
drained:
if !gotUpdate {
return nil
}
if progressUpdate.Err != nil {
// Handle error
newMsg, err := NewStringItem(
fmt.Sprintf("Status: %s", progressUpdate.Err.Error()),
p.font,
colors.Red,
)
if err != nil {
return err
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
} else {
// Update progress message using ONLY the latest update.
percentComplete := float64(progressUpdate.Cur) / float64(progressUpdate.Max) * 100
msg := fmt.Sprintf(
"Status: Downloading assets %.1f%% Complete",
percentComplete,
)
newMsg, err := NewStringItem(msg, p.font, colors.White)
if err != nil {
return err
}
messageScale := float32(28) / float32(p.baseFontSize)
newMsg.W = int32(float32(newMsg.W) * messageScale)
newMsg.H = int32(float32(newMsg.H) * messageScale)
p.message = newMsg
}
return nil
}