Forge success label and real progress bar tied to server compile stages.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Replace Dispensed with Forged in the reveal modal, poll builder/progress with indeterminate-until-first-byte UX, and emit interpolated compile progress during long garble builds.
This commit is contained in:
AetherForge
2026-06-08 19:48:24 -07:00
parent 0c7b676e23
commit 6ab43a468b
12 changed files with 273 additions and 147 deletions

View File

@@ -253,8 +253,9 @@ func (h *Handler) buildAPKAgent(ctx context.Context, req *BuildRequest) (BuildRe
}
platform := BuildPlatform{GOOS: "linux", GOARCH: "arm64", Ext: ""}
h.setProgress(req.CancelToken, "Compiling agent (linux/arm64)", 25)
stopCompileProgress := h.tickCompileProgress(ctx, req.CancelToken, "Compiling agent (linux/arm64)", 25, 54, false)
outputPath, err := h.compileWorker(ctx, agentDir, buildDir, req, buildID, platform, false)
stopCompileProgress()
if err != nil {
cleanupBuild()
return BuildResponse{Success: false, Error: err.Error()}, http.StatusInternalServerError, ""

View File

@@ -34,10 +34,17 @@ func (h *Handler) buildUniversalAgent(ctx context.Context, req *BuildRequest, pr
platforms := platformsForRequest(req)
workerPaths := map[string]string{}
total := len(platforms)
obfuscated := h.shouldObfuscate(req) && h.garblePath != ""
for i, p := range platforms {
pct := 14 + (i*56)/total
h.setProgress(req.CancelToken, fmt.Sprintf("Compiling %s", p.Label()), pct)
startPct := 14 + (i*56)/total
endPct := 14 + ((i+1)*56)/total
if endPct > 71 {
endPct = 71
}
stage := fmt.Sprintf("Compiling %s", p.Label())
stopCompileProgress := h.tickCompileProgress(ctx, req.CancelToken, stage, startPct, endPct, obfuscated)
wp, err := h.compileWorker(ctx, agentDir, buildDir, req, buildID, p, req.FusionEnabled)
stopCompileProgress()
if err != nil {
cleanupBuild()
return BuildResponse{Success: false, Error: err.Error()}, http.StatusInternalServerError, ""

View File

@@ -690,15 +690,16 @@ func (h *Handler) buildAgent(ctx context.Context, req *BuildRequest, prepPath st
platforms := platformsForRequest(req)
p := platforms[0]
h.setProgress(req.CancelToken, "Compiling agent", 20)
obfuscated := h.shouldObfuscate(req) && h.garblePath != ""
stopCompileProgress := h.tickCompileProgress(ctx, req.CancelToken, "Compiling agent", 20, 71, obfuscated)
outputPath, err := h.compileWorker(ctx, agentDir, buildDir, req, buildID, p, req.FusionEnabled)
stopCompileProgress()
if err != nil {
cleanupBuild()
log.Printf("Build failed: %v", err)
return BuildResponse{Success: false, Error: err.Error()}, http.StatusInternalServerError, ""
}
h.setProgress(req.CancelToken, "Compiled — linking output", 72)
obfuscated := h.shouldObfuscate(req) && h.garblePath != ""
workerName := filepath.Base(outputPath)
finalPath := outputPath
finalName := workerName

View File

@@ -0,0 +1,45 @@
package builder
import (
"context"
"time"
)
// tickCompileProgress emits interpolated progress during long compile steps (garble can run 10+ minutes).
// Returns a stop function; call it when the compile finishes.
func (h *Handler) tickCompileProgress(ctx context.Context, token, stage string, startPct, capPct int, obfuscated bool) func() {
if token == "" || capPct <= startPct {
return func() {}
}
est := 3 * time.Minute
if obfuscated {
est = 12 * time.Minute
}
done := make(chan struct{})
go func() {
h.setProgress(token, stage, startPct)
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
start := time.Now()
for {
select {
case <-done:
return
case <-ctx.Done():
return
case <-ticker.C:
elapsed := time.Since(start)
ratio := float64(elapsed) / float64(est)
if ratio > 0.92 {
ratio = 0.92
}
pct := startPct + int(float64(capPct-startPct)*ratio)
if pct >= capPct {
pct = capPct - 1
}
h.setProgress(token, stage, pct)
}
}
}()
return func() { close(done) }
}