diff --git a/tui/view/tap/style.go b/tui/view/tap/style.go index d72b0e4..f51e442 100644 --- a/tui/view/tap/style.go +++ b/tui/view/tap/style.go @@ -1,23 +1,8 @@ package tap -import "github.com/charmbracelet/lipgloss" - -var base = lipgloss.NewStyle() - -// Width -var ( - widthAmount = 5 - widthCategory = 8 - widthLast = 13 -) - -// Margin -var mStats = 2 - -// Barchart -var ( - widthBar = 40 - heightBar = 20 +import ( + "github.com/charmbracelet/lipgloss" + "github.com/zeusWPI/scc/tui/view" ) // Colors @@ -31,20 +16,62 @@ var ( cStatsTitle = lipgloss.Color("#EE4B2B") ) -// Styles Chart +// Base style +var base = lipgloss.NewStyle() + +// Styles for the barchart var ( - sMate = base.Foreground(cMate) - sSoft = base.Foreground(cSoft) - sBeer = base.Foreground(cBeer) - sFood = base.Foreground(cFood) - sUnknown = base + // Widths + wBarGap = 1 // Gap between bars + wBar = 5 // Width of bar, gets dynamically adjusted + wBarMin = 4 // Minimum width required for the bar label + wBarAmount = len(categoryToStyle) // Amount of bars. Is the same as the amount of categories + + sBar = base.MarginBottom(1) + sBarOne = base + sBarLabel = base.Align(lipgloss.Center) +) + +// Styles for the stats +var ( + // Widths + wStatAmount = 5 // Supports up to 9999 with a space after it (or 99999 without a space) + wStatCategory = 4 // Longest label is 4 chars + wStatLast = 11 // 11 characters, for example '18:53 20/12' + wStatGapMin = 3 // Minimum gap size between the category and last purchase + + sStat = base.BorderStyle(lipgloss.ThickBorder()).BorderForeground(cBorder).BorderLeft(true).Margin(0, 1, 1, 1).PaddingLeft(1) + sStatTitle = base.Foreground(cStatsTitle).Bold(true).BorderStyle(lipgloss.NormalBorder()).BorderForeground(cBorder).BorderBottom(true).Align(lipgloss.Center).MarginBottom(1) + sStatAmount = base.Width(wStatAmount).Bold(true) + sStatCategory = base.Width(wStatCategory) + sStatLast = base.Width(wStatLast).Align(lipgloss.Right).Italic(true).Faint(true) ) -// Styles stats +// Styles for the different categories var ( - sStats = base.Border(lipgloss.NormalBorder(), false, false, false, true).BorderForeground(cBorder).MarginLeft(mStats).PaddingLeft(mStats) - sStatsTitle = base.Foreground(cStatsTitle).Bold(true).Width(widthAmount+widthCategory+widthLast).Border(lipgloss.NormalBorder(), false, false, true, false).BorderForeground(cBorder) - sStatsAmount = base.Width(widthAmount).Bold(true) - sStatsCategory = base.Width(widthCategory) - sStatsLast = base.Width(widthLast).Align(lipgloss.Right).Italic(true).Faint(true) + sMate = base.Foreground(cMate) + sSoft = base.Foreground(cSoft) + sBeer = base.Foreground(cBeer) + sFood = base.Foreground(cFood) ) + +func (m *Model) updateStyles() { + wStatWithoutGap := wStatAmount + wStatCategory + wStatLast + view.GetOuterWidth(sStat) + wBar = (m.width - wStatWithoutGap - wStatGapMin - wBarAmount*wBarGap) / wBarAmount + if wBar < wBarMin { + // Screen too small + return + } + + // Adjust bar styles + sBar = sBar.Width(wBarAmount*wBar + view.GetOuterWidth(sBar)).Height(m.height - view.GetOuterHeight(sBar)) + sBarLabel = sBarLabel.Width(wBar) + + // Adjust stat styles + wStatGap := m.width - wStatWithoutGap - (wBarAmount * wBar) + wStat := wStatAmount + wStatCategory + wStatGap + wStatLast + + sStat = sStat.Width(wStat + view.GetOuterWidth(sStat)).Height(m.height - view.GetOuterHeight(sStat)).MaxHeight(m.height - view.GetOuterHeight(sStat)) + sStatTitle = sStatTitle.Width(wStat) + sStatCategory = sStatCategory.Width(wStatCategory + wStatGap) +} diff --git a/tui/view/tap/tap.go b/tui/view/tap/tap.go index 499b030..814a33c 100644 --- a/tui/view/tap/tap.go +++ b/tui/view/tap/tap.go @@ -35,6 +35,9 @@ type Model struct { db *db.DB lastOrderID int32 items []tapItem + + width int + height int } // Msg represents a tap message @@ -67,6 +70,20 @@ func (m *Model) Name() string { // Update updates the tap model func (m *Model) Update(msg tea.Msg) (view.View, tea.Cmd) { switch msg := msg.(type) { + case view.MsgSize: + // Size update! + // Check if it's relevant for this view + entry, ok := msg.Sizes[m.Name()] + if ok { + // Update all dependent styles + m.width = entry.Width + m.height = entry.Height + + m.updateStyles() + } + + return m, nil + case Msg: m.lastOrderID = msg.lastOrderID @@ -102,9 +119,6 @@ func (m *Model) View() string { chart := m.viewChart() stats := m.viewStats() - // Give them same height - stats = sStats.Height(lipgloss.Height(chart)).Render(stats) - // Join them together view := lipgloss.JoinHorizontal(lipgloss.Top, chart, stats) return view diff --git a/tui/view/tap/view.go b/tui/view/tap/view.go index 65433ae..d5236f8 100644 --- a/tui/view/tap/view.go +++ b/tui/view/tap/view.go @@ -8,21 +8,21 @@ import ( ) func (m *Model) viewChart() string { - chart := barchart.New(widthBar, heightBar) + chart := barchart.New(sBar.GetWidth(), sBar.GetHeight(), barchart.WithNoAutoBarWidth(), barchart.WithBarGap(wBarGap), barchart.WithBarWidth(wBar)) bars := make([]barchart.BarData, 0, len(m.items)) for _, item := range m.items { style, ok := categoryToStyle[item.category] if !ok { - style = sUnknown + continue } bars = append(bars, barchart.BarData{ - Label: string(item.category), + Label: sBarLabel.Render(string(item.category)), Values: []barchart.BarValue{{ Name: string(item.category), Value: float64(item.amount), - Style: style, + Style: style.Inherit(sBarOne), }}, }) } @@ -37,9 +37,9 @@ func (m *Model) viewStats() string { rows := make([]string, 0, len(m.items)) for _, item := range m.items { - amount := sStatsAmount.Render(strconv.Itoa(item.amount)) - category := sStatsCategory.Inherit(categoryToStyle[item.category]).Render(string(item.category)) - last := sStatsLast.Render(item.last.Format("15:04 02/01")) + amount := sStatAmount.Render(strconv.Itoa(item.amount)) + category := sStatCategory.Inherit(categoryToStyle[item.category]).Render(string(item.category)) + last := sStatLast.Render(item.last.Format("15:04 02/01")) text := lipgloss.JoinHorizontal(lipgloss.Top, amount, category, last) rows = append(rows, text) @@ -48,8 +48,8 @@ func (m *Model) viewStats() string { view := lipgloss.JoinVertical(lipgloss.Left, rows...) // Add title - title := sStatsTitle.Render("Leaderboard") + title := sStatTitle.Render("Leaderboard") view = lipgloss.JoinVertical(lipgloss.Left, title, view) - return view + return sStat.Render(view) } diff --git a/tui/view/zess/style.go b/tui/view/zess/style.go index 874c9d9..790326c 100644 --- a/tui/view/zess/style.go +++ b/tui/view/zess/style.go @@ -19,11 +19,11 @@ var base = lipgloss.NewStyle() var ( // Widths wBarGap = 1 // Gap between bars - wBar = 5 // Width of a bar - wBarMin = 3 // Required for the bar label, for example 'W56' + wBar = 5 // Width of a bar, gets dynamically adjusted + wBarMin = 3 // Minimum width required for the bar label, for example 'W56' wBarAmountMax = 10 // Maximum amount of bars - sBar = base + sBar = base.MarginBottom(1) sBarOne = base sBarLabel = base.Align(lipgloss.Center) ) @@ -33,20 +33,16 @@ var ( // Widths wStatDate = 11 // 11 characters, for example 'W56 - 29/12' wStatAmount = 4 // Supports up to 9999 - wStatGapMin = 3 // Minumum gap size between the date and amount + wStatGapMin = 3 // Minimum gap size between the date and amount - sStat = base.BorderStyle(lipgloss.ThickBorder()).BorderForeground(cBorder).BorderLeft(true).MarginLeft(1).PaddingLeft(1) + sStat = base.BorderStyle(lipgloss.ThickBorder()).BorderForeground(cBorder).BorderLeft(true).Margin(0, 1, 1, 1).PaddingLeft(1) //.Align(lipgloss.Center) sStatTitle = base.Foreground(cStatsTitle).Bold(true).BorderStyle(lipgloss.NormalBorder()).BorderForeground(cBorder).BorderBottom(true).Align(lipgloss.Center).MarginBottom(1) sStatDate = base.Width(wStatDate) - sStatAmount = base.Width(wStatAmount) + sStatAmount = base.Width(wStatAmount).Align(lipgloss.Right) sStatTotal = base.BorderStyle(lipgloss.NormalBorder()).BorderForeground(cBorder).BorderTop(true).MarginTop(1) sStatTotalTitle = sStatDate.Bold(true) sStatTotalAmount = sStatAmount.Bold(true) -) - -// Styles for the max amount -var ( - sMax = base.Foreground(cZeus).Bold(true) + sStatMax = base.Foreground(cZeus).Bold(true) ) // Bar colors @@ -76,58 +72,29 @@ var colors = []string{ // updateStyles updates all the affected styles when a size update message is received func (m *Model) updateStyles() { - if m.width-wStatDate-wStatAmount-wStatGapMin < 0 { - // Screen is way too small + wStatWithoutGap := wStatDate + wStatAmount + view.GetOuterWidth(sStat) + if m.width-wStatWithoutGap-wStatGapMin < 0 { + // Screen is too small // Avoid entering an infinite loop down below return } // Adjust bar styles - wBar = wBarMin - wStatWithoutGap := wStatDate + wStatAmount + view.GetOuterWidth(sStat) for (m.width-wStatWithoutGap-wStatGapMin-wBarAmountMax*wBarGap)/wBar >= wBarAmountMax { wBar++ } bars := (m.width - wStatWithoutGap - wStatGapMin) / wBar - sBar = sBar.Width(bars * wBar).Height(m.height - view.GetOuterHeight(sBar)) + sBar = sBar.Width(bars*wBar + view.GetOuterWidth(sBar)).Height(m.height - view.GetOuterHeight(sBar)) sBarLabel = sBarLabel.Width(wBar) // Adjust stat styles wStatGap := m.width - wStatWithoutGap - (bars * wBar) wStat := wStatDate + wStatGap + wStatAmount - sStat = sStat.Width(wStat + view.GetOuterWidth(sStat)).Height(m.height).MaxHeight(m.height) + sStat = sStat.Width(wStat + view.GetOuterWidth(sStat)).Height(m.height - view.GetOuterHeight(sStat)).MaxHeight(m.height - view.GetOuterHeight(sStat)) sStatTitle = sStatTitle.Width(wStat) - sStatDate = sStatDate.Width(sStatDate.GetWidth() + wStatGap) + sStatDate = sStatDate.Width(wStatDate + wStatGap) sStatTotal = sStatTotal.Width(sStatTitle.GetWidth()) sStatTotalTitle = sStatTotalTitle.Width(sStatDate.GetWidth()) - } - -// // Width -// var ( -// widthAmount = 5 -// widthWeek = 8 -// ) - -// // Margin -// var mOverview = 2 - -// // Barchart -// var ( -// widthBar = 60 -// heightBar = 20 -// ) - -// // Styles stats -// var ( -// sStats = base.Border(lipgloss.NormalBorder(), false, false, false, true).BorderForeground(cBorder).MarginLeft(mOverview).PaddingLeft(mOverview) -// sStatsTitle = base.Foreground(cStatsTitle).Bold(true).Border(lipgloss.NormalBorder(), false, false, true, false).BorderForeground(cBorder).Width(widthAmount + widthWeek).Align(lipgloss.Center) -// sStatsWeek = base.Width(widthWeek) -// sStatsAmount = base.Bold(true).Width(widthAmount).Align(lipgloss.Right) -// sStatsAmountMax = sStatsAmount.Foreground(cZeus) -// sStatsTotal = base.Border(lipgloss.NormalBorder(), true, false, false, false).BorderForeground(cBorder).MarginTop(1) -// sStatsTotalTitle = sStatsWeek -// sStatsTotalAmount = sStatsAmount -// ) diff --git a/tui/view/zess/view.go b/tui/view/zess/view.go index e130254..54e0938 100644 --- a/tui/view/zess/view.go +++ b/tui/view/zess/view.go @@ -9,7 +9,7 @@ import ( ) func (m *Model) viewChart() string { - chart := barchart.New(sBar.GetWidth(), sBar.GetHeight(), barchart.WithNoAutoBarWidth(), barchart.WithBarGap(0), barchart.WithBarWidth(wBar)) + chart := barchart.New(sBar.GetWidth(), sBar.GetHeight(), barchart.WithNoAutoBarWidth(), barchart.WithBarGap(wBarGap), barchart.WithBarWidth(wBar)) for _, scan := range m.scans { bar := barchart.BarData{ @@ -38,7 +38,7 @@ func (m *Model) viewStats() string { var amount string if scan.amount == m.maxWeekScans { - amount = sMax.Inherit(sStatAmount).Render(strconv.Itoa(int(scan.amount))) + amount = sStatMax.Inherit(sStatAmount).Render(strconv.Itoa(int(scan.amount))) } else { amount = sStatAmount.Render(strconv.Itoa(int(scan.amount))) } diff --git a/tui/view/zess/zess.go b/tui/view/zess/zess.go index 34a0850..1eda17f 100644 --- a/tui/view/zess/zess.go +++ b/tui/view/zess/zess.go @@ -114,6 +114,7 @@ func (m *Model) Update(msg tea.Msg) (view.View, tea.Cmd) { } return m, nil + // New scan(s) case scanMsg: m.lastScanID = msg.lastScanID @@ -182,9 +183,6 @@ func (m *Model) View() string { chart := m.viewChart() stats := m.viewStats() - // // Give them the same height - // stats = sStat.Height(lipgloss.Height(chart)).Render(stats) - // Join them together view := lipgloss.JoinHorizontal(lipgloss.Top, chart, stats) return view