Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: release v2 #34

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
21 changes: 21 additions & 0 deletions cmd/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cmd

import (
"github.com/isabelroses/izrss/lib"
)

type context struct {
prev string
curr string
feeds lib.Feeds
post lib.Post
feed lib.Feed
}

func (m *Model) swapPage(next string) {
m.context.prev = m.context.curr
m.context.curr = next
if m.context.prev == "reader" {
m.viewport.Height = m.viewport.Height + 2
}
}
187 changes: 187 additions & 0 deletions cmd/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package cmd

// modified from https://github.com/charmbracelet/bubbles/blob/master/help/help.go
// I did this so it would be easier to pass context to the help model

import (
"strings"

"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/isabelroses/izrss/lib"
)

// KeyMap is a map of keybindings used to generate help. Since it's an
// interface it can be any type, though struct or a map[string][]key.Binding
// are likely candidates.
//
// Note that if a key is disabled (via key.Binding.SetEnabled) it will not be
// rendered in the help view, so in theory generated help should self-manage.
type KeyMap interface {
// ShortHelp returns a slice of bindings to be displayed in the short
// version of the help. The help bubble will render help in the order in
// which the help items are returned here.
ShortHelp(m Model) []key.Binding

// FullHelp returns an extended group of help items, grouped by columns.
// The help bubble will render the help in the order in which the help
// items are returned here.
FullHelp(m Model) [][]key.Binding
}

// KeyModel contains the state of the help view.
type KeyModel struct {
Style lipgloss.Style
ShortSeparator string
FullSeparator string
Ellipsis string
Width int
ShowAll bool
}

// New creates a new help view with some useful defaults.
func NewHelp() KeyModel {
return KeyModel{
ShortSeparator: " • ",
FullSeparator: " • ",
Ellipsis: "…",
Style: lib.HelpStyle,
}
}

// Update helps satisfy the Bubble Tea Model interface. It's a no-op.
func (m KeyModel) Update(_ tea.Msg) (KeyModel, tea.Cmd) {
return m, nil
}

// View renders the help view's current state.
func (km KeyModel) View(k KeyMap, m Model) string {
if km.ShowAll {
return km.FullHelpView(k.FullHelp(m))
}
return km.ShortHelpView(k.ShortHelp(m))
}

// ShortHelpView renders a single line help view from a slice of keybindings.
// If the line is longer than the maximum width it will be gracefully
// truncated, showing only as many help items as possible.
func (m KeyModel) ShortHelpView(bindings []key.Binding) string {
if len(bindings) == 0 {
return ""
}

var b strings.Builder
var totalWidth int
separator := m.Style.Inline(true).Render(m.ShortSeparator)

for i, kb := range bindings {
if !kb.Enabled() {
continue
}

var sep string
if totalWidth > 0 && i < len(bindings) {
sep = separator
}

str := sep +
m.Style.Inline(true).Render(kb.Help().Key) + " " +
m.Style.Inline(true).Render(kb.Help().Desc)

w := lipgloss.Width(str)

// If adding this help item would go over the available width, stop
// drawing.
if m.Width > 0 && totalWidth+w > m.Width {
// Although if there's room for an ellipsis, print that.
tail := " " + m.Style.Inline(true).Render(m.Ellipsis)
tailWidth := lipgloss.Width(tail)

if totalWidth+tailWidth < m.Width {
b.WriteString(tail)
}

break
}

totalWidth += w
b.WriteString(str)
}

return b.String()
}

// FullHelpView renders help columns from a slice of key binding slices. Each
// top level slice entry renders into a column.
func (m KeyModel) FullHelpView(groups [][]key.Binding) string {
if len(groups) == 0 {
return ""
}

// Linter note: at this time we don't think it's worth the additional
// code complexity involved in preallocating this slice.
//nolint:prealloc
var (
out []string

totalWidth int
sep = m.Style.Render(m.FullSeparator)
sepWidth = lipgloss.Width(sep)
)

// Iterate over groups to build columns
for i, group := range groups {
if group == nil || !shouldRenderColumn(group) {
continue
}

var (
keys []string
descriptions []string
)

// Separate keys and descriptions into different slices
for _, kb := range group {
if !kb.Enabled() {
continue
}
keys = append(keys, kb.Help().Key)
descriptions = append(descriptions, kb.Help().Desc)
}

col := lipgloss.JoinHorizontal(lipgloss.Top,
m.Style.Render(strings.Join(keys, "\n")),
m.Style.Render(" "),
m.Style.Render(strings.Join(descriptions, "\n")),
)

// Column
totalWidth += lipgloss.Width(col)
if m.Width > 0 && totalWidth > m.Width {
break
}

out = append(out, col)

// Separator
if i < len(group)-1 {
totalWidth += sepWidth
if m.Width > 0 && totalWidth > m.Width {
break
}
out = append(out, sep)
}
}

return lipgloss.JoinHorizontal(lipgloss.Top, out...)
}

func shouldRenderColumn(b []key.Binding) (ok bool) {
for _, v := range b {
if v.Enabled() {
return true
}
}
return false
}
Loading