Skip to content

Commit

Permalink
chore(zess): better dynamic scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
Topvennie committed Dec 22, 2024
1 parent 2e95a78 commit afe7e9f
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 67 deletions.
27 changes: 10 additions & 17 deletions tui/screen/cammie/cammie.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,20 @@ func (c *Cammie) View() string {

// Render top
// Render tabs
var topTabs []string
var tabs []string
for i, view := range c.top {
if i == c.indexTop {
topTabs = append(topTabs, sActiveTab.Render(view.Name()))
tabs = append(tabs, sActiveTab.Render(view.Name()))
} else {
topTabs = append(topTabs, sTabNormal.Render(view.Name()))
tabs = append(tabs, sTabNormal.Render(view.Name()))
}
}
topTab := lipgloss.JoinHorizontal(lipgloss.Bottom, topTabs...)
topTabsLine := sTabNormal.Render(strings.Repeat(" ", max(0, (c.width/2)-lipgloss.Width(topTab)-10)))
topTab = lipgloss.JoinHorizontal(lipgloss.Bottom, topTab, topTabsLine)
tab := lipgloss.JoinHorizontal(lipgloss.Bottom, tabs...)
tabLine := sTabNormal.Render(strings.Repeat(" ", max(0, sTop.GetWidth()-lipgloss.Width(tab)-2))) // -2 comes from sTab padding
tab = lipgloss.JoinHorizontal(lipgloss.Bottom, tab, tabLine)

// Render top view
top := lipgloss.JoinVertical(lipgloss.Left, topTab, c.top[c.indexTop].View())
top := lipgloss.JoinVertical(lipgloss.Left, tab, c.top[c.indexTop].View())
top = sTop.Render(top)

// Render bottom
Expand Down Expand Up @@ -144,18 +144,11 @@ func (c *Cammie) GetUpdateViews() []view.UpdateData {
func (c *Cammie) GetSizeMsg() tea.Msg {
sizes := make(map[string]view.Size)

msgW := sMsg.GetWidth()
msgH := sMsg.GetHeight()
sizes[c.messages.Name()] = view.Size{Width: msgW, Height: msgH}

bottomW := sBottom.GetWidth()
bottomH := sBottom.GetHeight()
sizes[c.bottom.Name()] = view.Size{Width: bottomW, Height: bottomH}
sizes[c.messages.Name()] = view.Size{Width: sMsg.GetWidth(), Height: sMsg.GetHeight()}
sizes[c.bottom.Name()] = view.Size{Width: sBottom.GetWidth(), Height: sBottom.GetHeight()}

for _, top := range c.top {
topW := sTop.GetWidth()
topH := sTop.GetHeight()
sizes[top.Name()] = view.Size{Width: topW, Height: topH}
sizes[top.Name()] = view.Size{Width: sTop.GetWidth(), Height: sTop.GetHeight() - view.GetOuterHeight(sTop) - view.GetOuterHeight(sTab)}
}

return view.MsgSize{Sizes: sizes}
Expand Down
2 changes: 1 addition & 1 deletion tui/view/song/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var base = lipgloss.NewStyle()
var (
// Widths
wStatEnum = 3
wStatAmount = 4
wStatAmount = 4 // Supports up to 1000
wStatEntryMax = 35

// Styles
Expand Down
124 changes: 94 additions & 30 deletions tui/view/zess/style.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,55 @@
package zess

import "github.com/charmbracelet/lipgloss"
import (
"github.com/charmbracelet/lipgloss"
"github.com/zeusWPI/scc/tui/view"
)

// Colors
var (
cBorder = lipgloss.Color("#383838")
cZeus = lipgloss.Color("#FF7F00")
cStatsTitle = lipgloss.Color("#EE4B2B")
)

// Base style
var base = lipgloss.NewStyle()

// Width
// Styles for the barchart
var (
widthAmount = 5
widthWeek = 8
)
// Widths
wBarGap = 1 // Gap between bars
wBar = 5 // Width of a bar
wBarMin = 3 // Required for the bar label, for example 'W56'
wBarAmountMax = 10 // Maximum amount of bars

// Margin
var mOverview = 2
sBar = base
sBarOne = base
sBarLabel = base.Align(lipgloss.Center)
)

// Barchart
// Styles for the stats
var (
widthBar = 60
heightBar = 20
// 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

sStat = base.BorderStyle(lipgloss.ThickBorder()).BorderForeground(cBorder).BorderLeft(true).MarginLeft(1).PaddingLeft(1)
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)
sStatTotal = base.BorderStyle(lipgloss.NormalBorder()).BorderForeground(cBorder).BorderTop(true).MarginTop(1)
sStatTotalTitle = sStatDate.Bold(true)
sStatTotalAmount = sStatAmount.Bold(true)
)

// Colors
// Styles for the max amount
var (
cBorder = lipgloss.Color("#383838")
cZeus = lipgloss.Color("#FF7F00")
cStatsTitle = lipgloss.Color("#EE4B2B")
sMax = base.Foreground(cZeus).Bold(true)
)

// Message colors
// Bar colors
var colors = []string{
"#FAF500", // Yellow
"#3AFA00", // Green
Expand All @@ -51,19 +74,60 @@ var colors = []string{
"#B3D2F9", // Boring Blue
}

// Styles chart
var (
sBar = base
)
// 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
// Avoid entering an infinite loop down below
return
}

// 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
)
// 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))
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)
sStatTitle = sStatTitle.Width(wStat)
sStatDate = sStatDate.Width(sStatDate.GetWidth() + 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
// )
25 changes: 13 additions & 12 deletions tui/view/zess/view.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package zess

import (
"fmt"
"strconv"

"github.com/NimbleMarkets/ntcharts/barchart"
"github.com/charmbracelet/lipgloss"
)

func (m *Model) viewChart() string {
chart := barchart.New(widthBar, heightBar)
chart := barchart.New(sBar.GetWidth(), sBar.GetHeight(), barchart.WithNoAutoBarWidth(), barchart.WithBarGap(0), barchart.WithBarWidth(wBar))

for _, scan := range m.scans {
bar := barchart.BarData{
Label: scan.label,
Label: sBarLabel.Render(fmt.Sprintf("W%d", scan.time.week)),
Values: []barchart.BarValue{{
Name: scan.label,
Name: scan.start,
Value: float64(scan.amount),
Style: sBar.Foreground(lipgloss.Color(scan.color)),
Style: sBarOne.Foreground(lipgloss.Color(scan.color)),
}},
}

Expand All @@ -33,13 +34,13 @@ func (m *Model) viewStats() string {
rows := make([]string, 0, len(m.scans))

for _, scan := range m.scans {
week := sStatsWeek.Render(scan.label)
week := sStatDate.Render(fmt.Sprintf("W%d - %s", scan.time.week, scan.start))

var amount string
if scan.amount == m.maxWeekScans {
amount = sStatsAmountMax.Render(strconv.Itoa(int(scan.amount)))
amount = sMax.Inherit(sStatAmount).Render(strconv.Itoa(int(scan.amount)))
} else {
amount = sStatsAmount.Render(strconv.Itoa(int(scan.amount)))
amount = sStatAmount.Render(strconv.Itoa(int(scan.amount)))
}

text := lipgloss.JoinHorizontal(lipgloss.Top, week, amount)
Expand All @@ -49,15 +50,15 @@ func (m *Model) viewStats() string {
view := lipgloss.JoinVertical(lipgloss.Left, rows...)

// Title
title := sStatsTitle.Render("Overview")
title := sStatTitle.Render("Overview")

// Total scans
total := sStatsTotalTitle.Render("Total")
amount := sStatsTotalAmount.Render(strconv.Itoa(int(m.seasonScans)))
total := sStatTotalTitle.Render("Total")
amount := sStatTotalAmount.Render(strconv.Itoa(int(m.seasonScans)))
total = lipgloss.JoinHorizontal(lipgloss.Top, total, amount)
total = sStatsTotal.Render(total)
total = sStatTotal.Render(total)

view = lipgloss.JoinVertical(lipgloss.Left, title, view, total)

return view
return sStat.Render(view)
}
30 changes: 23 additions & 7 deletions tui/view/zess/zess.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"go.uber.org/zap"
)

// yearWeek represents a yearWeek object by keeping the year and week number
// yearWeek is used to represent a date by it's year and week
type yearWeek struct {
year int
week int
Expand All @@ -23,7 +23,7 @@ type yearWeek struct {
type weekScan struct {
time yearWeek
amount int64
label string
start string // The date when the week starts
color string
}

Expand All @@ -36,6 +36,9 @@ type Model struct {
maxWeekScans int64
currentSeason yearWeek // Start week of the season
seasonScans int64

width int
height int
}

// Msg is the base message to indicate that something changed in the zess view
Expand Down Expand Up @@ -98,6 +101,19 @@ func (m *Model) Name() string {
// Update updates the zess 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
// New scan(s)
case scanMsg:
m.lastScanID = msg.lastScanID
Expand Down Expand Up @@ -164,13 +180,13 @@ func (m *Model) Update(msg tea.Msg) (view.View, tea.Cmd) {
// View returns the view for the zess model
func (m *Model) View() string {
chart := m.viewChart()
overview := m.viewStats()
stats := m.viewStats()

// Give them the same height
overview = sStats.Height(lipgloss.Height(chart)).Render(overview)
// // Give them the same height
// stats = sStat.Height(lipgloss.Height(chart)).Render(stats)

// Join them together
view := lipgloss.JoinHorizontal(lipgloss.Top, chart, overview)
view := lipgloss.JoinHorizontal(lipgloss.Top, chart, stats)
return view
}

Expand Down Expand Up @@ -232,7 +248,7 @@ func updateScans(view view.View) (tea.Msg, error) {
zessScanMsg.scans = append(zessScanMsg.scans, weekScan{
time: newTime,
amount: 1,
label: newScan.ScanTime.Time.Format("02/01"),
start: newScan.ScanTime.Time.Format("02/01"),
color: randomColor(),
})
}
Expand Down

0 comments on commit afe7e9f

Please sign in to comment.