chores/random chores (#60)

* fix(tui): remove horrible code that was taking up space

* fix(tui): rework error and notice messages to be at the top of the tui, fixing the entire UI shifting when a message pops up
This commit is contained in:
2026-06-29 20:14:05 +02:00
committed by GitHub
parent 9d5096b270
commit ebd3e20285
7 changed files with 28 additions and 23 deletions

View File

@@ -20,7 +20,7 @@ import (
func (m Model) accountBodyHeight() int { func (m Model) accountBodyHeight() int {
headerHeight := lipgloss.Height(m.BuildHeader()) headerHeight := lipgloss.Height(m.BuildHeader())
footerHeight := lipgloss.Height(m.BuildFooter()) footerHeight := lipgloss.Height(m.BuildFooter())
budget := m.heightContainer - headerHeight - footerHeight - 2 budget := m.heightContainer - headerHeight - footerHeight - 2 - 1
cards := budget / orderCardHeight cards := budget / orderCardHeight
cards = max(cards, 1) cards = max(cards, 1)
return cards*orderCardHeight - 2 return cards*orderCardHeight - 2
@@ -678,7 +678,7 @@ func (m Model) PrivacyView(width int) string {
}, },
} }
out := bodyStyle.Render(wordWrap("", width)) out := ""
for _, s := range sections { for _, s := range sections {
out += labelStyle.Render(s.title) + "\n" out += labelStyle.Render(s.title) + "\n"
out += bodyStyle.Render(wordWrap(s.body, width)) + "\n\n" out += bodyStyle.Render(wordWrap(s.body, width)) + "\n\n"

View File

@@ -14,7 +14,7 @@ func (m Model) updateCartViewport() Model {
breadH := lipgloss.Height(m.BuildBreadcrumbs()) breadH := lipgloss.Height(m.BuildBreadcrumbs())
footerH := lipgloss.Height(m.BuildFooter()) footerH := lipgloss.Height(m.BuildFooter())
// 2 = blank gap rows around the cart list // 2 = blank gap rows around the cart list
availH := m.heightContainer - headerH - footerH - breadH - 2 availH := m.heightContainer - headerH - footerH - breadH - 2 - 1
if availH < 1 { if availH < 1 {
availH = 1 availH = 1
} }

View File

@@ -70,7 +70,7 @@ func (m Model) updateConfirmViewport() Model {
headerH := lipgloss.Height(m.BuildHeader()) headerH := lipgloss.Height(m.BuildHeader())
breadH := lipgloss.Height(m.BuildBreadcrumbs()) breadH := lipgloss.Height(m.BuildBreadcrumbs())
footerH := lipgloss.Height(m.BuildFooter()) footerH := lipgloss.Height(m.BuildFooter())
availH := m.heightContainer - headerH - footerH - breadH availH := m.heightContainer - headerH - footerH - breadH - 1
if availH < 1 { if availH < 1 {
availH = 1 availH = 1
} }

View File

@@ -296,7 +296,7 @@ func (m Model) updatePaymentViewport() Model {
headerH := lipgloss.Height(m.BuildHeader()) headerH := lipgloss.Height(m.BuildHeader())
breadH := lipgloss.Height(m.BuildBreadcrumbs()) breadH := lipgloss.Height(m.BuildBreadcrumbs())
footerH := lipgloss.Height(m.BuildFooter()) footerH := lipgloss.Height(m.BuildFooter())
availH := m.heightContainer - headerH - footerH - breadH availH := m.heightContainer - headerH - footerH - breadH - 1
availH = max(availH, 1) availH = max(availH, 1)
if !m.payment.viewportReady { if !m.payment.viewportReady {
m.payment.viewport = viewport.New(viewport.WithWidth(m.widthContent), viewport.WithHeight(availH)) m.payment.viewport = viewport.New(viewport.WithWidth(m.widthContent), viewport.WithHeight(availH))

View File

@@ -257,7 +257,7 @@ func (m Model) updateShippingViewport() Model {
headerH := lipgloss.Height(m.BuildHeader()) headerH := lipgloss.Height(m.BuildHeader())
breadH := lipgloss.Height(m.BuildBreadcrumbs()) breadH := lipgloss.Height(m.BuildBreadcrumbs())
footerH := lipgloss.Height(m.BuildFooter()) footerH := lipgloss.Height(m.BuildFooter())
availH := m.heightContainer - headerH - footerH - breadH availH := m.heightContainer - headerH - footerH - breadH - 1
if availH < 1 { if availH < 1 {
availH = 1 availH = 1
} }

View File

@@ -93,4 +93,8 @@ func (t Theme) PanelError() lipgloss.Style {
return t.Base().Background(lipgloss.Color("52")).Foreground(lipgloss.Color("196")) return t.Base().Background(lipgloss.Color("52")).Foreground(lipgloss.Color("196"))
} }
func (t Theme) PanelNotice() lipgloss.Style {
return t.Base().Background(lipgloss.Color("#009000")).Foreground(lipgloss.Color("#00FF00"))
}
func (t Theme) Form() huh.Theme { return t.form } func (t Theme) Form() huh.Theme { return t.form }

View File

@@ -67,7 +67,8 @@ func (m Model) renderString() string {
marginTop := 1 marginTop := 1
marginBottom := 1 marginBottom := 1
bufferSpace := 1 bufferSpace := 1
reservedHeight := headerHeight + breadcrumbsHeight + footerHeight + marginTop + marginBottom + bufferSpace bannerHeight := 1
reservedHeight := bannerHeight + headerHeight + breadcrumbsHeight + footerHeight + marginBottom + marginTop + bufferSpace
availableContentHeight := m.heightContainer - reservedHeight availableContentHeight := m.heightContainer - reservedHeight
// Ensure minimum content height // Ensure minimum content height
@@ -81,22 +82,21 @@ func (m Model) renderString() string {
if m.Loading { if m.Loading {
loadingStyle := m.theme.TextLoading().Padding(2, 4) loadingStyle := m.theme.TextLoading().Padding(2, 4)
content = loadingStyle.Render("Loading products from API...") content = loadingStyle.Render("Loading products from API...")
} else if m.error != nil {
errorStyle := m.theme.PanelError().Padding(0, 1).MarginBottom(1)
// soft-wrap long messages instead of clipping.
if m.widthContent > 4 {
errorStyle = errorStyle.Width(m.widthContent - 4)
}
errorBanner := errorStyle.Render(m.error.message)
content = errorBanner + "\n" + m.buildPageContent()
} else if m.notice != nil {
noticeStyle := m.theme.TextSuccess().Border(lipgloss.NormalBorder()).BorderForeground(m.theme.Success()).Padding(0, 1).MarginBottom(1)
noticeBanner := noticeStyle.Render(m.notice.message)
content = noticeBanner + "\n" + m.buildPageContent()
} else { } else {
content = m.buildPageContent() content = m.buildPageContent()
} }
bannerW := lipgloss.Width(header) - 2
var topBanner string
switch {
case m.error != nil:
topBanner = m.theme.PanelError().Width(bannerW).MaxWidth(bannerW).Render(m.error.message)
case m.notice != nil:
topBanner = m.theme.PanelNotice().Width(bannerW).MaxWidth(bannerW).Render(m.notice.message)
default:
topBanner = lipgloss.NewStyle().Width(m.widthContent).Render("")
}
isViewportPage := m.currentPage == shopPage || m.currentPage == cartPage || isViewportPage := m.currentPage == shopPage || m.currentPage == cartPage ||
m.currentPage == shippingPage || m.currentPage == paymentPage || m.currentPage == shippingPage || m.currentPage == paymentPage ||
m.currentPage == confirmPage || m.currentPage == accountPage m.currentPage == confirmPage || m.currentPage == accountPage
@@ -104,20 +104,21 @@ func (m Model) renderString() string {
var child string var child string
if isViewportPage { if isViewportPage {
if breadcrumbs != "" { if breadcrumbs != "" {
child = lipgloss.JoinVertical(lipgloss.Left, header, breadcrumbs, content, footer) child = lipgloss.JoinVertical(lipgloss.Left, topBanner, header, breadcrumbs, content, footer)
} else { } else {
child = lipgloss.JoinVertical(lipgloss.Left, header, content, footer) child = lipgloss.JoinVertical(lipgloss.Left, topBanner, header, content, footer)
} }
} else if breadcrumbs != "" { } else if breadcrumbs != "" {
contentWithPadding := lipgloss.NewStyle().MarginTop(marginTop).MarginBottom(marginBottom).Height(availableContentHeight).Render(content) contentWithPadding := lipgloss.NewStyle().MarginTop(marginTop).MarginBottom(marginBottom).Height(availableContentHeight).Render(content)
child = lipgloss.JoinVertical(lipgloss.Left, header, breadcrumbs, contentWithPadding, footer) child = lipgloss.JoinVertical(lipgloss.Left, topBanner, header, breadcrumbs, contentWithPadding, footer)
} else { } else {
contentWithPadding := lipgloss.NewStyle().MarginTop(marginTop).MarginBottom(marginBottom).Height(availableContentHeight).Render(content) contentWithPadding := lipgloss.NewStyle().MarginTop(marginTop).MarginBottom(marginBottom).Height(availableContentHeight).Render(content)
child = lipgloss.JoinVertical(lipgloss.Left, header, contentWithPadding, footer) child = lipgloss.JoinVertical(lipgloss.Left, topBanner, header, contentWithPadding, footer)
} }
// Constrain the assembled layout to the container dimensions // Constrain the assembled layout to the container dimensions
constrained := lipgloss.NewStyle(). constrained := lipgloss.NewStyle().
Width(m.widthContainer).
MaxWidth(m.widthContainer). MaxWidth(m.widthContainer).
MaxHeight(m.heightContainer). MaxHeight(m.heightContainer).
Render(child) Render(child)