From 69cfa837355c41504cd7771eceab93a793ac7057 Mon Sep 17 00:00:00 2001 From: frozendolphin <122843077+frozendolphin@users.noreply.github.com> Date: Tue, 2 Jun 2026 06:07:01 -0700 Subject: [PATCH 1/2] Show XP in CLI success output --- client/lessons.go | 8 ++++++++ messages/messages.go | 6 ++++-- render/models.go | 16 +++++++++------- render/render.go | 8 ++++++-- render/view.go | 26 ++++++++++++++++++++++++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/client/lessons.go b/client/lessons.go index f4ce9bf..f58b414 100644 --- a/client/lessons.go +++ b/client/lessons.go @@ -199,9 +199,17 @@ type SubmissionDebugData struct { ResponseBody string } +type XPBreakdownItem struct { + Name string + Percent float64 + XP int +} + type LessonSubmissionEvent struct { ResultSlug VerificationResultSlug StructuredErrCLI *StructuredErrCLI + XPReward int + XPBreakdown []XPBreakdownItem } type StructuredErrCLI struct { diff --git a/messages/messages.go b/messages/messages.go index 37359da..073fa8c 100644 --- a/messages/messages.go +++ b/messages/messages.go @@ -21,8 +21,10 @@ type ResolveTestMsg struct { } type DoneStepMsg struct { - Result api.VerificationResultSlug - Failure *api.StructuredErrCLI + Result api.VerificationResultSlug + Failure *api.StructuredErrCLI + XPReward int + XPBreakdown []api.XPBreakdownItem } type ResolveStepMsg struct { diff --git a/render/models.go b/render/models.go index 7705f26..1574b6e 100644 --- a/render/models.go +++ b/render/models.go @@ -22,13 +22,15 @@ type stepModel struct { } type rootModel struct { - steps []stepModel - spinner spinner.Model - result api.VerificationResultSlug - failure *api.StructuredErrCLI - isSubmit bool - finalized bool - clear bool + steps []stepModel + spinner spinner.Model + result api.VerificationResultSlug + failure *api.StructuredErrCLI + xpReward int + xpBreakdown []api.XPBreakdownItem + isSubmit bool + finalized bool + clear bool } func initModel(isSubmit bool) rootModel { diff --git a/render/render.go b/render/render.go index 183cead..91dbe94 100644 --- a/render/render.go +++ b/render/render.go @@ -36,6 +36,8 @@ func (m rootModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case messages.DoneStepMsg: m.result = msg.Result m.failure = msg.Failure + m.xpReward = msg.XPReward + m.xpBreakdown = msg.XPBreakdown m.clear = true return m, tea.Quit @@ -121,8 +123,10 @@ func StartRenderer(data api.CLIData, isSubmit bool, ch chan tea.Msg) func(api.Le return func(submissionEvent api.LessonSubmissionEvent) { ch <- messages.DoneStepMsg{ - Result: submissionEvent.ResultSlug, - Failure: submissionEvent.StructuredErrCLI, + Result: submissionEvent.ResultSlug, + Failure: submissionEvent.StructuredErrCLI, + XPReward: submissionEvent.XPReward, + XPBreakdown: submissionEvent.XPBreakdown, } wg.Wait() } diff --git a/render/view.go b/render/view.go index 5d36643..46643d7 100644 --- a/render/view.go +++ b/render/view.go @@ -151,8 +151,30 @@ func (m rootModel) View() string { } if m.result == api.VerificationResultSlugSuccess && m.isSubmit { - str.WriteString("\n\n" + green.Render("All tests passed! 🎉") + "\n\n") - str.WriteString(green.Render("Return to your browser to continue with the next lesson.") + "\n\n") + str.WriteString("\n\n" + green.Render("All tests passed! 🎉") + "\n") + if m.xpReward > 0 { + str.WriteString("\n") + str.WriteString(green.Bold(true).Render(fmt.Sprintf("Gained +%d XP", m.xpReward))) + str.WriteByte('\n') + for _, item := range m.xpBreakdown { + if item.XP == 0 { + continue + } + sign := "+" + xp := item.XP + if xp < 0 { + sign = "-" + xp = -xp + } + if item.Percent > 0 { + str.WriteString(gray.Render(fmt.Sprintf("%s%3d XP (%-4s %s)", sign, xp, fmt.Sprintf("%.0f%%", item.Percent*100), item.Name))) + } else { + str.WriteString(gray.Render(fmt.Sprintf("%s%3d XP (%s)", sign, xp, item.Name))) + } + str.WriteByte('\n') + } + } + str.WriteString("\n" + green.Render("Return to your browser to continue with the next lesson.") + "\n\n") } else if m.result == api.VerificationResultSlugNoop { str.WriteString("\n\nTests failed! ❌") fmt.Fprintf(&str, "\n\nFailed Step: %v", m.failure.FailedStepIndex+1) From 11cfd41b18eed0b28cecb80913d993aa94ccd1f5 Mon Sep 17 00:00:00 2001 From: frozendolphin <122843077+frozendolphin@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:05:25 -0700 Subject: [PATCH 2/2] bump version patch number to 1.29.6 --- render/view.go | 2 +- version.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/render/view.go b/render/view.go index 46643d7..1f9712b 100644 --- a/render/view.go +++ b/render/view.go @@ -152,7 +152,7 @@ func (m rootModel) View() string { if m.result == api.VerificationResultSlugSuccess && m.isSubmit { str.WriteString("\n\n" + green.Render("All tests passed! 🎉") + "\n") - if m.xpReward > 0 { + if m.xpReward >= 0 { str.WriteString("\n") str.WriteString(green.Bold(true).Render(fmt.Sprintf("Gained +%d XP", m.xpReward))) str.WriteByte('\n') diff --git a/version.txt b/version.txt index e5bb4cb..84f4142 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v1.29.5 +v1.29.6