diff --git a/ui/stash.go b/ui/stash.go index 74b1824..a0ee9de 100644 --- a/ui/stash.go +++ b/ui/stash.go @@ -4,7 +4,6 @@ import ( "fmt" "math" "sort" - "strconv" "strings" "time" @@ -27,13 +26,6 @@ const ( setNotePromptText = "Memo: " ) -var ( - faintGreen = common.NewColorPair("#2B4A3F", "#ABE5D1") - green = common.NewColorPair("#04B575", "#04B575") - dullYellow = common.NewColorPair("#9BA92F", "#6CCCA9") // renders light green on light backgrounds - dullFuchsia = common.NewColorPair("#AD58B4", "#F9ACFF") -) - // MSG type stashSpinnerTickMsg struct{} @@ -437,7 +429,7 @@ func stashView(m stashModel) string { } s += fmt.Sprintf( - "%s\n\n%s\n\n%s\n\n%s%s\n\n%s", + " %s\n\n %s\n\n%s\n\n%s %s\n\n %s", glowLogoView(" Glow "), header, stashPopulatedView(m), @@ -446,7 +438,7 @@ func stashView(m stashModel) string { stashHelpView(m), ) } - return "\n" + indent.String(s, 2) + return "\n" + indent.String(s, 1) } func glowLogoView(text string) string { @@ -467,21 +459,10 @@ func stashPopulatedView(m stashModel) string { start, end := m.paginator.GetSliceBounds(len(m.markdowns)) docs := m.markdowns[start:end] - for i, v := range docs { - state := markdownStateNormal - if i == m.index { - switch m.state { - case stashStatePromptDelete: - state = markdownStateDeleting - case stashStateSettingNote: - state = markdownStateSettingNote - default: - state = markdownStateSelected - } - } - s += stashListItemView(*v).render(m, state) + "\n\n" + for i, md := range docs { + s += stashItemView(m, i, md) + "\n\n" } - s = strings.TrimSpace(s) // trim final newlines + s = strings.TrimRight(s, "\n") // If there aren't enough items to fill up this page (always the last page) // then we need to add some newlines to fill up the space to push the @@ -521,97 +502,6 @@ func stashHelpView(m stashModel) string { return common.HelpView(h...) } -// markdownState is used in a deterministic fashion to aid rendering stash item -// views. -type markdownState int - -const ( - markdownStateNormal markdownState = iota - markdownStateSelected - markdownStateDeleting - markdownStateSettingNote -) - -// stashListItemView contains methods for rendering an item as it appears in -// the stash view -type stashListItemView markdown - -func (m stashListItemView) render(mdl stashModel, state markdownState) string { - - // General key color - keyColor := common.NoColor - line := common.VerticalLine(common.StateNormal) - switch state { - case markdownStateSettingNote: - keyColor = common.YellowGreen - line = common.VerticalLine(common.StateActive) - case markdownStateSelected: - keyColor = common.Fuschia - line = common.VerticalLine(common.StateSelected) - case markdownStateDeleting: - keyColor = common.Red - line = common.VerticalLine(common.StateDeleting) - default: - if m.markdownType == newsMarkdown { - keyColor = common.Green - } - } - - titleKey := "#" + strconv.Itoa(m.ID) - if state == markdownStateSettingNote { - titleKey = textinput.View(mdl.noteInput) - } else { - if m.markdownType == newsMarkdown { - titleKey = "System Announcement" - } - if m.Note != "" { - titleKey += ":" - } - } - - dateKey := "Stashed:" - if m.markdownType == newsMarkdown { - dateKey = "Posted:" - } - - var titleVal string - if state != markdownStateSettingNote { - titleVal = truncate(m.Note, mdl.terminalWidth-(stashViewHorizontalPadding*2)-len(titleKey)) - titleVal = m.title(titleVal, state) - } - - titleKey = te.String(titleKey).Foreground(keyColor.Color()).String() - dateKey = te.String(dateKey).Foreground(keyColor.Color()).String() - dateVal := m.date(state) - - var s string - s += fmt.Sprintf("%s %s %s\n", line, titleKey, titleVal) - s += fmt.Sprintf("%s %s %s", line, dateKey, dateVal) - return s -} - -func (m stashListItemView) date(state markdownState) string { - c := common.Indigo - if state == markdownStateDeleting { - c = common.FaintRed - } else if state == markdownStateSettingNote { - c = dullYellow - } - s := relativeTime(*m.CreatedAt) - return te.String(s).Foreground(c.Color()).String() -} - -func (m stashListItemView) title(title string, state markdownState) string { - if title == "" { - return "" - } - c := common.Indigo - if state == markdownStateDeleting { - c = common.Red - } - return te.String(title).Foreground(c.Color()).String() -} - // CMD func loadStash(m stashModel) boba.Cmd { diff --git a/ui/stashitem.go b/ui/stashitem.go new file mode 100644 index 0000000..9615a5b --- /dev/null +++ b/ui/stashitem.go @@ -0,0 +1,82 @@ +package ui + +import ( + "fmt" + + "github.com/charmbracelet/boba/textinput" + "github.com/charmbracelet/charm/ui/common" + te "github.com/muesli/termenv" +) + +const ( + newsPrefix = "News: " + verticalLine = "│" + noMemoTitle = "No Memo" +) + +var ( + faintGreen = common.NewColorPair("#2B4A3F", "#ABE5D1") + green = common.NewColorPair("#04B575", "#04B575") + dullFuchsia = common.NewColorPair("#AD58B4", "#F793FF") + dullYellow = common.NewColorPair("#9BA92F", "#6BCB94") // renders light green on light backgrounds + warmGray = common.NewColorPair("#918892", "#847A85") + subtleIndigo = common.NewColorPair("#514DC1", "#7D79F6") +) + +func stashItemView(m stashModel, index int, md *markdown) string { + truncateTo := m.terminalWidth - stashViewHorizontalPadding*2 + + gutter := " " + title := md.Note + date := relativeTime(*md.CreatedAt) + + if md.markdownType == newsMarkdown { + if title == "" { + title = "News" + } else { + title = newsPrefix + truncate(title, truncateTo-len(newsPrefix)) + } + } else { + if title == "" { + title = noMemoTitle + } + title = truncate(title, truncateTo) + } + + if index == m.index { + switch m.state { + case stashStatePromptDelete: + // Deleting + gutter = te.String(verticalLine).Foreground(common.FaintRed.Color()).String() + title = te.String(title).Foreground(common.Red.Color()).String() + date = te.String(date).Foreground(common.FaintRed.Color()).String() + case stashStateSettingNote: + // Setting note + gutter = te.String(verticalLine).Foreground(dullYellow.Color()).String() + title = textinput.View(m.noteInput) + date = te.String(date).Foreground(dullYellow.Color()).String() + default: + // Selected + gutter = te.String(verticalLine).Foreground(dullFuchsia.Color()).String() + title = te.String(title).Foreground(common.Fuschia.Color()).String() + date = te.String(date).Foreground(dullFuchsia.Color()).String() + } + } else { + // Normal + if md.markdownType == newsMarkdown { + gutter = " " + title = te.String(title).Foreground(common.Indigo.Color()).String() + date = te.String(date).Foreground(subtleIndigo.Color()).String() + } else { + if title == noMemoTitle { + title = te.String(title).Foreground(warmGray.Color()).String() + } + gutter = " " + date = te.String(date).Foreground(warmGray.Color()).String() + } + } + + s := fmt.Sprintf("%s %s\n", gutter, title) + s += fmt.Sprintf("%s %s", gutter, date) + return s +}